Follow-up to #12 (v1 shipped in PR #14: static njump hand-off links + server-side 9735 counts).
v2 keeps the whole zap experience first-party while blog pages stay JS-free:
- New apex-class route
GET /zap?a=30023:<pubkey>:<d> (deliberately NOT an /npub1… path, so it gets APEX_CSP with script-src 'self'), first-party JS only.
- Resolve the author's
lud16 → LNURL-pay endpoint; check allowsNostr/nostrPubkey (server already has this cached in lnurl_cache — consider a thin authed JSON endpoint to reuse it and avoid client-side CORS pain with arbitrary wallet domains).
- Build a
kind 9734 zap request with the post's a tag, amount, relays (editorRelays), p, lnurl; sign via the existing NbreadSigner (all four backends) or offer an anonymous/ephemeral-key zap.
- GET the LNURL callback → show the returned
bolt11 (QR + copy button, plus window.webln when present).
- The LNURL server publishes the 9735; the existing cron pass (
src/services/zaps.ts) counts it — no new ingestion work.
- Repoint the blog post footer's
⚡ Zap this post link from njump.me/<naddr> to https://<MAIN_HOST>/zap?a=… (one-line change in src/routes/tenant.ts postZap).
Also worth picking up from v1's documented bounds:
- Relay paging for the 9735 fetch (v1 reads one 60-event page per run; a spam flood can evict real receipts from the page — bounded suppression, not counts inflation).
- CSP: the callback GET goes to the wallet's domain —
connect-src on the /zap page needs either a relaxation for https: on that route class or a server-side proxy for the callback (proxy keeps CSP tight; weigh subrequest cost).
Follow-up to #12 (v1 shipped in PR #14: static njump hand-off links + server-side 9735 counts).
v2 keeps the whole zap experience first-party while blog pages stay JS-free:
GET /zap?a=30023:<pubkey>:<d>(deliberately NOT an/npub1…path, so it getsAPEX_CSPwithscript-src 'self'), first-party JS only.lud16→ LNURL-pay endpoint; checkallowsNostr/nostrPubkey(server already has this cached inlnurl_cache— consider a thin authed JSON endpoint to reuse it and avoid client-side CORS pain with arbitrary wallet domains).kind 9734zap request with the post'satag,amount,relays(editorRelays),p,lnurl; sign via the existingNbreadSigner(all four backends) or offer an anonymous/ephemeral-key zap.bolt11(QR + copy button, pluswindow.weblnwhen present).src/services/zaps.ts) counts it — no new ingestion work.⚡ Zap this postlink fromnjump.me/<naddr>tohttps://<MAIN_HOST>/zap?a=…(one-line change insrc/routes/tenant.tspostZap).Also worth picking up from v1's documented bounds:
connect-srcon the /zap page needs either a relaxation for https: on that route class or a server-side proxy for the callback (proxy keeps CSP tight; weigh subrequest cost).