diff options
| author | Adam Soltys <[email protected]> | 2026-10-22 22:06:01 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-10-22 22:06:01 -0700 |
| commit | f4997d29a0c97eac61338448854c7ab9724cdc92 (patch) | |
| tree | 14f2d56a06bd4bfb093c6bb5f6a21a0321de1dfa /tools/nwc-sw-test.js | |
| parent | 648a5503089d33232855925a24ff60f78cab6df4 (diff) | |
| download | coinosv3-f4997d29a0c97eac61338448854c7ab9724cdc92.tar.gz coinosv3-f4997d29a0c97eac61338448854c7ab9724cdc92.zip | |
The third custody tier keeps exits cheap by depth, not by date: "Keep my exit cheap" renews a coin once its history is four hops deep
Why: a unilateral exit publishes one on-chain transaction per off-chain hop, so depth — not age — is what makes an exit expensive, and a renewal a week before expiry flattens exactly the same history a renewal in the last hours does. The week-ahead "early" tier only guarded against the server being unreachable at the very end, which is not the case worth selling. (Adam, 2026-10-23.)
exit = self (last-hours renewal, free bracket + base, the same grid-snapped backstop) plus: any coin whose genesis chain is 4+ hops deep is renewed in the next round the app runs, paying the top bracket + base — but only when that fee is under a tenth of the coin (flattening a 21-sat coin for 300 sats helps nobody; its exit is uneconomic anyway). Deep coins ride along with an expiry renewal when one is due, or get a round of their own. The server-side backstop stays near-expiry only: depth changes only while the wallet transacts, i.e. while the app is open. A stored 'early' reads as 'exit'. Card copy says what the hop count means and what the two prices are for.
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 | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/tools/nwc-sw-test.js b/tools/nwc-sw-test.js index 2d07963..f037275 100644 --- a/tools/nwc-sw-test.js +++ b/tools/nwc-sw-test.js @@ -360,9 +360,9 @@ console.log('\n[tending renewals while closed]'); await tendRenewals({ recordsFn: async () => [{ walletKey: 'w6', rec: rec6 }], saveFn: async () => {} }); check('custodial (default, or a mirror without the field) → claims only, no orders', JSON.stringify(calls) === JSON.stringify([['init', 'mainnet'], ['tip'], ['drive', 0]]), JSON.stringify(calls)); calls.length = 0; - const rec7 = baseRec(); rec7.key4 = 'ff'.repeat(32); rec7.custody = 'early'; rec7.mgr.nextKeyIndex = 5; rec7.keys = { 1: 'aa', 5: 'bb' }; + const rec7 = baseRec(); rec7.key4 = 'ff'.repeat(32); rec7.custody = 'exit'; rec7.mgr.nextKeyIndex = 5; rec7.keys = { 1: 'aa', 5: 'bb' }; await tendRenewals({ recordsFn: async () => [{ walletKey: 'w7', rec: rec7 }], saveFn: async () => {} }); - check('early tier → a week ahead on the daily grid', JSON.stringify(calls) === JSON.stringify([['init', 'mainnet'], ['tip'], ['drive', 0], ['ensure', 1008, 1, 144]]), JSON.stringify(calls)); + check('exit tier → the same backstop as self (depth is the app\'s business)', JSON.stringify(calls) === JSON.stringify([['init', 'mainnet'], ['tip'], ['drive', 0], ['ensure', 36, 1, 48]]), JSON.stringify(calls)); calls.length = 0; const rec2 = baseRec(); rec2.key4 = 'ff'.repeat(32); rec2.custody = 'self'; rec2.ark.network = 'regtest'; rec2.mgr.nextKeyIndex = 9; rec2.keys = { 1: 'aa' }; // no upcoming key |
