aboutsummaryrefslogtreecommitdiffstats
path: root/src/ark
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-08-28 21:08:33 -0700
committerAdam Soltys <[email protected]>2026-08-28 21:08:33 -0700
commit065d50b3ef553f540c6471c60abd804abed61b28 (patch)
tree6f0661549ad23464d8c95b171c1da9e87d90668c /src/ark
parentf13acc1bf4ffa3d0e2733dc53041bbc61659a5af (diff)
downloadcoinosv3-065d50b3ef553f540c6471c60abd804abed61b28.tar.gz
coinosv3-065d50b3ef553f540c6471c60abd804abed61b28.zip
One payment, one line: the settle path is idempotent (the mailbox push and the status poll raced past each other's step checks — a toque got two history entries), movements carry their payment hash, and the sync merge folds same-preimage lightning records into the earliest telling
Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_019eA8JRq9Wr7z2fRQk99HLi
Diffstat (limited to 'src/ark')
-rw-r--r--src/ark/manager.js10
1 files changed, 8 insertions, 2 deletions
diff --git a/src/ark/manager.js b/src/ark/manager.js
index a2c69d8..cfb7436 100644
--- a/src/ark/manager.js
+++ b/src/ark/manager.js
@@ -990,16 +990,22 @@ export class ArkManager {
}
_settleLnPay(action, preimageHex) {
+ // The mailbox push and the status poll both land here, and their step
+ // checks happen BEFORE awaits — settle once, however many callers race
+ // (a hat purchase once wrote its history line twice this way).
+ if (action.step === 'done') return;
for (const id of action.htlcVtxoIds || [action.htlcVtxoId]) {
const htlc = this._vtxo(id);
if (htlc) htlc.state = 'spent';
}
action.preimage = preimageHex;
action.step = 'done';
- this._movement({
+ const dup = this.state.movements.some((m) =>
+ m.type === 'ln-send' && (m.paymentHash === action.paymentHash || (m.preimage && m.preimage === preimageHex)));
+ if (!dup) this._movement({
type: 'ln-send', amountSat: action.amountSat, status: 'complete',
detail: action.feeSat ? `fee ${action.feeSat} sat` : undefined,
- invoice: action.invoice, preimage: preimageHex,
+ invoice: action.invoice, preimage: preimageHex, paymentHash: action.paymentHash,
});
this._save();
}