aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/features/names.js27
-rw-r--r--src/features/nostrlogin.js15
2 files changed, 36 insertions, 6 deletions
diff --git a/src/features/names.js b/src/features/names.js
index 77b2554..d430d98 100644
--- a/src/features/names.js
+++ b/src/features/names.js
@@ -99,14 +99,29 @@ export function namesFeature(ctx) {
if (!st.name) {
// The address people see should be the identity they know the user
// by: their real npub when a nostr account is linked, else the
- // wallet's own. Both are claimed the same way; the registrar checks
- // that an npub-shaped name really belongs to its claimant.
+ // wallet's own. Claiming the real one has to be SIGNED by that
+ // identity (the registrar won't let anyone else take an npub-shaped
+ // name), so it needs a live signer — after a reload an extension can
+ // usually be re-attached silently; anything else falls back to the
+ // wallet's own identity rather than retrying a claim that can only
+ // ever fail.
const linked = hook('nostrLoginIdentity');
- const npub = (linked && linked.npub) || (wallet.nostrNpub && wallet.nostrNpub());
+ let signer = linked && linked.signer;
+ if (linked && !signer) { try { signer = await hook('nostrLoginResume'); } catch {} }
+ const useReal = !!(linked && signer);
+ const npub = useReal ? linked.npub : (wallet.nostrNpub && wallet.nostrNpub());
if (npub) {
- await claim(npub.slice(0, 20), linked
- ? { signer: linked.signer, manager: wallet.nostrPubkey() }
- : {});
+ const opts = useReal ? { signer, manager: wallet.nostrPubkey() } : {};
+ try {
+ await claim(npub.slice(0, 20), opts);
+ } catch (e) {
+ // A refusal is permanent — never spin on it. Fall back to the
+ // wallet's own name so the user always ends up with an address.
+ const permanent = /belongs to another|is taken|reserved|invalid/i.test(e.message);
+ const own = wallet.nostrNpub && wallet.nostrNpub();
+ if (permanent && useReal && own) await claim(own.slice(0, 20), {});
+ else if (!permanent) throw e;
+ }
st = load();
}
}
diff --git a/src/features/nostrlogin.js b/src/features/nostrlogin.js
index c5369e9..cea13b4 100644
--- a/src/features/nostrlogin.js
+++ b/src/features/nostrlogin.js
@@ -176,6 +176,21 @@ export function nostrLoginFeature(ctx) {
if (!st.pubkey) return null;
return { pubkey: st.pubkey, npub: npubOf(st.pubkey), signer: live };
},
+ // A page reload loses the signer. An installed extension can usually be
+ // re-attached without prompting, which is what lets the payment address
+ // stay tied to the user's real identity across reloads. Returns null for
+ // signers we cannot silently reattach (pasted keys, bunkers).
+ async nostrLoginResume() {
+ if (live) return live;
+ const st = load();
+ if (!st.pubkey || typeof window === 'undefined' || !window.nostr) return null;
+ try {
+ const s = await extensionSigner();
+ if (s.pubkey !== st.pubkey) return null;
+ live = s;
+ return s;
+ } catch { return null; }
+ },
unlockExtra() { return unlockExtra(); },
settingsCards() { return [settingsCard()]; },
};