🦞
PQSafe · SpendEnvelope Generator

Issue a SpendEnvelope.

Real ML-DSA-65 + ECDSA P-256 dual-signature. Ephemeral keypairs generated in your browser, JCS canonicalization per RFC 8785. Nothing is sent to PQSafe servers. Paste the result into the verifier with the public keys shown below.

Note: Envelopes generated here are signed with ephemeral demo keys not registered with the real PQSafe issuer. For production envelopes from the canonical issuer, use @pqsafe/cli or the issuer API. This page demonstrates the cryptographic shape so integrators can wire up a verifier against a known good envelope.

How issuance works

  1. 1. Capture intent. The agent records what it wants to spend, where, and under what policy. These become the mandate fields above.
  2. 2. Canonicalize. Mandate fields (without signature) are serialized via RFC 8785 JCS — sorted keys, normalized numbers, deterministic encoding. Any equivalent JSON produces identical bytes.
  3. 3. Fingerprint. SHA-256 of the canonical bytes produces a 32-byte fingerprint. The signature is over the fingerprint, not the raw JSON.
  4. 4. Dual-sign. The fingerprint is signed with both ECDSA P-256 (~71 bytes DER) and ML-DSA-65 (3309 bytes per FIPS 204). Either signing key alone produces a valid signature; the verifier checks both.
Spec: NIST FIPS 204 · RFC 8785 JCS · AP2 Post-Quantum Profile (RFC · FIDO open letter)

For production

Ephemeral keys are for exploration only. In production, the canonical PQSafe issuer holds the long-lived keypair, registers the public key fingerprint on-chain (Arbitrum), and exposes a controlled HTTP issuance API.

npm i -g @pqsafe/cli
pqsafe issue \
  --agent did:web:youragent.com:agent-1 \
  --amount 50.00 --currency USD \
  --recipient did:web:merchant.com:payee \
  --output envelope.json

@pqsafe/cli docs →