# 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:<hex>` 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:<hex>` 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.
