From fc8a160d9a3b2a6468b09477cb9d0e34aaf687a7 Mon Sep 17 00:00:00 2001 From: codytseng Date: Thu, 26 Feb 2026 23:36:42 +0800 Subject: [PATCH] fix: prevent bunker reconnection from blocking app startup When reconnecting a bunker signer (e.g. Amber) after page reload, skip the getPublicKey() call since the pubkey is already known from storage. This prevents the app from hanging indefinitely when the remote signer is unreachable. Also add a 10s timeout to getPublicKey() for safety. Co-Authored-By: Claude Opus 4.6 --- src/constants.ts | 4 ++-- src/providers/NostrProvider/bunker.signer.ts | 14 +++++++++++--- src/providers/NostrProvider/index.tsx | 11 +---------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index 0a569dd..32f907d 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -161,9 +161,9 @@ export const NIP_96_SERVICE = [ export const DEFAULT_NIP_96_SERVICE = 'https://nostr.build' export const DEFAULT_NOSTRCONNECT_RELAY = [ - 'wss://relay.nsec.app/', 'wss://bucket.coracle.social/', - 'wss://relay.primal.net/' + 'wss://relay.primal.net/', + 'wss://relay.damus.io/' ] export const DEFAULT_FAVICON_URL_TEMPLATE = 'https://{hostname}/favicon.ico' diff --git a/src/providers/NostrProvider/bunker.signer.ts b/src/providers/NostrProvider/bunker.signer.ts index 47e09cf..ab29a69 100644 --- a/src/providers/NostrProvider/bunker.signer.ts +++ b/src/providers/NostrProvider/bunker.signer.ts @@ -25,16 +25,24 @@ export class BunkerSigner implements ISigner { }) if (isInitialConnection) { await this.signer.connect() + return await this.getPublicKey() } - return await this.signer.getPublicKey() + // For reconnection, skip getPublicKey - the caller already knows the pubkey + this.pubkey = bunkerPointer.pubkey + return this.pubkey } - async getPublicKey() { + async getPublicKey(timeout = 10_000) { if (!this.signer) { throw new Error('Not logged in') } if (!this.pubkey) { - this.pubkey = await this.signer.getPublicKey() + this.pubkey = await Promise.race([ + this.signer.getPublicKey(), + new Promise((_, reject) => + setTimeout(() => reject(new Error('Bunker getPublicKey timeout')), timeout) + ) + ]) } return this.pubkey } diff --git a/src/providers/NostrProvider/index.tsx b/src/providers/NostrProvider/index.tsx index ba909ba..8bbad75 100644 --- a/src/providers/NostrProvider/index.tsx +++ b/src/providers/NostrProvider/index.tsx @@ -608,16 +608,7 @@ export function NostrProvider({ children }: { children: React.ReactNode }) { } else if (account.signerType === 'bunker') { if (account.bunker && account.bunkerClientSecretKey) { const bunkerSigner = new BunkerSigner(account.bunkerClientSecretKey) - const pubkey = await bunkerSigner.login(account.bunker, false) - if (!pubkey) { - storage.removeAccount(account) - return null - } - if (pubkey !== account.pubkey) { - storage.removeAccount(account) - account = { ...account, pubkey } - storage.addAccount(account) - } + await bunkerSigner.login(account.bunker, false) return login(bunkerSigner, account) } } else if (account.signerType === 'npub' && account.npub) {