Identity
Verifiable on-chain agent identity via ERC-8004. Register your agent, verify others, discover and check reputation across 18 chains.
What is ERC-8004?
ERC-8004 is an Ethereum standard for registering AI agent identities on-chain. Each agent is an ERC-721 NFT stored on a registry contract. The NFT points to a JSON registration file containing the agent's name, services, and cross-chain registrations.
When Agent A wants to connect to Agent B, it looks up B's global ID on-chain, fetches the registration file, verifies the back-reference, and extracts the MCP endpoint. This is the foundation of trustless agent-to-agent communication.
Global ID format
eip155:{chainId}:{registry}#{agentId}
Example: eip155:8453:0x8004A169FB4a3325136EB29fA0ceB6D2e539a432#2376
AgentIdentity class
The AgentIdentity class handles registration and updates for a specific wallet on one chain.
import { AgentIdentity } from "@a3stack/identity";
import { base } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount(process.env.PRIVATE_KEY);
const identity = new AgentIdentity({
account,
chain: base,
rpc: "https://mainnet.base.org", // optional
// registry: "0x8004...", // optional, uses default
});register()
Register your agent on-chain. One-time transaction per chain (~$0.01 gas on Base).
const { agentId, globalId, txHash } = await identity.register({
name: "MyAgent",
description: "An AI agent that does X",
image: "https://example.com/agent-logo.png", // optional
services: [
{
name: "MCP",
endpoint: "https://mcp.myagent.ai/mcp",
version: "2025-06-18",
},
{
name: "web",
endpoint: "https://myagent.ai",
},
],
x402Support: true, // accepts x402 payments
active: true,
supportedTrust: ["reputation"], // optional
});
// globalId: "eip155:8453:0x8004A169FB4a3325136EB29fA0ceB6D2e539a432#42"
console.log(`Registered! ID: ${globalId}`);
console.log(`Tx: https://basescan.org/tx/${txHash}`);isRegistered()
const { registered, agentId } = await identity.isRegistered();
if (registered) {
console.log(`Already registered as #${agentId}`);
} else {
console.log("Not yet registered on this chain");
}setAgentURI()
// Update your registration after deploy (e.g., new MCP endpoint)
await identity.setAgentURI(agentId, "https://new-uri.com/agent.json");setPaymentWallet()
Link a separate payment wallet to your agent identity. Useful if your signing key and payment key are different.
// Link a separate payment wallet to your agent
// (proves control of newWallet via EIP-712 signature)
const deadline = Math.floor(Date.now() / 1000) + 3600; // 1 hour
await identity.setPaymentWallet(agentId, "0xNewWallet...", deadline, signature);
// Get the current payment wallet
const wallet = await identity.getPaymentWallet(agentId);Verification
verifyAgent()
Verify any agent by global ID. This reads from the registry, fetches the registration file, and validates the back-reference (agentId + registry match).
import { verifyAgent } from "@a3stack/identity";
// Verify by global agent ID (recommended)
const result = await verifyAgent("eip155:8453:0x8004...#2376");
console.log(result.valid); // true / false
console.log(result.owner); // "0x1be93C..."
console.log(result.paymentWallet); // null (defaults to owner)
console.log(result.registration); // full AgentRegistration
console.log(result.registration?.services); // [{ name: "MCP", ... }]
console.log(result.registration?.x402Support); // true
// On failure:
console.log(result.error); // e.g., "agentId mismatch in back-reference"Alternative forms
// Verify by chain + numeric agentId
const result = await verifyAgent({ chain: base, agentId: 2376 });
// Find all agents by owner wallet
import { findAgentsByOwner } from "@a3stack/identity";
const agents = await findAgentsByOwner("0x1be93C...", { chain: base });Discovery & Reputation
A3Stack integrates the ag0 SDK for cross-chain agent discovery and reputation. Search the entire ERC-8004 ecosystem, check reputation scores, and read feedback — all indexed via subgraph.
🏗️ Compose, don't compete
A3Stack handles registration + gasless + payments. ag0 handles discovery + reputation. Each layer is best-in-class.
AgentDiscovery
Search for agents and check reputation. Read-only — no wallet needed.
import { AgentDiscovery } from "@a3stack/identity";
const discovery = new AgentDiscovery({
chainId: 8453, // Base
rpcUrl: "https://base-mainnet.g.alchemy.com/v2/YOUR_KEY",
});
// Search agents across the ecosystem (subgraph-indexed)
const agents = await discovery.search({ name: "weather" });
// Search with reputation filter
const trusted = await discovery.search({
feedback: { minValue: 80 },
active: true,
});Reputation & Feedback
Get reputation scores and detailed feedback entries for any agent.
// Get reputation summary for an agent
const rep = await discovery.getReputation("8453:102");
console.log(`Score: ${rep.averageValue}/100 (${rep.count} reviews)`);
// Get detailed feedback entries
const reviews = await discovery.getFeedback("1:22775");
for (const r of reviews) {
console.log(`${r.value}/100 by ${r.reviewer} — [${r.tags.join(", ")}]`);
}Via A3Stack core
Discovery is also available directly on the A3Stack class.
import { A3Stack } from "@a3stack/core";
// Integrated into the main A3Stack class
const stack = new A3Stack({ account, chain: base, rpc: "..." });
const agents = await stack.discover({ name: "weather" });
const rep = await stack.reputation("8453:102");
const reviews = await stack.feedback("1:22775");Utilities
parseAgentId()
import { parseAgentId } from "@a3stack/identity";
const ref = parseAgentId("eip155:8453:0x8004A169FB4a3325136EB29fA0ceB6D2e539a432#2376");
// {
// namespace: "eip155",
// chainId: 8453,
// registry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
// agentId: 2376
// }getMcpEndpoint() / getA2aEndpoint()
import { getMcpEndpoint, getA2aEndpoint } from "@a3stack/identity";
const mcpUrl = await getMcpEndpoint("eip155:8453:0x8004...#2376");
// "https://mcp.arcabot.ai/mcp"
const a2aUrl = await getA2aEndpoint("eip155:8453:0x8004...#2376");
// null (if not configured)findAllRegistrations()
Find all ERC-8004 registrations for a wallet across all supported chains.
import { findAllRegistrations } from "@a3stack/core";
// Find all registrations across all supported chains for a wallet
const regs = await findAllRegistrations("0x1be93C...");
// [
// { chainName: "Base", chainId: 8453, agentId: 2376, globalId: "eip155:8453:..." },
// { chainName: "Ethereum", chainId: 1, agentId: 88, globalId: "eip155:1:..." },
// ...
// ]discoverAgents() (legacy)
On-chain discovery (slower than subgraph). Prefer AgentDiscovery above.
import { discoverAgents } from "@a3stack/identity";
const agents = await discoverAgents({
chain: base,
filter: {
hasService: "MCP", // has an MCP endpoint
x402Support: true, // accepts payments
active: true,
}
});
// Returns AgentRegistration[] with resolved registration filesType Reference
interface AgentRegistration {
type: string;
name: string;
description: string;
image?: string;
services: AgentService[];
x402Support: boolean;
active: boolean;
registrations: AgentRef[]; // cross-chain registrations
supportedTrust?: string[];
}
interface AgentService {
name: string; // "MCP" | "A2A" | "web" | "ENS" | ...
endpoint: string;
version?: string;
skills?: string[];
domains?: string[];
}
interface AgentRef {
namespace: string; // "eip155"
chainId: number; // 8453
registry: `0x${string}`;
agentId: number;
}
interface VerificationResult {
valid: boolean;
agentId: number;
owner: string;
paymentWallet: string | null;
registration: AgentRegistration | null;
error?: string;
}Supported Chains (17)
The registry contract is deployed at the same address on all chains. Arcabot.eth (agent #2376) is registered on all 17 chains.
| Chain | Chain ID | Registry Address |
|---|---|---|
| Ethereum | 1 | 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 |
| Base | 8453 | 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 |
| Arbitrum | 42161 | 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 |
| Polygon | 137 | 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 |
| Optimism | 10 | 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 |
| Celo | 42220 | 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 |
| BNB Chain | 56 | 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 |
| Gnosis | 100 | 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 |
| Linea | 59144 | 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 |
| Scroll | 534352 | 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 |
| Taiko | 167000 | 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 |
| Avalanche | 43114 | 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 |
| Mantle | 5000 | 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 |
| Metis | 1088 | 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 |
| Abstract | 2741 | 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 |
| Monad | 10143 | 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 |
| X Layer | 196 | 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 |
CLI verification
You can also verify agents from the command line without any code:
$npx a3stack verify eip155:8453:0x8004A169FB4a3325136EB29fA0ceB6D2e539a432#2376$npx a3stack lookup 0x1be93C...