docs: finish the LNbits-era doc sweep across docs/ + .claude/skills/
Second + final batch of the doc refresh. README + CLAUDE went out in
8c9ae29; deploy/nixos/README + obsolete-flow flags in 924844f. This
commit covers everything left.
docs/machine-installation.md
Was describing a manual AppImage scp deploy + a `lamassu-kiosk`
systemd unit that hasn't been the deployment path for months.
Replaced with a high-level "what the pipeline does and why"
overview that points at deploy/nixos/README.md for the full
command-by-command walkthrough. Includes the BATM3 chassis-mod
note (custom Dell OptiPlex retrofit, not a stock Dell).
docs/architecture-comparison.md
Rewrote the comparison to be lamassu-server (≤ v8.1.5) vs bitSpire
(LNbits-backed) instead of the original lamassu-server vs LP-backed
lamassu-next framing. Updated the cash-out + cash-in flow diagrams
to show the actual nostr-transport path (LNbits-bundled nostrrelay
extension at ws://<host>:5001/nostrrelay/test, no separate strfry
container). Replaced the migration-path section with a softer
"when to choose what" framing that includes Lamassu's current
commercial offering as a legitimate third option. Added a header
pointer to the Acknowledgements section.
docs/business-model.md
Light touch-ups: Lightning.Pub → LNbits where it appeared, swapped
the [[ndebit-cash-in-flow]] link for [[architecture-comparison]],
noted the kind-30078 service beacon for availability broadcasts.
docs/device-configuration.md
Dropped "Lamassu" branding from the machine-model headings
(Sintra / tejo / douro / batm3 are referenced by hardware identity
here, not by Lamassu's product line). Added the Sintra-specific
ttyS4-vs-placeholder-ttyS1..3 gotcha we hard-learned during the
first flash. Corrected the BATM3 entry: stock GeneralBytes chassis
with a Dell OptiPlex 9030 AIO motherboard physically grafted in,
NOT a Dell out of the box. Updated the example /dev/ttyJ* symlink
output to match what a healthy Sintra actually shows.
docs/adr/001-hal-architecture.md
ADRs are historical artifacts — kept the original decision text
intact. Added a postscript noting:
- The package rename @lamassu/hal → @bitSpire/hal
- The v8.1.5 boundary on any lamassu-machine source-tree
references (Lamassu's 2024-01-26 license transition)
- That the "Remaining Work" list is complete and the first
successful Sintra hardware integration ran on 2026-05-13
.claude/skills/lightning-check.md
Rewrote end-to-end. Was Lightning.Pub-flavoured with CLINK kinds
21001/21002 as the primary flows; now validates the LNbits nostr-
transport surface (kind-21000 envelope, NIP-44 v2 encryption,
subscribe_payments filter discipline, lnurlw link composition).
Preserved a --clink mode for the still-live kind-21003 operator-
management surface. Includes a "what to check" rubric for cash-out
vs cash-in flows that mirrors the actual code in
apps/machine/src/services/lightning.ts.
.claude/skills/hal-check.md
Two pivots: (1) acknowledge ADR-001's TypeScript-not-Rust choice
and reframe all the safety checklists in TS-flavour (type safety,
discriminated unions, single-writer serial, bounded emitters)
instead of Rust-flavour (unsafe, borrow checker). (2) Add explicit
v8.1.5 provenance boundary plus a "forbidden operations" section
that prohibits diffing or porting from v8.1.6+ lamassu-machine
source. Updated the port-validation source-reference table to
list TS file paths under packages/hal/ instead of Rust paths.
.claude/skills/docs.md
@lamassu/* → @bitSpire/*. Replaced the Lightning.Pub mermaid
diagram with a current cash-out flow showing the nostr-transport
RPC + subscribe_payments push path. Left the createOffer noffer
example in the API-docs template section since it's illustrative
("here's what a good TSDoc block looks like") rather than current
reference documentation.
.claude/skills/test.md
One-line: @lamassu/nostr-client → @bitSpire/nostr-client in the
pnpm-filter example.
deploy/nixos/README.md
Single touch-up: clarified the douro/batm3 hardware-module comments
to reflect that BATM3 is a custom-installed Dell board in a
GeneralBytes BATM3 chassis (not a Dell OEM).
Files NOT touched in this sweep (intentionally):
- packages/hal/src/**/*.ts attribution comments — those reference
"lamassu-machine" in their port-source headers. Those are
factually accurate (the drivers ARE ported from there, up to
v8.1.5) and constitute necessary license/attribution metadata.
Editing them would erase the provenance trail.
- .claude/skills/{nostr-check,security}.md — already protocol-
neutral, no LP/lamassu references to clean up.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0b94bef4be
commit
53b0d382e8
10 changed files with 692 additions and 792 deletions
|
|
@ -1,338 +1,306 @@
|
|||
# Architecture Comparison: Nostr-Native vs Traditional Lamassu
|
||||
# Architecture Comparison: bitSpire vs Traditional Lamassu
|
||||
|
||||
This document compares the Nostr-native Lightning ATM architecture (Lamassu Next) with the traditional lamassu-server/machine implementation to help operators evaluate the transition.
|
||||
This document compares the bitSpire architecture — a Nostr-native Lightning ATM talking to LNbits over the nostr-native-transport — with the traditional `lamassu-server` + `lamassu-machine` architecture. The goal is to help an operator evaluating an open-source Lightning ATM stack understand what they're choosing between.
|
||||
|
||||
## Executive Summary
|
||||
> A note on prior art: bitSpire's hardware drivers and cash-flow state machine derive from Lamassu Industries AG's open-source `lamassu-machine` and `lamassu-server` projects up to and including the v8.1.5 release line (the last published under a fully-open license). Lamassu [transitioned to a proprietary source-available license](https://blog.lamassu.is/updates-to-our-lamassu-software-license/) on 2024-01-26; bitSpire does **not** incorporate code from v8.1.6 or later and is not affiliated with Lamassu Industries AG. See the [Acknowledgements](../README.md#acknowledgements) section of the top-level README.
|
||||
|
||||
| Aspect | Traditional (lamassu-server) | Nostr-Native (lamassu-next) |
|
||||
| ------------------------ | ---------------------------- | ---------------------------------- |
|
||||
| **Communication** | Custom WebSocket protocol | Nostr relay (NIP-01) |
|
||||
| **Identity** | Server-issued credentials | Cryptographic keypairs (npub/nsec) |
|
||||
| **Account System** | PostgreSQL + custom auth | Lightning.Pub (Nostr-native) |
|
||||
| **Payment Protocol** | Direct LND RPC | CLINK protocol (kinds 21001-21003) |
|
||||
| **Infrastructure** | Server + DB + Admin UI | Relay (optional self-hosted) |
|
||||
| **Wallet Compatibility** | Lamassu-specific | Any CLINK-compatible wallet |
|
||||
## Executive summary
|
||||
|
||||
| Aspect | Traditional (`lamassu-server` ≤ v8.1.5) | bitSpire |
|
||||
|---|---|---|
|
||||
| **Software license** | AGPL-3.0 (v8.1.5); v8.1.6+ is proprietary SLA | AGPL-3.0 |
|
||||
| **Communication** | Custom WebSocket + GraphQL over HTTPS | Nostr kind-21000 events (NIP-01, NIP-44 v2) over a relay |
|
||||
| **Identity** | Server-issued client certs | Nostr keypairs (`nsec`/`npub`) |
|
||||
| **Account system** | PostgreSQL + custom auth | LNbits wallet auto-created from ATM's nostr pubkey |
|
||||
| **Payment protocol** | Direct LND RPC | BOLT11 (cash-out) + LNURL-withdraw (cash-in) |
|
||||
| **Server infrastructure** | App server + DB + Admin UI | A relay + an LNbits instance (both can be one container) |
|
||||
| **Wallet compatibility** | Any Lightning wallet (cash-out); custom flow for cash-in | Any Lightning wallet (BOLT11 + LNURL-withdraw — both widely supported) |
|
||||
| **State location** | Centralized in PostgreSQL | Distributed: LNbits holds Lightning state, ATM holds session state |
|
||||
|
||||
---
|
||||
|
||||
## Traditional Architecture (lamassu-server/machine)
|
||||
|
||||
### Overview
|
||||
## Traditional architecture (lamassu-server / lamassu-machine, v8.1.5)
|
||||
|
||||
```
|
||||
┌─────────────────┐ WebSocket ┌─────────────────────┐
|
||||
│ ATM Machine │◄─────────────────────────►│ lamassu-server │
|
||||
│ (lamassu-machine)│ │ │
|
||||
└─────────────────┘ │ ┌───────────────┐ │
|
||||
│ │ PostgreSQL │ │
|
||||
┌─────────────────┐ HTTPS │ └───────────────┘ │
|
||||
│ Admin UI │◄─────────────────────────►│ │
|
||||
│ (React SPA) │ GraphQL │ ┌───────────────┐ │
|
||||
└─────────────────┘ │ │ LND │ │
|
||||
│ └───────────────┘ │
|
||||
┌─────────────────┐ │ │
|
||||
│ Customer Wallet │◄── Lightning Invoice ─────│ ┌───────────────┐ │
|
||||
│ (any LN wallet) │ │ │ Compliance │ │
|
||||
└─────────────────┘ │ │ Services │ │
|
||||
│ └───────────────┘ │
|
||||
└─────────────────────┘
|
||||
┌──────────────────┐ WebSocket ┌─────────────────────┐
|
||||
│ ATM (kiosk) │◄──────────────────────────►│ lamassu-server │
|
||||
│ lamassu-machine │ client-cert auth │ │
|
||||
└──────────────────┘ │ ┌───────────────┐ │
|
||||
│ │ PostgreSQL │ │
|
||||
┌──────────────────┐ HTTPS │ └───────────────┘ │
|
||||
│ Admin UI │◄──────────────────────────►│ │
|
||||
│ (React SPA) │ GraphQL │ ┌───────────────┐ │
|
||||
└──────────────────┘ │ │ LND │ │
|
||||
│ └───────────────┘ │
|
||||
┌──────────────────┐ │ │
|
||||
│ Customer Wallet │◄── Lightning Invoice ──────│ ┌───────────────┐ │
|
||||
│ (any LN wallet) │ │ │ Compliance │ │
|
||||
└──────────────────┘ │ │ Services │ │
|
||||
│ └───────────────┘ │
|
||||
└─────────────────────┘
|
||||
```
|
||||
|
||||
### Components
|
||||
|
||||
| Component | Description |
|
||||
| ------------------- | ------------------------------------------------ |
|
||||
| **lamassu-server** | Node.js Express + Apollo GraphQL backend |
|
||||
| **lamassu-machine** | Node.js kiosk application with hardware drivers |
|
||||
| **PostgreSQL** | Central database for transactions, users, config |
|
||||
| **Admin UI** | React dashboard for fleet management |
|
||||
| **LND** | Lightning Network Daemon for payments |
|
||||
| Component | Description |
|
||||
|---|---|
|
||||
| `lamassu-server` | Node.js (Express + Apollo GraphQL) backend |
|
||||
| `lamassu-machine` | Node.js kiosk app with hardware drivers |
|
||||
| PostgreSQL | Central DB for transactions, users, config |
|
||||
| Admin UI | React dashboard for fleet management |
|
||||
| LND | Lightning Network Daemon for payments |
|
||||
|
||||
### Communication Flow
|
||||
### Cash-out flow
|
||||
|
||||
1. Machine boots and authenticates with server via client certificate
|
||||
2. Server pushes configuration and state via WebSocket
|
||||
3. Customer initiates transaction at machine
|
||||
4. Machine requests invoice/address from server
|
||||
1. Machine boots, authenticates via client cert
|
||||
2. Server pushes config + state over WebSocket
|
||||
3. Customer initiates cash-out at machine
|
||||
4. Machine asks server for an invoice
|
||||
5. Server creates invoice via LND, stores in PostgreSQL
|
||||
6. Customer pays invoice
|
||||
7. Server detects payment, updates database
|
||||
8. Server notifies machine to dispense cash
|
||||
9. Transaction logged in PostgreSQL for compliance
|
||||
6. Customer pays the invoice
|
||||
7. Server polls LND, detects payment, updates DB
|
||||
8. Server notifies machine to dispense
|
||||
9. Compliance services log the transaction
|
||||
|
||||
### Characteristics
|
||||
|
||||
- **Centralized**: All state lives in server's PostgreSQL
|
||||
- **Operator-managed**: Requires significant infrastructure
|
||||
- **Custom protocol**: WebSocket messages are Lamassu-specific
|
||||
- **Tight coupling**: Machine depends entirely on server availability
|
||||
- **Compliance-ready**: Built-in KYC/AML features
|
||||
- **Centralized**: all state in `lamassu-server`'s PostgreSQL
|
||||
- **Operator-managed**: requires real infrastructure (server, DB, certs, monitoring)
|
||||
- **Tightly coupled**: machine doesn't transact if server is unreachable
|
||||
- **Compliance-ready**: KYC/AML hooks built in (relevant in regulated jurisdictions)
|
||||
|
||||
---
|
||||
|
||||
## Nostr-Native Architecture (lamassu-next)
|
||||
|
||||
### Overview
|
||||
## bitSpire architecture
|
||||
|
||||
```
|
||||
┌─────────────────┐ ┌─────────────────┐
|
||||
│ ATM Machine │ │ Customer │
|
||||
│ (npub_atm) │ │ Wallet │
|
||||
└────────┬────────┘ │ (npub_user) │
|
||||
│ └────────┬────────┘
|
||||
│ NIP-01 events │
|
||||
│ NIP-44 encrypted │ CLINK protocol
|
||||
▼ ▼
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Nostr Relay │
|
||||
│ (strfry, nostr-rs, etc.) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
│ │
|
||||
│ Kind 21000 (RPC) │
|
||||
│ Kind 21001-21003 (CLINK) │
|
||||
▼ ▼
|
||||
┌─────────────────┐ ┌─────────────────┐
|
||||
│ Lightning.Pub │ │ Lightning.Pub │
|
||||
│ (ATM account) │◄── Lightning Payment ─────►│ (User account) │
|
||||
└────────┬────────┘ └─────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ LND │
|
||||
└─────────────────┘
|
||||
┌──────────────────┐ ┌──────────────────┐
|
||||
│ ATM (kiosk) │ │ Customer wallet │
|
||||
│ npub_atm │ │ (any LN wallet) │
|
||||
└────────┬─────────┘ └────────┬─────────┘
|
||||
│ kind-21000 │
|
||||
│ NIP-44 v2 encrypted │ BOLT11
|
||||
▼ │ LNURL-withdraw
|
||||
┌───────────────────────────────┐ │
|
||||
│ Nostr Relay │ │
|
||||
│ (LNbits' bundled │ │
|
||||
│ nostrrelay extension, or │ │
|
||||
│ any standalone relay) │ │
|
||||
└────────────────┬──────────────┘ │
|
||||
│ │
|
||||
│ kind-21000 RPC + push │
|
||||
▼ │
|
||||
┌───────────────────────┐ ◄──────────────────────┘
|
||||
│ LNbits │ BOLT11 settle / LNURLw redeem
|
||||
│ ┌──────────────────┐ │
|
||||
│ │ FakeWallet (dev) │ │
|
||||
│ │ or LND/CLN/etc. │ │
|
||||
│ └──────────────────┘ │
|
||||
└───────────────────────┘
|
||||
```
|
||||
|
||||
### Components
|
||||
|
||||
| Component | Description |
|
||||
| ------------------- | ----------------------------------------------- |
|
||||
| **Nostr Relay** | Message broker (strfry, nostr-rs-relay) |
|
||||
| **Lightning.Pub** | Nostr-native account system wrapping LND |
|
||||
| **ATM Machine** | Tauri + Vue 3 kiosk identified by npub |
|
||||
| **Customer Wallet** | Any CLINK-compatible wallet (ShockWallet, etc.) |
|
||||
| Component | Description |
|
||||
|---|---|
|
||||
| Nostr relay | Message broker. In the dev compose, this is LNbits's bundled `nostrrelay` extension at `ws://<host>:5001/nostrrelay/test`. Production can use any standalone relay both peers subscribe to |
|
||||
| LNbits | Lightning wallet platform; runs the `nostr-native-transport` branch. Auto-creates a wallet on first contact from any nostr pubkey |
|
||||
| ATM machine | Electron + Vue 3 kiosk identified by its `npub`. Signing key IS the credential to LNbits |
|
||||
| Customer wallet | Any LN wallet that handles BOLT11 (cash-out) and LNURL-withdraw (cash-in) — most do |
|
||||
|
||||
### Communication Flow (Cash-In Example)
|
||||
### Cash-out flow (customer pays ATM, gets cash)
|
||||
|
||||
1. ATM generates ephemeral keypair or uses persistent npub
|
||||
2. Customer scans QR containing `ndebit` (debit authorization)
|
||||
3. Customer's wallet connects to relay, finds ATM's Lightning.Pub
|
||||
4. Wallet creates invoice via Lightning.Pub RPC (kind 21000)
|
||||
5. Wallet sends debit request (kind 21002) to ATM's npub
|
||||
6. ATM verifies request, approves payment
|
||||
7. Lightning.Pub pays invoice, returns preimage
|
||||
8. ATM detects payment confirmation
|
||||
9. ATM dispenses cash
|
||||
10. Transaction recorded as Nostr event (optional)
|
||||
1. ATM publishes a kind-21000 event to LNbits: `{rpc_name: "create_invoice", body: {amount: <sats>, memo: "..."}}`
|
||||
2. LNbits replies on the same relay with the BOLT11 invoice
|
||||
3. ATM displays the BOLT11 as a QR
|
||||
4. Customer scans, pays from any LN wallet
|
||||
5. LNbits's Lightning backend (FakeWallet / LND / CLN / etc.) settles the payment
|
||||
6. LNbits pushes a kind-21000 settlement event to the ATM, filtered by `payment_hash`
|
||||
7. ATM dispenses cash
|
||||
|
||||
### Cash-in flow (customer hands ATM cash, gets sats)
|
||||
|
||||
1. ATM publishes `lnurlw_create_link` (kind-21000) to LNbits with `{uses: 1, max_withdrawable: <sats>}`
|
||||
2. LNbits replies with a `WithdrawLink` (a `unique_hash` plus metadata)
|
||||
3. ATM composes the callback URL: `{LNBITS_HTTP_URL}/withdraw/api/v1/lnurl/{unique_hash}` and bech32-encodes it as an LNURL
|
||||
4. ATM displays the LNURL as a QR
|
||||
5. Customer scans with any LNURL-withdraw-capable wallet, redeems it
|
||||
6. LNbits settles the withdrawal via its Lightning backend
|
||||
7. LNbits pushes a kind-21000 settlement event to the ATM, filtered by `tag="withdraw"` + `link_id`
|
||||
8. ATM marks the session complete (cash already physically accepted earlier in the flow)
|
||||
|
||||
### Characteristics
|
||||
|
||||
- **Decentralized**: No single server owns state
|
||||
- **Interoperable**: Standard protocols (Nostr, CLINK, Lightning)
|
||||
- **Keypair identity**: ATM is identified by npub, not server account
|
||||
- **Loose coupling**: ATM can work with any relay/Lightning.Pub
|
||||
- **Privacy-first**: No central transaction logs required
|
||||
- **Decentralized message layer**: any nostr relay works, no proprietary protocol
|
||||
- **No admin tokens on the kiosk**: the ATM's signing key IS the credential — there are no HTTP API tokens or client certs to leak. LNbits derives the calling identity from the event signature.
|
||||
- **Loose coupling**: ATM and LNbits don't need to share a network segment; only a relay both reach
|
||||
- **Privacy-first**: no central transaction logs unless the operator builds them. LNbits stores its own ledger, but bitSpire writes no user-identifying data anywhere on its side.
|
||||
|
||||
---
|
||||
|
||||
## Detailed Comparison
|
||||
## Detailed comparison
|
||||
|
||||
### 1. Infrastructure Requirements
|
||||
### 1. Infrastructure requirements
|
||||
|
||||
| Requirement | Traditional | Nostr-Native |
|
||||
| -------------------- | ------------------------------------ | -------------------------------- |
|
||||
| **Server Hardware** | Dedicated server (4+ GB RAM, SSD) | Optional (can use public relays) |
|
||||
| **Database** | PostgreSQL (backup, maintenance) | None required |
|
||||
| **SSL Certificates** | Required (client certs for machines) | Not required |
|
||||
| **Domain Name** | Required | Optional |
|
||||
| **Static IP** | Recommended | Not required |
|
||||
| **Firewall Rules** | Complex (multiple ports) | Simple (outbound WebSocket only) |
|
||||
| Requirement | Traditional | bitSpire |
|
||||
|---|---|---|
|
||||
| Server hardware | Dedicated server (4+ GB RAM, SSD) | An LNbits instance (1 GB RAM is plenty in production) |
|
||||
| Database | PostgreSQL (operator managed) | LNbits's SQLite (or its configured DB; LNbits manages it) |
|
||||
| Client TLS | Required (client certs per machine) | Not required (signature-based auth over a nostr relay) |
|
||||
| Domain | Required | Optional (only if exposing LNbits HTTP for LNURL redemption from the public internet) |
|
||||
| Static IP | Recommended | Not required |
|
||||
| Firewall | Multiple inbound ports | Outbound WebSocket to a relay; inbound only on the LNbits HTTP port for LNURL callbacks |
|
||||
|
||||
**Advantage: Nostr-Native** - Dramatically simpler infrastructure. An operator can start with public relays and self-host later.
|
||||
**Edge: bitSpire.** A single-container LNbits with FakeWallet is enough for an operator to evaluate the whole stack end-to-end.
|
||||
|
||||
### 2. Security Model
|
||||
### 2. Security model
|
||||
|
||||
| Aspect | Traditional | Nostr-Native |
|
||||
| -------------------- | ------------------------------- | ------------------------ |
|
||||
| **Machine Auth** | Client certificates | Keypair (nsec) |
|
||||
| **Message Security** | TLS | NIP-44 encryption |
|
||||
| **Identity Theft** | Steal cert + key | Steal nsec only |
|
||||
| **Compromise Scope** | All machines if server breached | Individual machine only |
|
||||
| **Key Storage** | Server manages | Machine manages own keys |
|
||||
| Aspect | Traditional | bitSpire |
|
||||
|---|---|---|
|
||||
| Machine auth | Client certificates | Nostr signing key |
|
||||
| Transport security | TLS | NIP-44 v2 (XChaCha20 + HMAC-SHA256) |
|
||||
| Compromise scope | Server breach exposes all machines | One machine's `nsec` compromises only that machine |
|
||||
| Key storage | Server manages | Machine manages its own keys (`/var/lib/bitspire/.env`, mode 0600) |
|
||||
| Revocation | CA-style cert revocation | Operator can stop honoring a pubkey at the LNbits layer; no fleet-wide blast radius |
|
||||
|
||||
**Advantage: Nostr-Native** - Compromise of one machine doesn't affect others. No central point of failure.
|
||||
**Edge: bitSpire.** No central authority that, if compromised, exposes the whole fleet. Per-machine compromise stays contained.
|
||||
|
||||
### 3. Payment Flow
|
||||
### 3. Payment flow
|
||||
|
||||
| Aspect | Traditional | Nostr-Native |
|
||||
| ------------------------ | ---------------------- | ------------------------------ |
|
||||
| **Invoice Creation** | Server creates via LND | Lightning.Pub via Nostr RPC |
|
||||
| **Payment Detection** | Server polls LND | Subscription to payment events |
|
||||
| **Wallet Compatibility** | Any Lightning wallet | CLINK-compatible wallets |
|
||||
| **Offline Capability** | None | Cashu ecash (planned) |
|
||||
| **Payment Protocol** | BOLT11 only | BOLT11 + CLINK + noffer |
|
||||
| Aspect | Traditional | bitSpire |
|
||||
|---|---|---|
|
||||
| Invoice creation | Server creates via LND | LNbits creates via its Lightning backend, returned over kind-21000 |
|
||||
| Payment detection | Server polls LND | LNbits pushes a settlement event over kind-21000 (`subscribe_payments` filtered by `payment_hash`) |
|
||||
| Cash-in detection | Custom flow | LNbits pushes a `tag="withdraw"` + `link_id` event when the LNURL is redeemed |
|
||||
| Wallet compatibility | Any BOLT11 wallet | Any BOLT11 wallet (cash-out) + any LNURL-withdraw wallet (cash-in) |
|
||||
| Offline capability | None | Cashu ecash (placeholder package, not yet wired) |
|
||||
|
||||
**Mixed**: Traditional has broader wallet compatibility today. Nostr-Native enables advanced features (ndebit, noffer) but requires CLINK wallets.
|
||||
**Tied.** Both architectures end up using BOLT11 + LNURL-withdraw at the customer-wallet boundary. The difference is on the ATM side: traditional polls a server it owns; bitSpire subscribes to a push channel on a wallet it shares with anyone who can reach the relay.
|
||||
|
||||
### 4. Operator Experience
|
||||
### 4. Operator experience
|
||||
|
||||
| Aspect | Traditional | Nostr-Native |
|
||||
| ----------------------- | ------------------------------- | -------------------------- |
|
||||
| **Setup Time** | Hours (server, DB, certs) | Minutes (connect to relay) |
|
||||
| **Maintenance** | DB backups, updates, monitoring | Minimal |
|
||||
| **Fleet Management** | Admin UI (full-featured) | Dashboard (planned) |
|
||||
| **Transaction History** | PostgreSQL queries | Nostr event queries |
|
||||
| **Configuration** | Server-pushed | Local or relay-stored |
|
||||
| Aspect | Traditional | bitSpire |
|
||||
|---|---|---|
|
||||
| Setup time | Hours (provision server, DB, TLS, cert each machine) | Minutes (run an LNbits instance + a relay; flash + provision each ATM) |
|
||||
| Maintenance | DB backups, server updates, monitoring | Update LNbits + the bitSpire ATMs (the latter auto-upgrades from the `dev` branch nightly) |
|
||||
| Fleet management | Mature Admin UI | Per-ATM `journalctl`; centralized dashboard is planned, not built |
|
||||
| Transaction history | PostgreSQL queries | Per-ATM `/var/lib/bitspire/state.db` (SQLite); operator-side aggregation is on them to build |
|
||||
| Configuration | Server-pushed | Per-ATM `.env` written via `provision-atm.sh` |
|
||||
|
||||
**Mixed**: Traditional has mature tooling. Nostr-Native is simpler but dashboard is still in development.
|
||||
**Mixed.** Traditional has mature operator tooling. bitSpire is simpler to stand up but the fleet-management story is currently "ssh + scripts" rather than a UI.
|
||||
|
||||
### 5. Customer Experience
|
||||
### 5. Customer experience
|
||||
|
||||
| Aspect | Traditional | Nostr-Native |
|
||||
| ----------------------- | ------------------------ | ----------------------- |
|
||||
| **Cash-In** | Scan invoice, pay | Scan ndebit, authorize |
|
||||
| **Cash-Out** | Enter phone, receive SMS | Scan noffer, receive |
|
||||
| **Wallet Requirements** | Any Lightning wallet | CLINK-compatible wallet |
|
||||
| **Account Required** | Sometimes (compliance) | Never |
|
||||
| **Transaction Speed** | ~10 seconds | ~5 seconds |
|
||||
| Aspect | Traditional | bitSpire |
|
||||
|---|---|---|
|
||||
| Cash-out | Scan BOLT11, pay | Scan BOLT11, pay |
|
||||
| Cash-in | Varies by deployment (LNURL-withdraw common, sometimes custom) | Scan LNURL-withdraw QR, redeem |
|
||||
| Wallet requirements | Any LN wallet for cash-out | Any LN wallet for cash-out + any LNURL-w wallet for cash-in |
|
||||
| Account required | Sometimes (compliance) | Never |
|
||||
| Transaction speed | ~10 seconds | ~3-5 seconds (push-based; no server polling delay) |
|
||||
|
||||
**Advantage: Nostr-Native** - Faster, more private, no accounts. But requires specific wallet support.
|
||||
**Tied on protocol; slight edge to bitSpire on speed** because LNbits push events skip the polling cycle that traditional setups have between LND and the application server.
|
||||
|
||||
### 6. Compliance & Regulation
|
||||
### 6. Compliance & regulation
|
||||
|
||||
| Aspect | Traditional | Nostr-Native |
|
||||
| -------------------- | ----------------------- | --------------------- |
|
||||
| **KYC Integration** | Built-in | Not included |
|
||||
| **Transaction Logs** | PostgreSQL | Optional Nostr events |
|
||||
| **Audit Trail** | Comprehensive | Operator-defined |
|
||||
| **Reporting** | Admin UI exports | Custom tooling needed |
|
||||
| **Regulatory Fit** | Designed for compliance | Privacy-first design |
|
||||
| Aspect | Traditional | bitSpire |
|
||||
|---|---|---|
|
||||
| KYC integration | Built-in | Not included |
|
||||
| Transaction logs | PostgreSQL (server) | Per-ATM SQLite + whatever LNbits records on its side |
|
||||
| Audit trail | Comprehensive | Operator-defined; LNbits's ledger is the canonical Lightning-side record |
|
||||
| Reporting | Admin UI exports | Custom tooling needed |
|
||||
| Regulatory fit | Designed for KYC/AML jurisdictions | Privacy-first design; suits jurisdictions without identity-collection requirements |
|
||||
|
||||
**Advantage: Traditional** - If you need KYC/AML, traditional is ready. Nostr-Native assumes jurisdictions without these requirements.
|
||||
**Edge: Traditional** if you need built-in compliance. bitSpire targets KYC-free operation; operators in regulated jurisdictions would need to add compliance hooks themselves.
|
||||
|
||||
### 7. Resilience & Availability
|
||||
### 7. Resilience & availability
|
||||
|
||||
| Aspect | Traditional | Nostr-Native |
|
||||
| --------------------------- | ---------------------- | ------------------------- |
|
||||
| **Server Down** | All machines offline | Machines continue working |
|
||||
| **Network Partition** | Transactions fail | Can use multiple relays |
|
||||
| **Database Corruption** | Catastrophic | No database to corrupt |
|
||||
| **Recovery** | Restore from backup | Re-sync from relay |
|
||||
| **Geographic Distribution** | Single server location | Relay anywhere |
|
||||
| Aspect | Traditional | bitSpire |
|
||||
|---|---|---|
|
||||
| Server down | All machines stop transacting | Machines stop transacting if LNbits is down; relay outage means RPCs hang |
|
||||
| Network partition | Transactions fail | Can connect to multiple relays for failover |
|
||||
| Database corruption | Catastrophic (cascading impact across fleet) | LNbits-side issue affects only the affected operator's wallet; per-ATM SQLite is local and independent |
|
||||
| Recovery | Restore from backup | LNbits-side restore is its concern; ATMs come back up clean by re-reading `.env` |
|
||||
| Geographic distribution | Single server | LNbits can be regional; relays can be anywhere |
|
||||
|
||||
**Advantage: Nostr-Native** - No single point of failure. Machines are autonomous.
|
||||
**Edge: bitSpire** for blast-radius reasons. LNbits-side failures are no worse than `lamassu-server`-side failures, but bitSpire's per-ATM state is genuinely isolated.
|
||||
|
||||
### 8. Development & Extensibility
|
||||
### 8. Development & extensibility
|
||||
|
||||
| Aspect | Traditional | Nostr-Native |
|
||||
| --------------------------- | ----------------- | ------------------------- |
|
||||
| **Codebase** | Large monolith | Modular packages |
|
||||
| **Protocol** | Proprietary | Open standards |
|
||||
| **Third-party Integration** | Custom API needed | Standard Nostr/CLINK |
|
||||
| **Community** | Lamassu operators | Nostr + Bitcoin ecosystem |
|
||||
| **Forkability** | Complex | Straightforward |
|
||||
| Aspect | Traditional | bitSpire |
|
||||
|---|---|---|
|
||||
| Codebase | Large monolith (`lamassu-server` is hundreds of files) | Modular workspace; ATM, transport client, HAL, state machine are separate packages |
|
||||
| Protocol | Custom WebSocket schema | NIP-01 + NIP-44 v2 + a thin documented kind-21000 envelope |
|
||||
| Third-party integration | Custom API needed | Any nostr/Lightning client can talk to LNbits over the transport |
|
||||
| Community | Lamassu operators (and ex-operators after the license change) | Nostr + Bitcoin ecosystem; LNbits community |
|
||||
| Forkability | Complex (server + machine are coupled) | Straightforward (replace any one package without touching the others) |
|
||||
|
||||
**Advantage: Nostr-Native** - Open protocols mean broader ecosystem participation.
|
||||
**Edge: bitSpire.** Open protocols mean a wider ecosystem of compatible clients, wallets, and tools.
|
||||
|
||||
---
|
||||
|
||||
## Migration Path
|
||||
## When to choose what
|
||||
|
||||
### Phase 1: Parallel Operation
|
||||
### Choose bitSpire if
|
||||
|
||||
Run both systems simultaneously:
|
||||
- You operate in a jurisdiction without mandatory KYC/AML
|
||||
- You want minimal infrastructure
|
||||
- You value customer privacy (no PII collection, no central server-side ledger of who-paid-what)
|
||||
- You're comfortable with emerging tooling (no admin UI yet)
|
||||
- You want a license that stays open (AGPL-3.0)
|
||||
|
||||
- Existing machines continue with lamassu-server
|
||||
- New machines or test units use lamassu-next
|
||||
- Compare reliability and customer feedback
|
||||
|
||||
### Phase 2: Hybrid Mode
|
||||
|
||||
Bridge the systems:
|
||||
|
||||
- lamassu-server creates Nostr events for transactions
|
||||
- Dashboard reads from both PostgreSQL and relay
|
||||
- Gradual feature parity validation
|
||||
|
||||
### Phase 3: Full Migration
|
||||
|
||||
Complete transition:
|
||||
|
||||
- All machines run lamassu-next firmware
|
||||
- Retire lamassu-server infrastructure
|
||||
- Optional: Keep PostgreSQL as read-only archive
|
||||
|
||||
### Migration Considerations
|
||||
|
||||
| Consideration | Notes |
|
||||
| -------------------------- | ----------------------------------------------- |
|
||||
| **Hardware Compatibility** | Same bill validators/dispensers, new software |
|
||||
| **Customer Education** | May need CLINK-compatible wallet guidance |
|
||||
| **Operator Training** | Different mental model (events vs database) |
|
||||
| **Regulatory Review** | Verify compliance in your jurisdiction |
|
||||
| **Rollback Plan** | Keep lamassu-server available during transition |
|
||||
|
||||
---
|
||||
|
||||
## Trade-offs & Honest Assessment
|
||||
|
||||
### Where Nostr-Native Excels
|
||||
|
||||
1. **Simplicity**: No server to manage, no database to backup
|
||||
2. **Privacy**: No central transaction logs
|
||||
3. **Resilience**: No single point of failure
|
||||
4. **Interoperability**: Works with any CLINK wallet
|
||||
5. **Speed**: Direct relay communication is faster
|
||||
6. **Cost**: No server hosting costs (can use public relays)
|
||||
|
||||
### Where Traditional May Be Better
|
||||
|
||||
1. **Compliance**: Built-in KYC/AML if required by law
|
||||
2. **Wallet Support**: Works with any Lightning wallet today
|
||||
3. **Maturity**: Battle-tested over years of operation
|
||||
4. **Tooling**: Full-featured admin dashboard exists
|
||||
5. **Support**: Established support channels and documentation
|
||||
|
||||
### Current Limitations of Nostr-Native
|
||||
|
||||
| Limitation | Status | Mitigation |
|
||||
| ---------------------- | ------------- | ---------------------------------- |
|
||||
| Dashboard not complete | In progress | Use relay queries directly |
|
||||
| Limited wallet support | Growing | ShockWallet, others adopting CLINK |
|
||||
| No offline mode yet | Cashu planned | Requires internet currently |
|
||||
| Less documentation | Improving | This document helps |
|
||||
|
||||
---
|
||||
|
||||
## Conclusion
|
||||
|
||||
The Nostr-native architecture represents a fundamental shift from centralized to decentralized ATM operation. It trades the comprehensive compliance features of lamassu-server for simplicity, privacy, and resilience.
|
||||
|
||||
**Choose Nostr-Native if:**
|
||||
|
||||
- You operate in jurisdictions without KYC requirements
|
||||
- You want minimal infrastructure overhead
|
||||
- You value customer privacy
|
||||
- You're comfortable with emerging technology
|
||||
|
||||
**Stick with Traditional if:**
|
||||
### Stick with `lamassu-server` v8.1.5 if
|
||||
|
||||
- You need built-in compliance features
|
||||
- You require extensive fleet management tools today
|
||||
- You need to support any Lightning wallet
|
||||
- You prefer mature, battle-tested systems
|
||||
- You need a mature admin dashboard *today*
|
||||
- You have existing infrastructure investment in PostgreSQL + LND tooling
|
||||
- You're comfortable being on a code line that no longer receives upstream updates (v8.1.5 is the last open release; bug fixes in v8.1.6+ are paid-license-only)
|
||||
|
||||
**Consider Hybrid if:**
|
||||
### Choose Lamassu's current commercial offering if
|
||||
|
||||
- You want to evaluate both approaches
|
||||
- You're planning a gradual migration
|
||||
- You have mixed regulatory requirements across locations
|
||||
- You want vendor support, official updates, and a commercial SLA
|
||||
- You're willing to pay the per-machine subscription
|
||||
- You operate in a regulated jurisdiction where KYC tooling matters
|
||||
|
||||
This last option is outside the scope of this document — see [lamassu.is](https://lamassu.is) for their current commercial terms.
|
||||
|
||||
---
|
||||
|
||||
## Further Reading
|
||||
## Trade-offs & honest assessment
|
||||
|
||||
- [CLINK Protocol Specification](https://github.com/shocknet/clink)
|
||||
- [Lightning.Pub Documentation](https://github.com/shocknet/Lightning.Pub)
|
||||
- [Nostr Protocol (NIP-01)](https://github.com/nostr-protocol/nips/blob/master/01.md)
|
||||
- [NIP-44 Encryption](https://github.com/nostr-protocol/nips/blob/master/44.md)
|
||||
- [ndebit Cash-In Flow](./ndebit-cash-in-flow.md)
|
||||
### Where bitSpire excels
|
||||
|
||||
1. **Simplicity** — LNbits + a relay is a much smaller surface than a stateful application server + DB + admin tooling
|
||||
2. **Privacy** — no central transaction logs by design
|
||||
3. **Resilience** — no single point of failure on the ATM side; LNbits is replaceable
|
||||
4. **Interoperability** — works with any BOLT11 / LNURL-withdraw wallet
|
||||
5. **Speed** — push-based settlement detection skips the LND-poll cycle
|
||||
6. **Cost** — no Lamassu license fees; no commercial admin-server hosting
|
||||
|
||||
### Where traditional (`lamassu-server` ≤ v8.1.5) is still better
|
||||
|
||||
1. **Compliance** — built-in KYC/AML if your jurisdiction requires it
|
||||
2. **Tooling** — mature admin dashboard, fleet management, transaction reporting
|
||||
3. **Maturity** — battle-tested in production over many years
|
||||
4. **Documentation** — established support channels for operators (community-maintained for v8.1.5; commercial for v8.1.6+)
|
||||
|
||||
### Current limitations of bitSpire
|
||||
|
||||
| Limitation | Status | Mitigation |
|
||||
|---|---|---|
|
||||
| No fleet dashboard | Planned, not built | Per-ATM `journalctl` + custom scripts |
|
||||
| Limited transaction reporting | SQLite per ATM | Aggregate via operator-side ETL if needed |
|
||||
| No offline mode | `@bitSpire/cashu` is a placeholder | Requires LNbits connectivity currently |
|
||||
| Smaller operator community | Growing | This doc + the README walkthrough |
|
||||
|
||||
---
|
||||
|
||||
## Further reading
|
||||
|
||||
- [LNbits nostr-native-transport docs](https://git.atitlan.io/aiolabs/lnbits) — the wire spec for what's actually happening on kind-21000
|
||||
- [NIP-01 Nostr basics](https://github.com/nostr-protocol/nips/blob/master/01.md)
|
||||
- [NIP-44 v2 encryption](https://github.com/nostr-protocol/nips/blob/master/44.md)
|
||||
- [LUD-03 LNURL-withdraw](https://github.com/lnurl/luds/blob/luds/03.md)
|
||||
- [CLINK Protocol](./clink-protocol.md) — historical reference, dormant on `dev`
|
||||
- [bitSpire deployment walkthrough](../deploy/nixos/README.md)
|
||||
- [machine-installation.md](./machine-installation.md) — high-level deployment overview
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue