nip44Encrypt and nip04Encrypt took optional nonceOverride / ivOverride parameters. No production caller ever passed one -- but they were exported from @bitlogin/core/crypto, so "encrypt with a nonce I chose" was a discoverable feature of the package rather than an internal detail. That is worth closing because neither primitive degrades gracefully. NIP-44 is ChaCha20: a nonce reused under one conversation key recovers plaintext outright. NIP-04 is AES-CBC, where a repeated IV leaks block-equality between messages and a predictable one gives an attacker considerably more. A parameter that silently accepts a fixed nonce should not sit one autocomplete away from application code. The public functions now take no nonce or IV and always draw from the CSPRNG. The capability moved to crypto/testing.ts as __unsafeNip44EncryptWithNonce / __unsafeNip04EncryptWithIv, which is absent from both crypto/index.ts and the package.json exports map. crypto/index.ts also switches from `export *` to an explicit re-export list for these two modules, so the shared encryptWithNonce / encryptWithIv helpers stay off the surface even though their modules must export them for the test entry point to reach them. Closing this cost nothing: exactly one test used an override -- a nonce-length validation check -- and ivOverride had no callers at all. The official NIP-44 vectors do not need it. Verified from a throwaway consumer package linking the BUILT @bitlogin/core rather than from source. Deep imports of crypto/testing.js, dist/crypto/testing.js and crypto/nip44.js all fail with ERR_PACKAGE_PATH_NOT_EXPORTED; the crypto surface contains neither encryptWithNonce nor encryptWithIv; and nip44Encrypt/nip04Encrypt report arity 2/3, i.e. no nonce or IV parameter. Adds four regression tests pinning the closed surface, including that 64 calls with identical plaintext produce 64 distinct nonces and IVs. knownAnswer.test.ts stayed green throughout, which is the signal that matters here: no capsule bytes change and no existing account is affected. Typecheck, build and the full suite pass (185 tests). Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01HtNMsKzzFTPURemX7tT19u
BitLogin Documentation
BitLogin is a static, relay-backed portable account protocol that gives users a familiar login name and password while preserving a user-controlled Nostr identity and independent phrase recovery.
This directory contains the core protocol specification, implementation notes, and experimental designs for expanding BitLogin into a portable account layer for compatible applications.
Core protocol
spec.md— canonical BitLogin protocol specificationsecond-factor.md— second-factor design notes
Portable account layer
These documents describe proposed capabilities that build on BitLogin's core identity and recovery model.
account-switching.md— multiple independent accounts on one device, fast switching, locking, logout, and account-aware signer behaviorportable-app-state.md— encrypted, user-owned application settings and lightweight state that follow the account across devicesportable-entitlements.md— discovery, verification, recovery, and presentation of purchases, licenses, memberships, and access rightsrelay-and-messaging-portability.md— relay-role management, DM inbox and outbox synchronization, sent-message recovery, and conversation reconstruction
Connection Vault
The Connection Vault stores portable application credentials outside the core
identity capsules as independently encrypted records. Its protocol layer
(records, key hierarchy, relay sync, migration, tiers) is implemented in
@bitlogin/core's src/vault/; the widget authorization layer shipped 2026-07-30 in REVEAL mode
(requestNwcConnection, offerNwcConnection, and a Wallet-connections
screen). Durable per-origin grants and a Connected-apps page are still to
come; see connection-vault.md §19 for the open limitations.
connection-vault.md— overall vault architecture, key hierarchy, relay storage, authorization, recovery, and deletion; §18 records the implementation-time decisions (tier model, sudo key)vault-ux.md— the agreed user-experience walkthroughs, serving as the authorization layer's acceptance criterianwc-connections.md— Nostr Wallet Connect credential profile (parser/exporter implemented insrc/vault/nwc.ts)s3c-format.md— portables3c1:format for S3-compatible storage connections
How the pieces fit together
BitLogin account
├── Identity and recovery
│ ├── Credential capsule
│ ├── Recovery capsule
│ └── Everyday Nostr identity
│
├── Accounts and sessions
│ └── Multiple-account switching
│
├── Communication
│ ├── Relay preferences
│ ├── DM inbox synchronization
│ ├── DM outbox and sent-message recovery
│ └── Conversation reconstruction
│
├── Portable application experience
│ ├── App settings
│ ├── Saved state
│ └── Per-app authorization
│
├── Ownership
│ ├── Purchases
│ ├── Licenses
│ ├── Memberships
│ └── Access entitlements
│
└── Connection Vault
├── NWC wallet connections
├── S3-compatible storage connections
└── Future service credentials
Status terminology
Documents use these labels:
- Implemented — available in the current codebase
- Partially implemented — some required primitives or flows exist, but the complete user-facing feature does not
- Experimental design — documented for review and future implementation; wire formats and APIs may change
Experimental documents are not part of the stable BitLogin protocol until their schemas, security properties, migrations, and test vectors are finalized.
Recommended product sequence
A practical development sequence is:
- Complete the core account and messaging foundations.
- Add independent multi-account sessions and switching.
- Add relay management, inbox synchronization, and sent-message recovery.
- Add portable application state and per-app permissions.
- Add entitlement discovery and a portable ownership library.
- Implement the Connection Vault and its NWC and S3 profiles.
- Move high-value authorization into stronger extension, native, or cross-origin execution boundaries.
Design principle
BitLogin should coordinate portable identity, state, ownership, and service access without becoming the centralized custodian of the user's identity, money, files, messages, or purchases.