diff options
| author | Adam Soltys <[email protected]> | 2026-09-14 18:00:19 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-09-14 18:00:19 -0700 |
| commit | cb4e155ae6fb72282d5f186389d2ecca6db6a0f0 (patch) | |
| tree | 4d00f5696f377ba73a4d76244a86f7fb5f56235e /src/features | |
| parent | 082fc2e4005387697f77e485ae1c783ed3203e91 (diff) | |
| download | coinosv3-cb4e155ae6fb72282d5f186389d2ecca6db6a0f0.tar.gz coinosv3-cb4e155ae6fb72282d5f186389d2ecca6db6a0f0.zip | |
A remote signer that drops its socket comes back by itself.
"My signer keeps disconnecting": a phone freezing the tab cut the relay
socket the bunker session talks through, every request after that hung
to its deadline, and the app declared the signer gone — a Reconnect
button, tapped over and over. Three changes: the bunker client now talks
through a pool that pings and reconnects on its own, so a dropped socket
is re-opened and the subscription re-fired without anyone noticing; a
request that does fail on a dead connection drops the session and dials
again silently, so the notice only appears if that resume fails; and
coming back from the background probes the signer with a quick question,
replacing a dead session before the next real request runs into it.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QYJfZ4A1TDCEY4Foq3CApR
Diffstat (limited to 'src/features')
| -rw-r--r-- | src/features/nostrlogin.js | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/src/features/nostrlogin.js b/src/features/nostrlogin.js index 4d3fe50..503384f 100644 --- a/src/features/nostrlogin.js +++ b/src/features/nostrlogin.js @@ -67,7 +67,13 @@ export function nostrLoginFeature(ctx) { if (!signer || signer.kind !== 'bunker') return signer; const guard = (fn) => async (...args) => { try { return await fn(...args); } catch (e) { - if (live === wrapped && SIGNER_DEAD.test(e?.message || '')) live = null; + if (live === wrapped && SIGNER_DEAD.test(e?.message || '')) { + // drop it AND dial again, silently: the notice (and its Reconnect + // button) is for a resume that failed, not for every hiccup + live = null; + try { signer.close && signer.close(); } catch {} + resumeQuietly(); + } throw e; } }; @@ -701,6 +707,21 @@ export function nostrLoginFeature(ctx) { // null for signers we cannot silently reattach (pasted keys, bunkers // without a stored session). nostrLoginResume() { return resumeLogin(); }, + // Back from the background: a remote signer's socket may be gone even if + // the pool will bring it back — ask it something small now, and if the + // answer never comes, resume a fresh session before anyone notices. + resumed(awayMs) { + const s = liveSigner(); + if (!s || s.kind !== 'bunker' || !s.ping) return; + if (awayMs && awayMs < 5_000) return; + s.ping().catch(() => { + if (live !== s) return; + live = null; + try { s.close && s.close(); } catch {} + resumeQuietly(); + }); + return true; + }, unlockExtra() { return unlockExtra(); }, // The welcome screen's sign-in block: Google and passkey act right there; // the Nostr button steps into the wizard's signer list. |
