aboutsummaryrefslogtreecommitdiffstats
path: root/names
diff options
context:
space:
mode:
Diffstat (limited to 'names')
-rw-r--r--names/server.js41
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).