From ed1d996f9dbd6cedc18ec293daba0cfcd745ae2b Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Sat, 1 Aug 2026 20:46:12 -0700 Subject: Zappable offer codes and per-name Lightning offers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CLINK offers (noffer): every wallet gets a static offer keypair (synced across devices, first-minted wins) answering kind-21001 invoice requests — from open tabs and from the service worker while closed, which mints against the mirrored state (the record now carries chain-4 and chain-5 key windows) and raises an open-to-receive notification. Zap requests ride along and their kind-9735 receipts publish once the payment is claimed. The code is shown in the payment-address card for pasting into a Nostr profile; the notifier watches and relays kind 21001 alongside NWC. Payment names also gain a Lightning offer: the registrar creates a BOLT 12 offer per name on the node and appends lno= to the DNS record; a settle-forwarder pushes each received payment on to the name's ark destination from a small float wallet (custody window: seconds between Lightning settle and the ark send). Name resolution now runs full client-side DNSSEC validation (src/dnssec.js): binary DoH, root-anchor chain walk, RSA + ECDSA via WebCrypto — the resolver is untrusted transport, verified against live signed zones including the canonical BIP-353 test name. Co-Authored-By: Claude Fable 5 --- src/features/names.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/features/names.js') diff --git a/src/features/names.js b/src/features/names.js index d059516..d932af7 100644 --- a/src/features/names.js +++ b/src/features/names.js @@ -126,7 +126,7 @@ export function namesFeature(ctx) { if (!available()) return null; const st = load(); if (st.name) { - const addr = `₿${st.name}@${DOMAIN}`; + const addr = `${st.name}@${DOMAIN}`; return h('div', { class: 'card col' }, h('h3', {}, t('namesTitle')), h('div', { class: 'addr-box break', style: 'font-size:14px' }, addr), @@ -135,6 +135,14 @@ export function namesFeature(ctx) { h('button', { class: 'btn-ghost btn-sm', onClick: async () => { await release(); toast(t('namesReleased')); render(); } }, t('namesRelease'))), + (() => { + const code = hook('nwcOfferString'); + return code ? h('details', { class: 'small faint' }, + h('summary', {}, t('namesZapCode')), + h('p', { style: 'margin:4px 0' }, t('namesZapCodeHow')), + h('div', { class: 'addr-box break', style: 'font-size:10px' }, code), + copyBtn(code, t('namesZapCodeCopy'))) : null; + })(), h('details', { class: 'small faint' }, h('summary', {}, t('namesOwnDomain')), h('p', { style: 'margin:4px 0' }, t('namesOwnDomainHow')), -- cgit v1.2.3