summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--names/server.js28
-rw-r--r--src/features/names.js9
2 files changed, 30 insertions, 7 deletions
diff --git a/names/server.js b/names/server.js
index 0005782..bd62f81 100644
--- a/names/server.js
+++ b/names/server.js
@@ -189,14 +189,32 @@ const arkParamOf = (uri) => {
return m ? decodeURIComponent(m[1]) : null;
};
-// Forward one settled offer payment; queue it on failure (empty float, etc).
+// Deliver a settled payment to the name's owner. Two ways, and we try the
+// one that works while they're asleep first:
+// 1. an arkoor send from the float — instant, free, needs no cooperation
+// 2. ask their wallet for an invoice and pay it over Lightning — needs no
+// float at all, but only works while something of theirs is listening
+// Failing both, it queues and retries; nothing is ever dropped silently.
async function forward(name, sat) {
const rec = state.names[name];
const dest = rec && arkParamOf(rec.uri);
- if (!dest) { log(`forward: no ark destination for ${name}, dropping ${sat} sat`); return; }
- if (!fwd) throw new Error('no forwarder wallet');
- await fwd.send(dest, sat);
- log(`forwarded ${sat} sat to ${name}`);
+ if (!dest && !rec?.offerPk) { log(`forward: nowhere to send ${sat} sat for ${name}`); return; }
+
+ if (dest && fwd && fwd.balance().spendableSat >= sat) {
+ await fwd.send(dest, sat);
+ log(`forwarded ${sat} sat to ${name}`);
+ return;
+ }
+
+ if (rec?.offerPk && ln) {
+ const pr = await requestInvoiceFromWallet(rec.offerPk, { amountSat: sat, description: `${name} payment` });
+ if (pr) {
+ await ln.pay(pr, { maxfeeSat: Math.max(2, Math.ceil(sat * 0.005)) });
+ log(`delivered ${sat} sat to ${name} over lightning (no float needed)`);
+ return;
+ }
+ }
+ throw new Error(fwd && dest ? 'insufficient float and the wallet is not listening' : 'no delivery route');
}
// NIP-57: a zap we invoiced is only "a zap" once we publish the receipt,
diff --git a/src/features/names.js b/src/features/names.js
index 4c0ffaf..54f15f7 100644
--- a/src/features/names.js
+++ b/src/features/names.js
@@ -74,7 +74,7 @@ export function namesFeature(ctx) {
...(manager ? { manager } : {}),
}, signer);
const prev = load().name;
- save({ name, domain: DOMAIN, uri, updated: Date.now() });
+ save({ name, domain: DOMAIN, uri, offerPk: hook('nwcOfferPubkey') || null, updated: Date.now() });
if (prev && prev !== name) {
post('/register', 'DELETE', { name: prev, domain: DOMAIN }).catch(() => {});
}
@@ -147,7 +147,12 @@ export function namesFeature(ctx) {
render();
if (!st.name) return;
const uri = await currentUri();
- if (uri && uri !== st.uri) await claim(st.name);
+ // Re-publish when the address changed OR when the registrar doesn't yet
+ // know this wallet's offer key — that key is what lets an incoming
+ // Lightning payment be delivered straight to us instead of waiting on
+ // the operator's float.
+ const offerPk = hook('nwcOfferPubkey') || null;
+ if (uri && (uri !== st.uri || (offerPk && st.offerPk !== offerPk))) await claim(st.name);
} catch (e) {
console.warn('names: refresh failed —', e.message);
lastError = e.message;