The provenance section claimed v8.1.5 was the last fully-open release.
GitHub history says otherwise: a9234d124d ("chore: add LICENSE",
2023-09-19) removed UNLICENSE and added the proprietary Appendix A SLA,
and the v8.1.5 tag (2023-09-21) already ships it. The true public-domain
boundary is that commit's parent, c0b69d1 ("chore: v8.6.0-beta.9") —
which is further along than 8.1.5 feature-wise.
lamassu-server's own boundary is unverified; flagged in the doc.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Env table (CLAUDE.md), .env.example, and the deploy README still framed
VITE_RELAY_URL / VITE_LNBITS_SERVER_PUBKEY as required/provisioned; they now come
from the pairing seed and are env overrides only. Also refresh the slimmed seed
shape, the relayUrl/pubkey module examples ("" not wss://relay.aiolabs.dev), and
the stale lamassu-next autoUpgrade flake URL (→ aiolabs/bitspire).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Note the wizard flow next to VITE_SPIRE_SEED + a dedicated Pairing section
(aiolabs/bitspire#52): unpaired → scan seed off camera → persist + relaunch →
normal boot pairs. Records the qr-over-jsqr choice rationale by reference.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fund-atm resolves its signer by resuming the bunker binding from state.db
(the connect token is already spent by the main app, so it can't re-pair);
falls back to a dev nsec via VITE_ATM_PRIVATE_KEY. better-sqlite3 marked
external in the esbuild bundle. .env.example + CLAUDE.md document
VITE_SPIRE_SEED as the prod identity, VITE_ATM_PRIVATE_KEY as dev-only.
(fund-atm is slated for deprecation in favour of the operator funding the
wallet directly via the LNbits UI — kept working for now.)
Part of Phase C, aiolabs/bitspire#52.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Closes gap 2 from coord log 2026-06-01T18:30Z. The LNbits withdraw
extension's nostr-transport RPC now populates `link.lnurl` from
`settings.lnbits_baseurl` (aiolabs/withdraw#1 / commit e9d911e), so the
ATM no longer needs a separate HTTP URL on the wire to compose the
LNURL-withdraw callback itself.
What goes:
- `VITE_LNBITS_HTTP_URL` env var (renderer + Electron main)
- `lnbitsHttpUrl` field on `LightningConfig`, `RuntimeConfig`, and the
Window mirror in `src/types/electron.d.ts`
- The manual `${lnbitsHttpUrl}/withdraw/api/v1/lnurl/${unique_hash}`
composition in `generateLnurlWithdraw`
- The `encodeLnurl` bech32 helper in `lightning.ts` (LNbits returns
bech32-encoded; we just `.toUpperCase()` to match BOLT/LNURL convention)
- `@scure/base` dep from `apps/machine/package.json` (only used by the
removed helper; clink still uses it directly)
- The `lnbitsHttpUrl` option + `LNBITS_HTTP_URL=…` env var + boot echo
in `deploy/nixos/bitspire-atm.nix`
- Doc references in CLAUDE.md, README.md, deploy/nixos/README.md,
docs/architecture-comparison.md, and the lightning-check skill
What stays:
- `link.lnurl` consumption, with an explicit error if LNbits returns
null (which signals `LNBITS_BASEURL` is unset on the server side —
better to fail clearly than silently)
- The receiver-side bech32 uppercasing (LNbits returns lowercase per
the standard library)
Why this is a net win:
- Removes a config-drift surface — if LNbits's external URL moved
(DNS, port, reverse-proxy rewrite), every ATM in the field would
stop issuing redeemable LNURL-withdraw QRs until reconfigured.
Now LNbits derives its own URL from `settings.lnbits_baseurl`,
one source of truth.
- Removes an extra provisioning step. No more `LNBITS_HTTP_URL=…`
before running `provision-atm.sh`; the relay + server pubkey suffice.
- Removes the misleading boot echo that triggered the §`18:30Z`
smoke triage confusion ("LNbits HTTP: <url>" read like ATM-→-LNbits
connectivity, when it was only ever a URL embedded in customer QRs).
Also adds a `# pragma: allowlist secret` marker above the
`VITE_ATM_PRIVATE_KEY` doc block in `.env.example` so the global
secret scanner stops false-positiving on the documentation prose.
Workspace typecheck + 24/24 apps/machine tests still green.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
System-level half of the lamassu → bitspire rebrand the rest of dev
already did at the path / service / package layers. Touches user/group
declarations, every systemd `User=` block, the udev rules filename, all
chown calls in flake.nix + live.nix, the displayManager autoLogin user,
the trusted-users nix entry, provision-atm.sh's ATM_USER, plus README +
CLAUDE.md doc references.
In-place migration for the Sintra dev unit (which auto-pulls dev at
04:00) lives in `system.activationScripts.bitspire-user-migration` and:
- copies `/home/lamassu/.ssh/authorized_keys` → `/home/bitspire/` once,
so SSH access survives the rename
- recursively chowns `/var/lib/bitspire` to the new bitspire UID on
every boot — cheap no-op once done, but covers the case where the
data dir was written by the now-removed lamassu UID
- leaves `/home/lamassu/` in place as evidence; operator can `rm -rf`
after confirming bitspire login works
Recovery path if the migration breaks SSH access: root key is still in
configuration.nix:142-144 (padreug@gizmo), so ssh root@<host> works.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Both top-level docs were stale after the lamassu-next → bitSpire +
Lightning.Pub → LNbits migration shipped on this branch. They still
listed @lamassu/* package scopes, treated Lightning.Pub as the backend,
described cash-in as ndebit/CLINK, and pointed at removed packages.
README.md: rewritten end-to-end. Calls out the branch model (main vs
dev) so contributors don't accidentally affect production ATMs.
Documents the actual cash-out (BOLT11 + subscribe_payments by hash)
and cash-in (LNURL-withdraw + subscribe_payments by tag/link_id) wire
flows. Quick-start uses the dev compose's bundled LNbits with
nostr-transport + the LNbits-internal nostrrelay extension (the relay
endpoint is ws://<host>:5001/nostrrelay/test — no separate strfry
container, this was a pitfall during Sintra provisioning). Disk-image
deployment summary points at deploy/nixos/README for full details.
CLAUDE.md: rewritten to describe dev-branch reality. Lists actual
package names (@bitSpire/*), notes packages/lightning was deleted in
3d, calls out the LightningBackend adapter pattern in services/
lightning.ts, and gives an env-var reference table + a wire-envelope
crib for kind-21000. Sintra-specific hardware notes (UART layout,
initrd modules for the ACPI eMMC controller) bake in everything we
hard-learned during the first flash.
Both docs now include an Acknowledgements / Provenance section that:
- credits Lamassu Industries AG's open-source lamassu-machine /
lamassu-server (the v8.1.5 release line) as the prior art the
HAL drivers and state machine derive from — bitSpire wouldn't
exist without that foundation
- explicitly states Lamassu transitioned to a proprietary,
source-available "Appendix A SLA" on 2024-01-26 with v8.1.6+
gated behind a paid OSA subscription, and that bitSpire
incorporates no code from v8.1.6 or later
- declares bitSpire independent of Lamassu Industries AG
- in CLAUDE.md specifically: a hard rule that future contributors
(or future Claude runs) must not pull / port / copy code from
lamassu-machine at v8.1.6+; only the 8.1.5 tree is in-scope
License clarification: AGPL-3.0 (matches LNbits, which we link
against) — dropped the earlier "matches LNbits + lamassu-machine
pedigree" phrasing since lamassu-machine is no longer under a free
license.
References:
https://blog.lamassu.is/updates-to-our-lamassu-software-license/https://github.com/lamassu/lamassu-machine
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Final rename commit covering user-facing copy and the docs that
describe current state. The mechanics of the rename are done after
this; the LNbits backend swap (phase 3) is the next concern.
Code branding strings (Lightning invoice descriptions):
apps/machine/src/services/lightning.ts
apps/machine/src/stores/atm.ts
docs/clink-protocol.md (example code blocks)
"Lamassu ATM Payment" → "bitSpire Payment"
"Lamassu ATM - Cash Out" → "bitSpire - Cash Out"
`Lamassu ATM - Buy ${n} sats`→ `bitSpire - Buy ${n} sats`
Top-level docs:
README.md, CLAUDE.md — title + intro + dir-tree references.
deploy/nixos/README.md — title + worktree-path commands.
docs/machine-installation.md — opening line carries the historical
note ("Lamassu Next" → "bitSpire"). The body still uses
`/opt/lamassu/` paths and the `lamassu-kiosk` systemd unit
because the dev branch is moving to NixOS disk-image flash
(phase 4) — this AppImage-sideload doc represents the legacy
deploy path. Leaving the LP/lamassu refs in there as part of
its historical context; a separate doc will describe the
NixOS path.
.claude/skills/nostr-check.md — header only.
DELIBERATELY left as "Lamassu Next" (pedagogical / historical):
- docs/adr/001-hal-architecture.md — frozen ADR; renaming
distorts the historical decision context.
- docs/architecture-comparison.md — deliberately contrasts
"lamassu-server" (prior) with "lamassu-next" (us at the time
of writing).
NOT done in this commit (deferred to LNbits/clean-up phase):
- docker/docker-compose.dev.yml container names
(lamassu-relay, lamassu-bitcoind, etc.) — these belong to the
LP-bearing dev stack that 3c/3d will significantly reshape.
Verified: pnpm typecheck clean (12/12 cached).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Failed dispenses (sats debited, cash not dispensed) were invisible —
transactions only recorded on 'complete'. Now records on 'dispenseError'
with status ('dispense_error'|'partial'|'complete'), error message, and
per-cassette detail.
Also fixes a bug in both HAL services where dispense results were mapped
by amounts-array index instead of cassette position, causing swapped
denomination counts when cassette order differs from request order.
Schema v3→v4: adds status/error columns to transactions, new
cassette_bills table for per-cassette provisioned/dispensed/rejected.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add dev.sh script for managing regtest development environment
- Implement cmd_fund to fund ATM app owner via Lightning.Pub API
- Add --fund flag to cmd_up for automatic funding on startup
- Update setup_atm_app to write VITE_APP_ID to machine .env
- Fix Electron IPC to pass appId and extensionApiUrl to renderer
- Restructure repo from nested lamassu-next/ to root
The dev.sh script now supports:
- ./dev.sh up --fund # Start regtest and auto-fund ATM
- ./dev.sh fund # Fund existing ATM app
- ./dev.sh status # Show environment status
- ./dev.sh reset # Clean restart
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add lamassu-server, lamassu-machine, lamassu-install as submodules
- Add CLAUDE.md with development guidance
- Add docs/modernization-plan.md with 2026 refactoring roadmap
- Add .gitignore for Node.js/Nix development
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>