feat(pairing,ui): optional machine_npub + bunker_relay override + fee decimal-input UX #29
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/optional-machine-npub-pairing-ux"
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?
Three changes from the nsecbunkerd#27 bunker-pairing smoke — validated end-to-end on the Sintra (2026-06-21) before this PR. Intermingled per-file, so landed in one commit.
1. Optional
machine_npub(model A1)Operators register a machine unpaired (blank npub); the bunker mints its identity at pairing. Previously the create form required an npub that
api_pair_machinethen overwrote — so the field was throwaway for the bunker flow.m011:dca_machines.machine_npub→ nullable (sqlite table-rebuild / postgresALTER … DROP NOT NULL;UNIQUEstays — NULLs don't collide, so any number of unpaired machines coexist). Validated on a copy of the live dev DB (rows preserved, multiple NULL inserts succeed).CreateMachineData.machine_npub→str | None; create skips the collision-check + fee publish when blank;api_pair_machinenow publishes the fee config after minting, so an unpaired machine clears itsawaiting-feesgate once paired (this gap would otherwise strand the spire).Requiredrule dropped, null-safe display (shortNpub → "unpaired", guarded slices), empty →null.2.
bunker_relayoverride onPOST /machines/{id}/pairPairMachineDatagainsbunker_relay;api_pair_machinethreads it topair_spire. Lets the seed'sbunker://relay differ from the relay lnbits uses to reach the bunker (internal docker host vs LAN/public) — needed for any split-relay / dev deploy. Without it, the smoke had to mint the seed via a server-side script.3. Fees are decimal fractions, not percents
Relabel super + operator fee inputs (
"decimal fraction, 0-0.15", dropping the misleading%) and add a shared_assertFeesDecimal()guard across the super/add/edit submits — so a percent typo (3instead of0.03) gets a clear toast, not a raw 400.Verification
py_compileclean; migration dry-run on a copy of the live DB ✓ (rows preserved, NULL-npub inserts succeed).bunker_relayoverride + the fee UX were both exercised.Apply
Backend (model + migration) takes effect on the lnbits restart that loads the extension (
spirekeeper.11runs at startup). Frontend on hard-refresh.refs: nsecbunkerd#27 / #36;
aiolabs/bitspire#52; coordination threadsmoke-bunker-pairing-sintra.md(2026-06-21).🤖 Generated with Claude Code
Three changes from the nsecbunkerd#27 bunker-pairing smoke (validated end-to-end on the Sintra, 2026-06-21); intermingled per-file, so landed together. 1. Optional machine_npub (model A1) — register UNPAIRED, bunker mints the identity at pairing: - machine_npub now nullable (migration m011 rebuilds dca_machines for sqlite / ALTER ... DROP NOT NULL for postgres; UNIQUE stays, NULLs don't collide so any number of unpaired machines coexist). - CreateMachineData.machine_npub -> str | None; create skips the collision-check + fee publish when blank; api_pair_machine now publishes the fee config after minting, so an unpaired machine clears its awaiting-fees gate once paired. - Supplying an npub up front is the DEVELOPMENT self-key path (a machine holding its own signing key) — available to anyone but the form field is explicitly marked DEVELOPMENT ONLY. - Frontend: npub field optional, required rule dropped, null-safe display (shortNpub -> "unpaired", guarded slices), empty -> null. 2. bunker_relay override on POST /machines/{id}/pair: PairMachineData gains bunker_relay; api_pair_machine threads it to pair_spire. Lets the seed's bunker:// relay differ from the relay lnbits uses to reach the bunker (internal docker host vs LAN/public) — needed for split-relay / dev deploys. Without it the smoke had to mint via a script. 3. Fees are decimal fractions, not percents: relabel super + operator fee inputs ("decimal fraction, 0-0.15") + a shared _assertFeesDecimal() guard (super/add/edit submits) so a percent typo (3 instead of 0.03) gets a clear toast, not a raw 400. refs: nsecbunkerd#27/#36; aiolabs/bitspire#52; coordination smoke 2026-06-21 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>