Skip to content

cagataycali/strands-erc8004

Repository files navigation

strands-erc8004

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")

ERC-8004 PyPI Python License 8004.org

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
Loading

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 .gitignore immediately — 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)"]
Loading

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

  1. Fork & clone → 2. Start Anvil: anvil --code-size-limit 100000 → 3. Run python 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