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
Design proposal (not implemented) for three opt-in, serverless additions
layered on the existing capsule/relay/NIP-44 primitives:
- Phone-approval sign-in via a 2-of-2 split credential-capsule key
- Backup codes (each an independent high-entropy recovery path)
- Importing an existing nsec as the everyday identity
Includes a "why not literal TOTP" section and per-feature threat notes.
Co-Authored-By: Claude <[email protected]>
Claude-Session: https://claude.ai/code/session_01GWJbXXhvTx9wo59jSz57J6