aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-29 09:52:21 -0700
committerAdam Soltys <[email protected]>2026-10-29 09:52:21 -0700
commit0677a8b3357ffb12537081df919a7251bf63e3d4 (patch)
treefa1eb73101187580e58b7dadd871f326673118a5 /tools
parent01b6c11555bb9a131dbcabe897327a9f928ccf1b (diff)
downloadcoinosv3-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.js23
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