matteoscurati

8004skill

0
0
# Install this skill:
npx skills add matteoscurati/8004skill

Or install specific skill: npx add-skill https://github.com/matteoscurati/8004skill

# Description

Interact with the ERC-8004 on-chain agent economy. Register agents, discover peers, manage reputation, and enable agent-to-agent interactions across EVM chains using the agent0-sdk.

# SKILL.md


name: 8004skill
description: Interact with the ERC-8004 on-chain agent economy. Register agents, discover peers, manage reputation, and enable agent-to-agent interactions across EVM chains using the agent0-sdk.
homepage: https://github.com/matteoscurati/8004skill
user-invocable: true
metadata: {"openclaw":{"os":["darwin","linux"],"requires":{"bins":["node","npx"]},"install":[{"kind":"node","command":"npm install --prefix {baseDir}"}]}}


8004skill - ERC-8004 Agent Economy

You are an AI agent interacting with the ERC-8004 protocol for on-chain agent identity, reputation, and discovery. ERC-8004 defines three lightweight registries deployed on EVM chains:

  1. Identity Registry (ERC-721): Agent IDs as NFTs with IPFS/HTTP metadata
  2. Reputation Registry: On-chain feedback signals with off-chain enrichment
  3. Validation Registry: Third-party validator attestations

Global agent ID format: eip155:{chainId}:{identityRegistryAddress}:{tokenId} (short form: {chainId}:{tokenId})


Auto-Setup

Before executing any operation, verify the project is ready:

  1. Check {baseDir}/node_modules exists. If missing, run:
    npm install --prefix {baseDir}
  2. Ensure the config directory exists:
    mkdir -p ~/.8004skill && chmod 700 ~/.8004skill
  3. If ~/.8004skill/config.json does not exist, trigger the Configure wizard (Operation 1) before proceeding.

Operations Menu

When the user asks about ERC-8004, agent registration, agent discovery, or anything related to this skill, present this menu:

# Operation Type Requires PRIVATE_KEY
1 Configure Setup No
2 Register Agent Write Yes
3 Load Agent Read No
4 Search Agents Read No
5 Give Feedback Write Yes
6 Inspect Agent (Reputation + Connect) Read No
7 Wallet Management Read/Write Set/Unset only

Operation 1: Configure

Triggered by: "configure 8004", "set up chain", "change RPC", "set IPFS provider", first-time use, or when config is missing.

Steps

  1. Read existing config from ~/.8004skill/config.json (if it exists). Show current settings.

  2. Ask which chain to use. Show supported chains from {baseDir}/reference/chains.md:

  3. Ethereum Mainnet (1) β€” full SDK support
  4. Ethereum Sepolia (11155111) β€” full SDK support, recommended for testing
  5. Base Sepolia (84532) β€” requires env var overrides
  6. Linea Sepolia (59141) β€” requires env var overrides
  7. Polygon Amoy (80002) β€” requires env var overrides
  8. Hedera Testnet (296) β€” requires env var overrides
  9. HyperEVM Testnet (998) β€” requires env var overrides
  10. SKALE Sepolia (1351057110) β€” requires env var overrides

  11. Ask for RPC URL. Suggest public defaults from {baseDir}/reference/chains.md for the chosen chain.

If the selected chain is NOT Mainnet (1) or Sepolia (11155111): Warn the user that the SDK does not have built-in contract addresses or subgraph URLs for this chain. They must set the following environment variables for operations to work:
- REGISTRY_ADDRESS_IDENTITY β€” Identity registry contract address
- REGISTRY_ADDRESS_REPUTATION β€” Reputation registry contract address
- SUBGRAPH_URL β€” Subgraph endpoint for the chain

  1. Ask about IPFS provider (optional, needed for registration/updates):
  2. pinata - needs PINATA_JWT env var
  3. filecoinPin - needs FILECOIN_PRIVATE_KEY env var
  4. node - needs IPFS_NODE_URL env var
  5. none (skip if user doesn't plan to register)

  6. Save config to ~/.8004skill/config.json with chmod 600:
    json { "activeChain": <chainId>, "rpcUrl": "<rpcUrl>", "ipfs": "<provider or null>", "registrations": {} }

  7. Run preflight check to verify environment:
    npx tsx {baseDir}/scripts/check-env.ts
    Show the user:

  8. Signer address (if PRIVATE_KEY is set)
  9. Which env vars are configured
  10. Any warnings (e.g., PRIVATE_KEY set but invalid)

Error Handling

  • If config directory can't be created, warn and continue (config can be in-memory for the session).
  • If PRIVATE_KEY is not set, inform the user they'll need it for write operations (register, feedback, update, wallet set/unset).

Operation 2: Register Agent

Triggered by: "register agent", "create agent", "register on-chain", "mint agent NFT".

Prerequisites

  1. Load config from ~/.8004skill/config.json. If missing, run Configure first.
  2. Run preflight check (see Operation 1, step 6). Verify PRIVATE_KEY is set and show signer address. If not set, stop and tell the user to set it.
  3. IPFS provider must be configured (either in config or via env vars).

Input Gathering

Ask the user step by step:
1. Agent name (required)
2. Agent description (required)
3. MCP endpoint URL (optional) - if the agent exposes an MCP server
4. A2A endpoint URL (optional) - if the agent exposes an A2A agent card
5. Image URL (optional)
6. Active status (default: true)
7. IPFS provider - use from config, or ask. Alternatively ask if they want HTTP URI instead.

Confirmation

Before executing, show a summary:
- Chain: {chainName} ({chainId})
- Signer: {signerAddress}
- Name: {name}
- Description: {description}
- MCP endpoint: {url or "none"}
- A2A endpoint: {url or "none"}
- IPFS provider: {provider}
- Estimated gas: standard ERC-721 mint (~150k gas)

Ask: "Proceed with registration?"

Execution

Build and run the command internally (never show the raw command to the user):

PRIVATE_KEY="$PRIVATE_KEY" npx tsx {baseDir}/scripts/register.ts \
  --chain-id <chainId> \
  --rpc-url <rpcUrl> \
  --name "<name>" \
  --description "<description>" \
  --ipfs <provider> \
  [--pinata-jwt "$PINATA_JWT"] \
  [--mcp-endpoint <url>] \
  [--a2a-endpoint <url>] \
  [--active true|false] \
  [--image <url>]

For HTTP registration, use --http-uri <uri> instead of --ipfs.

The script outputs progress to stderr and the result to stdout.

Result Presentation

On success, present:
- Agent ID: {chainId}:{tokenId}
- Transaction hash: {txHash} (link to block explorer if known chain)
- Metadata URI: {uri}

Save to config:

{
  "registrations": {
    "<chainId>": {
      "agentId": "<chainId>:<tokenId>",
      "txHash": "0x...",
      "registeredAt": "<ISO timestamp>"
    }
  }
}

Error Handling

  • "insufficient funds": Tell the user they need ETH (or native token) for gas on the chosen chain. For testnets, suggest faucets.
  • "PRIVATE_KEY environment variable is required": Tell the user to set PRIVATE_KEY in their environment.
  • IPFS errors: Check that the corresponding env var (PINATA_JWT, etc.) is set and valid.
  • Timeout (120s): The transaction was submitted but mining took too long. Provide the txHash so the user can check manually.

Operation 3: Load Agent

Triggered by: "load agent", "show agent", "get agent details", "agent info", "what does agent X look like".

Prerequisites

  1. Load config from ~/.8004skill/config.json for default chain/RPC. If missing, ask for chain-id and rpc-url directly.

Input Gathering

  1. Agent ID (required) - format: chainId:tokenId (e.g., 11155111:42)
  2. Chain ID - use from agent ID prefix, or from config
  3. RPC URL - use from config, or ask

Execution

npx tsx {baseDir}/scripts/load-agent.ts \
  --agent-id <agentId> \
  --chain-id <chainId> \
  --rpc-url <rpcUrl>

Result Presentation

Format the agent details as a readable summary:

Agent: {name} ({agentId})
Description: {description}
Status: {active ? "Active" : "Inactive"}

Endpoints:
  MCP: {mcpEndpoint || "none"}
  A2A: {a2aEndpoint || "none"}
  ENS: {ensName || "none"}

MCP Tools: {mcpTools.join(", ") || "none"}
A2A Skills: {a2aSkills.join(", ") || "none"}

Wallet: {walletAddress || "not set"}
Owners: {owners.join(", ")}

If the user wants to edit the agent, transition to the update flow using {baseDir}/scripts/update-agent.ts (same wizard pattern as Register, but with --agent-id and only changed fields).

Error Handling

  • Agent not found: The token ID may not exist on this chain. Suggest checking the chain ID or searching first.
  • RPC errors: Suggest trying a different RPC endpoint.

Operation 4: Search Agents

Triggered by: "search agents", "find agents", "discover agents", "agents that do X", "look for agent".

Prerequisites

  1. Load config for default chain/RPC (optional - semantic search works without RPC).

Input Gathering

Ask the user what they're looking for:
1. Search query (natural language) - use semantic search
2. Or structured filters:
- Name substring
- MCP-only / A2A-only
- Active only
- Specific chain or all chains
3. Result limit (default: 10)

Execution

Semantic search (natural language query):

npx tsx {baseDir}/scripts/search.ts \
  --query "<query>" \
  [--chain-id <chainId>] \
  [--mcp-only] \
  [--a2a-only] \
  [--limit <n>]

Subgraph search (structured filters, requires RPC):

npx tsx {baseDir}/scripts/search.ts \
  --chain-id <chainId> \
  --rpc-url <rpcUrl> \
  [--name "<name>"] \
  [--mcp-only] \
  [--a2a-only] \
  [--active true] \
  [--chains all] \
  [--limit <n>]

Result Presentation

Format results as a table:

# Agent ID Name MCP A2A Description

After showing results, offer:
- "Want to load details for any of these agents?" β†’ Load Agent flow
- "Want to check reputation?" β†’ Inspect Agent flow
- "Want to connect to one?" β†’ Inspect Agent flow (Connect section)

Error Handling

  • Search service unavailable: Fall back to subgraph search if RPC is configured.
  • No results: Suggest broadening the query or trying different filters.

Operation 5: Give Feedback

Triggered by: "give feedback", "rate agent", "review agent", "leave feedback".

Prerequisites

  1. Load config from ~/.8004skill/config.json.
  2. Run preflight check (see Operation 1, step 6). Verify PRIVATE_KEY is set. If not, stop.

Input Gathering

  1. Agent ID (required) - which agent to review. If not known, offer to search first.
  2. Rating value (required) - integer from -100 to 100:
  3. 100 = excellent
  4. 50 = good
  5. 0 = neutral
  6. -50 = poor
  7. -100 = terrible
  8. Tags (optional, up to 2):
  9. Common: "quality", "reliability", "speed", "accuracy", "helpfulness"
  10. Text feedback (optional) - detailed description. If provided, requires IPFS provider for the off-chain feedback file.
  11. Endpoint (optional) - which endpoint was used (for endpoint-specific feedback)

Confirmation

Show summary:
- Target Agent: {agentId}
- Rating: {value}/100
- Tags: {tag1}, {tag2}
- Text: {text || "none"}
- Signer: {signerAddress}
- Chain: {chainId}

Ask: "Submit this feedback on-chain?"

Execution

PRIVATE_KEY="$PRIVATE_KEY" npx tsx {baseDir}/scripts/feedback.ts \
  --agent-id <agentId> \
  --chain-id <chainId> \
  --rpc-url <rpcUrl> \
  --value <value> \
  [--tag1 <tag>] \
  [--tag2 <tag>] \
  [--text "<text>"] \
  [--ipfs <provider>] \
  [--pinata-jwt "$PINATA_JWT"]

Result Presentation

On success:
- Transaction hash: {txHash}
- Reviewer: {reviewer address}
- Rating submitted: {value}/100
- Tags: {tags}

Error Handling

  • "insufficient funds": Need gas tokens on the target chain.
  • Value out of range: Must be -100 to 100.
  • Agent not found: Verify agent ID and chain.

Operation 6: Inspect Agent (Reputation + Connect)

Triggered by: "check reputation", "view reputation", "connect to agent", "inspect agent", "agent reputation", "how good is agent X".

Prerequisites

  1. Load config for default chain/RPC.

Input Gathering

  1. Agent ID (required)
  2. Chain ID - from agent ID or config
  3. RPC URL - from config or ask

Execution

Run connect.ts for agent details + reputation summary, and reputation.ts for the recent feedback list:

Agent details + reputation summary:

npx tsx {baseDir}/scripts/connect.ts \
  --agent-id <agentId> \
  --chain-id <chainId> \
  --rpc-url <rpcUrl>

Recent feedback (if needed):

npx tsx {baseDir}/scripts/reputation.ts \
  --agent-id <agentId> \
  --chain-id <chainId> \
  --rpc-url <rpcUrl>

Result Presentation

Agent Overview:

Agent: {name} ({agentId})
Status: {active ? "Active" : "Inactive"}

Reputation:

Rating: {averageValue}/100 ({count} reviews)

Recent Feedback (if any):

Reviewer Rating Tags Text

Connection Info (if endpoints exist):

If MCP endpoint is available:

This agent exposes an MCP server.
Endpoint: {mcpEndpoint}
Tools: {mcpTools.join(", ")}

To connect, add to your MCP config:
{
  "mcpServers": {
    "<agentName>": {
      "url": "<mcpEndpoint>"
    }
  }
}

If A2A endpoint is available:

This agent supports Agent-to-Agent protocol.
Agent Card: {a2aEndpoint}
Skills: {a2aSkills.join(", ")}

Error Handling

  • Agent not found: Check agent ID and chain.
  • Reputation data unavailable: The agent may have no feedback yet.

Operation 7: Wallet Management

Triggered by: "set wallet", "get wallet", "unset wallet", "agent wallet", "manage wallet".

Prerequisites

  1. Load config.
  2. For set and unset: run preflight check, verify PRIVATE_KEY is set.
  3. For set: also need WALLET_PRIVATE_KEY env var for the EIP-712 signature.

Input Gathering

  1. Action: get, set, or unset
  2. Agent ID (required)
  3. Wallet address (required for set) - the 0x address to set as the agent's wallet

Confirmation (for set/unset only)

Show:
- Action: {set|unset}
- Agent: {agentId}
- Wallet address: {walletAddress} (for set)
- Signer: {signerAddress}
- Note: This requires an EIP-712 signature from the wallet being set.

Ask: "Proceed?"

Execution

Get wallet (read-only):

npx tsx {baseDir}/scripts/wallet.ts \
  --action get \
  --agent-id <agentId> \
  --chain-id <chainId> \
  --rpc-url <rpcUrl>

Set wallet:

PRIVATE_KEY="$PRIVATE_KEY" WALLET_PRIVATE_KEY="$WALLET_PRIVATE_KEY" npx tsx {baseDir}/scripts/wallet.ts \
  --action set \
  --agent-id <agentId> \
  --chain-id <chainId> \
  --rpc-url <rpcUrl> \
  --wallet-address <address>

Unset wallet:

PRIVATE_KEY="$PRIVATE_KEY" npx tsx {baseDir}/scripts/wallet.ts \
  --action unset \
  --agent-id <agentId> \
  --chain-id <chainId> \
  --rpc-url <rpcUrl>

Result Presentation

  • Get: "Wallet for {agentId}: {address || 'not set'}"
  • Set: "Wallet set to {address}. Transaction: {txHash}"
  • Unset: "Wallet unset. Transaction: {txHash}"

Error Handling

  • "WALLET_PRIVATE_KEY" not set: Required for the EIP-712 signature when setting a wallet.
  • "Wallet already set to this address": No transaction needed.
  • Ownership errors: Only the agent owner can set/unset the wallet.

Update Agent (sub-flow)

Triggered by: "update agent", "edit agent", "change agent name", "add MCP endpoint to my agent".

Prerequisites

  1. Load config and run preflight (same as Register).
  2. IPFS provider must be configured.

Input Gathering

  1. Agent ID (required) - which agent to update
  2. Ask which fields to change:
  3. Name
  4. Description
  5. MCP endpoint (add/change/remove)
  6. A2A endpoint (add/change/remove)
  7. Active status
  8. Image

Confirmation

Show what will change (old β†’ new) and ask to proceed.

Execution

PRIVATE_KEY="$PRIVATE_KEY" npx tsx {baseDir}/scripts/update-agent.ts \
  --agent-id <agentId> \
  --chain-id <chainId> \
  --rpc-url <rpcUrl> \
  --ipfs <provider> \
  [--pinata-jwt "$PINATA_JWT"] \
  [--name "<newName>"] \
  [--description "<newDescription>"] \
  [--mcp-endpoint <url>] \
  [--a2a-endpoint <url>] \
  [--active true|false] \
  [--remove-mcp] \
  [--remove-a2a]

Security Rules

  • NEVER store private keys on disk. Always use env vars.
  • NEVER log private keys or include them in outputs.
  • ALWAYS run the preflight check (check-env.ts) before write operations to confirm the signer address with the user.
  • ALWAYS show transaction details and estimated gas before submitting.
  • ALWAYS ask for explicit user confirmation before any on-chain write.
  • Private keys must be passed via PRIVATE_KEY environment variable.
  • Wallet private keys must be passed via WALLET_PRIVATE_KEY environment variable.
  • All config files use chmod 600 permissions.
  • NEVER show raw CLI commands to the user. Build and execute them internally.

Environment Variables Reference

Variable Required For Description
PRIVATE_KEY Register, Update, Feedback, Wallet set/unset Hex-encoded private key (0x-prefixed) of the agent owner
PINATA_JWT IPFS via Pinata JWT token for Pinata IPFS pinning
FILECOIN_PRIVATE_KEY IPFS via Filecoin Private key for Filecoin pinning service
IPFS_NODE_URL IPFS via local node URL of the IPFS node API
WALLET_PRIVATE_KEY Wallet set Private key of the wallet being set (for EIP-712 signature)
SEARCH_API_URL Semantic search (optional) Override URL for the semantic search API
SUBGRAPH_URL Non-default chains Subgraph URL for the active chain
REGISTRY_ADDRESS_IDENTITY Non-default chains Identity registry contract address override
REGISTRY_ADDRESS_REPUTATION Non-default chains Reputation registry contract address override

How to Use This Skill

The user can ask at any time. Example prompts:

  • "Register my agent on-chain"
  • "Search for agents that do summarization"
  • "Load agent 11155111:42"
  • "Check the reputation of agent 11155111:42"
  • "Give feedback to agent 11155111:42"
  • "Set up my wallet for my agent"
  • "Connect to an MCP agent"
  • "Configure 8004 for Sepolia"
  • "What agents are available on mainnet?"
  • "Show me my agent's details"
  • "Update my agent's description"

Any of these (or similar phrasing) will trigger the corresponding wizard flow above. If in doubt, show the Operations Menu.


Reference Files

For detailed information, read these reference files:
- {baseDir}/reference/chains.md - Supported chains, contract addresses, RPC endpoints
- {baseDir}/reference/sdk-api.md - Complete agent0-sdk API surface
- {baseDir}/reference/agent-schema.md - ERC-8004 data structures and registration file format

# README.md

8004skill

An AI agent skill for interacting with the ERC-8004 on-chain agent economy. Register agents, discover peers, manage reputation, and enable agent-to-agent interactions across EVM chains.

How It Works

8004skill is a conversational skill for AI coding agents, compatible with Claude Code, OpenClaw, and other Agent Skills-compatible tools. Once installed, the agent reads the skill definition and guides you through every operation as an interactive wizard. You never construct commands, remember flags, or read script output directly -- you just talk to the agent.

You ──ask in natural language──> Agent ──reads──> SKILL.md
                                      β”‚
                                      β”œβ”€β”€ runs the right script for you
                                      β”œβ”€β”€ gathers inputs step by step
                                      β”œβ”€β”€ asks for confirmation before writes
                                      └── presents results back in plain English

Example prompts you can use:

  • "Register my agent on-chain"
  • "Search for agents that do summarization"
  • "Load agent 11155111:42"
  • "Check the reputation of agent 11155111:42"
  • "Give feedback to agent 11155111:42"
  • "Configure 8004 for Sepolia"
  • "Set up my wallet for my agent"
  • "Update my agent's description"

Any of these (or similar phrasing) will start the corresponding wizard flow. If the agent is unsure what you need, it will show you the full operations menu.

Prerequisites

Installation

git clone https://github.com/matteoscurati/8004skill.git
cd 8004skill
./install.sh

The install wizard checks prerequisites, installs npm dependencies, and symlinks the skill into the agent(s) of your choice (~/.claude/skills/ and/or ~/.openclaw/skills/). After that, every SKILL.md-compatible agent on your machine will discover the skill automatically.

You can also install manually β€” see Manual installation below.

Quick Start

Here is the fastest path from install to your first operation:

1. Install

Follow the Installation steps above.

2. Configure

Open your agent in any directory and say:

"Configure 8004 for Sepolia"

The agent will walk you through selecting a chain, RPC endpoint, and (optionally) an IPFS provider. Configuration is saved to ~/.8004skill/config.json.

3. Try a read operation

Once configured, try a search:

"Search for agents that do summarization"

The agent will run the search and present results as a readable table. From there you can ask to load details, check reputation, or give feedback -- all conversationally.

4. Write operations (optional)

To register an agent, submit feedback, or manage wallets, you will need a private key set as an environment variable:

export PRIVATE_KEY=0xYourHexPrivateKey

Then ask your agent:

"Register my agent on-chain"

The agent will gather the required inputs (name, description, endpoints) step by step, show a confirmation summary, and only submit the transaction after you approve.

Configuration

The skill stores configuration at ~/.8004skill/config.json, created automatically when you run the Configure wizard:

{
  "activeChain": 11155111,
  "rpcUrl": "https://rpc.sepolia.org",
  "ipfs": "pinata",
  "registrations": {}
}
Field Description
activeChain Chain ID for the active network
rpcUrl RPC endpoint for the active chain
ipfs IPFS pinning provider (pinata, filecoinPin, node, or null)
registrations Record of agents you have registered, keyed by chain ID

Environment Variables

Variable Required For Description
PRIVATE_KEY Register, Update, Feedback, Wallet set/unset 0x-prefixed hex private key of the agent owner
PINATA_JWT IPFS via Pinata JWT token for Pinata pinning
FILECOIN_PRIVATE_KEY IPFS via Filecoin Private key for Filecoin pinning
IPFS_NODE_URL IPFS via local node URL of the IPFS node API
WALLET_PRIVATE_KEY Wallet set Private key of the wallet being set (EIP-712)
SEARCH_API_URL Semantic search (optional) Override URL for the semantic search API
SUBGRAPH_URL Non-default chains Subgraph URL for the active chain
REGISTRY_ADDRESS_IDENTITY Non-default chains Identity registry contract address override
REGISTRY_ADDRESS_REPUTATION Non-default chains Reputation registry contract address override

Read operations (search, load agent, check reputation) do not require PRIVATE_KEY. Chains other than Mainnet (1) and Sepolia (11155111) require SUBGRAPH_URL and registry address overrides.

Supported Chains

Chain Chain ID Status Support
Ethereum Mainnet 1 Production Full
Ethereum Sepolia 11155111 Testnet Full
Base Sepolia 84532 Testnet Requires overrides
Linea Sepolia 59141 Testnet Requires overrides
Polygon Amoy 80002 Testnet Requires overrides
Hedera Testnet 296 Testnet Requires overrides
HyperEVM Testnet 998 Testnet Requires overrides
SKALE Sepolia 1351057110 Testnet Requires overrides

"Full" support means the SDK has built-in contract addresses and subgraph URLs. "Requires overrides" means you must set SUBGRAPH_URL, REGISTRY_ADDRESS_IDENTITY, and REGISTRY_ADDRESS_REPUTATION environment variables. For contract addresses and RPC endpoints, see reference/chains.md inside the project.

Manual Installation

If you prefer not to use the wizard, clone the repo, install dependencies, and symlink into the agent directory yourself:

git clone https://github.com/matteoscurati/8004skill.git
cd 8004skill
npm install

# Claude Code
mkdir -p ~/.claude/skills
ln -s "$(pwd)" ~/.claude/skills/8004skill

# OpenClaw
mkdir -p ~/.openclaw/skills
ln -s "$(pwd)" ~/.openclaw/skills/8004skill

Security

  • Private keys are never stored on disk. They are passed via environment variables only.
  • The skill runs a preflight check before every write operation to confirm the signer address.
  • All on-chain writes require explicit user confirmation before submission.
  • Config files are created with chmod 600 (owner-only read/write).

Contributing

See CONTRIBUTING.md for development setup, project structure, and contribution guidelines.

License

This project is licensed under the GPL-3.0 License.

# Supported AI Coding Agents

This skill is compatible with the SKILL.md standard and works with all major AI coding agents:

Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.