402 Payment Required response, constructing and signing the EIP-712 payment payload via Fireblocks, and retrying the original request with proof of payment. Gasless signing happens off-chain — the agent never submits an on-chain transaction itself.
Source: github.com/fireblocks/x402-agent
Ships in two forms: an MCP server for Claude Desktop, Cursor, and other MCP clients, and a CLI for scripting and testing payment flows from the terminal. Before production use, combine the four security layers in Secure deployment so the agent can only spend what you explicitly allow.
Requirements
- Node.js 18+
- Fireblocks API account with a vault configured
- Sufficient token balance on the target network (for example, USDC on Base)
How it works
Payment sequence
- Initial request — Agent sends GET to the resource server.
- 402 Payment Required — Resource server returns a
PaymentRequiredJSON body withaccepts[]payment options. - (Optional) Integrity check — Agent verifies the envelope against the facilitator’s
did:webkey (see Payment Instruction Integrity). - Select mechanism — Agent picks the first supported
accepts[]entry (preference:eip3009→permit2; overridable viaMECHANISM). - Build and sign EIP-712 — Agent constructs typed data locally and signs via Fireblocks.
- Retry with signature — Agent resends the GET with a
PAYMENT-SIGNATUREheader. Resource server settles the payment and returns the resource with aPAYMENT-RESPONSEreceipt header.
Transfer mechanisms
ERC-7710 delegation is not supported — Fireblocks cannot sign delegation payloads.
Permit2 supports two schemes, chosen by the server in the 402
accepts[].scheme field:
exact— authorizes the merchant to pull exactly the amount in the 402 body. Recommended default.upto— authorizes the merchant to pull up to the amount in the 402 body (the actual debit is decided by the facilitator at settlement time). Useful for variable-cost endpoints, but gives the merchant discretion within the cap. Pair with tighter Policy Engine rules if you use it.
Payment Instruction Integrity
The agent can verify that thePaymentRequired body wasn’t tampered with between the facilitator and the client.
- The facilitator emits a base64url-encoded envelope on
PaymentRequired.integrity(also mirrored on theX-402-Integrityresponse header). - The envelope is signed ES256 (P-256) and the key is resolved via
did:web. - Canonical bytes:
SHA-256( JCS({x402Version, accepts}) || "\n" || iat || "\n" || exp ). resource.url,error, andextensionsare intentionally excluded from the signed slice.
VERIFY_INTEGRITY=true for best-effort verification (warns if missing or invalid), or REQUIRE_INTEGRITY=true to abort when the envelope is absent or invalid. The require_integrity parameter on x402_get_and_pay enforces integrity for a single call and cannot relax env settings.
Get started
FIREBLOCKS_PRIVATE_KEY_PATH.
Usage
MCP server
The MCP server exposes four tools:
Start the server (stdio):
Connect to Claude Desktop
Edit~/Library/Application Support/Claude/claude_desktop_config.json (macOS) — use absolute paths. Windows config lives at %APPDATA%\Claude\claude_desktop_config.json; Linux at ~/.config/Claude/claude_desktop_config.json.
Test with MCP Inspector
Example prompts
x402_get_and_pay options
Auto selection picks the best-funded option in preference order:
eip-3009 → permit2. Set MECHANISM=permit2 to force a specific mechanism.
Manual selection returns the full list of funded options when more than one is available. Re-call with option_index=<N> to complete the payment.
CLI
Run a one-shot payment from the terminal:npx (no global install):
Secure deployment
The agent never custodies keys — it asks Fireblocks to sign. Combine four controls so the agent can only spend what you’ve explicitly allowed, even if the host running it is compromised or an LLM driving it goes off-rails.Provision a scoped Fireblocks API user
Grant only the minimum permissions the agent actually needs. Create a dedicated API user in the Fireblocks Console — don’t reuse a workspace-admin key. See the official Fireblocks guides on creating a new API user and best practices for choosing user roles.- Role: Signer (or any role limited to
Create Transaction/ signing operations). No policy edit, no user management, no workspace admin. - Vault scope: Restrict to a single dedicated vault used only for x402 spend. Keep its balance small — top it up as needed rather than parking your treasury there.
- IP allowlist: Add the machine(s) that will run the agent.
- CSR / API key fingerprint: Record both so you can rotate confidently.
Store the API credentials securely
The Fireblocks API key and its private signing key file are highly sensitive credentials. Store the private key file with restricted access (chmod 600), preferably outside the repo, and never bake it into a container image. The agent reads FIREBLOCKS_API_KEY (the API user ID, a UUID) and FIREBLOCKS_PRIVATE_KEY_PATH (path to the API user’s private signing key). Treat both like production secrets.
Never commit
.env, .secrets/, the API user PEM, or the rendered .mcp.json (the project’s .gitignore already excludes these — keep it that way).
Enforce human-in-the-loop signing via the Policy Engine
This is the strongest control and the one most worth setting up. The Fireblocks Policy Engine (TAP) gates every signing request at the Fireblocks side — not in agent code — so it survives a compromise of the agent host or its API key. See the Fireblocks rule parameters guide for the full schema. Recommended rules for an x402 agent vault:- Whitelist destinations. Allow only the asset types and recipient addresses you expect (for example, USDC on Base to specific facilitator settlement contracts). Deny everything else.
- Per-tx amount cap matched to a single x402 micropayment (for example, ≤ 1 USDC).
- Per-period velocity cap (hourly / daily) matched to the agent’s autonomous budget.
- Designate a manual signer / approver above a threshold. Configure the policy to require a designated approver for any transaction above your auto-sign threshold; approvals are pushed to the Fireblocks mobile app and enforced cryptographically by the policy, not by trust in the agent code. This is the canonical Fireblocks human-in-the-loop pattern (same approach recommended by the
fireblocks-mcpserver). - 2-eyes for any change to the policy itself so a compromised admin can’t widen the rules silently.
Constrain the agent at the application layer
These are defense-in-depth — the Policy Engine is still the source of truth. Useful for autonomous-agent flows where the URL or LLM context can’t be trusted:- Fireblocks base-URL allowlist (on by default).
FIREBLOCKS_BASE_URLmust be HTTPS under*.fireblocks.io. The Fireblocks SDK does not validate this URL itself, and its signed JWT only binds the request path — not the host — so an attacker who tampers withFIREBLOCKS_BASE_URL(via a poisoned.env, shell compromise, or CI env injection) could MITM the API channel and replay signed requests against the real Fireblocks within the 55s JWT validity window. For private / alternative endpoints, setFIREBLOCKS_BASE_URL_ALLOWED_HOSTS=host1,host2with the exact additional hostnames you trust. - SSRF guard (on by default). Every outbound URL is validated before any request is made: non-
http/httpsschemes are rejected, and IP literals or DNS results in private / loopback / link-local / metadata-range space (including169.254.169.254, GCPmetadata.google.internal, Alibaba100.100.100.200, IPv6fc00::/7/fe80::/10/::1) are blocked. HTTP redirects (maxRedirects: 0) are disabled so a 3xx can’t bypass the upfront check. SetALLOW_LOCAL_TARGETS=trueonly for local development. ALLOWED_MERCHANT_HOSTS— agent refuses any request whose host isn’t in the comma-separated list. Recommended whenever the URL can come from an LLM or external feed.REQUIRE_CONFIRM=true(MCP only) —x402_get_and_payreturns a payment preview and refuses to sign until called again withconfirmed=true.REQUIRE_INTEGRITY=true— refuse to sign 402 responses that fail Payment Instruction Integrity verification.- Prefer Permit2
exactoveruptounless you specifically need variable-cost semantics.
Troubleshooting
References
- EIP-3009: Transfer With Authorization
- EIP-712: Typed structured data hashing and signing
- Permit2
- Fireblocks Web3 Provider
- Repository source layout —
src/index.ts(CLI),src/mcp-server.ts(MCP),src/HttpX402Service.ts(payment logic),src/FireblocksService.ts(Web3 provider),src/IntegrityVerifier.ts(integrity checks)