Skip to main content

Documentation Index

Fetch the complete documentation index at: https://sigil-10dddbf2.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

@sigil-xyz/x402 implements a request authentication flow on top of HTTP 402 Payment Required. It lets any server verify that an incoming request comes from a credentialed, in-budget agent — without a separate auth service.

How it works

1

Agent builds signed headers

The agent calls buildSigilHeaders with its keypair, the principal public key, the request method, path, and spend amount. This produces four HTTP headers containing the agent’s public key, the principal’s public key, a timestamp, and an ed25519 signature.
2

Server receives request

The middleware extracts the four x-sigil-* headers and validates them.
3

Signature verification

The middleware reconstructs the signed message {timestamp}:{METHOD}:{path}:{spendAmount} and verifies the ed25519 signature against the agent’s public key.
4

Timestamp check

Rejects the request if the timestamp is older than maxRequestAgeMs (default 60 seconds). Prevents replay attacks.
5

On-chain Sigil check

Calls client.verifySigil(agentPubkey, { requiredCapability, maxSpendAmount }). Returns 402 if the Sigil is missing, revoked, expired, or lacking the required capability.
6

Record spend

If spendAmount > 0, calls client.recordSpend(agentPubkey, amount) on-chain. This debits the agent’s daily limit and rejects the request if the limit would be exceeded.
7

Request forwarded

On success, the verified agent public key is attached to the request object (req.sigilAgent) and the next handler is called.

Required headers

Agents must attach these four headers to every request:
HeaderValue
x-sigil-agentBase58 agent public key
x-sigil-principalBase58 principal public key that issued the agent’s Sigil
x-sigil-timestampUnix timestamp in milliseconds
x-sigil-signatureBase58 ed25519 signature

Signature payload

{timestamp}:{METHOD}:{path}:{spendAmount}
Example: 1714300000000:POST:/api/generate:50000 The message is UTF-8 encoded and signed with the agent’s ed25519 secret key using nacl.sign.detached.

402 response body

When authorization fails, the middleware returns HTTP 402 with:
{
  "protocol": "sigil-v1",
  "message": "reason for rejection",
  "requiredCapability": "image-generation",
  "spendAmount": "50000",
  "credentialProgram": "ZFK63KBXDhGCYm5orVo5QiTBaBhWD4PUcUDBG6fjTkH",
  "network": "devnet",
  "docs": "https://docs.sigil.xyz/x402"
}

SigilMiddlewareConfig

All adapters (Express and Next.js) share the same config interface:
interface SigilMiddlewareConfig {
  connection: Connection                   // Solana RPC connection
  serverWallet: AnchorProvider['wallet']   // signs record_spend transactions
  requiredCapability?: string              // capability the agent must have
  spendAmount?: BN                         // micro-USDC to debit per request (0 = verify only)
  maxRequestAgeMs?: number                 // max timestamp age, default 60_000
  network?: 'devnet' | 'mainnet-beta' | 'testnet' // returned in 402 responses, default 'devnet'
}
Setting spendAmount to zero (or omitting it) runs verification only — the Sigil is checked but no spend is recorded.