Quickstart (5 min)
This guide walks you from zero to a working payment in 5 minutes. You’ll generate a post-quantum key pair, create a bounded spend envelope, and execute a real payment.
Prerequisites
@pqsafe/agent-payinstalled (installation guide)- A PQSafe account with at least one active rail configured
- Node.js ≥ 18
-
Generate a key pair
ML-DSA-65 key generation is async and requires ~50ms on modern hardware.
import { generateKeyPair } from '@pqsafe/agent-pay'const { publicKey, secretKey } = await generateKeyPair()// Store secretKey securely — treat it like a private key// publicKey is safe to log, share with your issuer, or embed in metadataconsole.log('Public key (hex):', publicKey.slice(0, 32) + '...') -
Create a spend envelope
A spend envelope defines the cryptographic authorization bounds for a payment. The agent can only spend within these bounds.
import { createSpendEnvelope } from '@pqsafe/agent-pay'const envelope = createSpendEnvelope({maxAmount: 50, // Maximum USD the agent may spendcurrency: 'USD',allowedRails: ['airwallex'],allowedRecipients: ['anthropic.com'],validUntil: new Date(Date.now() + 3_600_000), // Expires in 1 houragentId: 'my-agent-v1',memo: 'Anthropic API credits top-up',}) -
Sign the envelope
Signing produces a 6,586-character ML-DSA-65 signature bound to the canonical JSON of the envelope.
import { createSignedEnvelope } from '@pqsafe/agent-pay'const signed = createSignedEnvelope(envelope, secretKey)console.log('Signature length:', signed.signature.length) // 6586 hex charsconsole.log('Envelope ID:', signed.envelopeId) -
Execute the payment
import { executeAgentPayment } from '@pqsafe/agent-pay'const result = await executeAgentPayment(signed, {recipient: 'anthropic.com/billing',amount: 25, // Must be ≤ envelope.maxAmountmemo: 'API credits — monthly top-up',})console.log('Payment status:', result.status) // 'settled' | 'pending' | 'failed'console.log('Rail used:', result.rail) // 'airwallex'console.log('Transaction ID:', result.txId)console.log('Ledger entry:', result.ledgerHash) -
Verify in the ledger
Every payment is appended to the immutable ledger automatically.
import { submitToLedger, buildLedgerRecord } from '@pqsafe/agent-pay'const record = buildLedgerRecord(signed, result)const ledgerEntry = await submitToLedger(record)console.log('Ledger hash:', ledgerEntry.hash)console.log('Sequence:', ledgerEntry.sequence)
Complete example
import { generateKeyPair, createSpendEnvelope, createSignedEnvelope, executeAgentPayment, buildLedgerRecord, submitToLedger,} from '@pqsafe/agent-pay'
async function quickstart() { // 1. Key pair const { publicKey, secretKey } = await generateKeyPair()
// 2. Envelope const envelope = createSpendEnvelope({ maxAmount: 50, currency: 'USD', allowedRails: ['airwallex'], allowedRecipients: ['anthropic.com'], validUntil: new Date(Date.now() + 3_600_000), agentId: 'quickstart-agent', })
// 3. Sign const signed = createSignedEnvelope(envelope, secretKey)
// 4. Execute const result = await executeAgentPayment(signed, { recipient: 'anthropic.com/billing', amount: 25, memo: 'Quickstart test payment', })
// 5. Ledger await submitToLedger(buildLedgerRecord(signed, result))
return result}
quickstart().then(r => console.log('Done:', r.status))Expected output
Public key (hex): a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4...Signature length: 6586Envelope ID: env_01J3X...Payment status: settledRail used: airwallexTransaction ID: txn_airwallex_...Ledger entry: 0xabc123...Done: settledNext steps
- Understanding Spend Envelopes — deep dive on envelope fields
- Recipes: Pay Anthropic Credits — production pattern for AI billing
- Add a Telegram Approval Gate — require human approval for large payments