# Plan: Deferred NIP-46 bunker transport mode Status: **deferred (design only, not in current implementation scope)** This document records a future transport mode where `n_signer` can operate as a NIP-46-compatible bunker over relays, while keeping the current local/TCP framed JSON-RPC path intact. Current implementation priority remains [`plans/caller_token_identity.md`](caller_token_identity.md): required per-request caller authentication for TCP/URL using signed auth envelopes and existing `n_signer` request flow. --- ## 1. Why this is deferred NIP-46 adds more than caller authentication: - Relay session lifecycle and routing - NIP-44 encrypted request/response payloads - `connect` ceremony and secret verification - Signer service identity (`remote-signer-pubkey`) management - Compatibility behavior for `nostrconnect://` and `bunker://` That is a separate subsystem from the immediate bugfix (stable, authenticated caller identity over TCP reconnects). Combining both now would increase risk and delay rollout. --- ## 2. Future objective Add an optional mode (example: `--listen nip46`) that accepts NIP-46 `kind:24133` requests and returns NIP-46 `kind:24133` responses as defined in [`resources/nips/46.md`](../resources/nips/46.md). This mode should: 1. Authenticate client requests using NIP-46 client keypairs and encrypted content. 2. Map NIP-46 caller identity to the same deny-by-default approval model already used by current transports. 3. Reuse existing dispatcher/enforcement/policy machinery after transport decoding. --- ## 3. Compatibility stance (future) - Keep current framed JSON-RPC transports (`AF_UNIX`, `qrexec`, `tcp`) as first-class for local deployments. - Add NIP-46 as **additional** transport, not replacement. - Shared internal core: once a request is decoded into `(caller_id, method, params, selector)`, the same policy and enforcement pipeline runs. --- ## 4. Planned phases ### Phase A — Transport shell - Add `nip46` listen mode and relay I/O loop. - Parse and validate incoming `kind:24133` envelope. - Decrypt NIP-44 payload and extract JSON-RPC-like `method` + `params`. ### Phase B — Identity + approval binding - Derive caller identity from NIP-46 `client-pubkey`. - Represent as `caller_id = pubkey:` to align with the current TCP auth direction in [`plans/caller_token_identity.md`](caller_token_identity.md). - Route to existing policy checks and prompt behavior. ### Phase C — Response path - Convert dispatcher results into NIP-46 response payloads. - Encrypt via NIP-44 and emit `kind:24133` response event. - Preserve request `id` correlation and error mapping. ### Phase D — Connect / secret / perms polish - Implement full `connect` handshake semantics from [`resources/nips/46.md`](../resources/nips/46.md:100). - Validate optional secret behavior. - Support requested permissions metadata and signer-side policy translation. ### Phase E — Operational hardening - Relay switching behavior (`switch_relays`), lifecycle recovery. - Rate limits and replay protections specific to relay transport. - Audit/event logs for NIP-46 connections and requests. --- ## 5. Open design questions (for later) 1. Should NIP-46 mode require a dedicated signer identity key, or may it reuse the user signing identity? 2. How should `connect` permissions map to `n_signer` role/selector approvals? 3. Should NIP-46 callers and TCP-auth callers share the same `pubkey:` approval namespace by default? 4. Do we support both relay-initiated and direct-client initiation flows from day one? 5. What minimum relay trust assumptions are required in `documents/SECURITY.md`? --- ## 6. Out of scope for current code work The current implementation task does **not** include: - Adding relay networking - NIP-44 tunnel encryption for requests - NIP-46 `connect` handshake - `nostrconnect://` URI flow Those remain deferred to this plan.