{"id":30596434,"url":"https://github.com/ac12644/lightning-paywall","last_synced_at":"2025-08-29T21:43:32.835Z","repository":{"id":310878360,"uuid":"1041596532","full_name":"ac12644/lightning-paywall","owner":"ac12644","description":"A micro paywall using LNbits Lightning invoices for instant payments.","archived":false,"fork":false,"pushed_at":"2025-08-20T18:20:01.000Z","size":2995,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-20T20:41:14.251Z","etag":null,"topics":["bitcoin","lightning","lnbits"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ac12644.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-20T18:10:57.000Z","updated_at":"2025-08-20T18:21:22.000Z","dependencies_parsed_at":"2025-08-20T20:41:16.584Z","dependency_job_id":"b8913668-83eb-479a-8c9e-6401e1982a82","html_url":"https://github.com/ac12644/lightning-paywall","commit_stats":null,"previous_names":["ac12644/lightning-paywall"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/ac12644/lightning-paywall","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ac12644%2Flightning-paywall","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ac12644%2Flightning-paywall/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ac12644%2Flightning-paywall/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ac12644%2Flightning-paywall/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ac12644","download_url":"https://codeload.github.com/ac12644/lightning-paywall/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ac12644%2Flightning-paywall/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272767559,"owners_count":24989523,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-29T02:00:10.610Z","response_time":87,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bitcoin","lightning","lnbits"],"created_at":"2025-08-29T21:43:32.223Z","updated_at":"2025-08-29T21:43:32.819Z","avatar_url":"https://github.com/ac12644.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ⚡ Lightning Micro Paywall\n\nA **Next.js** app implementing a **Bitcoin Lightning paywall** with optional on-chain fallback.\nUses **LNbits** for invoice creation/checking, **BIP32 (XPUB)** for address derivation, and **JWT** for access tokens.\n\n---\n\n## ✨ Features\n\n- ⚡ Lightning invoice creation via LNbits\n- 🔄 Polling to check payment status\n- 🪙 Optional on-chain BTC fallback (XPUB-based address derivation)\n- 🔑 JWT tokens issued after successful payment\n- 🛡️ In-memory stores (replaceable with DB/Redis in production)\n- 🖥️ Next.js frontend with QR code display\n\n---\n\n## Demo\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"content/video.gif\" width=\"600\" /\u003e\n\u003c/p\u003e\n\n---\n\n## 🗂️ Project Structure\n\n```bash\nlightning-paywall/\n├─ .env.example           # env vars template\n├─ app/\n│  ├─ page.tsx            # main Paywall page\n│  └─ api/\n│     ├─ create-invoice/route.ts\n│     ├─ check-invoice/route.ts\n│     ├─ address/new/route.ts\n│     ├─ address/check/route.ts\n│     └─ verify/route.ts\n├─ components/\n│  └─ Paywall.tsx         # frontend paywall UI\n├─ lib/\n│  ├─ lnbits.ts           # LNbits helpers\n│  ├─ jwt.ts              # JWT mint/verify\n│  ├─ derive.ts           # BTC XPUB derivation\n│  └─ state.ts            # in-memory invoice/address\n```\n\n---\n\n## ⚙️ Setup\n\n### 1. Clone \u0026 install\n\n```bash\ngit clone https://github.com/ac12644/lightning-paywall.git\ncd lightning-paywall\nnpm install\n```\n\n### 2. Configure environment\n\nCopy `.env.example` → `.env.local` and fill in:\n\n```bash\n# LNbits invoice API\nLNBITS_API_BASE=https://demo.lnbits.com\nLNBITS_API_KEY=your_invoice_key_here\n\n# JWT signing\nJWT_SECRET=your-long-random-secret\n\n# On-chain fallback (optional)\nBTC_NETWORK=mainnet\nBTC_XPUB_TESTNET=your_testnet_xpub_here\nONCHAIN_MIN_CONF=1\n\n# Price \u0026 invoice expiry\nPRICE_SATS=50\nINVOICE_EXPIRY_SECS=600\n```\n\n\u003e ⚠️ Use **invoice/read keys** from LNbits (not admin).\n\n### 3. Run dev server\n\n```bash\nnpm run dev\n```\n\nOpen: http://localhost:3000\n\n---\n\n## 🔌 API Endpoints\n\n### `POST /api/create-invoice`\n\nCreate a Lightning invoice.\n\n```json\n{\n  \"amountSats\": 50,\n  \"memo\": \"Paywall access\"\n}\n```\n\nResponse:\n\n```json\n{\n  \"paymentHash\": \"62e9…7075\",\n  \"paymentRequest\": \"lnbc50n1p…\"\n}\n```\n\n---\n\n### `GET /api/check-invoice?hash=...`\n\nCheck if invoice is paid.\n\n```json\n{ \"paid\": true }\n```\n\n---\n\n### `POST /api/address/new`\n\nDerive new on-chain BTC address from XPUB.\n\n```json\n{ \"amountSats\": 1000 }\n```\n\nResponse:\n\n```json\n{\n  \"paymentId\": \"addr_123\",\n  \"address\": \"tb1qxyz...\",\n  \"amountSats\": 1000\n}\n```\n\n---\n\n### `GET /api/address/check?id=...`\n\nCheck if address has received required funds.\n\n```json\n{ \"confirmed\": true }\n```\n\n---\n\n### `POST /api/verify`\n\nVerify JWT token.\n\n```\n{ \"token\": \"...\" }\n```\n\nResponse:\n\n```json\n{ \"ok\": true, \"payload\": { … } }\n```\n\n---\n\n## 🔄 Payment Flow\n\n1. **Frontend** calls `/api/create-invoice` with amount.\n2. User scans QR (BOLT11 invoice).\n3. Frontend polls `/api/check-invoice?hash=...`.\n4. When paid:\n   - Invoice is marked `paid` in `state.ts`\n   - A **JWT access token** is minted and returned.\n5. Client can now call protected APIs with the token.\n6. (Optional) If LN fails, user requests `/api/address/new` and pays on-chain.\n\n---\n\n## 📦 Deployment\n\n```\nnpm run build\nnpm start\n```\n\nFor production:\n\n- Use **Redis/Postgres** instead of in-memory `Map`\n- Use **secure JWT secret**\n- Use a dedicated LNbits instance (self-hosted or trusted provider)\n\n---\n\n## 🧪 Testing\n\n- Get **test sats** from a faucet (e.g. mutinynet)\n- Pay Lightning invoice with **Zeus Wallet** or **Alby** (testnet mode)\n- For on-chain fallback, request tBTC from Bitcoin Testnet Faucet\n\n---\n\n## 🚧 TODO\n\n- [ ] Webhook push from LNbits (instead of polling)\n- [ ] Replace memory store with Redis/DB\n- [ ] Multi-currency pricing\n- [ ] UI polish \u0026 content unlock demo\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fac12644%2Flightning-paywall","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fac12644%2Flightning-paywall","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fac12644%2Flightning-paywall/lists"}