Skip to content

Commit 7b8483d

Browse files
vveerrggclaude
andcommitted
docs: add NWC/NUT-24 micropayment research and Apple compliance TODO
Research section for HTTP 402 interception via Cashu (NUT-24) with NWC wallet connections (Coinos, Alby Hub, Zeus, etc.) and Apple App Store compliance considerations for Safari extension builds. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e3c6bec commit 7b8483d

1 file changed

Lines changed: 91 additions & 0 deletions

File tree

TODO.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,94 @@ Add a Remote Signing (nsecBunker) settings panel to NostrKey. Default bunker rel
8383
- [ ] Connect to bunker relay WebSocket when remote signing is enabled
8484
- [ ] Handle NIP-46 request/response lifecycle (decrypt → sign → encrypt → publish)
8585
- [ ] Mirror UX to iOS and Android apps
86+
87+
---
88+
89+
## TODO-RESEARCH: HTTP 402 Micropayments via NWC + Cashu (NUT-24)
90+
91+
**Status:** Research / Exploration
92+
**Reference:** https://402fordummies.dev/
93+
**Specs:** NUT-24 (HTTP 402 + Cashu), NUT-18 (payment requests), NUT-10 (lock conditions), NIP-47 (Nostr Wallet Connect)
94+
95+
### Concept
96+
97+
Intercept HTTP 402 ("Payment Required") responses in the browser and handle micropayments automatically via a connected wallet. The server returns a 402 with an `X-Cashu` header containing a NUT-18 encoded payment request. NostrKey decodes it, pays via a connected NWC wallet, and retries the request with a `cashuB` token. Content unlocks seamlessly.
98+
99+
NostrKey already holds the user's Nostr identity — adding a wallet connection layer turns it into a unified identity + payments extension. NUT-10 lock conditions can require proofs locked to a Nostr pubkey, which NostrKey can sign natively.
100+
101+
### Payment Flow (5-Step Handshake)
102+
103+
1. Client requests a protected resource (normal HTTP GET)
104+
2. Server responds 402 + `X-Cashu` header with NUT-18 payment request
105+
3. NostrKey decodes the header → extracts amount, unit, accepted mints, lock conditions
106+
4. NostrKey sends pay request to connected wallet via NWC (NIP-47) → gets proof/token back
107+
5. NostrKey retries original request with `X-Cashu: cashuB...` → server validates → 200 OK
108+
109+
### Wallet Connection via NWC (NIP-47)
110+
111+
NostrKey does NOT become a wallet. It connects to an external wallet via NWC — a Nostr-native protocol where communication happens over relays using encrypted events (kind 23194 requests, kind 23195 responses).
112+
113+
**User setup:** Paste a `nostr+walletconnect://` URI from their wallet into NostrKey settings. That's it.
114+
115+
**NWC-compatible wallets (known):**
116+
- Coinos (coinos.io) — web-based, Lightning + Cashu, open-source NWC: `github.com/coinos/coinos-server/blob/master/lib/nwc.ts`
117+
- Alby Hub — most popular NWC wallet, self-hostable, multiple backends (LDK, LND, Cashu, Phoenixd)
118+
- Zeus — mobile multi-wallet with embedded node, NWC from v0.10+
119+
- Nutstash — Cashu ecash wallet with experimental NWC
120+
- Alby Go — simple mobile NWC interface
121+
- Any future NWC-compatible wallet (protocol is standardized)
122+
123+
One implementation covers all wallets — NWC is "the USB-C of Bitcoin wallets."
124+
125+
### UX Direction (from discussion)
126+
127+
**Wallet connection is NOT a Connected App** — it's an outbound connection (NostrKey → Wallet), not inbound (App → NostrKey). Connected Apps = apps asking NostrKey to sign. NWC = NostrKey asking a wallet to pay. The directionality is flipped.
128+
129+
**Preferred approach (Option B):** Wallet gets its own section in Settings, separate from the Apps tab. It's infrastructure (configure once, forget until a 402 hits), not an app relationship.
130+
131+
**Settings panel concept:**
132+
- "Connect Wallet" button → modal with paste field for NWC URI (or QR scan on mobile)
133+
- Dropdown of known wallets (Coinos, Alby Hub, Zeus, Nutstash, Other) with logos + "How to connect" link for each
134+
- Auto-detect wallet name from NWC info event
135+
- Connection status indicator (green/red dot)
136+
- Optional auto-approve threshold: "Auto-approve payments under ___ sats"
137+
- Disconnect per connection
138+
139+
**Main popup indicator:** Small `⚡ Coinos` with green dot in header bar — always visible, minimal footprint.
140+
141+
### Components to Build
142+
143+
- [ ] **NWC connection manager** — UI to paste/scan `nostr+walletconnect://` URI, parse + store secret securely in extension storage
144+
- [ ] **NWC client** — send NIP-47 encrypted requests (kind 23194) over configured relay, listen for responses (kind 23195). Evaluate `@getalby/sdk` or `@nostr-dev-kit/ndk` for existing NWC support
145+
- [ ] **402 interceptor**`chrome.webRequest.onHeadersReceived` listener catching 402 responses, parsing `X-Cashu` headers
146+
- [ ] **NUT-18 decoder** — decode `creqA...` payment request format (amount, unit, mints, NUT-10 lock conditions)
147+
- [ ] **Payment approval UX** — popup/badge notification showing amount + mint, approve/deny, optional auto-approve under threshold
148+
- [ ] **Wallet dropdown in settings** — known wallets with logos + setup instructions, generic "Other" option
149+
- [ ] **Popup wallet indicator** — small status badge in main extension popup header
150+
151+
### Research Questions
152+
153+
- Should NostrKey ever hold Cashu tokens directly (embedded wallet), or always delegate to external wallets via NWC?
154+
- How do NUT-10 lock conditions interact with Nostr pubkey signing? Can NostrKey sign proofs natively?
155+
- What's the fallback UX when no wallet is connected and a 402 is encountered? (Toast notification with "Connect a wallet to pay" link?)
156+
- Can the 402 interceptor work in Safari (different extension APIs)?
157+
- Evaluate `@getalby/sdk` vs `@nostr-dev-kit/ndk` vs minimal custom NWC client for bundle size
158+
- How does Alby's existing browser extension handle this? What can we learn / differentiate?
159+
160+
### Strategic Angle
161+
162+
NostrKey would be the first extension combining **Nostr key management + NWC wallet connection + HTTP 402 payment interception** in one package. Identity, payments, and access control — unified. Alby does WebLN + NWC but doesn't manage Nostr identity. NostrKey does identity but doesn't do payments. This bridges the gap.
163+
164+
Also relevant for gating access to The Factory / Lx7.ca and NostrKeep premium features without any traditional payment processor.
165+
166+
### Apple Compliance — Safari Extension + iOS App
167+
168+
**Critical research before implementation.** See also: `nostrkey.app.ios.src/TODO.md` for full iOS-specific breakdown.
169+
170+
Apple may require NWC features to be hidden or omitted from Safari extension and iOS app builds:
171+
172+
- [ ] **App Store Review Guideline 3.1.5** — does connecting to an external wallet via NWC trigger Apple's crypto app rules? NostrKey is NOT a wallet (just a bridge), but Apple may not see it that way.
173+
- [ ] **IAP bypass risk** — could Apple view NWC-powered 402 payments as circumventing In-App Purchase? Payments go to third-party content providers, not to us.
174+
- [ ] **Safari extension API gaps** — does Safari's WebExtension API support intercepting 402 responses and modifying request headers the same way Chrome does?
175+
- [ ] **Precedent** — how do Zeus, Alby Go, and other NWC/Lightning apps handle Apple review?
176+
- [ ] **Feature flag strategy** — if Apple blocks it, gate NWC behind a build-time or remote config flag. Ship in Chrome/Firefox, omit from Safari/iOS. Code stays unified, feature availability varies by platform.

0 commit comments

Comments
 (0)