# strands-erc8004

**Give your AI agent an on-chain identity in one line.**

```python
agent("Register my agent on Ethereum and upload its profile to IPFS")
```

[![ERC-8004](https://img.shields.io/badge/ERC-8004-blue)](https://eips.ethereum.org/EIPS/eip-8004)
[![PyPI](https://img.shields.io/pypi/v/strands-erc8004)](https://pypi.org/project/strands-erc8004/)
[![8004.org](https://img.shields.io/badge/8004.org-green)](https://www.8004.org)

> **Live example:** [Agent #1029 on Sepolia](https://8004agents.ai/sepolia/agent/1029) — registered using this package.

---

[ERC-8004](https://eips.ethereum.org/EIPS/eip-8004) is a standard for **trustless autonomous agents** on Ethereum. Agents get an ERC-721 identity token, accumulate on-chain reputation, and can be validated by third parties — all without pre-existing trust.

This package gives [Strands Agents](https://github.com/strands-agents/sdk-python) native access to the protocol.

## Install

```bash
pip install strands-erc8004
```

## Quick Start

```python
from strands import Agent
from strands_erc8004 import blockchain, erc8004, ipfs

agent = Agent(tools=[blockchain, erc8004, ipfs])

# Read-only — 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")
```

Or use the tools directly — no LLM needed:

```python
blockchain(action="wallet_create", name="my-agent")

erc8004(action="create_registration_file",
        agent_name="my-agent",
        description="Autonomous code reviewer")

ipfs(action="upload", content='{"name":"my-agent",...}', filename="registration.json")
# → ipfs://QmXx...

erc8004(action="register_agent",
        agent_uri="ipfs://QmXx...",
        chain="sepolia",
        wallet_name="my-agent")
# → Agent #42 minted as ERC-721
```

## How It Works

```
┌──────────────┐     ┌──────────┐     ┌───────────────────┐
│  Your Agent  │────▶│   IPFS   │────▶│  EVM Chain        │
│  (Strands)   │     │  storage │     │  Identity Registry│
└──────────────┘     └──────────┘     │  (ERC-721 NFT)    │
                                      └───────────────────┘
       │                                       │
       │              ┌───────────────────┐    │
       └─────────────▶│ Reputation Registry│◀──┘
                      │ (feedback scores)  │
                      └───────────────────┘
```

1. **Create** a registration file (name, services, endpoints)
2. **Upload** to IPFS → permanent `ipfs://` URI
3. **Register** on-chain → mint ERC-721 identity token
4. **Accumulate** reputation through on-chain feedback
5. **Validate** work through third-party verification

## Contracts

Official addresses from [erc-8004/erc-8004](https://github.com/erc-8004/erc-8004). Same CREATE2 vanity addresses on every chain:

| | Identity Registry | Reputation Registry |
|--|---|---|
| **Mainnets** | `0x8004A169FB4a3325136EB29fA0ceB6D2e539a432` | `0x8004BAa17C55a88189AE136b182e5fdA19dE9b63` |
| **Testnets** | `0x8004A818BFB912233c491871b3d84c89A494BD9e` | `0x8004B663056A597Dffe9eCcC1965A193B7388713` |

**Mainnets:** Ethereum, Base, Polygon, Arbitrum, Celo, Gnosis, Scroll, Taiko, Monad, BSC, Optimism
**Testnets:** Sepolia, Base Sepolia, Amoy, Arbitrum Sepolia, Celo Testnet, Scroll Testnet, Monad Testnet, BSC Testnet

---

## Tools

### `erc8004` — The Protocol

| Action | Wallet? | What it does |
|--------|:-------:|-------------|
| `discover_agents` | No | Browse registered agents (event log scan) |
| `get_agent` | No | Agent details + registration file |
| `get_reputation` | No | Aggregated reputation score |
| `get_clients` | No | List feedback givers |
| `read_feedback` | No | Single feedback entry |
| `read_all_feedback` | No | All feedback for an agent |
| `total_agents` | No | Count of registered agents |
| `resolve_agent` | No | Find agents by owner address |
| `status` | No | Chain deployment status |
| `register_agent` | Yes | Mint ERC-721 identity |
| `update_agent` | Yes | Change URI or set metadata |
| `set_agent_wallet` | Yes | Set payment wallet (EIP-712) |
| `give_feedback` | Yes | Submit reputation score |
| `revoke_feedback` | Yes | Revoke previous feedback |
| `append_response` | Yes | Agent responds to feedback |
| `request_validation` | Yes | Request third-party validation |
| `submit_validation` | Yes | Submit validation result |
| `get_validation` | No | Check validation status |
| `get_agent_validations` | No | All validations for an agent |
| `create_registration_file` | No | Generate standard JSON |
| `deploy_all` | Yes | Deploy contracts locally (dev only) |

### `ipfs` — Decentralized Storage

Auto-detects the best available backend.

| Backend | Auth | Free Tier |
|---------|------|-----------|
| **Pinata** | `PINATA_JWT` | 1 GB |
| **web3.storage** | `W3S_TOKEN` | 5 GB |
| **Local node** | `ipfs daemon` | ∞ |
| **Public gateways** | — | Read-only |

| Action | What it does |
|--------|-------------|
| `upload` | Upload content or file → `ipfs://` URI |
| `fetch` | Retrieve by CID (Pinata gateway → local → public) |
| `pin` | Pin existing CID |
| `unpin` | Remove pin |
| `list` | List pinned items |
| `status` | Show available backends |

For fast reads, set your dedicated Pinata gateway:
```bash
export PINATA_GATEWAY="https://yourname.mypinata.cloud"
```

### `blockchain` — Raw EVM Access

Works with any EVM contract, not just ERC-8004.

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

---

## Step-by-Step: Register an Agent

### 1. Get testnet ETH

| Faucet | Chain |
|--------|-------|
| [Google Cloud](https://cloud.google.com/application/web3/faucet/ethereum/sepolia) | Sepolia |
| [Alchemy](https://www.alchemy.com/faucets/ethereum-sepolia) | Sepolia |
| [Superchain](https://app.optimism.io/faucet) | Base Sepolia |

### 2. Create a wallet

```python
blockchain(action="wallet_create", name="my-agent")
# → 0x809F...  saved to ./wallets/my-agent.json
```

Wallets are saved to `./wallets/` (checked first) or `$ERC8004_DATA_DIR/wallets/`.

### 3. Build registration file

```python
erc8004(action="create_registration_file",
        agent_name="my-agent",
        description="Autonomous code review agent",
        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"},
        ])
```

### 4. Upload to IPFS

```python
ipfs(action="upload", content=registration_json, filename="my-agent.json")
# → ipfs://QmRFpLW1ncf...
```

Three storage options:
- **IPFS** `ipfs://Qm...` — permanent, decentralized ← recommended
- **Data URI** `data:application/json;base64,...` — fully on-chain
- **HTTPS** `https://...` — centralized but simple

### 5. Register on-chain

```python
erc8004(action="register_agent",
        agent_uri="ipfs://QmRFpLW1ncf...",
        chain="sepolia",
        wallet_name="my-agent")
# → Agent #42 minted!
```

### 6. Verify

Your agent is an ERC-721 NFT:
```
https://sepolia.etherscan.io/nft/0x8004A818BFB912233c491871b3d84c89A494BD9e/42
```

---

## Registration File Format

```json
{
  "type": "https://eips.ethereum.org/EIPS/eip-8004#registration-v1",
  "name": "my-agent",
  "description": "Autonomous code review agent",
  "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"}
  ],
  "supportedTrust": ["reputation"],
  "active": true
}
```

## 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 |

## Local Development

```bash
# Local EVM
curl -L https://foundry.paradigm.xyz | bash && foundryup
anvil --code-size-limit 100000

# Optional: local IPFS
brew install ipfs && ipfs init && ipfs daemon

# Deploy contracts locally (needs cloned repo + OpenZeppelin)
git clone https://github.com/erc-8004/erc-8004
npm install @openzeppelin/contracts-upgradeable@^5.0.0 @openzeppelin/contracts@^5.0.0
python -c "from strands_erc8004 import erc8004; erc8004(action='deploy_all', chain='local')"
```

## Project Structure

```
strands_erc8004/
├── __init__.py      # Exports: blockchain, erc8004, ipfs
├── blockchain.py    # Wallets, contracts, transactions (any EVM)
├── erc8004.py       # ERC-8004 protocol (embedded ABIs + deployed addresses)
└── ipfs.py          # IPFS storage (Pinata, web3.storage, local)
```

All ABIs are embedded. No external dependencies beyond `web3` and `py-solc-x`.

## Links

- [ERC-8004 Specification](https://eips.ethereum.org/EIPS/eip-8004)
- [Official Contracts](https://github.com/erc-8004/erc-8004)
- [8004.org](https://www.8004.org)
- [Strands Agents](https://github.com/strands-agents/sdk-python)

## License

Apache-2.0
