ShutterSats Backend (Demo)
A tiny Express + TypeScript service that demonstrates core ideas:
- Create a Lightning invoice (mock provider)
- Poll invoice status
- Seed a chat with a paywalled image message
- Media upload-init placeholder (replace with S3/R2 in production)
Quickstart
cd backend
cp .env.example .env
npm i
npm run dev
# Server on http://localhost:4000
Endpoints
POST /api/v1/payments/invoices->{ amountSats, memo?, assetId?, expiresInSec? }GET /api/v1/payments/invoices/:id->{ id, status, bolt11, amountSats }POST /api/v1/payments/mock/settle->{ id }(demo only)GET /api/v1/chats/demo-chat/messages-> seeded messagesPOST /api/v1/chats/:chatId/messages-> create messagePOST /api/v1/media/upload-init-> get fake upload URL
Production Notes
- Swap
FakePaymentProviderfor a real Lightning integration (LND/CLN/LNbits/LDK). - Replace media upload flow with signed URLs + S3-compatible storage and a thumbnail pipeline (libvips).
- Add auth, E2EE key exchange (e.g., Matrix/Olm or libsignal), and persistent DB (Postgres).
I’ll call the concept ShutterSats for now (other name ideas below). You’ve got the perfect combo: instant chat vibes, photo‑first UX, and ⚡ Lightning-fast sats flowing to creators. Here’s a crisp plan and a runnable starter kit you can download right away.
⬇️ Download the starter project (zip)
🚀 What you just got
A minimal, end‑to‑end prototype that shows the core magic:
- Mobile (Expo/React Native): A chat screen with a pay‑to‑unlock photo. Tap → creates a Lightning invoice → (demo) auto‑settles → unlocks.
- Backend (TypeScript/Express): Endpoints to create/poll invoices, seed a demo chat, and a stubbed upload‑init for encrypted media.
- Docs: Architecture overview, API endpoints, and a Postgres schema you can run with.
Quickstart (2 terminals)
Backend
cd backend
cp .env.example .env
npm i
npm run dev
Mobile
cd mobile
npm i
npm run start
Open the Expo app, tap Open Demo Chat, then tap the paywalled photo to see the flow.
💡 The vision (Telegram energy, photographer DNA, Bitcoin rails)
Core idea: a clean, fast messenger where images are the star, chats are E2EE by default, and creators get paid with Lightning—for tips, paywalls, channel subs, and client galleries.
MVP features (8–10 weeks)
- E2EE 1:1 + group chats (text, photos, read receipts, typing).
- Photo‑first UX: big previews, album threads, EXIF/IPTC respect, ICC‑aware thumbnails.
- Paywalls & tips: per‑message sat price, LNURL‑pay for profiles.
- Private client galleries: proofing & selects right inside chat.
- Storage: encrypted blobs on S3/R2 + CDN; resumable uploads for big RAWs.
- Provenance (opt‑in): file hash → OpenTimestamps on Bitcoin for proof‑of‑existence.
Future candy: live rooms with streaming sats, print‑store integrations, release‑form signing, RAW previews, AI denoise/resize (opt‑in and privacy‑respecting).
🏗️ Architecture you can actually ship
Messaging layer
- Recommended: start with Matrix (Synapse/Dendrite) for robust E2EE (Olm/Megolm), multi‑device, and private federation.
- Alternative: custom libsignal stack (more work).
Media pipeline
- Client‑side encryption → pre‑signed URL upload (S3/R2).
- Thumbs via libvips; preserve ICC/EXIF; BLAKE3 hashing for de‑dup + provenance.
- Large files: multipart uploads (tus.io or SDK), background retries.
Bitcoin/Lightning
- Invoices: BOLT11 for paywalls.
- Tips: LNURL‑pay (or Lightning Address) to the creator—prefer non‑custodial to avoid KYC burden.
- Payouts: LNURL‑withdraw if you must ever hold custody (try not to).
- SDK options: LDK/Breez for on‑device wallets; LND/CLN/LNbits for server‑issued invoices.
Identity & onboarding
- Handle + avatar; phone/email optional.
- Device key backup via passphrase or secure enclave.
- QR device link & emoji SAS verification.
Moderation & safety
- Public channels moderated server‑side; private E2EE rooms remain zero‑knowledge.
- CSAM safeguards for public media; report/ban flows; rate‑limits and anti‑spam.
🧩 Data model (high‑level)
(Full SQL included in the /docs/schema.sql)
- app_user(id, username, lightning_address, …)
- chat(id, is_group, title, …)
- chat_member(chat_id, user_id, role, …)
- media_asset(id, owner_id, sha256, mime, bytes, icc_profile, exif_json, storage_key, …)
- message(id, chat_id, sender_id, kind, ciphertext, media_asset_id, price_sats, …)
- payment_invoice(id, bolt11, amount_sats, status, asset_id, expires_at, …)
🔌 API sketch (MVP)
(Full details in /docs/api.md)
- POST /api/v1/payments/invoices → create BOLT11 invoice
- GET /api/v1/payments/invoices/:id → poll status
- POST /api/v1/payments/mock/settle → demo settle (for the prototype)
- GET /api/v1/chats/:chatId/messages / POST /api/v1/chats/:chatId/messages
- POST /api/v1/media/upload-init → (replace with signed S3 URL)
🛡️ Security & compliance checklist
- Non‑custodial by default: embed wallet SDK on device so you never hold user funds.
- Minimize metadata: server never sees plaintext content; only stores encrypted blobs + minimal routing info.
- Key backup: clear user education + export path; consider SRP/secret sharing for recovery.
- Legal: if you ever add custodial flows, design KYC/AML + proper licensing/ToS; geoblock where needed.
🗺️ Suggested build plan
Sprint 1–2 (Foundations)
- Matrix homeserver + user auth, minimal chat UI.
- S3/R2 encrypted uploads + thumbnailer + CDN.
Sprint 3 (Lightning MVP)
- Server‑issued invoices for message paywalls.
- Client pay → unlock, with robust polling and errors.
Sprint 4 (Photo polish)
- Gallery threads, EXIF/ICC preservation, fast zoom, offline cache.
Sprint 5 (Tips + profiles)
- LNURL‑pay on profiles, analytics for creators.
Sprint 6 (Hardening & beta)
- Backups, moderation, rate limits, crash reporting, CI/CD.
✨ Name ideas
- ShutterSats (snappy!)
- SnapSats
- TelePhoto
- LumiChat
- Silvergrain
- FrameWire
Pick your vibe—I’ll roll with your favorite in the next iteration.
🧪 What to replace next (to go from demo → production)
- Swap the mock Lightning provider with LND/CLN/LNbits or a non‑custodial client SDK (LDK/Breez).
- Wire chats to Matrix instead of the in‑memory seed in the demo.
- Replace upload-init with pre‑signed S3/R2 URLs and a libvips thumbnail service.
- Add auth, multi‑device E2EE, and a real Postgres.
If you want, I can next:
- Tailor the UI to your brand,
- Wire in a real Lightning node/provider,
- Or expand the schema for subscriptions and revenue splits.
Let’s make photographers smile and sats sizzle. ⚡📸