The first ever aarch64 build of the app died here, on a Raspberry Pi 4:
auto-patchelf could not satisfy dependency liblog.so wanted by
node_modules/@serialport/bindings-cpp/prebuilds/android-arm64/node.napi.armv8.node
auto-patchelf could not satisfy dependency libc++_shared.so wanted by
(the same file)
@serialport/bindings-cpp ships prebuilds for every platform it supports:
android-arm, android-arm64, darwin, linux-arm, linux-arm64, linux-x64 in
both glibc and musl, win32-ia32 and win32-x64. installPhase copied the
whole directory.
On x86_64 that was harmless because autoPatchelf skips ELF files whose
architecture does not match the host, so the Android and ARM prebuilds
were never touched. On aarch64 the android-arm64 prebuild IS the host
architecture, so autoPatchelf picks it up and goes looking for Android's
liblog.so and libc++_shared.so, which NixOS does not have. The failure was
invisible until someone built for a second architecture.
Keep only the prebuild the target can load, selected from
stdenv.hostPlatform: linux-arm64 on aarch64, linux-x64 elsewhere, glibc
rather than musl.
Pruning rather than adding those two libraries to
autoPatchelfIgnoreMissingDeps, which would have been the one-line fix.
Teaching autoPatchelf to tolerate a binary we never load, for a platform
we do not target, leaves the foreign prebuilds in the closure and leaves
the same trap set for the next architecture. The existing
"libc.musl-x86_64.so.1" entry in that list is this same problem solved the
other way; it is now redundant, and is left in place only because this
commit is unblocking a machine mid-build and is not the moment to find out
whether something else depended on it.
Verified on x86_64: the app still builds, ships linux-x64/node.napi.glibc.node
alone where it previously carried nine platforms, and comes to 25M.
Rebuild @pokusew/pcsclite (V8 C++ addon) against Electron headers like
better-sqlite3, and package nfc-pcsc + @pokusew/pcsclite into the runtime
node_modules. Its binding.gyp hardcodes Debian /usr/include/PCSC + /usr/lib,
so point the compiler/linker at nixpkgs pcsclite via CPATH/LIBRARY_PATH
(winscard.h lives under include/PCSC); pcsclite.lib in buildInputs lets
autoPatchelf wire libpcsclite.so.1 into the .node RPATH. Bumps the pnpmDeps
hash for the added nfc-pcsc dependency.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adding `qr` (and dropping `jsqr`) changed pnpm-lock.yaml, invalidating the
fixed-output hash for the vendored pnpm store. Without this the NixOS build
of the ATM app fails at the FOD before activation.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
nixpkgs 24.11 made `pkgs.python3` an alias for Python 3.12, which
removed `distutils` from stdlib. node-gyp@9.4.1 (transitively pulled
in by better-sqlite3) still imports `distutils.version`, so the app
derivation failed with `ModuleNotFoundError: No module named
'distutils'` on the better-sqlite3 rebuild step.
Pin to python311 — still in 24.11 nixpkgs. Drop once pnpm-lock bumps
better-sqlite3 to a release whose node-gyp@10+ doesn't need distutils.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three root-level identifier renames:
- Root package.json `name`: lamassu-next → bitSpire
- flake.nix nixosConfigurations.lamassu-live-*: kept (legacy
aliases) and ADDED bitSpire-live-* alongside. Both work.
Drop the lamassu-* aliases at the final cutover once nothing
references them.
- nix/mkAtmApp.nix `pname`: lamassu-atm-app → bitspire-atm-app
(lowercase to match nix package naming conventions; the
Electron app's externally-facing names get their own commit).
What's NOT renamed here (per the plan):
- Hardware-named outputs (douro, tejo, sintra, batm3) — those
are physical product names.
- nixosConfigurations.{douro,tejo,sintra,batm3} ergonomic
aliases — same reason.
- nixosModules.lamassu-atm + its imported file — that's the
systemd service, deferred to 2d.
- apps/machine/package.json appId/productName — Electron
identity, deferred to 2c.
Verified:
pnpm typecheck clean (12/12 cached)
nix eval .#nixosConfigurations.bitSpire-live-sintra ✓
nix eval .#packages.x86_64-linux.atm-app-sintra.pname ✓
→ "bitspire-atm-app"
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add support/help pages accessible via a ? button on the idle screen.
Pages are driven by .md files in /var/lib/lamassu-atm/support/ —
operators can customize content without rebuilding the app.
Features:
- Tabbed view with markdown rendering (via marked)
- Standalone URLs auto-render as QR codes (scannable from phone)
- Table URLs: click-to-reveal QR codes (prevents accidental scans)
- Yes/No rendered as green checkmarks / red X marks
- Wallet comparison table with download QR codes
- FAQ with Lightning-only clarification
- Support page with operator Nostr QR placeholder
- Custodial vs non-custodial footnote
- Large text for touchscreen accessibility
- Centered layout for short-content pages
Closes#36
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Standalone Node.js script that generates a Lightning invoice for
the ATM's Lightning.Pub account. Reads config from .env, connects
to the relay, creates an invoice via Nostr RPC, displays a QR code
in the terminal, and prints the BOLT11.
Bundled as self-contained CJS with esbuild (all dependencies inlined)
so it works from the nix store without separate node_modules.
Usage: fund-atm <amount_sats>
e.g. fund-atm 100000
fund-atm 100000 sats
Added to NixOS systemPackages for both live and installed configs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move deploy/nixos/flake.nix into the root flake.nix, adding mkAtmApp
for pure Nix builds of the Electron app (no local pnpm needed). Simplify
build-iso.sh to a thin wrapper around `nix build .#iso-<model>`. Add
douro hardware configuration. Streamline live.nix to consume the
Nix-built app package.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>