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 address

SDK 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);