feat(machine): on-machine QR-pairing wizard #68
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "qr-pairing-wizard"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes the last consumer-side gap in the bunker migration (aiolabs/bitspire#52): an unpaired machine can now be paired on the machine by scanning a spire-seed QR, instead of only by provisioning
VITE_SPIRE_SEEDinto.env.Flow
Unpaired (fresh, or binding revoked/expired) → boot lands on
unpaired→ under Electron, App.vue rendersPairingWizardinstead of the static "Pairing Required" card. The operator shows spirekeeper's/pairQR to the camera; the wizard:PairingSource(src/services/pairing/),ingestScannedSeed) — a stray QR is rejected with a hint and scanning resumes,VITE_SPIRE_SEED(state:save-spire-seedIPC) and relaunches (app:relaunch).Pairing itself is not done in the wizard — relaunch lets the normal boot path (
signer-resolver→connectNewSeed) redeem the one-shot token, so there's exactly one tested pairing path. Provisioning the seed up front still works and skips the wizard.Capture abstraction
PairingSourceis the seam so the wizard is agnostic to how the seed arrives:QrPairingSource— camera + decode. Usesqr(paulmillr), chosen over the dormant/unmaintainedjsqr: zero-dependency, auditable, dual MIT/Apache, actively maintained, and authored by the same person as the@noble/@scurecrypto our nostr stack already trusts. Itsqr/dom.jshelper wraps getUserMedia + the per-frame decode loop.NfcPairingSource— Web NFC scaffold; inert on the Sintra's Linux Electron (isAvailable()→ false), there for the NFC pairing method the user flagged as plausible-future without reworking the wizard later.Notes
unpairedwizard (re-pair = scan a fresh seed).getUserMediawebcam. If the unit's scanner is a HAL peripheral instead, onlyQrPairingSourcechanges — the seam, ingest, and UI are unaffected.Verification
vue-tsc --noEmitclean; full machine build (vite + electron tsc + fund-atm bundle) green.ingestScannedSeedunit tests (invalid-seed / no-bridge / persist-failed / happy path); all 34 machine tests pass.Commits
feat: persist scanned spire-seed + signal unpaired state for wizard— IPC +NoPairingError→unpaired.feat: pairing-source abstraction + QR/NFC capture + seed ingest—src/services/pairing/+qrdep + tests.feat: render QR-pairing wizard for unpaired machines—PairingWizard.vue+ App.vue wiring.docs: document the on-machine QR-pairing wizard.🤖 Generated with Claude Code