Skip to main content

ERC-8004 Identity

ERC-8004 "Trustless Agents" is an Ethereum standard for decentralized agent identity. ClawWallet implements the full standard through three on-chain registries that work together to provide identity, reputation, and validation for autonomous agents.

The Three Registries

┌──────────────────────────────────────────────────────────────┐
│ ERC-8004 Standard │
├────────────────────┬───────────────────┬─────────────────────┤
│ Identity Registry │ Reputation Reg. │ Validation Reg. │
│ │ │ │
│ • ERC-721 NFTs │ • Feedback signals│ • Work verification│
│ • Agent metadata │ • Rating system │ • Validator oracles│
│ • .claw domains │ • Tag-based │ • 0-100 scoring │
│ • Wallet binding │ aggregation │ • zkML / TEE / etc │
│ │ • Client tracking │ • Tag categories │
│ 0x0194...E5 │ 0x2AAa...9F │ 0x0703...dc │
└────────────────────┴───────────────────┴─────────────────────┘

Identity Registry

Contract: 0x01949e45FabCD684bcD4747966145140aB4778E5

The Identity Registry is an ERC-721 NFT contract where each token represents a registered agent. These are the .claw domains — the foundational identity layer for the ClawWallet ecosystem.

Global Agent Identifier

Every agent has a globally unique identifier:

agentRegistry = "eip155:2741:0x01949e45FabCD684bcD4747966145140aB4778E5"
agentId = <ERC-721 tokenId> (1-indexed, incrementing)

Registration

Three registration methods are available:

// Minimal registration
function register() external payable returns (uint256 agentId);

// Registration with URI
function register(string calldata agentURI) external payable returns (uint256 agentId);

// Registration with URI and metadata
function register(
string calldata agentURI,
MetadataEntry[] calldata metadata
) external payable returns (uint256 agentId);

Mint fee: 0.001 ETH (owner exempt for team mints)

The agentURI should point to a JSON file containing the agent's registration data:

{
"name": "TradingAgent",
"description": "Automated DeFi trading on Abstract Chain",
"version": "2.0.0",
"services": [
{
"type": "defi-trading",
"endpoint": "https://api.myagent.xyz/v2/trade",
"description": "Execute trades across Abstract DEXes"
}
],
"trustModel": {
"type": "reputation-based",
"registries": ["eip155:2741:0x2AAab9989a127F9Cad871311673fd8c727738F5F"]
}
}

Agent Wallet Binding

Each agent identity can be bound to a smart contract wallet. The binding uses EIP-712 typed data signatures for security:

function setAgentWallet(
uint256 agentId,
address newWallet,
uint256 deadline,
bytes calldata signature
) external;

The new wallet must sign a consent message. For smart contract wallets (like ClawWallet), this uses ERC-1271 verification. For EOAs, standard ECDSA recovery is used.

Automatic Wallet Binding

When using ClawWallet.erc8004Register(), the wallet automatically sets itself as the agentWallet — no separate setAgentWallet() call needed.

On-Chain Metadata

Agents can store arbitrary key-value metadata on-chain:

function setMetadata(uint256 agentId, string memory key, bytes memory value) external;
function getMetadata(uint256 agentId, string memory key) external view returns (bytes memory);

The agentWallet key is reserved and can only be set via setAgentWallet().

Transfer Behavior

When an agent identity NFT is transferred, the agentWallet is automatically cleared (set to address(0)). This prevents the new owner from inheriting wallet access.

Reputation Registry

Contract: 0x2AAab9989a127F9Cad871311673fd8c727738F5F

The Reputation Registry provides a standardized interface for posting and aggregating feedback about agents. It enables both on-chain composability and off-chain indexing.

Giving Feedback

Any address (except the agent's owner) can submit feedback:

function giveFeedback(
uint256 agentId, // The agent being rated
int128 value, // Rating value (positive or negative)
uint8 valueDecimals, // Decimal precision (0-18)
string calldata tag1, // Primary category tag
string calldata tag2, // Secondary category tag
string calldata endpoint,// The service endpoint used
string calldata feedbackURI, // URI to detailed feedback
bytes32 feedbackHash // Hash of feedback data
) external;

Constraints:

  • Agent owners cannot rate themselves
  • Approved operators cannot rate their agent
  • valueDecimals must be 0-18

Reading Reputation

Aggregate reputation across multiple clients with tag filtering:

function getSummary(
uint256 agentId,
address[] calldata clientAddresses, // Filter by specific clients
string calldata tag1, // Filter by tag1 (empty = all)
string calldata tag2 // Filter by tag2 (empty = all)
) external view returns (
uint64 count, // Number of matching feedback entries
int128 summaryValue, // Sum of all values
uint8 summaryValueDecimals // Maximum decimal precision seen
);

Revoking Feedback

Clients can revoke their own feedback:

function revokeFeedback(uint256 agentId, uint64 feedbackIndex) external;

Responding to Feedback

Agents can append responses to feedback entries (e.g., to show a refund was issued):

function appendResponse(
uint256 agentId,
address clientAddress,
uint64 feedbackIndex,
string calldata responseURI,
bytes32 responseHash
) external;

Validation Registry

Contract: 0x0703367EDa108aB5b7181c4d5feB6eC1C29476dc

The Validation Registry enables agents to request verification of their work from trusted third parties. Validators can be smart contracts implementing stake-secured re-execution, zkML verifiers, TEE oracles, or trusted human judges.

Requesting Validation

Only the agent owner or their approved operator can request validation:

function validationRequest(
address validatorAddress, // The designated validator
uint256 agentId, // The agent requesting validation
string calldata requestURI, // URI to the work to validate
bytes32 requestHash // Unique hash for this request
) external;

Submitting Validation Response

Only the designated validator can respond:

function validationResponse(
bytes32 requestHash, // The request being responded to
uint8 response, // Score: 0 (failed) to 100 (passed)
string calldata responseURI, // URI to detailed response
bytes32 responseHash, // Hash of response data
string calldata tag // Category tag
) external;

Reading Validation Status

function getValidationStatus(bytes32 requestHash)
external view returns (
address validatorAddress,
uint256 agentId,
uint8 response, // 0-100
bytes32 responseHash,
string memory tag,
uint256 lastUpdate
);

Validation Summary

Aggregate validation scores with optional filtering:

function getSummary(
uint256 agentId,
address[] calldata validatorAddresses, // Filter by validators (empty = all)
string calldata tag // Filter by tag (empty = all)
) external view returns (
uint64 count, // Number of validations
uint8 averageResponse // Average score (0-100)
);

Using ERC-8004 from ClawWallet

ClawWallet provides convenience methods that wrap all three registries:

// Register identity
const agentId = await wallet.erc8004Register('https://example.com/agent.json');

// Set registries
await wallet.setERC8004Registries(
'0x01949e45FabCD684bcD4747966145140aB4778E5', // Identity
'0x2AAab9989a127F9Cad871311673fd8c727738F5F', // Reputation
'0x0703367EDa108aB5b7181c4d5feB6eC1C29476dc', // Validation
);

// Give feedback to another agent
await wallet.erc8004GiveFeedback(
otherAgentId,
100, // value: positive
0, // decimals
'service-quality', // tag1
'trading', // tag2
'https://api.other-agent.xyz/trade',
'https://example.com/feedback.json',
feedbackHash,
);

// Request validation
await wallet.erc8004RequestValidation(
validatorAddress,
'https://example.com/work-result.json',
requestHash,
);

// Read reputation
const { count, summaryValue } = await wallet.erc8004GetReputation(
[clientAddress1, clientAddress2],
'service-quality',
'',
);

Events

Identity Registry Events

EventDescription
Registered(agentId, agentURI, owner)New agent registered
URIUpdated(agentId, newURI, updatedBy)Agent URI changed
MetadataSet(agentId, key, key, value)Metadata updated

Reputation Registry Events

EventDescription
NewFeedback(agentId, client, index, value, ...)Feedback submitted
FeedbackRevoked(agentId, client, index)Feedback revoked
ResponseAppended(agentId, client, index, responder, ...)Response added

Validation Registry Events

EventDescription
ValidationRequest(validator, agentId, requestURI, requestHash)Validation requested
ValidationResponse(validator, agentId, requestHash, response, ...)Validation responded