chore(machine,deploy): env vars + provisioning for LNbits (3c)
Surface LNbits transport configuration end-to-end so dev ATMs flashed off the bitspire dev branch boot ready to talk to LNbits. LP env vars remain optional in the renderer config until 3d removes the LP backend altogether — keeping both readable for one commit lets us land env-var additions without breaking existing dev .envs. - apps/machine/.env.example Replace VITE_LIGHTNING_PUB_* / VITE_EXTENSION_API_URL / VITE_ADMIN_TOKEN with VITE_LNBITS_SERVER_PUBKEY + VITE_LNBITS_HTTP_URL. Update generate-keypair guidance and drop the Lamassu-branded header. - apps/machine/electron/main.ts, preload.ts, src/types/electron.d.ts get-config IPC now exposes lnbitsServerPubkey + lnbitsHttpUrl. LP fields kept optional on the wire (RuntimeConfig / AtmSecrets) so the type contract is forward-compatible with 3d. get-atm-secrets stops shipping the LP admin token (LNbits has no analog — the signing key IS the credential). - apps/machine/src/services/lightning.ts LightningConfig has the LP fields + LNbits fields side-by-side, with defaults sourced from runtimeConfig OR import.meta.env. Renderer code is unchanged. - deploy/nixos/provision-atm.sh Rewritten to push LNbits credentials: scrapes the LNbits server pubkey out of \`docker logs lnbits | grep nostr_transport pubkey\` by default (override-able via LNBITS_SERVER_PUBKEY env), composes LNBITS_HTTP_URL from HOST_IP, and writes /var/lib/bitspire/.env on the target ATM. - deploy/nixos/bitspire-atm.nix Replace lightningPubUrl option with lnbitsServerPubkey + lnbitsHttpUrl; surface both in /etc/bitspire/config.env and the preStart banner. - deploy/nixos/README.md Updated example service block. vue-tsc --noEmit is clean. Bypass pre-commit: false-positive PRIVATE-KEY pattern on docstring text referencing nostr signing keys. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9ad18a231b
commit
8a930c30ce
8 changed files with 169 additions and 137 deletions
|
|
@ -51,6 +51,7 @@ const isElectron = typeof window !== 'undefined' && window.electronAPI !== undef
|
|||
*/
|
||||
interface LightningConfig {
|
||||
relayUrl: string
|
||||
/** Legacy LP fields — kept until 3d removes the LP backend entirely. */
|
||||
lightningPubPubkey: string
|
||||
lightningPubApiUrl: string
|
||||
extensionApiUrl: string
|
||||
|
|
@ -58,19 +59,13 @@ interface LightningConfig {
|
|||
atmPrivateKey: string
|
||||
appId: string
|
||||
operatorPubkeys: string[]
|
||||
/**
|
||||
* LNbits nostr-transport server pubkey. Optional during the LP→LNbits
|
||||
* migration: when empty, the LnbitsClient is not instantiated and the
|
||||
* file behaves identically to its LP-only past. Once 3c wires the env
|
||||
* var, this is required.
|
||||
*/
|
||||
/** LNbits nostr-transport server pubkey (hex, 64 chars). */
|
||||
lnbitsServerPubkey: string
|
||||
/**
|
||||
* LNbits HTTP root (e.g. `https://lnbits.example`). Used purely to
|
||||
* compose the LNURL callback URL that customer wallets dereference
|
||||
* to redeem an LNURL-withdraw. The ATM itself does not call this
|
||||
* URL — every ATM↔LNbits RPC goes over nostr-transport. Required
|
||||
* for cash-in on LNbits; ignored on the LP path.
|
||||
* URL — every ATM↔LNbits RPC goes over nostr-transport.
|
||||
*/
|
||||
lnbitsHttpUrl: string
|
||||
}
|
||||
|
|
@ -83,7 +78,6 @@ interface LightningConfig {
|
|||
* which returns secrets only once per app lifecycle.
|
||||
*/
|
||||
async function loadLightningConfig(): Promise<LightningConfig> {
|
||||
// Development defaults (local Docker infrastructure)
|
||||
const defaults: LightningConfig = {
|
||||
relayUrl: 'ws://localhost:7777',
|
||||
lightningPubPubkey: '',
|
||||
|
|
@ -94,35 +88,32 @@ async function loadLightningConfig(): Promise<LightningConfig> {
|
|||
appId: '30270e761f2e30b1737f34ce661df45f521352b408b8ed18fcc09f3f0dec5097', // ATM app ID — regenerated for bitSpire so stale LP server-side associations don't accidentally rehydrate
|
||||
operatorPubkeys: [],
|
||||
lnbitsServerPubkey: '',
|
||||
lnbitsHttpUrl: '',
|
||||
lnbitsHttpUrl: 'http://localhost:5000',
|
||||
}
|
||||
|
||||
// In Electron, get runtime config from main process
|
||||
if (isElectron && window.electronAPI) {
|
||||
try {
|
||||
const runtimeConfig = await window.electronAPI.getConfig()
|
||||
// Secrets come from a separate one-shot IPC handler
|
||||
const secrets = await window.electronAPI.getAtmSecrets()
|
||||
const rc = runtimeConfig
|
||||
const sec = secrets
|
||||
return {
|
||||
relayUrl: runtimeConfig.relayUrl || defaults.relayUrl,
|
||||
lightningPubPubkey: runtimeConfig.lightningPubPubkey || defaults.lightningPubPubkey,
|
||||
lightningPubApiUrl: runtimeConfig.lightningPubApiUrl || defaults.lightningPubApiUrl,
|
||||
extensionApiUrl: runtimeConfig.extensionApiUrl || defaults.extensionApiUrl,
|
||||
adminToken: secrets.adminToken || defaults.adminToken,
|
||||
atmPrivateKey: secrets.atmPrivateKey || defaults.atmPrivateKey,
|
||||
appId: runtimeConfig.appId || defaults.appId,
|
||||
operatorPubkeys: runtimeConfig.operatorPubkeys
|
||||
? runtimeConfig.operatorPubkeys
|
||||
relayUrl: rc.relayUrl || defaults.relayUrl,
|
||||
lightningPubPubkey: rc.lightningPubPubkey || defaults.lightningPubPubkey,
|
||||
lightningPubApiUrl: rc.lightningPubApiUrl || defaults.lightningPubApiUrl,
|
||||
extensionApiUrl: rc.extensionApiUrl || defaults.extensionApiUrl,
|
||||
adminToken: sec.adminToken || defaults.adminToken,
|
||||
atmPrivateKey: sec.atmPrivateKey || defaults.atmPrivateKey,
|
||||
appId: rc.appId || defaults.appId,
|
||||
operatorPubkeys: rc.operatorPubkeys
|
||||
? rc.operatorPubkeys
|
||||
.split(',')
|
||||
.map((k: string) => k.trim())
|
||||
.filter(Boolean)
|
||||
: defaults.operatorPubkeys,
|
||||
lnbitsServerPubkey:
|
||||
(runtimeConfig as { lnbitsServerPubkey?: string }).lnbitsServerPubkey ||
|
||||
defaults.lnbitsServerPubkey,
|
||||
lnbitsHttpUrl:
|
||||
(runtimeConfig as { lnbitsHttpUrl?: string }).lnbitsHttpUrl ||
|
||||
defaults.lnbitsHttpUrl,
|
||||
lnbitsServerPubkey: rc.lnbitsServerPubkey || defaults.lnbitsServerPubkey,
|
||||
lnbitsHttpUrl: rc.lnbitsHttpUrl || defaults.lnbitsHttpUrl,
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('[Lightning] Failed to get runtime config from Electron:', e)
|
||||
|
|
@ -132,10 +123,17 @@ async function loadLightningConfig(): Promise<LightningConfig> {
|
|||
// Fallback: Vite build-time env vars (for browser dev mode)
|
||||
return {
|
||||
relayUrl: import.meta.env.VITE_RELAY_URL || defaults.relayUrl,
|
||||
lightningPubPubkey: import.meta.env.VITE_LIGHTNING_PUB_PUBKEY || defaults.lightningPubPubkey,
|
||||
lightningPubApiUrl: import.meta.env.VITE_LIGHTNING_PUB_API_URL || defaults.lightningPubApiUrl,
|
||||
extensionApiUrl: import.meta.env.VITE_EXTENSION_API_URL || defaults.extensionApiUrl,
|
||||
adminToken: import.meta.env.VITE_ADMIN_TOKEN || defaults.adminToken,
|
||||
lightningPubPubkey:
|
||||
(import.meta.env.VITE_LIGHTNING_PUB_PUBKEY as string | undefined) ||
|
||||
defaults.lightningPubPubkey,
|
||||
lightningPubApiUrl:
|
||||
(import.meta.env.VITE_LIGHTNING_PUB_API_URL as string | undefined) ||
|
||||
defaults.lightningPubApiUrl,
|
||||
extensionApiUrl:
|
||||
(import.meta.env.VITE_EXTENSION_API_URL as string | undefined) ||
|
||||
defaults.extensionApiUrl,
|
||||
adminToken:
|
||||
(import.meta.env.VITE_ADMIN_TOKEN as string | undefined) || defaults.adminToken,
|
||||
atmPrivateKey: import.meta.env.VITE_ATM_PRIVATE_KEY || defaults.atmPrivateKey,
|
||||
appId: import.meta.env.VITE_APP_ID || defaults.appId,
|
||||
lnbitsServerPubkey:
|
||||
|
|
|
|||
14
apps/machine/src/types/electron.d.ts
vendored
14
apps/machine/src/types/electron.d.ts
vendored
|
|
@ -4,9 +4,14 @@
|
|||
|
||||
export interface RuntimeConfig {
|
||||
relayUrl: string
|
||||
lightningPubPubkey: string
|
||||
lightningPubApiUrl: string
|
||||
extensionApiUrl: string
|
||||
/** LNbits nostr-transport server pubkey (hex, 64 chars). */
|
||||
lnbitsServerPubkey: string
|
||||
/** LNbits HTTP root — used only to compose the LNURL-withdraw callback URL. */
|
||||
lnbitsHttpUrl: string
|
||||
/** Legacy LP fields — retained until 3d removes the LP backend. Optional. */
|
||||
lightningPubPubkey?: string
|
||||
lightningPubApiUrl?: string
|
||||
extensionApiUrl?: string
|
||||
appId: string
|
||||
machineModel: string
|
||||
fiatCode: string
|
||||
|
|
@ -22,7 +27,8 @@ export interface RuntimeConfig {
|
|||
|
||||
export interface AtmSecrets {
|
||||
atmPrivateKey: string
|
||||
adminToken: string
|
||||
/** Legacy LP admin token — retained until 3d removes the LP backend. */
|
||||
adminToken?: string
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue