bitspire/apps/machine/electron
Padreug ea4c1f406b fix(machine): make the dispenser optional, as the validator already was
initializeHal created and initialised the dispenser unconditionally, so a
missing dispenser device threw and aborted the WHOLE of HAL init — taking
the validator down with it, even when the validator was present and
working.

The Pi bring-up hit exactly that. With a Pyramid Apex correctly wired and
enumerated on /dev/ttyValidator0:

  [ATM] Validator device: /dev/ttyValidator0
  [ATM] Dispenser device: /dev/ttyDispenser-not-fitted
  [Electron] HAL init failed: cannot open /dev/ttyDispenser-not-fitted
  [Recovery] Reloading renderer to re-attempt initialization

and round again, forever, with a perfectly good acceptor attached.

The validator has been optional since it was written — it checks the
device exists, catches init failures, and logs "running dispenser-only".
The dispenser had no equivalent. That asymmetry was the bug, not the
placeholder device path that exposed it: a cash-in-only machine is a
legitimate configuration, and the Raspberry Pi reference build is one.

Mirrors the validator's handling exactly: existence check, try/catch,
null on failure, and a log line saying what the machine will do instead
("running cash-in only"). Three call sites then need guarding —
dispenseCash returns a clear "No dispenser fitted on this machine —
cash-out unavailable" rather than dereferencing null, setCassettes still
records the layout but skips the re-init, and cleanup uses an optional
call.

This also removes the sharp edge from the rpi4/rpi5 presets added in the
previous commit. Their dispenser block points at a path that does not
exist because DispenseType has no 'none' variant and DeviceConfig
requires the field. That is still worth fixing properly with a real
'none' variant, but the machine no longer has to care.
2026-09-29 18:16:41 +02:00
..
__tests__ fix(machine): decrement cassettes by position, not denomination, on cash-out 2026-07-04 00:28:24 +02:00
fund-atm.ts chore(machine): fund-atm resumes from binding; VITE_SPIRE_SEED docs/env 2026-06-19 00:15:59 +02:00
hal-service.ts fix(machine): make the dispenser optional, as the validator already was 2026-09-29 18:16:41 +02:00
lnurl-pay.test.ts feat(machine): Bolt Card (NFC) tap-to-receive on cash-in 2026-08-06 00:30:13 +02:00
lnurl-pay.ts feat(machine): Bolt Card (NFC) tap-to-receive on cash-in 2026-08-06 00:30:13 +02:00
lnurl-withdraw.test.ts feat(machine): LNURL-withdraw executor for Bolt Card cash-out (LUD-03) 2026-08-05 04:34:38 +02:00
lnurl-withdraw.ts feat(machine): LNURL-withdraw executor for Bolt Card cash-out (LUD-03) 2026-08-05 04:34:38 +02:00
main.ts feat(machine): Bolt Card (NFC) tap-to-receive on cash-in 2026-08-06 00:30:13 +02:00
nfc-service.test.ts fix(machine): read NTAG424 NDEF via Capability Container (Bolt Card FileID) 2026-08-05 20:02:26 +02:00
nfc-service.ts fix(nfc): auto-recover a wedged CCID reader via USB power-cycle 2026-08-06 19:51:39 +02:00
preload.ts feat(machine): Bolt Card (NFC) tap-to-receive on cash-in 2026-08-06 00:30:13 +02:00
state-store.ts fix(machine): decrement cassettes by position, not denomination, on cash-out 2026-07-04 00:28:24 +02:00
tsconfig.json feat(machine): add HAL IPC bridge for real hardware in Electron 2026-02-25 17:02:13 -05:00
tsconfig.preload.json feat(docker): add dev.sh with auto-funding and ATM app setup 2026-02-15 14:19:16 -05:00