Wires the server-side per-transaction cash-in ceiling the `create_withdraw`
handler already enforces (it read the value defensively via getattr; this
makes it a first-class config field).
- migrations.py m012: ADD COLUMN super_config.max_cash_in_sats INTEGER (NULL
= no cap).
- models.py: SuperConfig.max_cash_in_sats + UpdateSuperConfigData field with a
>= 0 validator.
- super-fee dialog: a "Max cash-in per transaction (sats)" input; blank sends
null (the PUT skips null, preserving the current value — set 0 to reject
every cash-in). crud `update_super_config` and the PUT endpoint flow the
field through automatically (dynamic dict update; check_super_user gated).
Why a sats cap and not the bunker ACL: the ACL / usage caps (#28) gate call
*rate*, not *sats*, and `principal_sats` is necessarily ATM-attested — so a
single in-rate call could request an arbitrarily large payout. This bounds a
compromised/buggy machine to one capped transaction.
Verified on the dev stack: m012 runs, the model round-trips the column
(GET returns the set value), and a negative value is rejected.
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>
The Pair dialog had two interleaved v-if/v-else sibling pairs
(q-card-section + q-card-actions per step). Vue requires v-else to
immediately follow its v-if sibling, so the second v-else (actions)
trailed a v-else (section) — illegal, throwing compiler error 30
("v-else has no adjacent v-if") and breaking the entire Vue mount.
Wrap each step's section+actions in one <template v-if> / <template
v-else> so there's exactly one adjacent pair. Verified with
@vue/compiler-dom and a live pair/revoke round-trip against regtest.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Follow-up to the satmachineadmin->spirekeeper issue migration. The 20
open issues were recreated on aiolabs/spirekeeper with reassigned
numbers; this repoints in-repo references to the migrated issues at
their new spirekeeper numbers (#3->#1, #4->#2, #8->#4, #9->#5, #10->#6,
#17->#11, #21->#12, #28->#16, #44->#20). References to closed/non-
migrated satmachineadmin issues (#20/#22/#26/#29/#32/#37/#38/#39) stay
pointing at the original repo where they were resolved.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fork of satmachineadmin's v2-bitspire line into its own repo. Renames
both identifiers so this extension is fully independent of the original
satmachineadmin install (which remains in service):
- extension id satmachineadmin -> spirekeeper
(router prefix, static path/static_url_for, module symbols, task
names, templates dir, config/manifest paths)
- database name satoshimachine -> spirekeeper
(Database(ext_spirekeeper), all schema-qualified table refs)
Also resets versioning to 0.1.0, sets the display name + manifest to
spirekeeper/aiolabs, and fixes the placeholder pyproject description.
Historical aiolabs/satmachineadmin#N issue references in comments are
left pointing at the original repo where those issues live.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 22:30:05 +02:00
Renamed from templates/satmachineadmin/index.html (Browse further)