Add nsec import: use an existing Nostr identity as the everyday key (§SF10)

core:
- registerAccount gains an optional everydayPrivateKey (validated scalar,
  used instead of generating); result carries an `imported` flag
- importAccount() + decodeEverydayPrivateKey() convenience helpers accept
  nsec (bech32) or 64-char hex, wiring in the existing decodeNsec primitive
- e2e tests: imported nsec round-trips to the same npub through both
  clean-device login and phrase recovery; malformed keys rejected

widget:
- worker gains a `previewImportKey` action (validate + preview npub without
  publishing) and passes importKey through `register`
- <bitlogin-auth> gets an "Import an existing Nostr key" screen: paste
  nsec/hex, check-key preview shows the resulting npub for confirmation,
  then the normal name -> password -> phrase flow, with the pasted key
  dropped from the main thread after registration (§11.10) and a
  risky-paste warning shown up front

docs: mark §SF10 implemented; note backup codes are redundant with the
phrase and unlikely to ship; README implemented-list updated.

Verified end-to-end in real Chromium (preview npub, import, clean-device
login all reproduce the imported identity). 51/51 tests pass.

Co-Authored-By: Claude <[email protected]>
Claude-Session: https://claude.ai/code/session_01GWJbXXhvTx9wo59jSz57J6
This commit is contained in:
Claude committed 2026-07-21 10:59:01 +00:00
1 parent 991c2ee639
commit a76c8484f7
8 files changed
+249 -17

No files matched your search

+6 -2
View File
@@ -1,7 +1,11 @@
# BitLogin Second Factor, Backup Codes, and Imported Identities
**Document version:** 0.1 (draft addendum to the v0.3 core specification)
**Status:** Design proposal — not implemented, not final
**Status:** Mixed. §SF10 (imported identities) is **implemented**. Phone-approval
sign-in (§SF5–SF7) and backup codes (§SF8) are **design proposals only** — and
backup codes are unlikely to ship, since the recovery phrase already covers the
same ground (see §SF8 note). The "why not TOTP" analysis (§SF2) is a settled
rejection, kept on the record.
**Depends on:** `docs/spec.md` (§ references below point there unless marked §SF)
---
@@ -307,7 +311,7 @@ Lost everything incl. phrase → unrecoverable (unchanged, §19.4)
---
# SF10. Imported identities
# SF10. Imported identities — IMPLEMENTED
An existing Nostr identity may be used as the everyday identity under all
of the above (§28.1 anticipated this; the everyday key is by design never