fix(machine): resolve signer before LNbits config so an unpaired machine reaches the pairing wizard
initializeLightningServices() validated VITE_LNBITS_SERVER_PUBKEY (and, in strict mode, rejected a localhost relay) *before* calling resolveSigner. An unpaired machine — no seed, no binding, blank .env — therefore threw a generic config Error that classifyInitError surfaces as the static "ATM Unavailable" screen, never the NoPairingError that routes to the QR-pairing wizard. Pairing is what's meant to provide the transport config, so the pairing check must come first. Move resolveSigner ahead of the strict + server-pubkey validation: an unpaired machine now throws NoPairingError → 'unpaired' → wizard regardless of relay/pubkey provisioning, while a paired machine still hits the config validation it legitimately needs. Surfaced testing the freshly-built Sintra images (live ISO + USB disk image), both of which ship a blank .env by design and booted straight to "ATM Unavailable". bitspire-#70 (part 1 of 2; part 2 = seed carries the LNbits server pubkey). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
b2099c7d48
commit
334cb86771
1 changed files with 19 additions and 12 deletions
|
|
@ -398,9 +398,22 @@ export async function initializeLightningServices(options?: {
|
||||||
console.log('[Lightning] Relay URL:', CONFIG.relayUrl)
|
console.log('[Lightning] Relay URL:', CONFIG.relayUrl)
|
||||||
console.log('[Lightning] LNbits server pubkey:', CONFIG.lnbitsServerPubkey || '(not configured)')
|
console.log('[Lightning] LNbits server pubkey:', CONFIG.lnbitsServerPubkey || '(not configured)')
|
||||||
|
|
||||||
// Strict mode: validate config is production-ready (no localhost). The
|
// Resolve the signing identity BEFORE validating the LNbits transport
|
||||||
// signing-identity check (a bunker pairing must exist) is enforced by
|
// config. An unpaired machine must reach the QR-pairing wizard regardless
|
||||||
// resolveSigner below via allowEphemeral=false.
|
// of relay/server-pubkey provisioning — pairing is what provides those — so
|
||||||
|
// resolveSigner (which throws NoPairingError → 'unpaired' → wizard for a
|
||||||
|
// machine with no seed and no binding) has to run ahead of the config
|
||||||
|
// checks below. The relay/pubkey validation then only gates a *paired*
|
||||||
|
// machine that's actually trying to talk to LNbits. See aiolabs/bitspire#70.
|
||||||
|
//
|
||||||
|
// In production this is a BunkerSigner over NIP-46 (the ATM holds only a
|
||||||
|
// transport key; the operator's nsecbunkerd holds the signing key); in dev
|
||||||
|
// it falls back to an in-process LocalSigner. The Phase-A Signer seam means
|
||||||
|
// nothing downstream changes. See aiolabs/bitspire#52.
|
||||||
|
const signer: Signer = await resolveSigner({ allowEphemeral: !options?.strict })
|
||||||
|
console.log('[Lightning] ATM pubkey:', signer.pubkey)
|
||||||
|
|
||||||
|
// Strict mode: validate config is production-ready (no localhost).
|
||||||
if (options?.strict) {
|
if (options?.strict) {
|
||||||
const errors: string[] = []
|
const errors: string[] = []
|
||||||
if (/localhost|127\.0\.0\.1/.test(CONFIG.relayUrl)) {
|
if (/localhost|127\.0\.0\.1/.test(CONFIG.relayUrl)) {
|
||||||
|
|
@ -414,7 +427,9 @@ export async function initializeLightningServices(options?: {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate required configuration
|
// Validate required configuration. Reached only for a paired machine (an
|
||||||
|
// unpaired one threw NoPairingError above) — it needs the LNbits server
|
||||||
|
// pubkey to talk to the transport.
|
||||||
if (!CONFIG.lnbitsServerPubkey) {
|
if (!CONFIG.lnbitsServerPubkey) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'[Lightning] VITE_LNBITS_SERVER_PUBKEY is required. ' +
|
'[Lightning] VITE_LNBITS_SERVER_PUBKEY is required. ' +
|
||||||
|
|
@ -422,14 +437,6 @@ export async function initializeLightningServices(options?: {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve the signing identity. In production this is a BunkerSigner over
|
|
||||||
// NIP-46 (the ATM holds only a transport key; the operator's nsecbunkerd
|
|
||||||
// holds the signing key); in dev it falls back to an in-process LocalSigner.
|
|
||||||
// The Phase-A Signer seam means nothing downstream changes. See
|
|
||||||
// aiolabs/bitspire#52.
|
|
||||||
const signer: Signer = await resolveSigner({ allowEphemeral: !options?.strict })
|
|
||||||
console.log('[Lightning] ATM pubkey:', signer.pubkey)
|
|
||||||
|
|
||||||
// Create Nostr client
|
// Create Nostr client
|
||||||
const nostrClient = new NostrClient({
|
const nostrClient = new NostrClient({
|
||||||
relays: [{ url: CONFIG.relayUrl }],
|
relays: [{ url: CONFIG.relayUrl }],
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue