NIP-46 decrypted bridge

The nip46-decrypted-bridge-v0 contract defines what the companion does with an already-decrypted NIP-46 payload. The bridge is intentionally narrow: it does not implement relay sessions, does not do encryption, and does not derive keys.

What the bridge accepts

The companion accepts a decrypted NIP-46 payload as JSON. The bridge:

  1. Validates the payload against the NIP-46 contract: it is a sign_event request, get_public_key, or another supported method.
  2. Maps it to the equivalent v0 nSealr signing request — or, if the request shape isn’t supported, returns a deterministic non-signing decision with a typed reason.
  3. Returns the decision to the calling companion surface. Routing, relay sessions, and signer I/O stay outside this narrow bridge contract.
$ nsealr nip46 decide --message decrypted.json --permissions sign_event:1 --out decision.json
# decision.json contains a sign_event conversion or a deterministic refusal

or:

$ nsealr nip46 decide --message unsupported-method.json --permissions sign_event:1 --out decision.json
 deterministic non-signing decision: UNSUPPORTED_METHOD

What it does not do

Out of scopeWhy
Open a relay sessionEncrypted relay sessions are upstream of the secretless companion
Decrypt NIP-46 envelopesDecryption requires keying material; the companion is secretless
Sign anything itselfThe companion never holds keys
Implement remote signer logicThat’s the signer’s job

Per-signer policy

The bridge produces standard v0 signing-request decisions for the calling companion surface. The signer then applies its policy (scoped-policy-automation-v0 on the USB/NIP-46 line, manual-only on QR vaults, external review acknowledgement on smartcards). The bridge does not enforce policy on its own.

Deterministic non-signing decisions

When the bridge cannot convert or allow a request, it returns one of a fixed enumeration. The caller can rely on these as typed values.

DecisionWhen
UNSUPPORTED_METHODThe NIP-46 method is not part of the v0 surface
BAD_PAYLOAD_SHAPEThe decrypted JSON doesn’t match the NIP-46 schema
IMPLEMENTATION_LIMITRequest exceeds shared v0 implementation limits
POLICY_DENY_BY_DEFAULTNo explicit allow rule covers this request
SIGNER_UNREACHABLENo active signer route can be reached now

A bridge that returns one of these has not signed and will not sign. The decision is final for the request id; the caller must build a fresh request to try again.

See also

Last updated 2026-05-20