diff --git a/apps/machine/.env.example b/apps/machine/.env.example
index 8124aa4..1bc2c2e 100644
--- a/apps/machine/.env.example
+++ b/apps/machine/.env.example
@@ -49,6 +49,13 @@ VITE_ATM_PRIVATE_KEY=
# (manual dispense, remote management). Decoupled from Lightning.Pub identity.
# VITE_OPERATOR_PUBKEYS=abcd1234...,ef567890...
+# =============================================================================
+# Maintenance Mode
+# =============================================================================
+
+# Show "Under Service" screen and block all transactions
+# VITE_MAINTENANCE_MODE=true
+
# =============================================================================
# Mock Fallback (Production Safety)
# =============================================================================
diff --git a/apps/machine/electron/main.ts b/apps/machine/electron/main.ts
index 04c61db..875cf73 100644
--- a/apps/machine/electron/main.ts
+++ b/apps/machine/electron/main.ts
@@ -187,6 +187,9 @@ ipcMain.handle('get-config', () => {
// Operator identity (comma-separated hex pubkeys)
operatorPubkeys: process.env.VITE_OPERATOR_PUBKEYS || '',
+
+ // Maintenance mode — show "out of service" screen
+ maintenanceMode: process.env.VITE_MAINTENANCE_MODE === 'true',
}
})
diff --git a/apps/machine/electron/preload.ts b/apps/machine/electron/preload.ts
index 952ede7..17f3ab4 100644
--- a/apps/machine/electron/preload.ts
+++ b/apps/machine/electron/preload.ts
@@ -26,6 +26,7 @@ export interface RuntimeConfig {
cassettes?: string
allowMockFallback: boolean
operatorPubkeys: string
+ maintenanceMode: boolean
}
/**
diff --git a/apps/machine/src/App.vue b/apps/machine/src/App.vue
index 4d06d80..c0d0bb1 100644
--- a/apps/machine/src/App.vue
+++ b/apps/machine/src/App.vue
@@ -33,6 +33,16 @@ onMounted(async () => {
})
}
+ // Check maintenance mode before initializing anything
+ const config = isElectron ? await window.electronAPI?.getConfig() : null
+ const maintenanceMode =
+ config?.maintenanceMode || import.meta.env.VITE_MAINTENANCE_MODE === 'true'
+
+ if (maintenanceMode) {
+ atmStore.initError = 'maintenance'
+ return
+ }
+
try {
if (isElectron) {
await atmStore.initializeForProduction()
@@ -88,11 +98,20 @@ function toggleLiveServices() {
- This machine is temporarily out of service. Please try again later or use another machine. + {{ + atmStore.initError === 'maintenance' + ? 'This machine is currently being serviced. We will be back shortly.' + : 'This machine is temporarily out of service. Please try again later or use another machine.' + }}
-+
{{ atmStore.initError }}
diff --git a/apps/machine/src/types/electron.d.ts b/apps/machine/src/types/electron.d.ts index bccb0e8..7e13fb7 100644 --- a/apps/machine/src/types/electron.d.ts +++ b/apps/machine/src/types/electron.d.ts @@ -15,6 +15,7 @@ export interface RuntimeConfig { cassettes?: string allowMockFallback: boolean operatorPubkeys: string + maintenanceMode: boolean } export interface AtmSecrets {