diff options
| author | Adam Soltys <[email protected]> | 2026-10-23 08:12:40 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-10-23 08:12:40 -0700 |
| commit | 91dbee408ad59ef4eb85dbec3eff4d512c9b4792 (patch) | |
| tree | c5337468eff5661658787032db57e89d95f6ac4f /tools/nwc-sw-test.js | |
| parent | 6c3b49a559c90954bf5ae6dbfada73ec5b3409cc (diff) | |
| download | coinosv3-91dbee408ad59ef4eb85dbec3eff4d512c9b4792.tar.gz coinosv3-91dbee408ad59ef4eb85dbec3eff4d512c9b4792.zip | |
Push handler: a notification the platform refuses is retried plain and never counts as shown
PullCap's iPhone paid four times overnight with the "payments sent"
notifications on and never showed a "Payment sent" line. The worker hands
the handler the heads-up (covered by a test now); the handler flagged the
push as answered BEFORE calling showNotification, so a refusal left the
push with no line at all — on iOS a silent push, a strike towards losing
the subscription. Now the flag follows success, a refused notification is
retried with the plainest options, and the stand-in covers the rest. iOS
never replaces by tag, so renotify is left out there.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Diffstat (limited to 'tools/nwc-sw-test.js')
| -rw-r--r-- | tools/nwc-sw-test.js | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/tools/nwc-sw-test.js b/tools/nwc-sw-test.js index f037275..1ce9944 100644 --- a/tools/nwc-sw-test.js +++ b/tools/nwc-sw-test.js @@ -178,6 +178,31 @@ const INV21 = 'lnbc210n1p4xuk2wpp506wkjr0xk3677nu7je9c55vq4lzlkyd0ztcq2mlvumap0z check('exhausted key window → wake the user', handled === false); } +console.log('\n[pay outcome]'); +{ + // a payment that goes through: the worker hands the push handler a + // "Payment sent" heads-up (unless the user turned those off) + const { ArkManager } = await import('../src/ark/manager.js'); + const orig = { init: ArkManager.prototype.init, pay: ArkManager.prototype.payLnInvoice, wait: ArkManager.prototype.awaitLnPay, act: ArkManager.prototype.lnAction }; + const done = { id: 'ln-1', step: 'done', amountSat: 21, feeSat: 0, preimage: 'ab'.repeat(32) }; + ArkManager.prototype.init = async function () { this.state = this.storage.load(); return this; }; + ArkManager.prototype.payLnInvoice = async () => 'ln-1'; + ArkManager.prototype.awaitLnPay = async () => done; + ArkManager.prototype.lnAction = () => done; + try { + const { deps, published, decryptReply } = harness(); + const handled = await respondFromBg({ type: 'nwc', event: ev(makeReq('pay_invoice', { invoice: INV21 })) }, deps); + check('a paid invoice answers with the preimage', published.length === 1 && decryptReply(published[0]).result?.preimage === done.preimage, JSON.stringify(handled)); + check('…and asks for a "Payment sent" notification', handled && handled.notify && handled.notify.title === 'Payment sent', JSON.stringify(handled)); + const rec = baseRec(); rec.prefs = { paySent: false }; + const h2 = harness({ rec }); + const quiet = await respondFromBg({ type: 'nwc', event: ev(makeReq('pay_invoice', { invoice: INV21 })) }, h2.deps); + check('payments-sent notifications off → paid quietly', quiet === true && h2.published.length === 1); + } finally { + Object.assign(ArkManager.prototype, { init: orig.init, payLnInvoice: orig.pay, awaitLnPay: orig.wait, lnAction: orig.act }); + } +} + console.log('\n[network fit]'); { // a mutinynet-era mirror must not answer a mainnet invoice with a nonsense |
