Multi-signer support: NIP-46 (Amber/bunker), NIP-55 Android intents, nsec paste - #7
Merged
Conversation
…port esbuild-bundled from the existing @noble deps into a committed plain-IIFE artifact (public/js/vendor/nostr-crypto.js): NIP-01 event id/signing byte-identical to src/nostr/event.ts, NIP-44 v2 + NIP-04, bech32 (npub/nsec) ported from src/nostr/nip19.ts, WebCrypto RNG only. Cross-checked in tests against the server modules, nostr-tools, and official NIP-44 vectors; CI rebuilds and fails on artifact drift.
…NIP-46 remote-signer client signer-core.js: pure helpers (nsec decode, NIP-55 intent build/parse, pending-record validation). signer.js: dispatcher with method persistence, redirect-signer resume (schnorr-verified against recomputed event id), and backend registry. signer-nip46.js: bunker:///nostrconnect pairing, kind-24133 RPC over relay wss with NIP-44 (NIP-04 fallback), envelope schnorr verification, random request ids, response-matches-request assertion, auth_url surfacing. 63 unit tests incl. scripted-transport state machine.
…-55/nsec) Login page grows a signer picker (extension / remote signer via bunker:\/\/ or nostrconnect:\/\/ / Amber on Android / paste-key with an explicit unencrypted-localStorage warning); all methods converge on the unchanged kind-22242 challenge flow. Editor signs through NbreadSigner with a pubkey-vs-session mismatch guard, NIP-55 stash/resume (mirror before broadcast, retry-without-re-sign, discard on rejection), and a NIP-42 AUTH client in the relay broadcast (auth-required OK handling, 8s deadline, redirect signers skip AUTH). Signer stack hardened: NIP-55 callbacks require the explicit marker and are bound to their pending-flow type.
docs/home/privacy copy now describes all four signing methods (and the localStorage caveat for pasted keys); public/js README documents the signer stack and load order; ops.md notes the vendor-bundle drift guard; docs/manual-signer-tests.md is the Amber/nsec.app/NIP-55/nsec-paste device checklist covering issue #2 acceptance.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #2.
What
Signing was NIP-07-only. This PR introduces a client-side signer abstraction with four backends — the existing browser extension plus three new ways to sign in and publish:
bunker://paste or client-initiatednostrconnect://) — Amber, nsec.app; kind-24133 RPC over relay wss, NIP-44 encryption with NIP-04 legacy auto-detect,auth_urlapproval links (https-only).returnType=signature; the unsigned event (pubkey + precomputed id) is stashed locally, reassembled and schnorr-verified on callback; publish/delete resume across the redirect with retry-without-re-sign and discard.script-src 'self') is the compensating control.Plus groundwork the relay work (#5) will reuse: the editor's relay broadcast now speaks NIP-42 AUTH (signs the challenge via the active signer, resends the event after auth; skipped for redirect signers).
How
public/js/vendor/nostr-crypto.js— committed, esbuild-generated IIFE (npm run build:vendor) from the existing@noble/*deps: NIP-01 id/signing byte-identical tosrc/nostr/event.ts, NIP-44 v2 (validated against official vectors + nostr-tools interop both directions), bech32 ported fromsrc/nostr/nip19.ts, WebCrypto RNG only. CI rebuilds and fails on drift.public/js/signer-core.js/signer.js/signer-nip46.js— pure cores + dispatcher, per repo IIFE conventions./loginand/api/mirrorcontracts and CSP unchanged (headers.spec.tspasses unmodified). Views/copy updated; no new runtime deps (esbuild +@noble/ciphersare pinned devDeps).Security notes
auth_urlrestricted to https.Testing
docs/manual-signer-tests.md— real-device checklist (Amber bunker + NIP-55, nsec.app incl. auth_url, nsec paste, NIP-07 regression, devtools no-secret audit). Device pass required before merge.