diff --git a/apps/machine/.env.example b/apps/machine/.env.example index 153066b..792fddd 100644 --- a/apps/machine/.env.example +++ b/apps/machine/.env.example @@ -6,17 +6,17 @@ # ============================================================================= # Machine model preset (sintra, gaia, or custom) -VITE_LAMASSU_MACHINE_MODEL=sintra +VITE_BITSPIRE_MACHINE_MODEL=sintra # Fiat currency code (ISO 4217) -VITE_LAMASSU_FIAT_CODE=USD +VITE_BITSPIRE_FIAT_CODE=USD # Custom device paths (optional - uses preset defaults if not set) -# VITE_LAMASSU_VALIDATOR_DEVICE=/dev/ttyJ5 -# VITE_LAMASSU_DISPENSER_DEVICE=/dev/ttyJ7 +# VITE_BITSPIRE_VALIDATOR_DEVICE=/dev/ttyJ5 +# VITE_BITSPIRE_DISPENSER_DEVICE=/dev/ttyJ7 # Cassette configuration (optional - JSON array) -# VITE_LAMASSU_CASSETTES='[{"denomination":20,"count":100}]' +# VITE_BITSPIRE_CASSETTES='[{"denomination":20,"count":100}]' # ============================================================================= # LNbits Connection (dev override — normally seed-provided) — nostr-native-transport diff --git a/apps/machine/electron/main.ts b/apps/machine/electron/main.ts index 9094eb7..7a87ac2 100644 --- a/apps/machine/electron/main.ts +++ b/apps/machine/electron/main.ts @@ -355,11 +355,11 @@ ipcMain.handle('get-config', () => { appId: process.env.VITE_APP_ID || '', // Hardware configuration - machineModel: process.env.VITE_LAMASSU_MACHINE_MODEL || 'sintra', - fiatCode: process.env.VITE_LAMASSU_FIAT_CODE || 'USD', - validatorDevice: process.env.VITE_LAMASSU_VALIDATOR_DEVICE, - dispenserDevice: process.env.VITE_LAMASSU_DISPENSER_DEVICE, - cassettes: process.env.VITE_LAMASSU_CASSETTES, + machineModel: process.env.VITE_BITSPIRE_MACHINE_MODEL || 'sintra', + fiatCode: process.env.VITE_BITSPIRE_FIAT_CODE || 'USD', + validatorDevice: process.env.VITE_BITSPIRE_VALIDATOR_DEVICE, + dispenserDevice: process.env.VITE_BITSPIRE_DISPENSER_DEVICE, + cassettes: process.env.VITE_BITSPIRE_CASSETTES, // SECURITY: In production (packaged app), mock fallback is always disabled. // Only allow it in development mode, and only when explicitly opted in via env. allowMockFallback: isDev && process.env.VITE_ALLOW_MOCK_FALLBACK === 'true', @@ -836,7 +836,7 @@ function startCommandPoller(): void { const result = await halInstance.dispenseCash(parsed.bills) const txid = `manual-${Date.now()}-${Math.random().toString(36).slice(2, 8)}` const totalFiatCents = parsed.bills.reduce((s, b) => s + b.denomination * b.count * 100, 0) - const fiatCode = process.env.VITE_LAMASSU_FIAT_CODE || 'USD' + const fiatCode = process.env.VITE_BITSPIRE_FIAT_CODE || 'USD' recordTransaction({ txid, @@ -908,19 +908,19 @@ app.whenReady().then(() => { if (existing.length === 0) { let seedCassettes: { denomination: number; count: number }[] = [] - // Priority 1: explicit VITE_LAMASSU_CASSETTES env var - const cassettesJson = process.env.VITE_LAMASSU_CASSETTES + // Priority 1: explicit VITE_BITSPIRE_CASSETTES env var + const cassettesJson = process.env.VITE_BITSPIRE_CASSETTES if (cassettesJson) { try { seedCassettes = JSON.parse(cassettesJson) } catch (e) { - console.warn('[Electron] Failed to parse VITE_LAMASSU_CASSETTES:', e) + console.warn('[Electron] Failed to parse VITE_BITSPIRE_CASSETTES:', e) } } // Priority 2: default presets per model if (seedCassettes.length === 0) { - const model = process.env.VITE_LAMASSU_MACHINE_MODEL || 'sintra' + const model = process.env.VITE_BITSPIRE_MACHINE_MODEL || 'sintra' const presets: Record = { douro: [ { denomination: 100, count: 50 }, diff --git a/apps/machine/src/config/device.ts b/apps/machine/src/config/device.ts index cffdaa3..ab7586d 100644 --- a/apps/machine/src/config/device.ts +++ b/apps/machine/src/config/device.ts @@ -6,7 +6,7 @@ * * Configuration priority (highest to lowest): * 1. Runtime overrides (passed directly to functions) - * 2. Environment variables (LAMASSU_*) + * 2. Environment variables (BITSPIRE_*) * 3. Machine preset defaults */ @@ -143,7 +143,7 @@ export const MACHINE_PRESETS: Record = {} // Validator device override (preserve validator type from preset) - const validatorDevice = import.meta.env.VITE_LAMASSU_VALIDATOR_DEVICE + const validatorDevice = import.meta.env.VITE_BITSPIRE_VALIDATOR_DEVICE if (validatorDevice) { overrides.validator = { type: MACHINE_PRESETS[model].validator.type, device: validatorDevice } } // Dispenser device override - const dispenserDevice = import.meta.env.VITE_LAMASSU_DISPENSER_DEVICE + const dispenserDevice = import.meta.env.VITE_BITSPIRE_DISPENSER_DEVICE if (dispenserDevice) { overrides.dispenser = { type: MACHINE_PRESETS[model].dispenser.type, @@ -248,7 +248,7 @@ export function loadDeviceConfigFromEnv(): DeviceConfig { } // Cassettes override (JSON) - const cassettesJson = import.meta.env.VITE_LAMASSU_CASSETTES + const cassettesJson = import.meta.env.VITE_BITSPIRE_CASSETTES if (cassettesJson) { try { const cassettes = JSON.parse(cassettesJson) as CassetteConfig[] @@ -262,7 +262,7 @@ export function loadDeviceConfigFromEnv(): DeviceConfig { } } } catch (e) { - console.error('[Config] Failed to parse LAMASSU_CASSETTES:', e) + console.error('[Config] Failed to parse BITSPIRE_CASSETTES:', e) } } diff --git a/deploy/nixos/configuration.nix b/deploy/nixos/configuration.nix index 458a239..f016179 100644 --- a/deploy/nixos/configuration.nix +++ b/deploy/nixos/configuration.nix @@ -479,6 +479,22 @@ in ''; }; + # In-place rename migration: VITE_LAMASSU_* → VITE_BITSPIRE_* in the + # provisioned .env. The machine reads MACHINE_MODEL / FIAT_CODE / CASSETTES + # from this file on every boot; renaming the keys in code without renaming + # them here would boot a live machine on preset defaults (wrong bays, wrong + # fiat) at the next nightly pull. Idempotent: a migrated file has nothing + # left to match. Runs before bitspire.service starts. + system.activationScripts.bitspire-env-migration = { + deps = [ "users" ]; + text = '' + if [ -f /var/lib/bitspire/.env ] && grep -q '^VITE_LAMASSU_' /var/lib/bitspire/.env; then + sed -i 's/^VITE_LAMASSU_/VITE_BITSPIRE_/' /var/lib/bitspire/.env + echo "bitspire: migrated VITE_LAMASSU_* keys in /var/lib/bitspire/.env" + fi + ''; + }; + # Journal configuration services.journald = { extraConfig = '' diff --git a/deploy/nixos/factory-reset-atm.sh b/deploy/nixos/factory-reset-atm.sh index b46e7a3..e223cc9 100755 --- a/deploy/nixos/factory-reset-atm.sh +++ b/deploy/nixos/factory-reset-atm.sh @@ -40,8 +40,8 @@ ENV=/var/lib/bitspire/.env DB=/var/lib/bitspire/state.db # Preserve model + fiat from the existing .env (fall back to sintra/EUR). -model=$(grep -E '^VITE_LAMASSU_MACHINE_MODEL=' "$ENV" 2>/dev/null | cut -d= -f2- || true) -fiat=$(grep -E '^VITE_LAMASSU_FIAT_CODE=' "$ENV" 2>/dev/null | cut -d= -f2- || true) +model=$(grep -E '^VITE_BITSPIRE_MACHINE_MODEL=' "$ENV" 2>/dev/null | cut -d= -f2- || true) +fiat=$(grep -E '^VITE_BITSPIRE_FIAT_CODE=' "$ENV" 2>/dev/null | cut -d= -f2- || true) model=${model:-sintra} fiat=${fiat:-EUR} @@ -52,8 +52,8 @@ rm -f "$DB" "$DB-wal" "$DB-shm" # Truncate .env to the minimal image-baked template. cat > "$ENV" <