From 75ec27747ec05da8990208d67052ad11d25f3c44 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Mon, 3 Aug 2026 22:28:53 -0700 Subject: Speak as the account you logged in with, or not at all MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Logging in with a remote signer and reloading left the app showing your avatar and profile while signing everything with the wallet's own key — so chat messages arrived under a different npub with a stranger's punk on them. identity() had a fallback: when the login signer wasn't available it quietly used the wallet key instead. That fallback is gone. If you logged in as a nostr account, the app speaks as that account or it refuses and says so. Refusing is only reasonable if the signer usually comes back, so a login now persists what it takes to be that identity again. A remote signer stores its NIP-46 client key and pointer — the signer authorised that client key, not one page load, so rebuilding from it resumes the session without prompting. A pasted key stores the key, which is already the seed of everything here since the wallet's mnemonic derives from it. Resume is single-flight with a pause after failure, because identity() is asked on every send and a signer that isn't answering must not mean a relay connection per keystroke. Existing remote-signer logins predate the stored session, so they need one more sign-in to become resumable. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi --- src/features/messages.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/features/messages.js') diff --git a/src/features/messages.js b/src/features/messages.js index 5aa8dfe..74abdd8 100644 --- a/src/features/messages.js +++ b/src/features/messages.js @@ -114,11 +114,15 @@ export function messagesFeature(ctx) { // ---- identity ----------------------------------------------------------- + // Who we speak as. If the user logged in with a nostr account we speak as + // that account or not at all — falling back to the wallet's own key would + // sign under a pubkey that isn't the one their avatar and profile show, + // which reads to everyone else as a different person entirely. async function identity() { const id = hook('nostrLoginIdentity'); if (id) { const signer = id.signer || (await hook('nostrLoginResume')); - if (signer) return { pubkey: id.pubkey, signer }; + return signer ? { pubkey: id.pubkey, signer } : null; } if (wallet.nostr && wallet.nostr.sk) return { pubkey: wallet.nostr.pk, signer: wallet.nostr.sk }; return null; -- cgit v1.2.3