Wiring Up an Agent: Identity (ERC-8004) and Payments (x402), Step by Step
Two of the four powers are live. Here is how to give an AI agent an ERC-8004 on-chain identity and x402 payments with the Abstraxn Agent Kit, step by step.

Enough Theory. Let's Give an Agent an Identity and a Wallet.
We named the four powers. Two of them, identity and payments, are live in the Agent Kit today. Here is how to wire them up, one part at a time, with real code and no hand-waving.
From "Here Is the Map" to "Here Is the Build"
Four posts ago I started drawing maps. We covered why an agent cannot really live on Web2, named the four powers an agent needs to function, argued about who is liable when one of them gets it wrong, and finally backed all the way up to ask what an agent even is.
Maps are useful. They are also where a lot of infrastructure writing quietly goes to retire. So this post is the part where we put the pen down and pick up a keyboard.
Two of the four powers are no longer roadmap. Identity and payments are live in the Abstraxn Agent Kit. You can give an agent a verifiable on-chain identity following ERC-8004, and the ability to discover and pay for services with x402, today. This post walks both, in order. Identity first, because an agent that can pay before anyone knows who it is is a horror story, not a feature. Payments second, because that is the part that turns a clever assistant into an agent that produces consequences.
It is beginner friendly on purpose. If you have never touched account abstraction, you will still finish this able to stand one up. If you can read a UserOperation in your sleep, skim the prose and steal the code.
One ground rule before we start, because it shapes everything: the Agent Kit SDK runs on your backend, never in the browser. Agents sign with a secret called an access key, and an access key in client side code is an agent someone else now controls. We will keep saying this. We mean it.
The short version: Install
@abstraxn/agent-kiton your backend and create an agent. That one call provisions a server wallet, an EVM address, and a one-time access key. Part one, register that agent's identity on-chain withregisterAgentIdentity, which writes it into the ERC-8004 IdentityRegistry and publishes an agent card other software can read. Part two, point MCP at the Agent Kit and let the agent discover paid APIs withdiscover_services, then pay and read them withpaid_fetch, signing each payment on your backend with the same access key. Identity says who it is. Payments let it act. Policy, the fourth power, is the leash, and it is the next post.
First, the Setup
You need three things: Node 18 or newer, a backend with a database to store per-agent secrets, and an Application API key. Grab the key from the dashboard at dashboard.abstraxn.com under Agentic Stack then Overview. There is a 30 day free trial, so you can follow the whole thing without committing to anything.
Install the kit and initialize the client.
npm install @abstraxn/agent-kitimport { AgentKitClient } from "@abstraxn/agent-kit";
const agentKit = new AgentKitClient({
apiKey: process.env.ABSTRAXN_API_KEY!, // same key as dashboard Overview
baseUrl: process.env.AGENT_KIT_BASE_URL, // optional; defaults to production
});Now create your agent. This is the one call everything else hangs off, so read what it gives back.
const { agent, wallet } = await agentKit.createAgent({
name: "Research Agent",
description: "Fetches and summarizes on-chain data within budget",
userIdentity: "user-123", // your stable user id
userEmail: "[email protected]", // optional
metadata: { tier: "pro" }, // optional
});
// Agent Kit record
console.log(agent.id); // UUID, used as the MCP agent_id
console.log(agent.apiKey); // optional per-agent MCP key
// Wallet, provisioned for you. Persist these on YOUR backend.
console.log(wallet.evmAddress);
console.log(wallet.solanaAddress); // when enabled
console.log(wallet.organizationId);
console.log(wallet.accessKey); // shown ONCE. Encrypt it at rest.Notice what just happened. One call registered the agent and provisioned an Abstraxn server wallet, so the agent has an EVM address (and a Solana one when enabled) before you wrote any contract or touched a seed phrase. That is Wallet-as-a-Service doing its job quietly underneath. The agent's signing credential is the accessKey, and it is shown exactly once. Encrypt it the moment you receive it, because it cannot be retrieved again. Lose it and the agent it belongs to is orphaned for good.
The sample backend stores it encrypted, and you should copy that pattern:
import { encrypt } from "./common/crypto.helper";
const accessKeyEncrypted = encrypt(wallet.accessKey, process.env.ENCRYPTION_KEY!);
await agentsRepo.save({
userId,
agentId: agent.id,
apiKey: agent.apiKey,
evmAddress: wallet.evmAddress,
organizationId: wallet.organizationId,
userIdentity: agent.userIdentity ?? userId,
accessKey: accessKeyEncrypted, // never returned in an API response
});That is the foundation. Your agent exists, it has a wallet, and you are holding its key safely. Now let us make it someone the network can recognize.
Part One: Identity, or Giving the Agent a Name the Network Can Trust
Here is the problem we established back in the "what is an agent" post, compressed into one sentence. On-chain, an agent is just an address that signs, and the chain cannot tell that address apart from yours. A raw EVM address does not tell a counterparty who operates the agent, which MCP endpoint to reach it on, or whether it even supports x402. It is anonymous, and anonymous is not a thing you wire money to.
ERC-8004, the Trustless Agents standard that became mainnet-ready in early 2026, fixes exactly this. It defines three registries: Identity, Reputation, and Validation. The Agent Kit implements the Identity layer today, and that is the one that matters first. It combines three things into a single recognizable agent:
- An on-chain record, an ERC-721-style id minted in an IdentityRegistry contract on the chain you choose.
- An off-chain agent card, a JSON file at a public URL listing the agent's name, description, service endpoints including its MCP address, and whether it supports x402.
- A global identifier, a portable id derived from the chain, the registry, and the on-chain agent id, so the same agent can be referenced across tools and explorers.
Registering the identity
The prerequisites are short. You need an agent created with createAgent so it has an evmAddress, the stored accessKey for signing, and a small amount of native gas in that EVM address on whatever chain you pick, because registration is a real contract call. Fund the address first, then register.
The SDK collapses the whole prepare, sign, broadcast, and confirm dance into one method.
const identity = await agentKit.registerAgentIdentity({
agentId: agent.id, // Agent Kit UUID
userIdentity: "user-123",
accessKey: decryptedAccessKey, // decrypt your stored key here
organizationId: wallet.organizationId,
evmAddress: wallet.evmAddress,
chainId: 84532, // Base Sepolia (a testnet, free to try)
});Agent Kit supports identity registration on a fixed set of chains, passed as a numeric chainId, not a string slug. Ethereum (1), Sepolia (11155111), Polygon (137), Polygon Amoy (80002), Base (8453), Base Sepolia (84532), BSC (56 and testnet 97), Arbitrum One (42161), and Avalanche C-Chain (43114). An agent registers once per chain. A nice touch worth noticing: the registry contracts live at vanity addresses that start with 0x8004, the same number as the standard, which makes them easy to spot in an explorer.
Once the transaction confirms, anyone can resolve the agent's card at a public URL, no API key required:
GET {AGENT_KIT_PUBLIC_URL}/agent/{agentUuid}/registration
{
"type": "https://eips.ethereum.org/EIPS/eip-8004#registration-v1",
"name": "Research Agent",
"description": "Fetches and summarizes on-chain data within budget",
"services": [
{
"name": "MCP",
"endpoint": "https://agent-kit.abstraxn.com/mcp",
"version": "2025-06-18"
}
],
"registrations": [
{
"agentId": 42,
"agentRegistry": "eip155:84532:0x8004A818BFB912233c491871b3d84c89A494BD9e"
}
],
"x402Support": true,
"active": true
}That file is the agent's public face. A counterparty, or another agent, can read it and learn the name, the operator, the MCP endpoint to reach it on, and that it accepts x402, all without a prior relationship and without calling your private APIs. That is the entire point of an identity registry: discovery without introduction.
Watching it in the dashboard
You register from your backend, but you monitor from the dashboard. Open Agentic Stack then All agents, click into an agent, and you get two tabs. The Identity tab shows the on-chain status, the copy-friendly global identifier, and per-chain cards with the on-chain agent id, owner, registry address, and a link to the transaction. The Activity log tab lists every MCP tool the agent has called, with status, duration, and timestamp, which is your audit trail when something behaves oddly at machine speed.
Why bother, in plain use cases
- Discoverability. Another agent can look up your agent, read its card, see that it speaks MCP and accepts x402, and decide to engage. No onboarding call.
- Accountability. When something goes wrong, "which agent did this and who runs it" has an answer, which is the thread we pulled on in the liability post.
- Fleets. Run ten agents for ten jobs, each with its own
userIdentity, its own address, its own registration, and its own clean audit trail.
One honest caveat, straight from the docs and the same one from last time. Identity does not prove an agent is honest or that it is inside its budget. It proves who the agent claims to be and where to reach it. A name is not a leash. Restraint is a separate job, and it belongs to spend policy and the wallet's own logic. We will get there. For now, your agent has a name. Let us give it something to do with it.
Part Two: Payments, or Letting the Agent Actually Spend
An assistant produces answers. An agent produces consequences. The most useful consequence you can hand a working agent is the ability to pay for the things it needs, the moment it needs them, without stopping to ask you. A research agent that finds a paid data API and then pauses to email you for a credit card is not autonomous. It is a very expensive intern.
The protocol that fixes this is x402. The name comes from HTTP 402 Payment Required, the status code the web reserved decades ago and never used. x402 finally gives it a job: an API answers a request with "that costs money," the caller pays inline, and the response comes back. Pay per call, at machine speed, no accounts, no invoices.
The Agent Kit exposes this to your agent as tools over MCP. Point your backend at the same MCP endpoint the dashboard uses:
export MCP_SERVER_URL="https://agent-kit.abstraxn.com/mcp"
export MCP_SERVER_AUTH_TOKEN="$ABSTRAXN_API_KEY"Four tools do the payment work. discover_services searches the service catalog, get_service resolves one service by its URL, paid_fetch makes the request and handles the pay-and-retry, and get_token_price is a fixed-price example that pays through Agent Kit's own internal x402 facilitator. The transfer tool and the read-only wallet tools are separate, used for moving funds rather than paying merchants.
The flow, step by step
Step one, discover. Ask the catalog for something the agent needs. Filter by network and by price so it never wanders into an expensive endpoint.
{
"agent_id": "AGENT_UUID",
"query": "token price oracle",
"network": "eip155:84532",
"maxUsdPrice": "0.10",
"limit": 5
}You get back a list of services[], each with a service_id that is the resource URL, the payment terms it accepts, and metadata. Pick one.
Step two, probe. Call paid_fetch without a payment first, to see what the merchant wants.
{
"name": "paid_fetch",
"arguments": {
"agent_id": "AGENT_UUID",
"url": "https://merchant.example.com/api/v1/data",
"method": "GET"
}
}If the endpoint needs payment, MCP responds with a JSON-RPC error code -32402 and a paymentRequired object describing the network, asset, recipient, and amount. This is the part people get wrong: that is not a failure. It is the signal to sign and retry.
Step three, sign on your backend. This is where the access key earns its keep, and where it absolutely must stay server side. The kit builds the signed payment for you.
import { AgentKitClient } from "@abstraxn/agent-kit";
// After paid_fetch returns paymentRequired, sign it with the agent's access key:
const paymentPayload = await agentSigningService.createX402PaymentPayloadForAgent(
localAgentId,
paymentRequired,
);Under that one call, the kit loads the encrypted access key, decrypts it, authenticates the server signer, builds a client for the network the merchant asked to be paid on, signs the EIP-712 data that x402 v2 requires, and hands back a paymentPayload. You never see the key, and neither does the browser. Fund the agent's EVM address with native gas before its first payment, the same address you funded for identity.
Step four, retry with payment. Send paid_fetch again, this time with the signed payload at the top level of the call.
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "paid_fetch",
"arguments": {
"agent_id": "AGENT_UUID",
"url": "https://merchant.example.com/api/v1/data",
"method": "GET"
},
"paymentPayload": { }
}
}On success you get back the response data, a payment_made flag, a payment_details summary, and a hint if anything needs attention. The agent paid cents, got its data, and kept working. That is the loop that felt like science fiction two years ago: an agent that funds its own work.
Keeping spend in bounds
Worth knowing before you turn an agent loose. Fixed-price tools like get_token_price run through Agent Kit's internal facilitator and respect a per-agent budget you set with updateSpendPolicy. If the agent exceeds its budgetUsd, the call is blocked rather than paid, and you will see a spend_policy_denied status in the activity log. Payments to third-party paid_fetch URLs do not pass through that same price table, so the lever there is maxUsdPrice in discover_services. Filter expensive services out before the agent ever reaches them.
There is a moat detail hiding in that paragraph. Because the Agent Kit runs its own x402 facilitator for its priced tools, payments that settle through it are verified and recorded on Abstraxn's own rails rather than borrowed from someone else's. On testnet that facilitator is x402.org/facilitator. On mainnet it routes through Coinbase CDP. Either way, you discover, pay, and read without standing up payment infrastructure yourself.
Why bother, in plain use cases
- Pay-per-call data and inference. The agent buys exactly the calls it needs, when it needs them, and nothing it does not.
- Agent-to-agent settlement. One agent hires another and pays on delivery, using the
transfertool whose unsigned transaction your backend signs with the same server wallet. - Metered access without subscriptions. Stop pre-buying API credits you may never use.
- Autonomous operation inside limits. The agent keeps itself working, as long as it stays inside the spend policy you set. Which, again, is the policy conversation, and the next post.
How the Two Halves Click Together
Strip the buzzwords and the shape is simple. Identity is recognition: the network knows who the agent is, who stands behind it, and how to reach it. Payments are action: the agent can spend at machine speed to get its job done. You built both from one API key and one createAgent call, mostly without writing contracts or touching a private key, and the same access key that registers the identity is the one that signs the payments.
What is deliberately missing is restraint. An agent with a name and a wallet and no limits is just a confident stranger holding your money. The fourth power, policy, is what turns "it can pay" into "it can pay up to this much, for these things, until this date." You met the edge of it already in updateSpendPolicy and the spend_policy_denied status. The full picture is the next build, and the one that lets you actually sleep.
For now, you have done the part that used to be hard. Two of the four powers, live, in an afternoon.
Where to Go From Here
- Create your first agent with the SDK quickstart. The 30 day trial covers the full flow above.
- Read the exact registration steps and chain list in the ERC-8004 identity guide.
- Wire the discover, probe, sign, retry loop with the x402 payments guide, and see it end to end in full-stack app integration.
Key Takeaways
- One call gives the agent a wallet.
@abstraxn/agent-kitcreateAgent()provisions a server wallet with an EVM address (and Solana when enabled) plus a one-time access key. Run the SDK on your backend only. - The access key is shown once. Encrypt it at rest the moment you receive it. It cannot be retrieved again, and it is what signs everything the agent does.
- Identity is an on-chain ERC-8004 registration.
registerAgentIdentity()writes the agent into the IdentityRegistry on a chain you choose and publishes a public agent card with the agent's MCP endpoint and x402 support. Fund the EVM address with gas first. - Identity is recognition, not restraint. It proves who an agent claims to be and where to reach it. It does not prove honesty or enforce a budget.
- Payments run over MCP with x402. Discover services, probe with
paid_fetch, sign thepaymentPayloadon your backend, retry with payment. A-32402response is the signal to pay, not a failure. - Spend has guardrails. Fixed-price tools respect
updateSpendPolicybudgets and Abstraxn's own x402 facilitator, while third-party calls are filtered withmaxUsdPriceat discovery time. - Identity and payments are two of the four powers. Identity is recognition, payments are action, and policy is the restraint that keeps autonomy inside limits. Policy is the next post.
Frequently Asked Questions
What package do I use to give an AI agent identity and payments? The @abstraxn/agent-kit npm package, used from your backend only. createAgent provisions the agent and its server wallet, registerAgentIdentity writes the ERC-8004 on-chain identity, and the x402 tools run over MCP for payments.
What is ERC-8004 and how does Abstraxn use it? ERC-8004, the Trustless Agents standard, gives autonomous agents discoverable on-chain trust primitives across three registries: Identity, Reputation, and Validation. The Agent Kit implements the Identity layer, registering the agent in an on-chain IdentityRegistry and publishing a public agent card with its endpoints and x402 support.
Which chains can I register an agent identity on? Agent Kit accepts numeric chain IDs for Ethereum (1), Sepolia (11155111), Polygon (137), Polygon Amoy (80002), Base (8453), Base Sepolia (84532), BSC (56 and 97), Arbitrum One (42161), and Avalanche C-Chain (43114). An agent registers once per chain and needs native gas in its EVM address first.
What is x402 and how does an agent pay with it? x402 uses the HTTP 402 Payment Required status to let an API charge per request. The agent finds payable services with discover_services, probes with paid_fetch, your backend signs the payment with the agent's access key, and paid_fetch is retried with the payment attached.
Why does a payment request come back as an error code -32402? That JSON-RPC code, or a paymentRequired object, is how MCP signals that the endpoint needs payment. It is not a hard failure. It is the cue to sign a paymentPayload on your backend and retry the same call once.
Where does the agent's signing happen, and is it safe in the browser? Signing happens on your backend with the agent's access key, never in the browser or a mobile client. Store the key encrypted, never log it, and trigger signing only through your authenticated backend routes.
How do I stop an agent from overspending? Set a per-agent budget with updateSpendPolicy, which blocks fixed-price tool calls that exceed budgetUsd and records a spend_policy_denied status. For third-party paid endpoints, filter by maxUsdPrice in discover_services. Full programmable policy is the subject of an upcoming post.
About the Author
Parth Chaudhary
Solution Architect
Parth Chaudhary is a Solution Architect at Antier, the team behind Abstraxn. He currently works at the intersection of account abstraction and agentic AI infrastructure, consistently shipping wallets, paymasters, identity primitives, and policy guardrails for autonomous agents in production. Find out more at abstraxn.com or easily spin up an agent at dashboard.abstraxn.com.