Source operator pubkey + fee config from LNbits over the transport, not env/seed (#70 P1) #71
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Summary
Make the ATM pull its operator pubkey + fee config from LNbits via a
get_machine_configkind-21000 RPC right after pairing, instead of reading the operator pubkey fromVITE_OPERATOR_PUBKEYS(env) and learning fees only from an operator-signed kind-30078 broadcast. This is the client half of #70 P1; the server RPC is the companion issue onaiolabs/spirekeeper.Outcome: a truly-fresh, seed-only machine (blank
.env, scannedspire-seed) leaves "awaiting configuration" with zero provisioning — and we never add a 3rd/4th npub to the seed.Background
The pairing seed carries the two channel anchors it must (relay +
lnbits_npubfor the LNbits channel;spire_npub+bunker_secretfor the NIP-46 bunker). The operator pubkey — which the ATM needs to trust the fee config — is config, not a channel anchor, and is currently only sourced fromVITE_OPERATOR_PUBKEYS(src/services/lightning.ts:91). A seed-only machine has it empty →startOperatorFeesService/startOperatorConfigServicedisable themselves (operator-fees.ts:105-108,operator-config.ts:75) →getFeeConfig()null → permanentawaiting-feesmaintenance (stores/atm.ts:1074-1081).The decided fix (see the spirekeeper issue for full rationale — NWC / NIP-46 / Lightning.Pub all keep the pairing secret minimal and let the server advertise the rest) is: LNbits delivers operator pubkey + fee config over the already-authenticated transport.
P0 (remnant hygiene — landed) already stopped provisioning
VITE_OPERATOR_PUBKEYS, so post-P0 a fresh machine honestly reports[Lightning] Operator pubkey(s): (none — …#70 P1). P1 closes it.Why it's a small client change
initializeForProductiondeliberately does NOT bail on awaiting-fees — it starts services and unblocks reactively (stores/atm.ts:1067-1081), andapplyFeeConfigalready does the watermark + range validation + reactive UI unblock (electron/state-store.ts:729). So the RPC reply just needs to flow into paths that already exist.Proposed implementation
LnbitsClient.getMachineConfig()— add topackages/lnbits/src/client.ts(+ types inpackages/lnbits/src/types.ts). Returns{ operator_pubkey, fee_config, fiat_code, cassettes?, machine_npub, wallet_id, created_at }.list_walletsinsrc/services/lightning.ts(~:491), on the same authenticated client.CONFIG.operatorPubkeysfromresponse.operator_pubkeywhenVITE_OPERATOR_PUBKEYSis empty (env stays an override; keep the provenance logging added in P0). This re-enables the fees/operator-config/management services.fee_configinto the existingapplyFeeConfigIPC path (electron/state-store.ts) using the RPC'screated_atas the replay watermark — so the existing guards work unchanged and the reactiveawaiting-fees→ idle unblock fires.operator_npub(or any new field) topackages/nostr-client/src/seed.ts.Notes / edges
operatorPubkeysis load-bearing in three places (operator-config.tsauthors filter + reverse-channel recipient,operator-fees.tsauthors filter,lightning.ts:504kind-21003 management allowlist). Sourcing all three from the RPC value is fine, but verify each once wired.created_atso re-pair +resetForRepair(P0) interplay stays correct.Related
Server RPC:
aiolabs/spirekeepercompanion issue. Parent: #70 (P0 remnant-hygiene commits landed; P1 is this). Context: the seed-shape + trust-domain analysis is in the spirekeeper issue.Companion server RPC issue: aiolabs/spirekeeper#41 (has the full seed-shape + trust-domain rationale).