NIP-07 sign-in: delegate to an installed extension behind the same facade

Implements login-methods.md §LM4. New signers/ layer in the widget:
detectForeignNip07Provider never mistakes BitLogin's own provider for an
extension, and Nip07Signer wraps the snapshotted provider with capability
probing (typed SignerUnsupportedError instead of TypeErrors off missing
nip44), deadlines on every call (SignerTimeoutError -- no silent hangs),
pubkey validation, and unsigned-event normalization.

The element routes its public API through the active signer, so hosts get
the extension backend transparently. Extension sessions are thin (§LM7):
no capsule, no vault (requestNwcConnection resolves null), no persistence,
and window.nostr is left to the extension -- claimSigner stays reserved
for BitLogin-account sessions. bitlogin-login now carries method and
capabilities; publicKey is unchanged for existing hosts.

Password-first pinned (owner decision, §LM9.1): the extension option
renders as a secondary link under the primary sign-in, enforced in
securityPolicy.test.ts alongside a pin that the extension confirm path
never claims window.nostr or writes storage. 14 new signer tests.

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
thePR0M3TH3ANandClaude Fable 5 committed 2026-08-04 09:28:24 -04:00
1 parent 20a3c50dc2
commit a7adef05f9
6 files changed
+533 -23

No files matched your search

+9 -6
View File
@@ -1,8 +1,10 @@
# BitLogin as the Single Login Surface — NIP-07 and NIP-46 Methods
**Document version:** 0.1 (design proposal)
**Status:** Proposal only — nothing here is implemented. §LM6 records a settled
rejection (nsec paste as a login method), kept on the record.
**Document version:** 0.2
**Status:** §LM4 (NIP-07) is **implemented** (2026-08-04): `signers/` in
`@bitlogin/widget`, thin sessions per §LM7, password-first presentation per
§LM9.1. §LM5 (NIP-46) remains a proposal. §LM6 records a settled rejection
(nsec paste as a login method), kept on the record.
**Depends on:** `docs/spec.md` (§ references point there unless marked §LM or
§SF), `docs/second-factor.md` §SF10 (imported identities, implemented)
@@ -222,9 +224,10 @@ Each step ships independently; the login UI grows one option at a time.
# LM9. Open questions
1. Method presentation: is password-first with an "other ways to sign in"
expander the right default, or should extension detection promote NIP-07
when present?
1. **Resolved 2026-08-04 (owner decision):** username/password stays the
primary presentation; alternative methods appear as secondary affordances
below it, never promoted above the password path even when an extension is
detected. Pinned by `securityPolicy.test.ts`.
2. Should a NIP-07 session survive reload by silently re-asking the
extension, or require an explicit click each visit (extension prompt
fatigue vs. surprise sessions)?