Names, policy and trust for AI agent cards

Pay by name. Trust runs both ways.

Card programs issue the cards. X Card gives each one an ENS name, a spend policy anyone can check and a human approver. Before your agent pays, X Card checks the merchant’s name. At checkout, the merchant checks your agent’s Visa signature. The card number never leaves the vault.

namespace
See how it works
X Card
AGENT · VIRTUAL
•••• •••• •••• 4021
01Name → card

A name is the whole interface.

A card program issues the card. X Card attaches it to an ENS name, and from then on everything (paying, funding, freezing, checking the policy) goes through the name. The 16-digit number exists, but your agent never sees it.

causeattach a card to scout.xcard.etheffectcard reachable by name, number never exposed
type an ENS name
X Card
AGENT · VIRTUAL
•••• •••• •••• ••••
number: never exposedhandle: scout.xcard.eth
02Policy lives in ENS

Limits are just text records.

Spend rules live on the name itself and are served by a signed ENS gateway, so any wallet, app, merchant or agent can read them. The records and the card’s controls are written together: what you read over ENS is what the card enforces.

causepolicy set on the nameeffectX Card and the card program both enforce it
researcher.xcard.ethTEXT
card.limit.tx50
card.limit.monthly500
card.mcc.allow5734,7372
X Card
AGENT · VIRTUAL
tx ≤ $50
month ≤ $500
mcc: software
•••• •••• •••• 7318
researcher.xcard.eth
03Pay

In-policy payments clear. The rest never reach the network.

The agent asks X Card to pay. The payment is checked against the ENS policy first, then the card program authorizes it against the same limits. A refusal tells the agent exactly which rule it hit, so it can adapt instead of retrying.

causepay $42 software · pay $18 casinoeffectone approved, one blocked with its rule
$42.00ModelHub API · MCC 5734
$18.00SpinPalace · MCC 7995
X Card
AGENT · VIRTUAL
tx ≤ $50mcc: software
•••• 7318
researcher.xcard.eth
SPENT / MO
$0 / $500
✓APPROVED · checked by policy, then the issuer
✕ BLOCKED · MERCHANT_CATEGORY_NOT_ALLOWED7995 ∉ card.mcc.allow · never reached the network
04Verified payee

Know who you’re paying.

Limits say how much. The payee check says who. A merchant’s ENS name lists the websites it takes payments on, and X Card reads those records before the card is charged. A lookalike checkout is blocked, and twice in ten minutes freezes the card. A merchant with no name waits for a human.

The records are the open x402 payee-name extension from x402 Identity Hub, so any name can opt in.

causepay modelhub.eth from three checkoutseffectone paid, one blocked, one held
modelhub.ethTEXT · mainnet
org.x402.originshttps://api.modelhub.example
api.modelhub.exampleclaims modelhub.eth
✓ VERIFIED · PAID
modelhub-pay.exampleclaims modelhub.eth
✕ PAYEE_MISMATCH
new-vendor.exampleno name given
HELD · alice.eth
checked before the card is charged
05Visa Trusted Agent Protocol

The merchant knows who’s paying.

At checkout, X Card signs the agent’s request with Visa’s Trusted Agent Protocol: an RFC 9421 signature over the merchant’s domain and path, tagged agent-payer-auth. The merchant checks it against X Card’s published key and serves a trusted agent instead of blocking a bot. X Card only signs a checkout it has already approved.

Two-way trust: the agent checks the merchant’s name, and the merchant checks the agent’s signature, both for the same domain.

causesign_request(checkout) after an approved paymenteffectmerchant: trusted agent, signature good once
GET /checkout
Host: api.modelhub.example
Signature-Input: sig2=("@authority" "@path");
  created=…;expires=…;keyid="BCwc4n…";
  alg="ed25519";nonce="qRXN…";tag="agent-payer-auth"
Signature: sig2=:jdq0SqOw…:
merchant · TAP check…
tag is agent-payer-auth
created / expires within 8 min
key from GET /keys
Ed25519 signature over host + path
nonce not seen before
✓TRUSTED AGENT · express checkout
✕ same headers again: REPLAYEDeach signature works once
06Funding by name

The agent asks. A human says yes.

When an agent asks for more than its policy allows, the request pauses. The approval is bound to that exact name, amount and currency. Approve once; the allowance and the ENS record update together.

causeyou press Approveeffectallowance $500 → $800
researcher.xcard.ethrequests funds · dataset license
+$300
policy idle
human in the loop · alice.eth
Monthly allowance$500
card.limit.monthly = 500$1,000
07Kill switch

Anomaly in. Card frozen.

A burst of payment attempts, or a second try at a blocked merchant. The engine freezes the card at the card program and writes the status to ENS, so every resolver sees it at once. An agent can freeze its own card; only a human can unfreeze it.

cause14 payment attempts in 10 mineffectcard.status = frozen
tx / 10slast 5 min
ANOMALY · 14 attempts in 10 min · limit 10
X Card
AGENT · VIRTUAL
•••• •••• •••• 7318
researcher.xcard.eth
FROZEN
card.status = active
next payment → CARD_FROZEN
Sample stream

Every agent, every payment, by name.

One feed across your fleet. Blocks and declines carry their rule, holds wait for a human, freezes show up the moment they happen.

Showing sample events. Real sandbox events appear here as agents use their cards.

→Under the hood

Real names. Real resolver. Sandbox money.

*.xcard.eth and *.x402card.eth resolve on Ethereum mainnet through an ENSIP-10 offchain resolver. The cards come from a card program behind one adapter interface; this demo uses the Airwallex sandbox, where card issuing is waiting on activation. Agents connect over MCP and never see a card number or an API key.

ENS · mainnet

OffchainResolver

Every lookup reverts with an EIP-3668 OffchainLookup. The contract checks the gateway’s signature before returning a record.

0xf11eb8f6…792a0 ↗
Gateway

Signed CCIP-Read

A Cloudflare Worker answers text() lookups from the card’s policy and signs each answer for five minutes. Card numbers and IDs are never stored in records.

x402card.dmpay.workers.dev/gateway
Agents · MCP

Seven tools, one token per card

pay, sign_request, get_card, request_funding, freeze, list_transactions, plus issue_card for the operator. An agent’s token only works for its own name.

// MCP client config
{ "xcard": {
    "type": "http",
    "url": "https://mcp.x-card.dev/mcp",
    "headers": { "Authorization": "Bearer x4c_…" } } }
Merchant identity · x402 payee-name

Verified payees

pay takes the checkout URL and the ENS name the merchant claims. X Card reads org.x402.origins on mainnet and applies card.payee: any, verified-or-escalate or verified-only. A held payment’s approval is bound to that exact merchant.

README · payee gate →
Agent identity · Visa TAP

Signed requests, published key

Ed25519 RFC 9421 signatures tagged agent-browser-auth or agent-payer-auth, 8 minutes, one use. The key is served as a JWK set and in the shape Visa’s reference merchant fetches; every signature is tested against a port of that verifier.

api.x-card.dev/keys →
Governance · Safe 2-of-3

No single key owns the root

The parent name and the resolver are owned by a 2-of-3 Safe, so re-pointing names, swapping the gateway or trusting a new signer takes two signatures. Escalated funding and unfreezes need a human; next, a signature from the wallet in card.approver.

0x5A578eDd…03602 ↗
→Built on

Open rails, one name.

Logos are trademarks of their owners. X Card is an independent open-source project built for the Airwallex Agentic Banking Hackathon. It is not affiliated with or endorsed by Airwallex, Visa, ENS Labs or the ENS DAO.

Give your agent a name, not a number.

Connect any MCP client with a token scoped to one name, and read any card’s policy from any ENS client. Open source, MIT licensed.

Read the docs on GitHub