fix(machine): resume from binding when a stored spire seed won't parse
resolveSigner parses the stored VITE_SPIRE_SEED on every boot before it checks the binding, so a machine whose .env still holds a legacy-shape seed would throw on the new parser (bitspire-#70) and surface "ATM Unavailable" on the next auto-pull — even though it has a perfectly good, server-persistent binding to resume from. Guard the parse: an unparseable stored seed with a binding present falls back to resuming the binding (authoritative); with no binding it still fails closed, since the seed is then the only pairing input. Also dedupes the three resume-from-binding call sites behind a small local. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
98bdd92044
commit
786789f517
1 changed files with 30 additions and 12 deletions
|
|
@ -26,6 +26,7 @@ import {
|
|||
parseSpireSeed,
|
||||
seedFingerprint,
|
||||
type Signer,
|
||||
type SpireSeed,
|
||||
} from '@bitSpire/nostr-client'
|
||||
import type { BunkerBindingRecord } from '@/types/electron'
|
||||
|
||||
|
|
@ -67,17 +68,38 @@ async function loadPairingState(): Promise<PairingState> {
|
|||
export async function resolveSigner(opts: ResolveSignerOptions): Promise<Signer> {
|
||||
const { spireSeed, binding } = await loadPairingState()
|
||||
|
||||
const resume = (b: BunkerBindingRecord): Promise<Signer> =>
|
||||
resumeFromBinding({
|
||||
clientSecretHex: b.clientSecretHex,
|
||||
spirePubkey: b.spirePubkey,
|
||||
bunkerUrl: b.bunkerUrl,
|
||||
})
|
||||
|
||||
if (spireSeed) {
|
||||
const seed = parseSpireSeed(spireSeed)
|
||||
const fingerprint = seedFingerprint(spireSeed)
|
||||
let seed: SpireSeed
|
||||
let fingerprint: string
|
||||
try {
|
||||
seed = parseSpireSeed(spireSeed)
|
||||
fingerprint = seedFingerprint(spireSeed)
|
||||
} catch (err) {
|
||||
// A stored seed we can't parse — e.g. a legacy-shape seed left in .env
|
||||
// after the seed format changed (bitspire-#70). If we already hold a
|
||||
// binding it's authoritative (server-persistent), so resume from it
|
||||
// rather than bricking a paired machine on the next boot. With no
|
||||
// binding the seed is our only pairing input, so fail closed.
|
||||
if (binding) {
|
||||
console.warn(
|
||||
'[Signer] Stored spire seed is unparseable; resuming from existing binding:',
|
||||
(err as Error).message,
|
||||
)
|
||||
return resume(binding)
|
||||
}
|
||||
throw err
|
||||
}
|
||||
|
||||
if (binding && binding.seedFingerprint === fingerprint) {
|
||||
console.log('[Signer] Resuming bunker session for spire', seed.spirePubkey)
|
||||
return resumeFromBinding({
|
||||
clientSecretHex: binding.clientSecretHex,
|
||||
spirePubkey: binding.spirePubkey,
|
||||
bunkerUrl: binding.bunkerUrl,
|
||||
})
|
||||
return resume(binding)
|
||||
}
|
||||
|
||||
// First pair or re-pair: redeem the one-shot connect secret.
|
||||
|
|
@ -105,11 +127,7 @@ export async function resolveSigner(opts: ResolveSignerOptions): Promise<Signer>
|
|||
// No seed in this boot but a binding survives → resume.
|
||||
if (binding) {
|
||||
console.log('[Signer] Resuming bunker session from stored binding (no seed this boot)')
|
||||
return resumeFromBinding({
|
||||
clientSecretHex: binding.clientSecretHex,
|
||||
spirePubkey: binding.spirePubkey,
|
||||
bunkerUrl: binding.bunkerUrl,
|
||||
})
|
||||
return resume(binding)
|
||||
}
|
||||
|
||||
if (opts.allowEphemeral) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue