diff options
Diffstat (limited to 'names/server.js')
| -rw-r--r-- | names/server.js | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/names/server.js b/names/server.js index a0a0bb7..591222b 100644 --- a/names/server.js +++ b/names/server.js @@ -654,10 +654,12 @@ async function settleLoop() { delete state.invoices[inv.payment_hash]; persist(); } + // a released name's custom offer still knows its owner's key + const pubkey = state.names[name]?.pubkey || (offerId && state.offers?.[offerId]?.pubkey) || undefined; try { - await forward(name, sat, inv.payment_hash, state.names[name]?.pubkey); + await forward(name, sat, inv.payment_hash, pubkey); } catch (e) { - const p = { name, sat, hash: inv.payment_hash, pubkey: state.names[name]?.pubkey, ts: Date.now() }; + const p = { name, sat, hash: inv.payment_hash, pubkey, ts: Date.now() }; if (queueFailedForward(p, e)) { log(`forward failed for ${name} (${sat} sat): ${e.message} — queued`); (state.pending ||= []).push(p); @@ -1387,7 +1389,10 @@ Bun.serve({ } catch (e) { return json({ error: e.message }, 500); } - state.offers[o.offer_id] = { key, memo, bolt12: o.bolt12, created: Date.now() }; + // the owner's key rides along: if the name is released (a v2 migration + // swaps a throwaway npub name for the real one) the offer's payments + // follow the key to its name now, like the name's own offer does + state.offers[o.offer_id] = { key, memo, bolt12: o.bolt12, created: Date.now(), pubkey: state.names[key]?.pubkey }; persist(); log(`offer for ${key}: ${memo ? JSON.stringify(memo) : '(no memo)'}`); return json({ ok: true, offerId: o.offer_id, memo, bolt12: o.bolt12 }); @@ -2046,10 +2051,10 @@ settleLoop().catch((e) => log('settle loop died:', e.message)); retireOtherNetworkOffers().catch((e) => log('retiring other-network offers failed: ' + e.message)); // Names that got one of our offers before otherNetwork() existed (staging -// names: 84 of them, plus 15 custom offers, on 2026-10-22): disable the offer -// on the node, take its lno= out of the published record, drop custom ones. -// Idempotent — a name it fixed has no offerId left — so every start re-runs -// it and a name that failed (Cloudflare down, say) gets another go. +// names: 83 of them, plus 13 custom offers, retired 2026-10-22): disable the +// offer on the node, take its lno= out of the published record. Idempotent — +// a name it fixed has no offerId left — so every start re-runs it and a name +// that failed (Cloudflare down, say) gets another go. async function retireOtherNetworkOffers() { if (!ln) return; let names = 0, customs = 0; @@ -2068,9 +2073,27 @@ async function retireOtherNetworkOffers() { names++; } catch (e) { log(`retiring the offer for ${key} failed: ${e.message}`); } } + // Custom offers: give each its owner's key (they predate the field), then + // retire the ones that can't reach a wallet — on another network, or + // orphaned by a released name with no owner to follow. An orphaned + // npub1xxxxxxx@ name finds its owner by that npub prefix when exactly one + // current name's key matches (2026-10-22: 27 orphans, rick@ had 4). + const byNpub = new Map(); + for (const r of Object.values(state.names)) { + if (!r.pubkey) continue; + const p = npubEncode(r.pubkey).slice(0, 12); + byNpub.set(p, byNpub.has(p) && byNpub.get(p) !== r.pubkey ? null : r.pubkey); + } + let owned = 0; for (const [id, o] of Object.entries(state.offers || {})) { const rec = state.names[o.key]; - if (!rec || !otherNetwork(rec.uri, rec.domain)) continue; + const domain = rec?.domain || o.key.split('@')[1]; + if (!o.pubkey) { + o.pubkey = rec?.pubkey || byNpub.get(o.key.split('@')[0].slice(0, 12)) || undefined; + if (o.pubkey) { persist(); owned++; } + } + const retire = rec ? otherNetwork(rec.uri, rec.domain) : (otherNetwork(null, domain) || !o.pubkey); + if (!retire) continue; try { await ln.call('disableoffer', { offer_id: id }).catch((e) => { if (!gone(e)) throw e; }); delete state.offers[id]; @@ -2078,7 +2101,7 @@ async function retireOtherNetworkOffers() { customs++; } catch (e) { log(`retiring custom offer ${id} for ${o.key} failed: ${e.message}`); } } - if (names || customs) log(`retired our offers for wallets on another network: ${names} names, ${customs} custom offers`); + if (names || customs || owned) log(`offers: retired ${names} names' and ${customs} custom offers that couldn't reach a wallet; ${owned} custom offers learned their owner's key`); } // The published uri minus our lno= parameter (the owner's other params kept). |
