Commit graph

26 commits

Author SHA1 Message Date
91c6994dd4 feat(deploy): add aarch64 Raspberry Pi 4 target
The Pi 4 twin of the Pi 5 build: `rpi4-installed` (in-place rebuild target),
`rpi4-image`, and `packages.aarch64-linux.{sd-image-rpi4,atm-app-rpi4}`, all
through the board-keyed machinery of the previous commit. The shared runtime
is untouched; only the board pair is new.

deploy/nixos/hardware/raspberry-pi-4.nix mirrors raspberry-pi-5.nix line for
line except where the boards differ:
- KMS for the kiosk display is an opt-in on the Pi 4
  (`hardware.raspberry-pi."4".fkms-3d`), which also injects the CMA + vc4
  device-tree overlays; the Pi 5 gets it by default. Without it X falls back
  to the framebuffer and Electron renders in software.
- fkms-3d sets videoDrivers itself, so the module doesn't.
Everything else — extlinux boot, console pinned to tty0 so the GPIO UART is
free for a validator, no-suspend, the ttyValidator{0,1,2} udev symlinks — is
identical by design.

Evaluation-verified only: rpi4-installed/rpi4-image instantiate, and against
rpi5 they differ solely in the expected places (bcm2711 device tree, the two
fkms overlays, the rpiVersion=4 kernel, no clk-rp1 in initrd, machine model
in the env seed). Not yet booted on hardware; the doc says so.

docs/raspberry-pi-setup.md covers both boards — build, flash, first boot +
provisioning via the spire seed, in-place updates, peripherals — since #87
shipped the Pi 5 without one. It replaces a never-committed Pi 4 sketch
(parked on wip/rpi4-sketch) whose flake wiring didn't evaluate and whose
provisioning section predated the pairing seed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013A6683cCHnQxFUosx1krY4
2026-09-24 21:44:25 +02:00
Patrick Mulligan
64582e7fe6 feat(machine): Bolt Card (NFC) tap-to-receive on cash-in
Tap-to-receive for the buy flow, the receive counterpart to #83's
cash-out tap-to-pay. A Bolt Card only emits an lnurlw withdraw voucher
(wrong direction to deposit into it), so the tap is used as an
authenticated identity (external_id + SUN p/c) to resolve the card
wallet's lnurlp/Lightning Address; the ATM then pays an invoice for the
payout over its existing nostr transport.

- electron/lnurl-pay.ts: resolveCardInvoice() — resolve card -> pay
  target -> LUD-16/LUD-06 -> BOLT11. scanUrlToResolver() is the single
  HTTPS-today / nostr-tomorrow transport seam. 13 tests.
- IPC lnurl:pay-card (main-process HTTPS to dodge renderer CORS) +
  preload/electron.d.ts surface.
- stores/atm.ts: handleBoltCardReceive() settles via the existing
  payInvoice -> PAYMENT_RECEIVED path; the one NFC listener now routes
  the same tap by flow (cash-out pulls, cash-in receives).
- CashInView.vue: NFC status + dev tap input.
- docs/boltcard-receive-resolver.md: spec for the custom LNbits
  /boltcards/api/v1/pay/<id> resolver endpoint (omni-private side).

Card issuance is unchanged — same NDEF/keys/external_id; receive is a
server-side reading of the same tap.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-06 00:30:13 +02:00
Patrick Mulligan
44f5c0dbcf docs(adr): amend ADR-002 — app recovery is first-line, SSH/NetBird last-resort
The access/recovery plane (SSH/NetBird) stands and may carry recovery
procedures, but it is explicitly NOT the only or first-line recovery. Add
a layered, cheapest-first recovery model: (1) app auto-recovery of its own
relay/Lightning connectivity, (2) an on-screen Retry for an operator at the
kiosk, (3) SSH/NetBird as the last-resort remote plane for genuine app/OS
failure. A public kiosk must not need remote shell access to recover from a
transient/boot-before-network outage.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-04 18:11:40 +02:00
627d5e63e5 docs(adr): ADR-002 remote access & fleet management — three planes, NetBird
Separate payment (Nostr↔LNbits, SaaS-operator-owned), fleet control
(Nostr #42, machine-operator-owned), and access/recovery (SSH) planes
by trust owner. Recovery access is provisioned at install and
app-independent. Adopt NetBird for the access plane (scale + fully FOSS
self-hostable control plane; rejects Tailscale's closed control plane).

Reject a dashboard 'revoke SaaS-operator access' toggle as a false
promise — the SaaS operator controls LNbits and the default control
plane, so exclusion is by ownership (operator self-hosts), not by
toggle.
2026-06-14 11:17:02 +02:00
4f68ddc40b refactor(machine): drop VITE_LNBITS_HTTP_URL — lnurl now arrives populated from LNbits (#57 gap 2)
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>
2026-06-01 20:33:28 +02:00
7c1011d382 chore(nix): bump nixpkgs 24.05 → 24.11
Three breakages handled:

- hardware.opengl → hardware.graphics (renamed in 24.11). Touches
  upboard.nix, douro.nix, batm3.nix, live.nix.
- vaapiIntel dropped — legacy pre-Broadwell driver, removed in
  nixpkgs. UP Board (Cherry Trail) and OptiPlex 9030 (Haswell) both
  use intel-media-driver, which stays.
- vaapiVdpau renamed → libva-vdpau-driver.

system.stateVersion stays 24.05 — convention is to never bump after
install. Existing Sintra and fresh flashes keep the 24.05 state
semantics; that's correct.

All 8 nixosConfigurations (4 models × {live,installed}) evaluate
clean with zero deprecation warnings on 24.11.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-01 19:12:11 +02:00
53b0d382e8 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>
2026-06-01 19:08:03 +02:00
0b94bef4be docs: refresh deploy/nixos/README + flag obsolete flow docs
deploy/nixos/README.md was the most-stale doc in the tree: it still
talked about a `lamassu-atm` systemd unit, `/opt/lamassu-atm` paths,
nixos-install with a non-existent `lamassu-atm` flake output, and an
scp-the-built-electron-bundle workflow that hasn't been the deploy
path for many months. Replaced with a rewrite that documents the
actual current pipeline:

  - File layout: bitspire-atm.nix (not lamassu-atm.nix), live.nix,
    hardware/{douro,batm3,upboard}.nix, and the udev / helper scripts
  - Build pipeline: `nix build .#disk-image-<model>` and the four
    flake-output flavours per model (live config, installed config,
    iso, disk-image)
  - Full Sintra walkthrough end-to-end: prep a flashing USB on the
    dev box, boot Alpine live on the Sintra, identify the eMMC,
    dd with count= to skip the trailing USB padding, repair the
    GPT secondary header + grow root with parted, poweroff, boot,
    provision via provision-atm.sh. Every quirk we hit during the
    first real flash is now baked in (mdev for /dev nodes, parted
    Fix prompt, lbu-style notes).
  - Runtime layout cheat-sheet: /var/lib/bitspire/.env (0600
    lamassu:lamassu), state.db, /etc/bitspire/config.env, etc.
  - Common-operations playbook: re-provision, nixos-rebuild switch
    over SSH with --use-remote-sudo (much faster than reflashing),
    journalctl filtering, hardware-side health checks.
  - NixOS module reference for services.bitspire, including the
    LNbits-flavoured options (relayUrl, lnbitsServerPubkey,
    lnbitsHttpUrl) instead of the retired lightningPubUrl.
  - Sintra-specific gotchas section: eMMC-via-sdhci-acpi, the
    ttyS4 dispenser placement, the ttyS1..3 phantom-node issue.
  - Security-notes section updated to reflect passwordless sudo
    enabled for nixos-rebuild deploys, and the implications.

Auto-upgrade behaviour explained explicitly (the ?ref=dev pin) so
contributors understand why production ATMs on main don't pick up
dev branch changes.

docs/ndebit-cash-in-flow.md: added a header banner flagging the
document as historical — cash-in on dev is LNURL-withdraw +
subscribe_payments push, not ndebit. Original content kept as a
reference for any future revival of nostr-native cash-in.

docs/clink-protocol.md: same treatment — flagged as dormant on dev,
explaining which pieces still apply (kind-21003 management) and
which are unused (kinds 21001/21002). Protocol reference content
left intact since the wire format is unchanged upstream.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-01 19:08:03 +02:00
219e7e1e4d refactor(rename): branding strings + active-use docs → bitSpire
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>
2026-06-01 19:08:03 +02:00
Patrick Mulligan
3634509ed4 fix(machine): mobile UI polish and shadcn-vue ScrollArea
- Use h-dvh instead of h-screen for mobile browser viewport
- Add ScrollArea component (shadcn-vue) to replace native scrollbars
- Move Hide Debug into debug bar row, show Show Debug only when off
- Responsive cash-out denomination grid (single col on mobile)
- Add safe-area padding for mobile gesture bar
- Add business model documentation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 14:44:39 -05:00
Patrick Mulligan
c98f126ba7 feat(docker): add dev.sh with auto-funding and ATM app setup
- 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>
2026-02-15 14:19:16 -05:00
Patrick Mulligan
e6f280a50b Add comprehensive hardware driver catalog and porting strategy
- Catalog all existing lamassu-machine drivers (7 validators, 5 dispensers,
  3 printers, 4 scanners)
- Add "Port, don't rewrite" principle - leverage battle-tested existing code
- Update HAL structure to include all drivers to port
- Replace NV200 example with ID003 (default validator in lamassu-machine)
- Add Printer trait definition
- Update napi-rs bindings with ValidatorDriver and DispenserDriver enums
- Add configuration mapping for migrating from legacy lamassu-machine config
- Update milestone checklist with prioritized driver porting tasks
- Add driver complexity ranking to guide porting order

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 16:08:47 -05:00
Patrick Mulligan
68b797d938 Prioritize cash-out flow based on market research (95%+ activity)
Market context added:
- 95%+ activity is cash-out (selling Bitcoin for cash)
- Typical for remittance corridors, Bitcoin-paid workers
- Bill dispenser is REQUIRED for testing, not optional

Updated development priorities:
- Cash-out first, cash-in second
- Dispenser in minimum dev kit (~$655-855)
- Bill validator becomes secondary priority

Updated milestones:
- Priority 1: Cash-out with real dispenser
- Priority 2: Cash-in (mock validator OK initially)
- Priority 3: Advanced features (Cashu, etc.)

Phase 4 reorganized to implement cash-out before cash-in.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 15:52:24 -05:00
Patrick Mulligan
05c6d9827c Add bill dispenser to implementation plan
Hardware section now includes:
- One-way dev kit (cash-in only): ~$535-735
- Two-way dev kit (cash-in + cash-out): ~$955-1,555
- Bill dispenser options: Puloon LCDM-1000/2000, Fujitsu F53
- Sourcing tips for used equipment

HAL section now includes:
- BillDispenser trait definition
- Puloon LCDM RS-232 implementation
- napi-rs bindings for dispenser
- TypeScript usage examples for both validator and dispenser

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 15:50:13 -05:00
Patrick Mulligan
b80f174b08 Add concrete implementation plan for Nostr-native ATM
Phased roadmap with code examples:

Phase 0: Foundation
- Monorepo structure (Turborepo + pnpm)
- devenv.nix for reproducible dev environment
- Lightning.Pub local setup
- Private strfry relay

Phase 1: Core Infrastructure
- @lamassu/nostr-client package
- Machine identity (nsec/npub generation)
- Relay connection with NIP-42
- @lamassu/clink package for CLINK offers

Phase 2: Machine Shell
- Tauri 2.x + Vue 3 application
- XState v5 state machine (full ATM logic)
- Nostr composable for Vue
- QR display, screen navigation

Phase 3: Hardware Abstraction Layer
- Rust HAL crate with napi-rs bindings
- BillValidator trait + NV200 implementation
- BillDispenser trait + Puloon implementation
- Mock drivers for development

Phase 4: Payment Flows
- Lightning.Pub client integration
- Cash-in: CLINK offers -> invoice -> payment
- Cash-out: Invoice -> payment -> dispense
- NIP-17 encrypted receipts
- Cashu offline mode

Phase 5: Operator Tools
- Vue 3 dashboard
- Real-time machine monitoring via Nostr
- Transaction history
- Remote command sending

Includes:
- Complete XState machine definition
- Rust HAL trait definitions
- TypeScript/Vue code examples
- Testing strategy
- Dev hardware recommendations (~$535-735)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 15:46:57 -05:00
Patrick Mulligan
af358bf158 Add Nostr-native architecture - Nostr as infrastructure backbone
Comprehensive redesign using Nostr for all ATM communication:

Lightning.Pub as Core Server:
- Replaces lamassu-server entirely
- Nostr-native account system wrapping LND
- Zero server config (no DNS/SSL/ports)
- CLINK native, one-line deployment
- Built-in liquidity management

Private Nostr Relay:
- NIP-42 authenticated relay (strfry/rnostr)
- Whitelist: ATM npubs + Operator npubs only
- Encrypted command/control channel
- Negentropy sync for offline reconciliation

Machine Identity:
- Each ATM has Nostr keypair (nsec/npub)
- Replaces client certificates
- Cryptographic authentication
- No PKI/CA required

Replacing SMS (KYC vector elimination):
- NIP-17 encrypted DMs for receipts
- No phone numbers collected
- User provides npub voluntarily
- Operator alerts via Nostr events

Event Schema:
- Kind 21001-21003: CLINK protocol
- Kind 30078: Machine status (replaceable)
- Kind 30079: Transaction records
- Kind 14: Encrypted receipt DMs

This is the logical extension of CLINK - if we're using
Nostr for payments, why not use it for everything?

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 15:36:10 -05:00
Patrick Mulligan
108cd83d69 Replace BOLT12 with CLINK Offers in architecture
BOLT12 problems (per @justin_shocknet):
- Onion messages add latency and failure probability
- Every hop is a point of failure (Tor-like)
- Normalizes mobile nodes (bad for Lightning)
- Redundant (LND keysend already exists)
- Astroturfed by NGOs with questionable motives

CLINK Offers advantages:
- Uses Nostr relays (commodity, trustless via NIP-44)
- No HTTP callbacks, WebSockets, or onion messages
- Keys decoupled from Lightning node identity
- Already working: ShockWallet, Lightning.Pub, Stacker News
- More traction in weeks than BOLT12 in years

Updated:
- Protocol stack recommendation
- New components (clink-handler)
- Implementation roadmap
- References section

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 15:25:34 -05:00
Patrick Mulligan
528c2d6fa8 Add KYC-free Lightning-first architecture review
Comprehensive rethinking of the project vision:

Core Principles:
- KYC-free: No identity collection
- Lightning-native: Security through protocol
- Self-custodial: Operator and user control keys
- Privacy by default: Minimize data retention
- Autonomous machines: Reduce server dependency

Key Technical Decisions:
- LNbits as primary Lightning backend
- Cashu ecash for offline capability and privacy
- LNURL-withdraw/pay for user-friendly flows
- BOLT12 offers for static payment codes
- NFC BOLT cards for tap-to-withdraw
- Fedimint option for community custody

Architecture Options:
- A: Lean Server (recommended starting point)
- B: Serverless Machine (maximum autonomy)
- C: Fedimint Community Model

Assessment: 60%+ of existing lamassu-server is compliance code.
Recommendation: Rebuild core, reuse hardware drivers.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 15:16:53 -05:00
Patrick Mulligan
e55f11ab3a Add experimental e-ink display section to hardware docs
Documents e-ink options for testing:
- Modos Paper (75Hz, open-source FPGA) - ships Jan 2026
- DASUNG Paperlike 253 (33Hz, frontlight)
- Waveshare development boards
- Industrial/outdoor options (SEEKINK, Geniatech)

Includes honest assessment of trade-offs and recommended
use cases (outdoor, solar-powered, idle signage).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 15:12:15 -05:00
Patrick Mulligan
f1469f9c5b Add hardware recommendations for lamassu-machine modernization
Comprehensive document covering:
- Compute: Raspberry Pi CM5 (recommended), Pine64 RISC-V (future)
- Bill validators: ITL NV200 with eSSP protocol, MEI Cashflow
- Bill dispensers: Puloon LCDM series, Fujitsu F53/F56
- Displays: Elo I-Series, Waveshare, Faytech open-frame
- Printers: ESC/POS compatible thermal printers
- NFC: ACR122U with libnfc, PN532 modules
- Protocol support matrix and driver migration strategy
- Bill of materials for MVP and full-featured ATMs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 15:07:24 -05:00
Patrick Mulligan
9550d132dd Switch UI component library from PrimeVue to shadcn-vue
Benefits of shadcn-vue:
- Copy components to repo (you own the code)
- Tailwind-native (no style conflicts)
- Radix Vue primitives (a11y-first)
- Much smaller bundle (~15kb vs ~80kb tree-shaken)
- Full control over styling and behavior

Updated:
- Admin UI: Complete shadcn-vue examples with TanStack Table
- Machine UI: Note about shared shadcn-vue components
- Modernization plan: Updated architecture diagram and bundle sizes
- Bundle target: ~60kb total (down from ~120kb with PrimeVue)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 14:54:45 -05:00
Patrick Mulligan
7251692464 Update modernization plan: Vue 3 for all UIs
- Update architecture diagram to show Vue 3 for both admin and machine
- Replace React decision with Vue 3 unification strategy
- Update machine UI section to include Vue 3 + Tauri
- Add Vue 3 to trade-offs table
- Link to new detailed migration docs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 14:48:34 -05:00
Patrick Mulligan
efddb0db5f Add Vue 3 migration plan for admin UI
Migrate from React 18 + MUI to Vue 3 for consistency with machine UI:
- PrimeVue for components (tree-shakeable vs MUI's 300kb)
- tRPC replacing Apollo GraphQL (~5kb vs ~50kb)
- Pinia for state (same as machine UI)
- Shared ui-shared package for common components

Benefits:
- Single framework across all UIs
- ~70% bundle size reduction (400kb → 120kb)
- End-to-end type safety with tRPC
- Shared composables between admin and machine

Includes:
- Complete project structure
- PrimeVue integration with Tailwind
- tRPC client setup
- Passkey authentication flow
- 4-phase migration strategy

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 14:46:42 -05:00
Patrick Mulligan
775c847c23 Add Vue 3 UI modernization plan for lamassu-machine
Replaces legacy vanilla JS + jQuery with modern stack:
- Vue 3 with Composition API
- TypeScript throughout
- Pinia for state management
- Vite for building
- Vue I18n for localization

Includes:
- Complete project structure
- Core component examples (App.vue, stores, composables)
- WebSocket integration pattern
- i18n strategy preserving existing translations
- 4-phase migration plan
- Testing patterns with Vitest
- Performance targets (<120kb total bundle)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 14:36:30 -05:00
Patrick Mulligan
a5e6b32c24 Add membership & LNbits integration documentation
Feature specification:
- Membership/loyalty system with tiered discounts (Bronze/Silver/Gold/Platinum)
- Lightning wallet integration via Lightning Addresses
- Simplified cash-in flow (no wallet QR needed for members)
- Database schema, API design, machine state changes

LNbits integration:
- Full TypeScript client implementation
- REST API reference
- Deployment architecture options
- NixOS configuration examples
- Monitoring & error handling patterns

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 14:33:04 -05:00
Patrick Mulligan
9adee6e37f Initial commit: Lamassu modernization project
- 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>
2026-01-22 14:19:00 -05:00