diff options
| author | Adam Soltys <[email protected]> | 2026-10-29 09:52:21 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-10-29 09:52:21 -0700 |
| commit | 0677a8b3357ffb12537081df919a7251bf63e3d4 (patch) | |
| tree | fa1eb73101187580e58b7dadd871f326673118a5 /tools | |
| parent | 01b6c11555bb9a131dbcabe897327a9f928ccf1b (diff) | |
| download | coinosv3-0677a8b3357ffb12537081df919a7251bf63e3d4.tar.gz coinosv3-0677a8b3357ffb12537081df919a7251bf63e3d4.zip | |
A closed wallet whose payment fails now says so: the error (INSUFFICIENT_BALANCE or PAYMENT_FAILED, with the reason) is left with the notifier at once and goes out unless someone answers within 5 s. Waiting the grace period out in the worker ran past iOS's ten seconds after a failed send, so the other app heard nothing (PullCap, 2026-10-29). A Lightning send no longer picks a coin at the server's depth cap, so such a coin fails here with a reason instead of at the ASP; a capped coin under 330 sats (a round won't take it) says to receive more instead of "waiting to be renewed", and the worker stops booking renewals the server would refuse as dust
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6TUeqTyZB8eXLGymUY
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/nwc-sw-test.js | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/tools/nwc-sw-test.js b/tools/nwc-sw-test.js index 376a12e..7e85ee1 100644 --- a/tools/nwc-sw-test.js +++ b/tools/nwc-sw-test.js @@ -317,6 +317,29 @@ console.log('\n[sends begun on an earlier wake]'); } } +console.log('\n[a send that fails]'); +// The ASP refused the cosign (a coin at the depth cap, PullCap 2026-10-29): +// the error is left with the notifier at once, not waited out in a worker +// iOS stops before it speaks. +{ + const { ArkManager } = await import('../src/ark/manager.js'); + const names = ['init', 'payLnInvoice']; + const orig = Object.fromEntries(names.map((k) => [k, ArkManager.prototype[k]])); + ArkManager.prototype.init = async function () { this.state = this.storage.load(); return this; }; + try { + for (const [why, code] of [ + ['insufficient ark balance (259 sat have a history too long to spend and are too few to renew; receive more to keep paying)', 'INSUFFICIENT_BALANCE'], + ['ln-pay failed: route not found', 'PAYMENT_FAILED'], + ]) { + ArkManager.prototype.payLnInvoice = async function () { throw new Error(why); }; + const { deps, published, declined, decryptReply } = harness(); + const handled = await respondFromBg({ type: 'nwc', event: ev(makeReq('pay_invoice', { invoice: INV21 })) }, { ...deps, errGraceMs: 60_000 }); + const r = declined.length ? decryptReply(declined[0]) : null; + check(`${code}: the error is handed to the notifier, nothing waited out here`, handled === true && declined.length === 1 && !published.length && r.error?.code === code && r.error.message === why, JSON.stringify(r)); + } + } finally { Object.assign(ArkManager.prototype, orig); } +} + console.log('\n[network fit]'); { // a mutinynet-era mirror must not answer a mainnet invoice with a nonsense |
