ERC-8004 Agent Identity
On-chain identity and reputation for AI agents.
Overview
The ERC-8004 standard provides on-chain identity for AI agents. MARC Protocol implements two contracts:
- * AgentIdentityRegistry — Register agents with metadata URIs and linked wallets
- * AgentReputationRegistry — Submit proof-of-payment feedback with scores and tags
Agent identity is intentionally public. This is the complementary counterpart to MARC's amount privacy: participants are known, amounts are encrypted.
Registering an Agent
function register(string calldata agentURI) external returns (uint256 agentId)
// 1. Assigns unique agentId (incrementing counter)
// 2. Stores agentURI (JSON metadata)
// 3. Links msg.sender as both owner and wallet
// Emits: AgentRegistered(agentId, msg.sender, agentURI)register-agent.tstypescript
import { ethers } from "ethers";
const registry = new ethers.Contract(
"0xf4609D5DB3153717827703C795acb00867b69567",
[
"function register(string) returns (uint256)",
"function getAgent(uint256) view returns (string, address, address)",
"function agentOf(address) view returns (uint256)",
],
wallet
);
// Register with metadata URI
const tx = await registry.register(
"https://example.com/agent-metadata.json"
);
const receipt = await tx.wait();
// Agent metadata JSON example:
// {
// "name": "DataFetcher Agent",
// "description": "Fetches and aggregates market data",
// "capabilities": ["data-fetch", "analysis"],
// "paymentMethods": [{ "scheme": "fhe-confidential-v1", ... }]
// }Wallet Linking
An agent can link a different wallet address for receiving payments. Only the agent owner can update the linked wallet.
function setAgentWallet(uint256 agentId, address wallet) external
// Only callable by agent owner
// Emits: AgentWalletSet(agentId, wallet)
function agentOf(address wallet) external view returns (uint256)
// Look up agent ID by wallet addressSDK Helpers
The SDK provides helpers for ERC-8004 registration files:
erc8004-helpers.tstypescript
import { fhePaymentMethod, fhePaymentProof } from "marc-protocol-sdk";
// Generate payment method for agent registration
const method = fhePaymentMethod({
tokenAddress: "0xE944754aa70d4924dc5d8E57774CDf21Df5e592D",
verifierAddress: "0x4503A7aee235aBD10e6064BBa8E14235fdF041f4",
});
// Returns: { scheme: "fhe-confidential-v1", network: "eip155:11155111", ... }
// Generate proof-of-payment for feedback
const proof = fhePaymentProof(nonce, verifierAddress);
// Returns: { type: "x402-nonce", nonce, verifier }Reputation System
The AgentReputationRegistry allows agents to submit feedback after completing payments. Feedback requires a valid payment nonce (proof-of-payment) from the X402PaymentVerifier.
function giveFeedback(
uint256 agentId,
uint8 score, // 1-5
bytes32[] calldata tags,
bytes calldata proofOfPayment
) external
// proofOfPayment must be a valid nonce from X402PaymentVerifier
// Emits: FeedbackGiven(agentId, reviewer, score)
function getSummary(uint256 agentId) external view
returns (uint256 totalFeedback, uint256 averageScore, uint256 lastUpdated)
function getFeedback(uint256 agentId, uint256 index) external view
returns (Feedback memory)
function feedbackCount(uint256 agentId) external view returns (uint256)Querying Agents
// Get full agent info
function getAgent(uint256 agentId) external view
returns (string memory uri, address owner, address wallet)
// Look up by wallet
function agentOf(address wallet) external view returns (uint256 agentId)
// Update metadata
function updateURI(uint256 agentId, string calldata newURI) external
// Emits: AgentURIUpdated(agentId, newURI)
// Deregister
function deregister(uint256 agentId) external
// Frees wallet mapping, removes agent
// Emits: AgentDeregistered(agentId)Events
// AgentIdentityRegistry
event AgentRegistered(uint256 indexed agentId, address indexed owner, string agentURI);
event AgentWalletSet(uint256 indexed agentId, address indexed wallet);
event AgentURIUpdated(uint256 indexed agentId, string newURI);
event AgentDeregistered(uint256 indexed agentId);
// AgentReputationRegistry
event FeedbackGiven(uint256 indexed agentId, address indexed reviewer, uint8 score);