QR envelope (nsealr1)

Stateless QR vault solutions use QR codes as the only transport. The envelope contract defines exactly what bytes the device decodes before request validation runs, and exactly what bytes the host expects back.

Two request variants

nsealr1: — static

A single QR code that contains a full signing request whose serialised length fits in one QR scan.

  • URI scheme: nsealr1:
  • Payload: base32 (Crockford) of a CBOR-encoded signing-request-v0.
  • Decoded length: bounded by the v0 implementation limits.
nsealr1:01HXY...   (base32 payload)

nsealr1a: — animated

For requests that exceed the single-QR budget. The host generates a sequence of QR frames, each carrying a chunk plus header metadata. The signer reassembles the chunks before request validation runs.

  • URI scheme: nsealr1a:
  • Each frame carries:
    • Request id (deterministically derived from the full payload).
    • Chunk index i and total chunk count n.
    • Chunk bytes.
    • Integrity tag (per-chunk CRC + reassembly hash).
  • The signer accepts frames in any order, refuses duplicate chunks with mismatching bytes, and stops with a deterministic error if the reassembly hash fails.
nsealr1a:01HXY...:i:n:<chunk>

Reassembly guarantees

  • Bounded: max chunk count and max chunk size are part of the contract; the signer rejects frames outside those bounds before doing any other work.
  • Integrity-checked: per-chunk CRC catches transmission flips; the reassembly hash catches the entire reassembled payload mismatch.
  • Deterministic errors: every failure mode (oversized, duplicate mismatch, hash mismatch, timeout) produces a fixed error code that the companion can recognise.

Response — qr-response-v0

A signer response is either a signed event or a deterministic error, never both, never a partial.

nsealr1r:<base32-cbor-response>

The response carries:

  • request_id — bound to the original request.
  • signer.pubkey — the public key that signed.
  • One of:
    • signed_event{ id, sig, pubkey, kind, created_at, tags, content }.
    • error — a code from a fixed enumeration with a short reason.
  • approval_digest — the digest the local approval was bound to.

The host (companion) refuses any response whose approval_digest does not reproduce the digest of the originally reviewed material — see approval_digest deep-dive.

What QR transport explicitly does not offer

  • Network connectivity: this is the QR vault line. The device never opens a socket; the host never speaks to the device except through frames on the air-gapped camera/display.
  • Plaintext key export: no QR can request a secret-key export.
  • Push notifications: every flow is initiated by the user (scan one, scan back).

See also

Last updated 2026-05-17