aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-09 16:24:58 -0700
committerAdam Soltys <[email protected]>2026-10-09 16:24:58 -0700
commit20369cae83fe02968ac4318f3b8f4e9dcbbaa1cf (patch)
tree569afd7b137500087f2517fd04b545f4639a967b /tools
parent52612bc8bc4c9ea18b0520fc23c98094f304cc05 (diff)
downloadcoinosv3-20369cae83fe02968ac4318f3b8f4e9dcbbaa1cf.tar.gz
coinosv3-20369cae83fe02968ac4318f3b8f4e9dcbbaa1cf.zip
Spending: a Lightning receive is one row. The ASP settles it as an arkoor the wallet claims — recorded as ln-receive, without its coin's id — and the same coin can reach the mailbox too, which (seeing no movement for that coin) recorded a plain receive as well: two "Received 1,005" rows and a "Payment received! 2,010" (The Daniel). The claim now stamps its coins' ids on the ln-receive, the mailbox backfill counts them, and lnFoldedIds leaves a receive of a claimed coin out of history, the celebration, the arkMovements hook and the LN tagging — derived at read time, never deleted, so a synced copy can't bring the twin back. Claims recorded before the stamp match by amount within ten minutes. tools/ln-receive-twin-test.js
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Vps2H27rhbG9ZqseGfMrc3
Diffstat (limited to 'tools')
-rw-r--r--tools/ln-receive-twin-test.js31
1 files changed, 31 insertions, 0 deletions
diff --git a/tools/ln-receive-twin-test.js b/tools/ln-receive-twin-test.js
new file mode 100644
index 0000000..bbec971
--- /dev/null
+++ b/tools/ln-receive-twin-test.js
@@ -0,0 +1,31 @@
+// One Lightning receive, told twice: the claim's ln-receive and the mailbox's
+// plain receive of the same coin (The Daniel: two "Received 1,005" rows and a
+// 2,010 celebration). lnFoldedIds names the twin; nothing else is folded.
+// Run: bun tools/ln-receive-twin-test.js
+import { lnFoldedIds } from '../src/ark/manager.js';
+let ok = true;
+const check = (n, c, d = '') => { console.log(` ${c ? '✓' : '✗'} ${n}${d ? ' — ' + d : ''}`); if (!c) ok = false; };
+const T = 1_790_000_000_000;
+const rcv = (id, sat, ts, extra = {}) => ({ id, type: 'receive', status: 'complete', amountSat: sat, ts, vtxoId: 'v-' + id, ...extra });
+const ln = (id, sat, ts, extra = {}) => ({ id, type: 'ln-receive', status: 'complete', amountSat: sat, ts, ...extra });
+
+let f = lnFoldedIds([ln('L', 1005, T, { vtxoIds: ['v-R'] }), rcv('R', 1005, T + 900)]);
+check('a claim stamped with its coin folds the mailbox\'s receive of it', f.has('R') && f.size === 1);
+f = lnFoldedIds([rcv('R', 1005, T - 400), ln('L', 1005, T, { vtxoIds: ['v-R'] })]);
+check('...whichever came first', f.has('R'));
+f = lnFoldedIds([ln('L', 1005, T, { vtxoIds: ['v-X'] }), rcv('R', 1005, T + 900)]);
+check('a stamped claim never folds some other coin of the same amount', f.size === 0);
+f = lnFoldedIds([ln('L', 1005, T), rcv('R', 1005, T + 60_000)]);
+check('an unstamped (older) claim folds the same amount within minutes', f.has('R'));
+f = lnFoldedIds([ln('L', 1005, T), rcv('R', 1005, T + 30 * 60_000)]);
+check('...not half an hour apart', f.size === 0);
+f = lnFoldedIds([ln('L', 1005, T), rcv('R', 1006, T + 1000)]);
+check('...nor a different amount', f.size === 0);
+f = lnFoldedIds([ln('L', 1005, T), rcv('R', 1005, T + 1000, { viaLn: true })]);
+check('...nor a name@ receive the registrar\'s receipts claimed', f.size === 0);
+f = lnFoldedIds([ln('L1', 500, T), ln('L2', 500, T + 5000), rcv('R1', 500, T + 1000), rcv('R2', 500, T + 6000)]);
+check('two claims of one amount fold one receive each', f.has('R1') && f.has('R2') && f.size === 2);
+f = lnFoldedIds([rcv('R', 1005, T), rcv('S', 2000, T)]);
+check('plain receives with no claim stay', f.size === 0);
+console.log(ok ? '\n✅ a claimed LN receive is told once' : '\n❌ failed');
+process.exit(ok ? 0 : 1);