mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
4.1 KiB
4.1 KiB
NIP-46 Client Overview
js/nostr/nip46Client.js implements the Nostr Connect (NIP-46) protocol, allowing the application to delegate event signing to a remote signer (e.g., a "Bunker" or mobile wallet) instead of managing private keys locally.
Architecture
The communication happens over standard Nostr relays using Kind 24133 (Nostr Connect) events. These events act as an RPC (Remote Procedure Call) transport layer.
Components
-
Nip46RpcClient: The central controller. It manages:- Encryption: Secures payloads using NIP-44 (XChaCha20) or NIP-04 (legacy AES).
- Subscription: Listens for responses from the specific remote signer pubkey.
- Queueing: Uses
Nip46RequestQueueto serialize and throttle requests (preventing "rate-limited" errors). - Session: Persists connection details (remote pubkey, relays) to
localStorage.
-
Nip46RequestQueue: A priority queue ensuring RPC calls are processed sequentially and respect relay rate limits.
Connection Flow
- Parsing: The app receives a connection URI (e.g.,
bunker://...ornostrconnect://...). - Handshake:
Nip46RpcClientinitiates aconnectRPC call. - Verification: If a
secretwas provided in the URI, the client verifies the signer's response matches it. - Metadata: The client fetches the user's public key via
get_public_key.
sequenceDiagram
participant App
participant Client as Nip46RpcClient
participant Relay
participant Signer as Remote Signer
App->>Client: connect(bunkerURI)
Client->>Client: parse URI & derive ephemeral keys
Client->>Relay: Publish Kind 24133 (method: "connect")
Relay->>Signer: Deliver Event
Signer->>Relay: Publish Kind 24133 (result: "ack")
Relay->>Client: Deliver Response
Client->>Client: Verify Secret & Permissions
Client-->>App: Connected
Signing Flow
When the app needs to publish a video or update a profile, it calls signEvent.
sequenceDiagram
participant App
participant Client as Nip46RpcClient
participant Relay
participant Signer
App->>Client: signEvent(unsignedEvent)
Client->>Client: JSON.stringify(unsignedEvent)
Client->>Client: Encrypt Payload (NIP-44)
Client->>Relay: Publish Kind 24133 (method: "sign_event")
Note over Client, Signer: Network Latency / Queueing
Signer->>Relay: Publish Kind 24133 (result: signedJson)
Relay->>Client: Deliver Response
Client->>Client: Decrypt & Parse
Client-->>App: Signed Event
Security & Encryption
- Ephemeral Keys: The client generates a random local key pair for each session. The user's main private key is never transmitted.
- Encryption Negotiation: The client prefers NIP-44 v2 but falls back to NIP-04 if the signer doesn't support it.
- Auth Challenges: If the signer requires out-of-band authentication (e.g., scanning a QR code), it returns an
auth_urlerror, which the client bubbles up to the UI.
Key Functions
parseNip46ConnectionString(uri): specific parser forbunker://andnostrconnect://URIs, extracting secrets, relays, and remote pubkeys.createNip46Cipher(...): Factory that creates an encryption interface (encrypt/decrypt) based on available libraries and negotiated algorithms.decryptNip46PayloadWithKeys(...): Helper to brute-force decrypt an incoming message using all available algorithms (handling legacy vs modern formats).
Error Handling
- Timeouts: RPC calls have a default timeout (15s).
- Rate Limiting: If relays reply with
rate-limited, the client performs exponential backoff. - Session Recovery: On page load,
readStoredNip46Sessionrehydrates the session fromlocalStorageto resume without re-connecting.
When to change
- Protocol Updates: If NIP-46 or NIP-44 standards are updated (e.g. new encryption vectors, new RPC methods).
- Security Audit: If a security review identifies weaknesses in the ephemeral key handling or encryption flow.
- Relay Logic: If the strategy for relay selection or rate-limiting needs to be optimized for better connectivity.