Verify your first envelope in 60 seconds.
One command. One paste. One signed mandate. No signup, no API key, no email.
Install the SDK
0:00 — 0:20
# core SDK npm i @pqsafe/agent-pay # conformance test vectors (optional) npm i @pqsafe/conformance
# core SDK pip install pqsafe # conformance test vectors (optional) pip install pqsafe-conformance
Verify a test envelope
0:20 — 0:40
import { verify } from '@pqsafe/agent-pay'; const vec = await fetch( 'https://pqsafe.xyz/spec/ap2-pq-test-vectors-v1.json' ).then(r => r.json()); const result = await verify(vec.tcs[0].envelope, { ecdsa_pub_hex: vec.ecdsa_public_key_compressed_hex, mldsa_pub_b64u: vec.mldsa_public_key_base64url, }); console.log(result.valid ? 'OK' : 'REJECTED'); // โ OK
from pqsafe import verify import urllib.request, json vec = json.load(urllib.request.urlopen( 'https://pqsafe.xyz/spec/ap2-pq-test-vectors-v1.json' )) result = verify( vec['tcs'][0]['envelope'], ecdsa_pub_hex=vec['ecdsa_public_key_compressed_hex'], mldsa_pub_b64u=vec['mldsa_public_key_base64url'], ) print('OK' if result.valid else 'REJECTED') # โ OK
Reject a tampered one
0:40 — 0:60
const evil = structuredClone(vec.tcs[0].envelope); evil.amount = '9999.00'; // mutate const r = await verify(evil, { ecdsa_pub_hex: vec.ecdsa_public_key_compressed_hex, mldsa_pub_b64u: vec.mldsa_public_key_base64url, }); console.log(r.valid ? 'OK' : 'REJECTED'); // โ REJECTED
import copy evil = copy.deepcopy(vec['tcs'][0]['envelope']) evil['amount'] = '9999.00' # mutate r = verify( evil, ecdsa_pub_hex=vec['ecdsa_public_key_compressed_hex'], mldsa_pub_b64u=vec['mldsa_public_key_base64url'], ) print('OK' if r.valid else 'REJECTED') # โ REJECTED
Drop into your agent framework
One import. The pqsafePay tool gates every payment call on a verified envelope. Snippets below are minimal — consult each plugin's README for production wiring.
pip install langchain-pqsafe
from langchain.agents import AgentExecutor from langchain_pqsafe import AgentPayTool agent = AgentExecutor( tools=[AgentPayTool(spend_cap='100.00', currency='USD')], ... ) # every payment the agent attempts is gated by a signed envelope
What just happened
The SDK fetched the canonical test vectors, ran RFC 8785 JCS canonicalization on the mandate (without the signature field), SHA-256'd the canonical bytes to get a 32-byte fingerprint, and verified two signatures over that fingerprint: ECDSA P-256 (legacy compatibility) and ML-DSA-65 (FIPS 204 post-quantum). Both must pass.
When you mutated amount, the canonical bytes changed, the fingerprint changed, and both signatures stopped matching. There is no way to flip a field and re-use the original signature — you would need the issuer's private keys.
This is what makes the SpendEnvelope a cryptographic permission slip rather than a session token. The amount, the recipient, the currency, and the nonce are bound to the signature. Replay protection comes from the nonce registry (on-chain + edge cache). Revocation comes from a separate signed revoke list. Audit comes from the canonical envelope retention.
Why two signatures? ECDSA P-256 gives you universal verifier compatibility today. ML-DSA-65 gives you forward security through the post-quantum transition. The cost is ~3KB of signature bytes and ~0.03 ms of native verify time on top of ECDSA — see /bench.
8 one-click mutations on a real envelope. See exactly which signature fails when which field changes.
Generate an ephemeral keypair and sign a SpendEnvelope client-side. No setup.
Capability matrix, where each one wins, when post-quantum matters.
Wire-level details of the canonical envelope shape and dual-signature scheme.