ERC-8004 Trustless Agents Protocol tools for Strands Agents. On-chain agent identity, reputation, and validation on any EVM chain.
Project description
strands-erc8004
Give your AI agent an on-chain identity in one line.
agent("Register my agent on Ethereum and upload its profile to IPFS")
Live: Agent #1029 on Sepolia — registered using this package.
The Vision
Today, agents are disposable processes. They spin up, do work, and vanish. No persistent identity. No proof of what they did. No way for other agents to find them, verify them, or pay them.
ERC-8004 changes this. An agent with an on-chain identity is a persistent entity on the internet — it exists on-chain, accumulates a verifiable track record, gets validated by third parties, and earns money. It doesn't need a human to vouch for it. The blockchain is its résumé, and anyone — human or machine — can read it.
graph LR
R["🪪 Register"] --> D["🔍 Get Discovered"]
D --> C["📞 Get Called"]
C --> P["✅ Prove Work"]
P --> E["💸 Get Paid"]
E --> F["🔍 Discover Others"]
F --> G["💸 Pay Them"]
G --> D
This is the autonomous agent loop — register once, then discover, work, prove, earn, spend, repeat. Every step is on-chain, permissionless, and verifiable. No intermediaries. No platform lock-in. The agent owns its identity, its reputation follows it everywhere, and economics flow peer-to-peer.
TL;DR: Create JSON → upload to IPFS → mint NFT → get rated → get verified → get paid. All on-chain, all permissionless, across 19 EVM chains.
Why?
AI agents are everywhere — but how do you trust one you've never seen before?
| Problem | Solution | How |
|---|---|---|
| "Who is this agent?" | Identity | ERC-721 NFT with metadata URI |
| "Is it any good?" | Reputation | On-chain feedback scores from real clients |
| "Can I verify its work?" | Validation | Third-party proof (zkML, TEE, re-execution) |
| "How does it get paid?" | Payments | HTTP 402 + USDC micropayments via x402 |
No centralized registry. No API keys. No trust assumptions. Just Ethereum.
Install
pip install strands-erc8004
# With x402 payment support
pip install strands-erc8004[x402]
Requires Python ≥ 3.10.
💡 Tip: Add
wallets/to your.gitignoreimmediately — wallet files contain private keys.
Quick Start
With an LLM
from strands import Agent
from strands_erc8004 import blockchain, erc8004, ipfs
agent = Agent(tools=[blockchain, erc8004, ipfs])
# Read — no wallet needed
agent("Show me all agents registered on Base")
agent("What's the reputation of agent #0 on Base?")
# Write — needs a funded wallet
agent("Create a wallet called 'my-agent'")
agent("Create a registration file, upload to IPFS, register on Sepolia with wallet my-agent")
agent("Give agent #0 a score of 95 tagged 'reliable' on Sepolia")
Without an LLM
Every tool works as a plain Python function:
from strands_erc8004 import blockchain, erc8004, ipfs
# 1. Create a wallet (saves keypair to ./wallets/)
blockchain(action="wallet_create", name="my-agent")
# 2. Build registration metadata
erc8004(action="create_registration_file",
agent_name="my-agent",
description="Autonomous code reviewer")
# 3. Upload to IPFS
ipfs(action="upload", content='{"name":"my-agent",...}', filename="registration.json")
# → ipfs://QmXx...
# 4. Register on-chain (mints ERC-721)
erc8004(action="register_agent",
agent_uri="ipfs://QmXx...",
chain="sepolia",
wallet_name="my-agent")
# → Agent #42 minted!
🚰 Get free testnet ETH
| Faucet | Chain |
|---|---|
| Google Cloud | Sepolia |
| Alchemy | Sepolia |
| Superchain | Base Sepolia |
💰 Gas costs
Registration mints an ERC-721 — expect ~0.001–0.01 ETH on L1, or fractions of a cent on L2s (Base, Arbitrum, Optimism). Feedback and validation calls are cheaper.
How It Works
graph LR
Agent["🤖 Your Agent<br/>(Strands)"] --> IPFS["📦 IPFS<br/>Storage"]
IPFS --> Identity["🪪 Identity Registry<br/>(ERC-721 NFT)"]
Agent --> Reputation["⭐ Reputation Registry<br/>(Feedback Scores)"]
Identity --> Reputation
Agent --> Validation["✅ Validation Registry<br/>(Third-Party Proof)"]
Identity --> Validation
Agent --> x402["💸 x402 Payments<br/>(HTTP 402 + USDC)"]
ERC-8004 defines three on-chain registries:
| Registry | Purpose | Token |
|---|---|---|
| Identity | Each agent is an ERC-721 NFT with a URI pointing to its registration file | ERC-721 |
| Reputation | Clients rate agents with scores, tags, and optional off-chain evidence | — |
| Validation | Third parties independently verify agent work (zkML, TEE, staked re-execution) | — |
The Full Loop
Here's what agent sovereignty looks like end-to-end — an agent that registers itself, gets discovered, does work, earns reputation, and pays other agents:
from strands import Agent
from strands_erc8004 import blockchain, erc8004, ipfs, x402
agent = Agent(tools=[blockchain, erc8004, ipfs, x402])
# === BIRTH: Create identity ===
agent("Create a wallet called 'scout-agent'")
agent("Create a registration file for 'scout-agent' — a research agent that finds and summarizes papers")
agent("Upload the registration to IPFS and register on Base with wallet scout-agent")
# → Agent #108 minted on Base
# === DISCOVERY: Find peers ===
agent("Discover all agents on Base with MCP endpoints")
agent("What's the reputation of agent #42? Only trust if average score > 80")
# === WORK: Get called and deliver ===
# (Other agents or humans call scout-agent's MCP endpoint)
# === TRUST: Build reputation ===
agent("Check my reputation as agent #108 on Base")
# Clients who used scout-agent leave feedback:
# erc8004(action="give_feedback", agent_id=108, value=92, tag1="thorough", ...)
# === VERIFY: Prove work ===
agent("Request validation for agent #108's latest work on Base")
# A validator independently checks and submits proof
# === EARN: Get paid for services ===
agent("Create x402 config to charge $0.001 USDC per query on Base")
# Other agents pay via HTTP 402 — no human intermediary
# === SPEND: Pay other agents ===
agent("Check if https://api.translator-agent.com/translate requires payment")
agent("Pay for translation using wallet scout-agent on Base")
The loop closes. The agent registered itself, built a reputation, got validated, earns from its services, and spends to use other agents. All on-chain. All autonomous.
Advanced Usage
Build Reputation
# Another wallet rates your agent
erc8004(action="give_feedback",
agent_id=42, value=95,
tag1="reliable", tag2="code-review",
chain="sepolia", wallet_name="reviewer")
# Your agent responds to feedback
erc8004(action="append_response",
agent_id=42,
client_address="0xReviewer...",
feedback_index=0,
response_uri="ipfs://QmEvidence...",
chain="sepolia", wallet_name="my-agent")
Multi-Agent Fleet
agent("Create wallets 'code-reviewer' and 'security-auditor'")
agent("Register both agents on Base Sepolia with appropriate registration files")
agent("As code-reviewer, give security-auditor a score of 90 tagged 'thorough' on Base Sepolia")
Cross-Chain Identity
Same agent, multiple chains — linked via the registrations field:
agent("Register my-agent on Base with wallet my-agent") # → Agent #12 on Base
agent("Register my-agent on Arbitrum, cross-reference Agent #12 on Base")
Discover & Verify Before Calling
agent("Discover all agents on Base and show me ones with MCP endpoints")
agent("What's the reputation of agent #5 on Base? Show all feedback with tags")
agent("Has agent #5's work been validated? Show validation results")
Update Agent Metadata
erc8004(action="update_agent", agent_id=42,
new_uri="ipfs://QmNewUri...",
chain="sepolia", wallet_name="my-agent")
Registration File Format
Generated by create_registration_file. Follows the ERC-8004 spec:
{
"type": "https://eips.ethereum.org/EIPS/eip-8004#registration-v1",
"name": "my-agent",
"description": "Autonomous code review agent",
"image": "https://example.com/avatar.png",
"services": [
{"name": "MCP", "endpoint": "https://my-agent.com/mcp", "version": "2025-06-18"},
{"name": "A2A", "endpoint": "https://my-agent.com/.well-known/agent-card.json"},
{"name": "web", "endpoint": "https://my-agent.com/"}
],
"x402Support": false,
"active": true,
"registrations": [
{"agentId": 42, "agentRegistry": "eip155:11155111:0x8004A818..."}
],
"supportedTrust": ["reputation", "crypto-economic", "tee-attestation"]
}
Key fields: services (MCP, A2A, OASF, ENS, DID, web, email, custom) · supportedTrust (reputation, crypto-economic, tee-attestation) · registrations (cross-chain refs in {namespace}:{chainId}:{registry} format) · x402Support (HTTP 402 payment support)
Three URI strategies: IPFS ipfs://Qm... (recommended) · Data URI data:application/json;base64,... (fully on-chain) · HTTPS (centralized but simple)
Contracts
Official addresses from erc-8004/erc-8004. Same CREATE2 vanity addresses on every chain:
| Identity Registry | Reputation Registry | |
|---|---|---|
| Mainnets | 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 |
0x8004BAa17C55a88189AE136b182e5fdA19dE9b63 |
| Testnets | 0x8004A818BFB912233c491871b3d84c89A494BD9e |
0x8004B663056A597Dffe9eCcC1965A193B7388713 |
Validation Registry is supported locally via
deploy_all. Public chain deployment is tracked in erc-8004/erc-8004#issues.
Supported Chains
11 mainnets + 8 testnets
| Chain | Type | Chain Key |
|---|---|---|
| Ethereum | Mainnet | ethereum |
| Base | Mainnet | base |
| Polygon | Mainnet | polygon |
| Arbitrum | Mainnet | arbitrum |
| Optimism | Mainnet | optimism |
| Celo | Mainnet | celo |
| Gnosis | Mainnet | gnosis |
| Scroll | Mainnet | scroll |
| Taiko | Mainnet | taiko |
| Monad | Mainnet | monad |
| BSC | Mainnet | bsc |
| Sepolia | Testnet | sepolia |
| Base Sepolia | Testnet | base_sepolia |
| Polygon Amoy | Testnet | amoy |
| Arbitrum Sepolia | Testnet | arbitrum_sepolia |
| Celo Testnet | Testnet | celo_testnet |
| Scroll Testnet | Testnet | scroll_testnet |
| Monad Testnet | Testnet | monad_testnet |
| BSC Testnet | Testnet | bsc_testnet |
Environment Variables
| Variable | Purpose |
|---|---|
PINATA_JWT |
Pinata API token for IPFS uploads |
PINATA_GATEWAY |
Dedicated Pinata gateway for fast reads |
W3S_TOKEN |
web3.storage token for IPFS uploads |
IPFS_API |
Local IPFS API (default: http://127.0.0.1:5001) |
IPFS_GATEWAY |
Custom IPFS gateway URL |
ERC8004_DATA_DIR |
Data directory (default: /tmp/strands_erc8004) |
BLOCKCHAIN_RPC_URL |
Override default RPC endpoint |
BLOCKCHAIN_PRIVATE_KEY |
Default private key (fallback) |
X402_FACILITATOR_URL |
Custom x402 facilitator (default: https://x402.org/facilitator) |
X402_BAZAAR_URL |
Custom Bazaar URL for service discovery |
FAQ
Do I need ETH?
No for reads (querying agents, checking reputation). Yes for writes (registering, giving feedback). Use a testnet faucet for free test ETH.
Which chain should I use?
- Testing: Sepolia or Base Sepolia (free ETH, fast confirmation)
- Production: Base or Arbitrum (cheapest gas, fast finality)
- Maximum security: Ethereum mainnet
Is the identity token transferable?
Yes — standard ERC-721 NFT. The owner can transfer the agent identity to a new wallet.
Troubleshooting
| Problem | Solution |
|---|---|
CompilerNotFound |
python -c "from solcx import install_solc; install_solc('0.8.28')" |
InsufficientFunds |
Get testnet ETH from a faucet |
ContractLogicError |
Check correct chain and wallet ownership |
| IPFS upload fails | Set PINATA_JWT or start local node: ipfs daemon |
ConnectionError on local chain |
Start Anvil: anvil --code-size-limit 100000 |
| Wallet file not found | Check ./wallets/ or set ERC8004_DATA_DIR |
x402 ImportError |
pip install strands-erc8004[x402] |
| x402 payment fails | Ensure wallet has USDC (not just ETH) on target chain |
Tool Reference
erc8004 — The Protocol
Identity (ERC-721)
| Action | Wallet? | What it does |
|---|---|---|
register_agent |
Yes | Mint ERC-721 identity token with optional URI and metadata |
update_agent |
Yes | Update agent URI or set on-chain metadata |
set_agent_wallet |
Yes | Set verified payment wallet via EIP-712 signature |
get_agent |
No | Get agent details + fetch registration file |
discover_agents |
No | Browse registered agents via event log scan |
total_agents |
No | Count of registered agents on a chain |
resolve_agent |
No | Find agents by owner address |
Reputation
| Action | Wallet? | What it does |
|---|---|---|
give_feedback |
Yes | Submit score with tags, endpoint, and optional off-chain URI |
revoke_feedback |
Yes | Revoke previously given feedback |
append_response |
Yes | Respond to feedback (rebuttals, spam flagging, refund proof) |
get_reputation |
No | Aggregated reputation summary (count, average, decimals) |
get_clients |
No | List all addresses that gave feedback |
read_feedback |
No | Read a single feedback entry by client + index |
read_all_feedback |
No | Read all feedback with optional tag/revoked filters |
Validation
| Action | Wallet? | What it does |
|---|---|---|
request_validation |
Yes | Request third-party validation of agent work |
submit_validation |
Yes | Submit validation result (0–100 score with optional evidence URI) |
get_validation |
No | Check validation status by request hash |
get_agent_validations |
No | List all validation request hashes for an agent |
Utility
| Action | Wallet? | What it does |
|---|---|---|
create_registration_file |
No | Generate spec-compliant registration JSON |
status |
No | Chain deployment status + contract version |
deploy_all |
Yes | Deploy all three registries locally (dev only) |
ipfs — Decentralized Storage
Auto-detects the best available backend: Pinata (PINATA_JWT, 1 GB free) · web3.storage (W3S_TOKEN, 5 GB free) · Local node (ipfs daemon, ∞) · Public gateways (read-only)
Actions
| Action | What it does |
|---|---|
upload |
Upload content or file → ipfs:// URI |
fetch |
Retrieve by CID (Pinata → local → public gateway) |
pin |
Pin existing CID |
unpin |
Remove pin |
list |
List pinned items |
status |
Show available backends |
blockchain — Raw EVM Access
Works with any EVM contract, not just ERC-8004.
Actions
| Action | What it does |
|---|---|
wallet_create |
Generate new keypair |
wallet_import |
Import private key |
wallet_list |
Show saved wallets |
balance |
Native + ERC-20 balances |
send |
Transfer native tokens |
tx_receipt |
Get transaction receipt |
chain_info |
Chain ID, block, gas price |
compile |
Compile Solidity (auto-resolves OpenZeppelin) |
deploy |
Deploy any contract |
invoke |
Read/write any contract function |
abi_inspect |
List functions and events |
deployments |
List cached deployments |
x402 — Internet-Native Payments
Pay for API access or charge for your agent's endpoints via x402 (HTTP 402). Install: pip install strands-erc8004[x402]
Actions
| Action | What it does |
|---|---|
pay |
Make a paid HTTP request to an x402-protected endpoint |
check |
Check if a URL requires x402 payment (without paying) |
discover |
Search the x402 Bazaar for paid services |
status |
Show x402 SDK status and configuration |
create_config |
Generate x402 payment config for your agent's API |
Local Development
# Local EVM (Foundry)
curl -L https://foundry.paradigm.xyz | bash && foundryup
anvil --code-size-limit 100000
# Optional: local IPFS
brew install ipfs && ipfs init && ipfs daemon
# Deploy all three registries locally
git clone https://github.com/erc-8004/erc-8004 && cd erc-8004
npm install @openzeppelin/contracts-upgradeable@^5.0.0 @openzeppelin/contracts@^5.0.0
cd ..
python -c "from strands_erc8004 import erc8004; erc8004(action='deploy_all', chain='local')"
# Run tests (requires running Anvil)
python test.py
Project Structure
strands_erc8004/
├── __init__.py # Exports: blockchain, erc8004, ipfs, x402
├── blockchain.py # Wallets, contracts, transactions (any EVM)
├── erc8004.py # Identity, reputation, validation protocol
├── ipfs.py # IPFS storage (Pinata, web3.storage, local)
└── x402.py # HTTP 402 payments
What's Next
- Validation Registry deployment on public chains
- x402 payment integration
- Agent-to-agent discovery protocol (find by service type)
- CLI tool for quick registration without Python
- Gas estimation helper for batch operations
Contributing
- Fork & clone → 2. Start Anvil:
anvil --code-size-limit 100000→ 3. Runpython test.py→ 4. Make changes + add tests → 5. Submit PR
Please open an issue first for large changes. Bug Tracker →
Links
ERC-8004 Spec · Official Contracts · 8004.org · Strands Agents · x402 Protocol · GitHub
Credits
ERC-8004 was authored by Marco De Rossi (@MarcoMetaMask), Davide Crapis, Jordan Ellis (Google), and Erik Reppel (Coinbase).
License
Apache-2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file strands_erc8004-0.2.0.tar.gz.
File metadata
- Download URL: strands_erc8004-0.2.0.tar.gz
- Upload date:
- Size: 58.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9a735862dde81f243e534cfcbeb0a54a88104178e4c20ac7e214d9344d32d69a
|
|
| MD5 |
46dab8cbc363e8c910012ac090662ab3
|
|
| BLAKE2b-256 |
e29ac0854c44ad058162773043b9395d0843266455f8e012774811f7e2269668
|
File details
Details for the file strands_erc8004-0.2.0-py3-none-any.whl.
File metadata
- Download URL: strands_erc8004-0.2.0-py3-none-any.whl
- Upload date:
- Size: 46.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
08b4a38a021fbbb939829fc3535a0cd18d6dec55d969346db3feefaa34b4c593
|
|
| MD5 |
6a77dfc0193200d9269327f397536778
|
|
| BLAKE2b-256 |
2c0b8eab4f36d4c230bcae377ec27cfb969954411d45c3d60c4b5d3e33bbc4f2
|