aboutsummaryrefslogtreecommitdiffstats
path: root/names
diff options
context:
space:
mode:
Diffstat (limited to 'names')
-rw-r--r--names/server.js22
1 files changed, 20 insertions, 2 deletions
diff --git a/names/server.js b/names/server.js
index f8fa378..f2a9f41 100644
--- a/names/server.js
+++ b/names/server.js
@@ -440,7 +440,24 @@ async function forwardOnce(name, sat, hash, pubkey) {
// 2026-10-27 ("crit1 … double payout", ~5M). So: done is done, still out
// is wait, and only a payment that really failed is tried again.
const sent = hash && state.inflight?.[hash];
- if (sent) {
+ // ...and the same for a float send: one that threw can still have moved
+ // the coins (the cosign landed, the answer didn't). The float wallet keeps
+ // every send as an action; the one made for this payment says what it did.
+ if (sent?.float) {
+ const acts = (fwd?.state?.actions || []).filter((a) => a.type === 'send' && a.destAddress === sent.dest
+ && a.amountSat === sent.sat && Number(String(a.id).slice(5).replace(/-+$/, '')) >= sent.after);
+ if (acts.some((a) => a.step === 'done')) {
+ delete state.inflight[hash];
+ recordLnReceipt(name, sat, hash);
+ persist();
+ log(`delivered ${sat} sat to ${name}: the earlier float send completed`);
+ return;
+ }
+ if (acts.some((a) => a.step !== 'failed')) throw new Error('float send for this payment still unresolved — not paying again');
+ log(`forward: the earlier float send for ${name} ${acts.length ? 'failed' : 'never started'} — trying again`);
+ delete state.inflight[hash];
+ persist();
+ } else if (sent) {
const pays = (await ln.call('listpays', { payment_hash: sent.paymentHash })).pays || [];
if (pays.some((x) => x.status === 'complete')) {
delete state.inflight[hash];
@@ -465,7 +482,8 @@ async function forwardOnce(name, sat, hash, pubkey) {
const viaFloat = async () => {
if (!ownServer || fwd.balance().spendableSat < sat) return false;
- try { await fwd.send(dest, sat); }
+ if (hash) { (state.inflight ||= {})[hash] = { float: true, dest, sat, name, after: Date.now() }; persist(); }
+ try { await fwd.send(dest, sat); settled(); }
catch (e) {
// enough sats, too many coins: merge them, and the queue's next try goes
if (/too many coins/.test(e.message)) consolidateFloat().catch((x) => log('float consolidate failed: ' + x.message));