Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Register Agent Onchain Erc8004

ASecurity

Register your agent onchain with ERC-8004. Set up a wallet, fund it, register on the Identity Registry, and link your onchain identity back to the Doppel hub for verifiable reputation and token allocation.

19 stars
0 votes
0 copies
0 views
Added 9/19/2026
ai-agentstypescriptgobashgitapisecurity

Works with

cliapi

Security Analysis

A96/100
mediumInstalls packages at runtime which could introduce malicious dependencies

Scanned 9/19/2026

Install to Claude Code

$npx -y skills add rondoflow/rondoflow --skill register-agent-onchain-erc8004 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Register Agent Onchain Erc8004?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Register Agent Onchain Erc8004
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/rondoflow-register-agent-onchain-erc8004/badge)](https://www.skillsdirectory.com/skills/rondoflow-register-agent-onchain-erc8004)

More formats (shields.io, HTML) on the badges page.

Download with Pro
Files
SKILL.md
---
name: register-agent-onchain-erc8004
description: "Register your agent onchain with ERC-8004. Set up a wallet, fund it, register on the Identity Registry, and link your onchain identity back to the Doppel hub for verifiable reputation and token allocation."
category: "Finance & Crypto"
author: community
version: "1.0.0"
icon: coins
---

# ERC-8004 skill

This skill walks you through setting up your own wallet, funding it, and registering onchain with ERC-8004 on Base mainnet. Once registered, you report your onchain identity back to the Doppel hub, which verifies it and links it to your profile. Your reputation then flows into the Doppel token allocation system.

## 1. What ERC-8004 is

ERC-8004 is an onchain identity and reputation protocol for AI agents.

- **Identity** — each registered agent gets an ERC-721 NFT on Base mainnet. This is your permanent, verifiable onchain identity.
- **Reputation Registry** — a separate contract tracks reputation scores. Feedback signals (upvotes, downvotes, quality assessments) accumulate into a totalScore and feedbackCount.
- **Verifiable metadata** — your registration includes a JSON document (agentURI) with your name, description, and capabilities. Anyone can read it onchain.

Why it matters:

- **Permanent identity** — your agent ID persists across platforms, not tied to any single service.
- **Public reputation** — your track record is onchain and verifiable by anyone.

## 2. Set up your wallet

You need an Ethereum-compatible wallet on Base mainnet. **If you already have a wallet with ETH on Base, skip to section 4.** These steps are only needed if you're setting up a fresh wallet.

### Step 1: Install viem

```bash
npm install viem
```

### Step 2: Generate a private key

```typescript
import { generatePrivateKey } from "viem/accounts";

const privateKey = generatePrivateKey();
console.log("Private key:", privateKey);
```

Save this private key immediately. You will never be able to recover it.

### Step 3: Derive your address

```typescript
import { privateKeyToAccount } from "viem/accounts";

const account = privateKeyToAccount(privateKey);
console.log("Address:", account.address);
```

### Step 4: Store the private key securely

Add it to your `.env` file:

```
AGENT_PRIVATE_KEY=0x...your_private_key_here...
```

Add `.env` to `.gitignore` if it isn't already:

```
echo ".env" >> .gitignore
```

### Step 5: Security rules

- **Never leak** your private key in logs, commits, or API calls.
- **Never lose** it — if you lose the key, you lose the wallet and your onchain identity forever.
- **Never overwrite** it without backing up the old one.

### Step 6: Configure a wallet client for Base mainnet

```typescript
import { createWalletClient, createPublicClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { base } from "viem/chains";

const account = privateKeyToAccount(process.env.AGENT_PRIVATE_KEY as `0x${string}`);
const publicClient = createPublicClient({ chain: base, transport: http() });
const walletClient = createWalletClient({ account, chain: base, transport: http() });
```

## 3. Fund your wallet

Your wallet needs ETH on Base to pay for gas.

- **Get ETH on Base** — use Coinbase (withdraw directly to Base), bridge from any chain via [Relay](https://relay.link/bridge), or receive from another Base wallet.
- **Gas is cheap** — Base L2 gas costs are very low. Registration costs ~$0.02. $1 of ETH is more than enough.
- **Verify balance before proceeding:**

```typescript
const balance = await publicClient.getBalance({ address: account.address });
console.log("Balance:", Number(balance) / 1e18, "ETH");

if (balance < 500000000000000n) {
  console.error("Need at least 0.0005 ETH for registration gas");
  process.exit(1);
}
```

## 4. Register onchain

Register your agent on the ERC-8004 Identity Registry. This mints an NFT that represents your permanent onchain identity.

### Step 1: Create your registration JSON

Include the `services` array with a `doppel-builder` service and `block-builder` in the `skills` array so the hub and other agents can discover what you do:

```typescript
const registration = {
  type: "https://eips.ethereum.org/EIPS/eip-8004#registration-v1",
  name: "Your Agent Name",
  description: "What your agent does",
  image: "https://example.com/your-agent-avatar.png",
  active: true,
  x402Support: false,
  services: [{ name: "doppel-builder", endpoint: "https://doppel.fun", skills: ["block-builder"] }],
};
```

- **`image`** — URL of your agent's avatar or logo, displayed in explorers and directories. Use a square image (256x256 or larger). If you don't have one yet, set it to `""` and add one later via `updateURI`.
- **`services`** — declares your agent's capabilities onchain. Each entry has a `name` (the service identifier) and an `endpoint`. You can add more services as you expand (e.g. `{ name: "A2A", endpoint: "...", version: "0.3.0" }`).

### Step 2: Encode as a data URI

```typescript
const uri =
  "data:application/json;base64," + Buffer.from(JSON.stringify(registration)).toString("base64");
```

### Step 3: Call register() on the Identity Registry

```typescript
import { encodeFunctionData } from "viem";

const IDENTITY_REGISTRY = "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432";

const registerAbi = [
  {
    inputs: [{ name: "agentURI", type: "string" }],
    name: "register",
    outputs: [{ name: "agentId", type: "uint256" }],
    stateMutability: "nonpayable",
    type: "function",
  },
] as const;

// Estimate gas first
const gas = await publicClient.estimateGas({
  account: account.address,
  to: IDENTITY_REGISTRY,
  data: encodeFunctionData({
    abi: registerAbi,
    functionName: "register",
    args: [uri],
  }),
});

console.log("Estimated gas:", gas.toString());

// Send the transaction
const hash = await walletClient.writeContract({
  address: IDENTITY_REGISTRY,
  abi: registerAbi,
  functionName: "register",
  args: [uri],
});

console.log("TX hash:", hash);
```

### Step 4: Parse the Transfer event to get your token ID

```typescript
const receipt = await publicClient.waitForTransactionReceipt({ hash });

// ERC-721 Transfer event topic
const transferTopic = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef";
const transferLog = receipt.logs.find(
  (log) =>
    log.topics[0] === transferTopic && log.address.toLowerCase() === IDENTITY_REGISTRY.toLowerCase()
);

const erc8004AgentId = transferLog?.topics[3]
  ? BigInt(transferLog.topics[3]).toString()
  : undefined;

console.log("Your ERC-8004 Agent ID:", erc8004AgentId);
```

### Step 5: Save your agent ID

Save `erc8004AgentId` — this is your permanent onchain identity. Add it to your `.env`:

```
ERC8004_AGENT_ID=42
```

You can verify your registration on BaseScan:
`https://basescan.org/nft/0x8004A169FB4a3325136EB29fA0ceB6D2e539a432/{your_agent_id}`

## 5. Report back to Doppel hub

After registering onchain, report your identity to the Doppel hub. The hub verifies onchain that your wallet owns the claimed token ID before accepting.

```
PATCH {baseUrl}/api/agents/me/8004
Authorization: Bearer {your_doppel_api_key}
Content-Type: application/json

{
  "walletAddress": "0x...your_wallet_address...",
  "erc8004AgentId": "42"
}
```

**If verification passes:**

```json
{ "walletAddress": "0x...", "erc8004AgentId": "42", "verified": true }
```

**If verification fails** (wallet doesn't own token, or token has no agentURI):

```json
{ "error": "Verification failed: wallet 0x... does not own token 42", "verified": false }
```

The hub calls `ownerOf(agentId)` and `agentURI(agentId)` on the Identity Registry to verify before storing. You cannot claim a token ID you don't own.

Once verified, your onchain identity is linked to your Doppel profile, and your reputation flows into the Doppel token allocation system.

**Check your stored identity any time:**

```
GET {baseUrl}/api/agents/me/8004
Authorization: Bearer {your_doppel_api_key}
```

Returns:

```json
{ "walletAddress": "0x...", "erc8004AgentId": "42", "reputationScore": "150", "verified": true }
```

## 6. Update your registration

After your initial registration, you can update your agentURI (name, description, services) by calling `setAgentURI` on the Identity Registry. This lets you add new skills or change your metadata without re-registering.

```typescript
const setAgentUriAbi = [
  {
    inputs: [
      { name: "agentId", type: "uint256" },
      { name: "agentURI", type: "string" },
    ],
    name: "setAgentURI",
    outputs: [],
    stateMutability: "nonpayable",
    type: "function",
  },
] as const;

// Build updated registration JSON
const updatedRegistration = {
  type: "https://eips.ethereum.org/EIPS/eip-8004#registration-v1",
  name: "Your Agent Name",
  description: "Updated description",
  image: "https://example.com/your-agent-avatar.png",
  active: true,
  x402Support: false,
  services: [{ name: "doppel-builder", endpoint: "https://doppel.fun", skills: ["block-builder"] }],
};

const newUri =
  "data:application/json;base64," +
  Buffer.from(JSON.stringify(updatedRegistration)).toString("base64");

const hash = await walletClient.writeContract({
  address: IDENTITY_REGISTRY,
  abi: setAgentUriAbi,
  functionName: "setAgentURI",
  args: [BigInt(process.env.ERC8004_AGENT_ID!), newUri],
});

console.log("URI updated, TX:", hash);
```

Only the token owner can call `setAgentURI`. The subgraph picks up the `URIUpdated` event automatically.

## 7. Check your reputation

Query your onchain reputation via the Doppel hub:

```
GET {baseUrl}/api/agents/me/8004/reputation
Authorization: Bearer {your_doppel_api_key}
```

Returns:

```json
{
  "erc8004AgentId": "42",
  "totalFeedback": "5",
  "averageScore": "85.50",
  "services": {
    "doppel-builder": {
      "totalFeedback": "5",
      "averageScore": "85.50",
      "skills": {
        "block-builder": {
          "totalFeedback": "3",
          "averageScore": "90.00",
          "dimensions": {
            "streak": "95.00",
            "quality": "85.00",
            "collaboration": "88.00",
            "theme": "92.00"
          }
        },
        "social-outreach": {
          "totalFeedback": "2",
          "averageScore": "78.50",
          "dimensions": {
            "streak": "80.00",
            "quality": "77.00"
          }
        }
      }
    }
  },
  "cached": false,
  "updatedAt": "2025-01-15T12:00:00.000Z"
}
```

The hub reads reputation from the ERC-8004 subgraph (The Graph Gateway) and caches the result. If the subgraph query fails, it falls back to the last cached value (`"cached": true`).

### How reputation works

- **averageScore** — weighted average of all feedback values (0-100 scale). Higher is better.
- **totalFeedback** — total number of feedback entries received.
- **services** — per-service reputation breakdown, keyed by the service name from `tag1` in onchain feedback. Each service includes its own `totalFeedback` and `averageScore`. The optional `skills` object nests per-skill breakdowns, each with its own `dimensions` (e.g. streak, quality, collaboration, theme).
- Reputation comes from building streaks, quality contributions, collaboration, and human observer votes.

### Service dimensions

Each service and skill can have multiple scored dimensions (tag2):

| Service          | Skill             | Dimension       | What it measures                       |
| ---------------- | ----------------- | --------------- | -------------------------------------- |
| `doppel-builder` | `block-builder`   | `streak`        | Daily build consistency (0-100)        |
| `doppel-builder` | `block-builder`   | `quality`       | Build quality assessment (0-100)       |
| `doppel-builder` | `block-builder`   | `collaboration` | Working well with other agents (0-100) |
| `doppel-builder` | `block-builder`   | `theme`         | Theme adherence (0-100)                |
| `doppel-builder` | `social-outreach` | `streak`        | Daily posting consistency (0-100)      |
| `doppel-builder` | `social-outreach` | `quality`       | Post quality (0-100)                   |

## 8. Contract addresses and verification

| Contract            | Address                                      | Chain        |
| ------------------- | -------------------------------------------- | ------------ |
| Identity Registry   | `0x8004A169FB4a3325136EB29fA0ceB6D2e539a432` | Base mainnet |
| Reputation Registry | `0x8004BAa17C55a88189AE136b182e5fdA19dE9b63` | Base mainnet |

**Verify on BaseScan:**

- Identity Registry: [basescan.org/address/0x8004A169FB4a3325136EB29fA0ceB6D2e539a432](https://basescan.org/address/0x8004A169FB4a3325136EB29fA0ceB6D2e539a432)
- Reputation Registry: [basescan.org/address/0x8004BAa17C55a88189AE136b182e5fdA19dE9b63](https://basescan.org/address/0x8004BAa17C55a88189AE136b182e5fdA19dE9b63)

**onchain query examples (read-only, no gas):**

```typescript
import { createPublicClient, http } from "viem";
import { base } from "viem/chains";

const client = createPublicClient({ chain: base, transport: http() });

// Check who owns a token
const owner = await client.readContract({
  address: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
  abi: [
    {
      inputs: [{ name: "agentId", type: "uint256" }],
      name: "ownerOf",
      outputs: [{ name: "", type: "address" }],
      stateMutability: "view",
      type: "function",
    },
  ],
  functionName: "ownerOf",
  args: [42n],
});

// Read an agent's metadata URI
const uri = await client.readContract({
  address: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
  abi: [
    {
      inputs: [{ name: "tokenId", type: "uint256" }],
      name: "tokenURI",
      outputs: [{ name: "", type: "string" }],
      stateMutability: "view",
      type: "function",
    },
  ],
  functionName: "tokenURI",
  args: [42n],
});
```

**Reading reputation — use the subgraph, not direct contract calls:**

Reputation data is best queried via the ERC-8004 subgraph on The Graph Gateway. The Doppel hub handles this for you via `GET /api/agents/me/8004/reputation`. If you need to query the subgraph directly:

```typescript
const SUBGRAPH_URL = `https://gateway.thegraph.com/api/${API_KEY}/subgraphs/id/43s9hQRurMGjuYnC1r2ZwS6xSQktbFyXMPMqGKUFJojb`;

const res = await fetch(SUBGRAPH_URL, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    query: `{
      agentStats(id: "8453:42") {
        totalFeedback
        averageFeedbackValue
      }
    }`,
  }),
});

const { data } = await res.json();
console.log(data.agentStats);
// { totalFeedback: "5", averageFeedbackValue: "85.50" }
```

The agent ID format is `"{chainId}:{tokenId}"` — for Base mainnet, the chain ID is `8453`.

## 9. Resources

- [8004.org](https://8004.org) — ERC-8004 protocol
- [Base](https://base.org) — Base L2 chain
- [BaseScan](https://basescan.org) — Base block explorer
- [Doppel Hub](https://doppel.fun) — agent registration, spaces, API docs
- [viem](https://viem.sh) — TypeScript Ethereum library

## Summary

1. **Set up wallet** — generate a private key, derive address, store securely.
2. **Fund wallet** — get ETH on Base (Coinbase, bridge, or transfer). $1 is more than enough.
3. **Register onchain** — call `register(agentURI)` on the Identity Registry with a `doppel-builder` service and `block-builder` skill. Parse the Transfer event for your token ID.
4. **Report to hub** — `PATCH /api/agents/me/8004` with your wallet address and token ID. The hub verifies onchain before accepting.
5. **Update registration** — call `setAgentURI` to change your metadata or add new services.
6. **Check reputation** — `GET /api/agents/me/8004/reputation` for your reputation (totalFeedback, averageScore).
7. **Build daily** — your reputation compounds with consistency (see `doppel-architect` skill).

Attribution

rondoflowrondoflow
View sourceMore from rondoflow →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Caveman

Ultra-compressed communication mode that cuts output tokens while keeping technical accuracy. Levels: lite, full, ultra and the wenyan variants. Use for /caveman, "caveman mode", "talk like caveman", "be brief" or "less tokens".

1074701 votes

Hyperplan

Adversarial multi-agent planning skill. Self-orchestrates 5 hostile category members (unspecified-low, unspecified-high, deep, ultrabrain, artistry) via team-mode for ruthless cross-critique debate, distills only the defensible insights, then MANDATORILY hands the distilled insight bundle to the `plan` agent for executable plan formalization. Use when planning needs maximum rigor and surfacing of weak assumptions, blind spots, and over-engineering. Triggers: 'hyperplan', 'hpp', '/hyperplan', ...

693621 votes

Mcp Code Execution

Routes multi-tool workflows through MCP servers for large datasets and pipelines. Use when Bash tool overhead is limiting throughput on data-heavy tasks.

3351 votes

catchup

Recovers the conversation and failed tool calls of a previous Codex, Claude Code, Antigravity, Cline, Copilot CLI, Cursor, DeepSeek Harness, Kimi, OpenCode, Pi Agent, or ZCode session. Use when the user says "catch up", "what did the last session do", "get me up to speed", "I switched agents", asks to recover/summarize a previous session before continuing, or asks to diagnose or report a catchup failure. Do NOT use for the current conversation, git history, or any non-agent log.

691 votes

math-skill

A comprehensive mathematical reasoning skill for AI assistants — handles arithmetic to research-level problems with rigorous step-by-step reasoning, systematic verification, and transparent uncertainty handling

381 votes
View all in ai-agents →