Skip to content
Architecture

Architecture

SuperSats is two cooperating open-source applications — an attendance tracker and a rewards server — connected via a private API. Together they form a complete loop: attendance in, sats out.

System overview

                    ┌──────────────────────────────────┐
                    │       Admin Dashboard             │
                    │  (supersats-attendance web UI)    │
                    │                                   │
                    │  • Register participants & groups │
                    │  • Review monthly reports         │
                    │  • Approve → trigger payout       │
                    └────────────┬─────────────────────┘
                                 │
              ┌──────────────────┼──────────────────────┐
              │                  │                       │
              ▼                  ▼                       ▼
   ┌────────────────┐  ┌──────────────────┐  ┌──────────────────────┐
   │  Marshal PWA   │  │  Attendance DB   │  │  Rewards Server      │
   │  (mobile-first)│  │  (SQLite/Prisma) │  │  (supersats-rewards) │
   │                │  │                  │  │                      │
   │  Coaches tap   │  │  Sessions,       │  │  • Card balances     │
   │  attendance    │  │  reports,        │  │  • LNURL-W (BoltCard)│
   │  per session   │  │  participants    │  │  • LNURL-P (LN addr) │
   └────────────────┘  └──────────────────┘  └──────────┬───────────┘
                                                         │
                                                         ▼
                                               ┌──────────────────┐
                                               │  Blink Wallet API│
                                               │  (GraphQL + WS)  │
                                               └──────────┬───────┘
                                                          │
                                                          ▼
                                               ┌──────────────────┐
                                               │  NFC Bolt Cards  │
                                               │  (participants)  │
                                               └──────────────────┘

Admin dashboard

The admin dashboard is the private web interface inside supersats-attendance. Only administrators can access it.

What it does:

  • Register participants — stores name, photo, SA ID, and assigns a sequential TSK ID
  • Manage groups (Turtles, Seals, Dolphins, Sharks, Free Surfers, etc.)
  • View per-group monthly attendance reports auto-generated from session data
  • Approve reports — this is the trigger that initiates Lightning payouts
  • Lock in the ZAR/sat exchange rate at approval time for auditable historical records

Tech: Next.js 15 (App Router) · TypeScript · SQLite via Prisma ORM · NextAuth.js v5

Marshal PWA

The Marshal PWA is a mobile-first Progressive Web App inside the supersats-attendance repo. It is the attendance capture tool used by coaches on the ground.

What it does:

  • Marshals install it to their Android home screen (no app store — Chrome PWA)
  • Each group has its own PIN-based passcode so marshals only access their group
  • Coaches mark each participant present or absent per session
  • Data saves instantly to the attendance database

Access model: Marshals have no access to reports, participant PII, or payout controls — only the attendance capture screen for their assigned group.

Rewards server

supersats-rewards is a standalone Express + TypeScript service that owns all Bitcoin logic. The attendance app calls it; it handles everything Bitcoin-related.

What it does:

  • Maintains a sats balance for each participant’s Bolt Card
  • Serves LNURL-W — when a participant taps their NFC card at a merchant, the card resolves the LNURL, the server checks the balance, and returns a Lightning invoice for the tap amount
  • Serves LNURL-P — participants can receive sats to their card via a Lightning address (user@yourdomain)
  • Exposes a batch payout API called by the attendance app on report approval — credits each participant’s card balance with their monthly reward
  • Tracks a sats reserve; generates top-up invoices via Blink when reserve runs low
  • Provides an admin dashboard for card management, balance views, and transaction history

Tech: Node.js 20 · Express 4 · TypeScript · SQLite via better-sqlite3 · React + Vite + Tailwind CSS

Blink Wallet API integration

The rewards server settles all real Bitcoin payments through Blink via their GraphQL API and WebSocket subscription.

Why Blink:

  • Hosted Lightning — no self-managed Lightning node required
  • GraphQL API makes programmatic invoice generation and payment sending straightforward
  • WebSocket subscriptions give real-time payment confirmation without polling

Credentials required:

SecretPurpose
BLINK_API_KEYAuthenticates API calls
BLINK_WALLET_IDIdentifies which Blink wallet to debit/credit
blinkapicredentials fileAlternative credential file (gitignored)

NFC Bolt Card management

Participants receive a physical NFC Bolt Card pre-programmed with an LNURL-W endpoint pointing at the rewards server. The card is the wallet.

Payment flow (participant spending sats):

  1. Participant taps card at an NFC-enabled merchant terminal
  2. Terminal resolves the LNURL-W on the card
  3. Rewards server receives the withdraw request and checks the participant’s balance
  4. If sufficient balance, server returns a Lightning invoice for the merchant
  5. Merchant’s wallet pays the invoice; Blink settles via Lightning
  6. Server deducts the amount from the participant’s card balance

Admin operations available:

  • Issue new cards and link them to a participant profile
  • View per-card balance and full transaction history
  • Filter cards by group
  • Manually adjust balances for corrections

Exponential rewards curve

Sats rewards are not linear — the system uses an exponential curve tied to monthly attendance percentage. This structure rewards consistency more than sporadic presence.

Default tiers (configurable in admin UI):

Attendance %Monthly reward
100%7 500 sats
90–99%7 000 sats
80–89%6 000 sats
70–79%5 000 sats
< 70%0 sats

The gap between tiers is intentionally larger at the top — the jump from 90% to 100% is the same reward as 70%→80% and 80%→90% combined. This is the exponential shape: the marginal value of each additional session attended increases as you approach perfect attendance.

Junior coaches are excluded from payout calculations regardless of attendance.

Security notes

  • The batch payout API is protected by BOLT_API_KEY — only the attendance app should know this key
  • Admin sessions in both apps are JWT-signed; rotate NEXTAUTH_SECRET / JWT_SECRET before deploying
  • Blink credentials live in environment variables and a gitignored credentials file — never in source
  • The Marshal PWA exposes no PII — group passcodes gate access to attendance capture only