Context
Depends on API endpoint POST /v4/auth/nostr (see #TBD). Once that lands, we can add Nostr as a sign-in method alongside username/password.
What to build
"Sign in with Nostr" button on /login page
- Detects NIP-07 browser extension (window.nostr) — desktop users with Alby, nos2x, etc.
- Falls back to NIP-46 / Nostr Connect QR code — mobile users scan with signer app (Amber, etc.)
- Signs a kind 27235 event, sends it to the API, receives a Bearer token
- Calls session.login() — same flow as password login, reuses all existing infrastructure
Server route
- POST /api/auth/nostr — proxies to POST /v4/auth/nostr (same CORS pattern as other server routes)
New files
- src/lib/nostr.ts — NIP-07 detection, event signing, NIP-46 relay flow
- src/routes/api/auth/nostr/+server.ts — server route proxy
- Update src/routes/login/+page.svelte — add Nostr sign-in button
Dependencies
- nostr-tools — NIP-07 detection, event creation/signing, NIP-46 protocol, nip19 encoding
UX flow
Desktop (NIP-07):
- User clicks "Sign in with Nostr"
- Browser extension popup asks to sign
- User approves → signed event sent to API → Bearer token returned → logged in
Mobile (NIP-46):
- User clicks "Sign in with Nostr"
- QR code shown with nostrconnect:// URI
- User scans with signer app (Amber)
- Signer signs via relay → signed event sent to API → Bearer token returned → logged in
Not in scope
- Linking Nostr to existing password accounts (can come later)
- Per-request NIP-98 signing (Bearer token approach is simpler)
- nsec direct entry (security risk)
References
Context
Depends on API endpoint POST /v4/auth/nostr (see #TBD). Once that lands, we can add Nostr as a sign-in method alongside username/password.
What to build
"Sign in with Nostr" button on /login page
Server route
New files
Dependencies
UX flow
Desktop (NIP-07):
Mobile (NIP-46):
Not in scope
References