track: legacy aiolabs/lamassu-server issue disposition under Nostr-native architecture (+ future: customer KYC via Nostr DM) #40

Closed
opened 2026-06-01 07:03:27 +00:00 by padreug · 1 comment
Owner

Consolidation tracker for the impending archival of aiolabs/lamassu-server (legacy pre-Nostr-pivot codebase). Captures the disposition of each open legacy issue under the current bitspire / lnbits / satmachineadmin architecture, and carries forward the one substantively novel feature design (#5 — Nostr DM verification codes) as a future workstream.

Why this exists

The legacy aiolabs/lamassu-server repo predates the Nostr-native pivot to bitspire + lnbits + satmachineadmin. Most of its open issues are no longer applicable. A few have substantive value worth preserving. This tracker:

  1. Documents the disposition of each legacy issue so nothing meaningful is lost when the repo is archived
  2. Carries forward one specific future workstream (customer KYC via Nostr DM, from legacy #5)
  3. Provides a single Forgejo destination Padreug can point at when archiving the legacy repo

Legacy issue disposition

Legacy issue Title Disposition
aiolabs/lamassu-server#1 Membership-Based Discount System Captured — cross-linked in aiolabs/satmachineadmin#37's "Future-proofing for promos" section. Full design parked at ~/dev/coordination/membership-discount-plan-legacy-reference.md with Nostr-native mapping header.
aiolabs/lamassu-server#2 API Key Authentication Obsolete. Nostr event signing IS the auth mechanism in our architecture (every kind-21000 RPC is signed by the sender's nsec; the signature itself authenticates). No bearer-token machinery needed. lnbits has LNBITS_KEY_MASTER envelope encryption for stored user nsecs (lnbits PR#17 / aiolabs/lnbits#9); operators use wallet admin keys / super-user sessions for HTTP auth. External integrations sign Nostr events instead of presenting bearer tokens.
aiolabs/lamassu-server#3 Verify lamassu-send-coins works with LNbits Obsolete. lamassu-send-coins CLI was for the legacy server-driven cash-in path. In our architecture, bitspire (the ATM) directly creates invoices via lnbits' nostr-transport create_invoice RPC; no CLI / server-side coin-sending.
aiolabs/lamassu-server#4 Funding page invoice spam Obsolete. Legacy lamassu-server funding page is not in our stack. Cash-in invoice creation happens on-demand at the bitspire ATM with explicit user flow; no spammable funding URL.
aiolabs/lamassu-server#5 Nostr as verification code method 🆕 Carried forward as future work — see "Future workstream" section below.
aiolabs/lamassu-server#6 Dispense result mapping bug Already fixed in aiolabs/lamassu-next feat/record-failed-dispense branch per the legacy issue body's own note. lamassu-server fix would be moot under archival.

When archiving aiolabs/lamassu-server, link this issue from each legacy issue's closing comment as the disposition pointer.


Future workstream — customer KYC compliance via Nostr DM (consolidates legacy aiolabs/lamassu-server#5)

Status: Out of scope for current work. Documented here so when KYC requirements scope (jurisdictional thresholds, regulatory pressure, etc.), the design intent isn't lost.

Use case

Operators in some jurisdictions need to enforce KYC verification above certain transaction thresholds. Legacy approach: customer provides phone number, server SMS's verification code, customer enters code at ATM. Costs money, requires telecom integration, leaks PII.

Nostr-native approach (from legacy aiolabs/lamassu-server#5)

  • Customer provides their npub during verification flow (scan QR or via existing path-B auth handshake — npub already in Payment.extra.nostr_sender_pubkey)
  • satmachineadmin generates verification code (or uses existing transaction context as the "what to verify")
  • Sends the verification challenge as encrypted DM (NIP-44 v2, the same crypto we use for cassette/fee config) from the operator's account to customer's npub
  • Customer's Nostr client receives + displays the code (or replies confirming verified)
  • Customer enters code at ATM (existing UI), OR — cleaner — customer's Nostr client signs a verification event that satmachineadmin's resolver picks up and approves

Why this works well under our architecture

  • Customer npub is already plumbed: Payment.extra.nostr_sender_pubkey from path B carries customer identity end-to-end
  • NIP-44 v2 envelope already used: cassette config (#29) + fee config (#37/#39/#57) use the exact same encryption shape; KYC DMs reuse the primitive
  • No telecom dependency: aligns with "no HTTP" / "no SMS" / Nostr-native direction
  • Privacy: no phone number stored; customer pseudonymously identified by npub
  • Decentralized: no carrier middleman; works wherever relays do
  • Optional fallback: SMS could remain as a fallback for users without Nostr clients (covered by lnbits' existing SMS plumbing if present)

Considerations

  • UX for Nostr-unfamiliar customers: needs a "what is this?" explainer + ideally a deep-link to a recommended Nostr client (Amber, Damus, Primal, etc.) for first-time users
  • Relay configuration: which relays does satmachineadmin publish through? Probably the same set already configured for nostrclient extension
  • Delivery confirmation: relays don't guarantee delivery; need retry / fallback path if customer doesn't receive DM within N seconds
  • Code lifecycle: code expires after N minutes; one-time-use; rate-limited per npub
  • Threshold configuration: per-machine or instance-wide? "KYC required above €X" — operator/admin-configurable

Implementation sketch (when scoped)

  • satmachineadmin: new kyc_verifications table (id, machine_id, customer_npub, challenge_code, status, created_at, expires_at). API to issue/check codes. NIP-44-encrypted DM publisher (reuses signer abstraction from PR#30).
  • bitspire: new kycPrompt state in the cash-in/cash-out flow — "This transaction requires verification. Scan your npub or your Nostr client." Existing camera/QR primitive.
  • lnbits side: probably zero changes — nostr-transport + nostrclient already handle the publish/subscribe machinery.

Cross-refs

  • Legacy issue: aiolabs/lamassu-server#5
  • Customer-npub plumbing precedent: path B (aiolabs/lnbits!43 be148054 + aiolabs/satmachineadmin!36)
  • NIP-44 envelope precedent: cassette config (aiolabs/satmachineadmin#29, PR #30)
  • Operator-config Nostr channel pattern to mirror: cassette config + fee config (aiolabs/satmachineadmin#37)

Out of scope (for this tracker)

  • Implementing KYC verification (this issue is documentation/future-tracker only)
  • Adapting legacy issues #2, #3, #4, #6 (marked obsolete above — no carry-forward needed)
  • Closing the legacy issues themselves (Padreug-owned operational decision, paired with the archival)

When to act

  • Immediately: nothing — this is a tracker, not a workstream
  • When promo/membership work scopes (#37 future-proofing) — pair with the legacy #1 reference doc
  • When KYC requirements appear — open a fresh implementation issue referencing the workstream sketch above
  • When aiolabs/lamassu-server gets archived — close each legacy issue with a comment pointing here
Consolidation tracker for the impending archival of **`aiolabs/lamassu-server`** (legacy pre-Nostr-pivot codebase). Captures the disposition of each open legacy issue under the current bitspire / lnbits / satmachineadmin architecture, and carries forward the one substantively novel feature design (#5 — Nostr DM verification codes) as a future workstream. ## Why this exists The legacy `aiolabs/lamassu-server` repo predates the Nostr-native pivot to bitspire + lnbits + satmachineadmin. Most of its open issues are no longer applicable. A few have substantive value worth preserving. This tracker: 1. Documents the disposition of each legacy issue so nothing meaningful is lost when the repo is archived 2. Carries forward one specific future workstream (customer KYC via Nostr DM, from legacy #5) 3. Provides a single Forgejo destination Padreug can point at when archiving the legacy repo ## Legacy issue disposition | Legacy issue | Title | Disposition | |---|---|---| | [`aiolabs/lamassu-server#1`](https://git.atitlan.io/aiolabs/lamassu-server/issues/1) | Membership-Based Discount System | ✅ **Captured** — cross-linked in `aiolabs/satmachineadmin#37`'s "Future-proofing for promos" section. Full design parked at `~/dev/coordination/membership-discount-plan-legacy-reference.md` with Nostr-native mapping header. | | [`aiolabs/lamassu-server#2`](https://git.atitlan.io/aiolabs/lamassu-server/issues/2) | API Key Authentication | ❌ **Obsolete.** Nostr event signing IS the auth mechanism in our architecture (every kind-21000 RPC is signed by the sender's nsec; the signature itself authenticates). No bearer-token machinery needed. lnbits has `LNBITS_KEY_MASTER` envelope encryption for stored user nsecs (lnbits PR#17 / `aiolabs/lnbits#9`); operators use wallet admin keys / super-user sessions for HTTP auth. External integrations sign Nostr events instead of presenting bearer tokens. | | [`aiolabs/lamassu-server#3`](https://git.atitlan.io/aiolabs/lamassu-server/issues/3) | Verify lamassu-send-coins works with LNbits | ❌ **Obsolete.** `lamassu-send-coins` CLI was for the legacy server-driven cash-in path. In our architecture, bitspire (the ATM) directly creates invoices via lnbits' nostr-transport `create_invoice` RPC; no CLI / server-side coin-sending. | | [`aiolabs/lamassu-server#4`](https://git.atitlan.io/aiolabs/lamassu-server/issues/4) | Funding page invoice spam | ❌ **Obsolete.** Legacy lamassu-server funding page is not in our stack. Cash-in invoice creation happens on-demand at the bitspire ATM with explicit user flow; no spammable funding URL. | | [`aiolabs/lamassu-server#5`](https://git.atitlan.io/aiolabs/lamassu-server/issues/5) | Nostr as verification code method | 🆕 **Carried forward as future work — see "Future workstream" section below.** | | [`aiolabs/lamassu-server#6`](https://git.atitlan.io/aiolabs/lamassu-server/issues/6) | Dispense result mapping bug | ✅ **Already fixed in `aiolabs/lamassu-next`** `feat/record-failed-dispense` branch per the legacy issue body's own note. lamassu-server fix would be moot under archival. | When archiving `aiolabs/lamassu-server`, link this issue from each legacy issue's closing comment as the disposition pointer. --- ## Future workstream — customer KYC compliance via Nostr DM (consolidates legacy `aiolabs/lamassu-server#5`) **Status**: Out of scope for current work. Documented here so when KYC requirements scope (jurisdictional thresholds, regulatory pressure, etc.), the design intent isn't lost. ### Use case Operators in some jurisdictions need to enforce KYC verification above certain transaction thresholds. Legacy approach: customer provides phone number, server SMS's verification code, customer enters code at ATM. Costs money, requires telecom integration, leaks PII. ### Nostr-native approach (from legacy `aiolabs/lamassu-server#5`) - Customer provides their **npub** during verification flow (scan QR or via existing path-B auth handshake — npub already in `Payment.extra.nostr_sender_pubkey`) - satmachineadmin generates verification code (or uses existing transaction context as the "what to verify") - Sends the verification challenge as encrypted DM (**NIP-44 v2**, the same crypto we use for cassette/fee config) from the operator's account to customer's npub - Customer's Nostr client receives + displays the code (or replies confirming verified) - Customer enters code at ATM (existing UI), OR — cleaner — customer's Nostr client signs a verification event that satmachineadmin's resolver picks up and approves ### Why this works well under our architecture - **Customer npub is already plumbed**: `Payment.extra.nostr_sender_pubkey` from path B carries customer identity end-to-end - **NIP-44 v2 envelope already used**: cassette config (#29) + fee config (#37/#39/#57) use the exact same encryption shape; KYC DMs reuse the primitive - **No telecom dependency**: aligns with "no HTTP" / "no SMS" / Nostr-native direction - **Privacy**: no phone number stored; customer pseudonymously identified by npub - **Decentralized**: no carrier middleman; works wherever relays do - **Optional fallback**: SMS could remain as a fallback for users without Nostr clients (covered by lnbits' existing SMS plumbing if present) ### Considerations - **UX for Nostr-unfamiliar customers**: needs a "what is this?" explainer + ideally a deep-link to a recommended Nostr client (Amber, Damus, Primal, etc.) for first-time users - **Relay configuration**: which relays does satmachineadmin publish through? Probably the same set already configured for nostrclient extension - **Delivery confirmation**: relays don't guarantee delivery; need retry / fallback path if customer doesn't receive DM within N seconds - **Code lifecycle**: code expires after N minutes; one-time-use; rate-limited per npub - **Threshold configuration**: per-machine or instance-wide? "KYC required above €X" — operator/admin-configurable ### Implementation sketch (when scoped) - **satmachineadmin**: new `kyc_verifications` table (id, machine_id, customer_npub, challenge_code, status, created_at, expires_at). API to issue/check codes. NIP-44-encrypted DM publisher (reuses signer abstraction from PR#30). - **bitspire**: new `kycPrompt` state in the cash-in/cash-out flow — "This transaction requires verification. Scan your npub or your Nostr client." Existing camera/QR primitive. - **lnbits side**: probably zero changes — nostr-transport + nostrclient already handle the publish/subscribe machinery. ### Cross-refs - Legacy issue: `aiolabs/lamassu-server#5` - Customer-npub plumbing precedent: path B (`aiolabs/lnbits!43` `be148054` + `aiolabs/satmachineadmin!36`) - NIP-44 envelope precedent: cassette config (`aiolabs/satmachineadmin#29`, PR #30) - Operator-config Nostr channel pattern to mirror: cassette config + fee config (`aiolabs/satmachineadmin#37`) ## Out of scope (for this tracker) - Implementing KYC verification (this issue is documentation/future-tracker only) - Adapting legacy issues #2, #3, #4, #6 (marked obsolete above — no carry-forward needed) - Closing the legacy issues themselves (Padreug-owned operational decision, paired with the archival) ## When to act - **Immediately**: nothing — this is a tracker, not a workstream - **When promo/membership work scopes** (`#37` future-proofing) — pair with the legacy #1 reference doc - **When KYC requirements appear** — open a fresh implementation issue referencing the workstream sketch above - **When `aiolabs/lamassu-server` gets archived** — close each legacy issue with a comment pointing here
Author
Owner

➡️ Migrated to aiolabs/spirekeeper#18 (aiolabs/spirekeeper#18).

The v2-bitspire line of this extension now lives in its own repo, aiolabs/spirekeeper. Tracking for this issue continues there; closing here. (Issue numbers were reassigned in the new repo.)

➡️ **Migrated to https://git.atitlan.io/aiolabs/spirekeeper/issues/18 (aiolabs/spirekeeper#18).** The v2-bitspire line of this extension now lives in its own repo, `aiolabs/spirekeeper`. Tracking for this issue continues there; closing here. (Issue numbers were reassigned in the new repo.)
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
aiolabs/satmachineadmin#40
No description provided.