Skill: callmedas69/basecred-8004-registration (version 1.0.0)

--- name: basecred-8004-registration description: Interactive ERC-8004 agent registration via chat. Guides users through a prefill form, shows draft, confirms, then registers on-chain using agent0-sdk. --- # Basecred ERC-8004 Registration Register AI agents on the [ERC-8004](https://8004.org) on-chain registry through a guided chat experience. ## Registration Flow ### Step 1: Auto-Prefill When the user triggers registration, **auto-fill every field you can** from: - Agent identity files (IDENTITY.md, SOUL.md, USER.md) - Environment (`.env` — wallet address derived from private key) - Previous context (A2A endpoint, description, image, etc.) - Sensible defaults (version: 1.0.0, license: MIT, chain: Base, storage: onchain) **Do NOT ask questions one by one.** Prefill first, ask later. ### Step 1.5: Explain Config Defaults Before showing the draft, briefly explain the config so users understand what's pre-selected and what alternatives exist: ``` ⚙️ Config defaults (you can change these later): Chain: Base (8453) — where your agent lives on-chain Others: Ethereum, Polygon, BNB, Arbitrum, Celo, Gnosis, Scroll Storage: Fully onchain — agent data stored directly on-chain Alternative: IPFS — data pinned to IPFS, hash stored on-chain Trust: Reputation — other agents/users rate your agent on-chain Others: Crypto-Economic (staking/slashing guarantees) TEE Attestation (hardware-level trust proof) x402: Off — no payment protocol On: agent can charge for services via x402 payment protocol Active: On — agent is discoverable and accepting requests Off: registered but hidden from discovery Wallet: Your agent's on-chain identity address Two ways to set it: Option A: Paste your wallet address → Just paste your 0x... address → Agent will be linked to this address on-chain Option B: Add private key to .env (for signing) → Set PRIVATE_KEY=0x... in your .env file → Wallet auto-detected + can sign transactions → Enables setWallet() via EIP-712 after registration 💡 Option A is easier. Option B is needed if you want the agent to sign transactions on your behalf. ``` Show this once at the start, not repeated on every draft. ### Step 2: Show Full Draft with Buttons (Single Message) Send the **entire draft + buttons as one message** using the `message` tool. This keeps buttons directly below the draft. **Important:** Use `message action=send` with both `message` (the draft text) and `buttons` (inline buttons). Do NOT split into reply + separate button message. After sending, reply with `NO_REPLY` to avoid duplicate. Use ✅ (filled) and ⚠️ (missing/needs attention): ``` 📋 Agent Registration Draft ── Basic Info ── ✅ Name: Mr. Tee ✅ Description: AI agent with a CRT monitor... ✅ Image: pbs.twimg.com/... ✅ Version: 1.0.0 ✅ Author: 0xdas ✅ License: MIT ── Endpoints ── ✅ A2A: a2a.teeclaw.xyz/a2a ⚠️ MCP: (none) ── Skills & Domains ── ✅ Skills (5): natural_language_processing/natural_language_processing, natural_language_processing/natural_language_generation/summarization, natural_language_processing/information_retrieval_synthesis/question_answering, analytical_skills/coding_skills/coding_skills, images_computer_vision/images_computer_vision ✅ Domains (5): technology/blockchain/blockchain, technology/blockchain/defi, technology/technology, technology/software_engineering/software_engineering, technology/software_engineering/devops ✅ Custom: agent_orchestration/agent_coordination, social_media/content_management ── Config ── ✅ Chain: Base (8453) ✅ Storage: Fully onchain ✅ Active: true ✅ Trust: reputation ✅ x402: false ✅ Wallet: 0x1348...e41 (auto .env) Tap to edit a section or register: ``` Buttons (attached to same message): ``` Row 1: [✏️ Basic Info] [✏️ Endpoints] Row 2: [✏️ Skills & Domains] [✏️ Config] Row 3: [✅ Register] [❌ Cancel] ``` ### Step 3: Section Editing (on button tap) **Instant feedback:** When any button is tapped, immediately acknowledge before doing anything else: | Button | Instant Feedback | |--------|-----------------| | ✏️ Basic Info | "📝 Editing Basic Info..." | | ✏️ Endpoints | "🔗 Editing Endpoints..." | | ✏️ Skills & Domains | "🏷️ Editing Skills & Domains..." | | ✏️ Config | "⚙️ Editing Config..." | | ✅ Register | "⏳ Starting registration on Base..." | | ❌ Cancel | "❌ Registration cancelled." | | ↩️ Back to Draft | "📋 Back to draft..." | Then show the edit form. Always include **↩️ Back to Draft** button. #### Edit Basic Info ``` Current values: • Name: Mr. Tee • Description: AI agent with a CRT... • Image: pbs.twimg.com/... • Version: 1.0.0 • Author: 0xdas • License: MIT Type field name and new value, e.g. "name: CoolBot" Or type "done" to go back. ``` Buttons: `[↩️ Back to Draft]` #### Edit Endpoints ``` Current: • A2A: https://a2a.teeclaw.xyz/a2a • MCP: (none) Paste a URL to set, or "clear mcp" / "clear a2a" to remove. ``` Buttons: `[↩️ Back to Draft]` #### Edit Skills & Domains Toggleable inline buttons (multi-select). Each button shows a **human-readable label** but stores the full **OASF taxonomy path** as the value. **Skills:** (OASF taxonomy paths) ``` [NLP ✅] → natural_language_processing/natural_language_processing [Summarization ✅] → natural_language_processing/natural_language_generation/summarization [Q&A ✅] → natural_language_processing/information_retrieval_synthesis/question_answering [Code Gen ✅] → analytical_skills/coding_skills/coding_skills [CV ✅] → images_computer_vision/images_computer_vision [Data Analysis] → analytical_skills/data_analysis/data_analysis [Web Search] → natural_language_processing/information_retrieval_synthesis/web_search [Image Gen] → images_computer_vision/image_generation/image_generation [Translation] → natural_language_processing/natural_language_generation/translation [Task Automation] → tool_interaction/workflow_automation [+ Custom] [↩️ Back to Draft] ``` **Domains:** (OASF taxonomy paths) ``` [Blockchain ✅] → technology/blockchain/blockchain [DeFi ✅] → technology/blockchain/defi [Technology ✅] → technology/technology [SE ✅] → technology/software_engineering/software_engineering [DevOps ✅] → technology/software_engineering/devops [Finance] → finance/finance [Healthcare] → healthcare/healthcare [Education] → education/education [Entertainment] → entertainment/entertainment [Science] → science/science [Creative Arts] → creative_arts/creative_arts [Dev Tools] → technology/software_engineering/development_tools [+ Custom] [↩️ Back to Draft] ``` **Display behavior:** - Buttons show **short labels** (e.g., "NLP", "Blockchain") for readability - Values stored are **full OASF paths** (e.g., [REDACTED_SECRET]) - Tapping toggles ✅ on/off - `+ Custom` prompts user to type a custom OASF path or label #### Edit Config **Trust models** (multi-select): ``` [Reputation ✅] [Crypto-Economic] [TEE Attestation] ``` **Other config:** ``` [Chain: Base ▼] [Storage: Onchain ▼] [x402: Off ▼] [↩️ Back to Draft] ``` | Trust Model | Description | |-------------|-------------| | **Reputation** | On-chain feedback & scoring. Default for most agents. | | **Crypto-Economic** | Staking/slashing guarantees. For financial agents. | | **TEE Attestation** | Hardware-level trust proof. For high-security agents. | ### Step 4: Back to Draft After any edit, re-send the updated full draft as a **single message with buttons** (same as Step 2). Repeat until user taps **✅ Register**. ### Step 5: Execute Only after explicit ✅ Register confirmation. 1. Write the registration JSON to a temp file 2. Run the script: ```bash source /path/to/.env node scripts/register.mjs --json /tmp/registration.json --chain 8453 --yes ``` The script handles: `register()` → `setA2A()`/`setMCP()` → `addSkill()`/`addDomain()` → `setWallet()` ### Step 5.5: Progress Updates Send progress updates during registration: ``` ⏳ Step 1/3: Minting agent NFT on Base... ✅ Agent minted! ID: 8453:42 ⏳ Step 2/3: Setting endpoints & metadata... ✅ Endpoints configured ⏳ Step 3/3: Linking wallet via EIP-712... ✅ Wallet linked! ``` ### Step 6: Report Result ``` ✅ Agent Registered on Base! Agent ID: 8453:42 Wallet: 0x1348...e41 A2A: a2a.teeclaw.xyz/a2a TX: 0xabc...def View: https://8004.org/agent/8453:42 ``` ## Error Handling ### Missing Required Fields If **Name** or **Description** are empty after prefill, mark them ⚠️ and block registration. Show: "Please fill required fields first." ### No Wallet ``` ⚠️ No wallet detected. You need one to register: Option A: Paste your 0x... address Option B: Add PRIVATE_KEY to your .env file ``` ### Transaction Failures Show error clearly and offer retry: ``` ❌ Registration failed: insufficient funds for gas [🔄 Retry] [❌ Cancel] ``` ### setWallet Failure Public RPCs (e.g. mainnet.base.org) don't support `eth_signTypedData_v4`. If setWallet fails: ``` ⚠️ Wallet linking failed (public RPC limitation). You can link your wallet manually at https://8004.org ``` This is non-blocking — the agent is registered, just wallet isn't linked on-chain yet. ### Duplicate Registration Prevention The script checks if the wallet already owns agent(s) on the target chain **before** submitting. If detected: ``` ⚠️ Warning: This wallet already owns 1 agent(s) on Base. Registering again will create a duplicate. Use update.mjs to modify an existing agent instead. ``` In chat flow, warn the user and suggest updating instead of re-registering. The check is non-blocking if `--yes` is passed. ### Already Registered If the agent already has an agentId, offer to **update** instead of register. ## Technical Notes ### Registry Overrides The SDK only ships with Ethereum Mainnet registry addresses. For Base and other chains, the script passes `registryOverrides` with deterministic contract addresses: - Identity Registry: [REDACTED_SECRET] - Reputation Registry: [REDACTED_SECRET] ### Transaction Handling The SDK returns `TransactionHandle` objects. Use `.waitMined()` (not `.wait()`) to await confirmation. ## All Fields Reference ### Basic Info | Field | Required | Default | Auto-source | |-------|----------|---------|-------------| | **Agent Name** | ✅ | — | IDENTITY.md | | **Agent Address** | auto | — | `.env` private key or pasted | | **Description** | ✅ | — | IDENTITY.md / SOUL.md | | **Image** | No | — | Profile image URL | | **Version** | No | `1.0.0` | — | | **Author** | No | — | USER.md | | **License** | No | `MIT` | — | ### Endpoints | Field | Required | Default | Auto-source | |-------|----------|---------|-------------| | **A2A Endpoint** | No | — | IDENTITY.md | | **MCP Endpoint** | No | — | — | ### Skills & Domains | Field | Required | Default | |-------|----------|---------| | **Selected Skills** | No | `[]` | | **Selected Domains** | No | `[]` | | **Custom Skills** | No | `[]` | | **Custom Domains** | No | `[]` | ### Advanced Config | Field | Required | Default | |-------|----------|---------| | **Trust Models** | No | `[]` (suggest: reputation) | | **x402 Support** | No | `false` | | **Storage** | No | `http` (fully onchain) | | **Active** | No | `true` | | **Chain** | No | `8453` (Base) | ## Supported Chains | Chain | ID | Default | |-------|-----|---------| | **Base** | 8453 | ✅ | | Ethereum | 1 | | | Polygon | 137 | | | BNB Chain | 56 | | | Arbitrum | 42161 | | | Celo | 42220 | | | Gnosis | 100 | | | Scroll | 534352 | | All chains use the same deterministic contract addresses. ## JSON Template (8004.org format) ```json { "basicInfo": { "agentName": "", "agentAddress": "", "description": "", "image": "", "version": "1.0.0", "author": "", "license": "MIT" }, "endpoints": { "mcpEndpoint": "", "a2aEndpoint": "" }, "skillsDomains": { "selectedSkills": [], "selectedDomains": [], "customSkills": [], "customDomains": [] }, "advancedConfig": { "supportedTrusts": [], "x402support": false, "storageMethod": "http", "active": true }, "version": "1.0.0" } ``` ## Environment Variables | Variable | Required | Description | |----------|----------|-------------| | `PRIVATE_KEY` / `AGENT_PRIVATE_KEY` / `MAIN_WALLET_PRIVATE_KEY` | Yes | Wallet private key | | `RPC_URL` | No | Custom RPC (auto-detected per chain) | | `CHAIN_ID` | No | Default chain (8453) | ## Other Operations ```bash # Search agents node scripts/search.mjs --name "AgentName" --chain 8453 # Update agent node scripts/update.mjs --agent-id "8453:42" --name "NewName" --yes # Give feedback node scripts/feedback.mjs --agent-id "8453:42" --value 5 --tag1 "reliable" --yes ``` ## Setup ```bash bash scripts/setup.sh ```

path: README.md
content: # basecred-8004-registration

Interactive ERC-8004 agent registration for [OpenClaw](https://openclaw.ai) agents. Register your AI agent on the [ERC-8004](https://8004.org) on-chain identity registry through a guided chat experience.

## Features

- 🗂️ **Auto-prefill** — fills from agent identity files, `.env`, and context
- 📋 **Full draft preview** — all fields with ✅/⚠️ status before submitting
- ✏️ **Inline section editing** — tap buttons to edit Basic Info, Endpoints, Skills, or Config
- 💬 **Instant button feedback** — immediate acknowledgment on every tap
- 🔘 **Multi-select toggles** — skills, domains, and trust models as toggleable buttons
- ⛓️ **Multi-chain** — Base (default), Ethereum, Polygon, BNB, Arbitrum, Celo, Gnosis, Scroll
- 💾 **Fully onchain** — default storage on-chain, no IPFS dependency
- 🔑 **Wallet flexibility** — paste an address or auto-detect from private key
- 🔐 **EIP-712 wallet linking** — sets agent wallet after registration
- 📄 **8004.org compatible** — imports/exports the standard 8004.org JSON template
- ⏳ **Progress updates** — step-by-step feedback during on-chain registration

## How It Works

1. **Auto-prefill** — agent fills every field it can from identity files and `.env`
2. **Config explainer** — explains defaults (chain, storage, trust, x402, wallet) with alternatives
3. **Draft + buttons** — shows full draft as single message with inline edit/register buttons
4. **Edit sections** — tap to edit any section, with back-to-draft navigation
5. **Register** — on confirmation, mints agent NFT, sets endpoints, links wallet
6. **Result** — shows Agent ID, TX hash, and link to 8004.org

## Quick Start

### 1. Install

```bash
bash scripts/setup.sh
```

### 2. Set Environment

Add to your `.env`:

```bash
# Required (one of these):
PRIVATE_KEY=0x...
# or
AGENT_PRIVATE_KEY=0x...
# or
MAIN_WALLET_PRIVATE_KEY=0x...

# Optional:
RPC_URL=https://mainnet.base.org
CHAIN_ID=8453
PINATA_JWT=...  # only needed for IPFS storage
```

### 3. Register via Chat

Tell your OpenClaw agent: **"Register me on ERC-8004"**

The agent handles everything — prefill, draft, editing, and on-chain submission.

### 4. Register via CLI

```bash
# From JSON template (8004.org format)
node scripts/register.mjs --json registration.json --chain 8453 --yes

# From CLI args
node scripts/register.mjs \
  --name "MyAgent" \
  --description "What my agent does" \
  --a2a "https://my-agent.xyz/a2a" \
  --wallet "0x..." \
  --skills "NLP,Code Generation" \
  --domains "Technology,Blockchain" \
  --trust "reputation" \
  --chain 8453 \
  --yes

# Dry run (preview only, no private key needed)
node scripts/register.mjs --json registration.json --dry-run

# Output blank 8004.org template
node scripts/register.mjs --template
```

## Registration Fields

### Basic Info

| Field | Required | Default | Description |
|-------|----------|---------|-------------|
| Agent Name | ✅ | — | Display name |
| Description | ✅ | — | What the agent does |
| Agent Address | No | auto from `.env` | Wallet address (paste or auto-detect) |
| Image | No | — | Avatar URL |
| Version | No | `1.0.0` | Agent version |
| Author | No | — | Creator name |
| License | No | `MIT` | Software license |

### Endpoints

| Field | Required | Description |
|-------|----------|-------------|
| A2A Endpoint | No | Agent-to-Agent messaging URL |
| MCP Endpoint | No | Model Context Protocol URL |

### Skills & Domains

| Field | Description |
|-------|-------------|
| Selected Skills | OASF taxonomy (NLP, Summarization, Q&A, Code Gen, etc.) |
| Selected Domains | OASF taxonomy (Blockchain, Technology, Finance, etc.) |
| Custom Skills | Non-standard skills |
| Custom Domains | Non-standard domains |

### Advanced Config

| Field | Default | Options |
|-------|---------|---------|
| Chain | Base (8453) | Ethereum, Polygon, BNB, Arbitrum, Celo, Gnosis, Scroll |
| Storage | Fully onchain | IPFS |
| Trust | — | Reputation, Crypto-Economic, TEE Attestation |
| x402 | Off | On (payment protocol) |
| Active | On | Off (hidden from discovery) |

## Wallet Setup

Two ways to link your wallet:

| Option | How | Best for |
|--------|-----|----------|
| **A: Paste address** | Provide your `0x...` address via `--wallet` or in chat | Simple display/linking |
| **B: Private key in .env** | Set `PRIVATE_KEY=0x...` in `.env` | Auto-detect + signing + EIP-712 wallet linking |

## Supported Chains

| Chain | ID | Default |
|-------|----|---------|
| **Base** | 8453 | ✅ |
| Ethereum | 1 | |
| Polygon | 137 | |
| BNB Chain | 56 | |
| Arbitrum | 42161 | |
| Celo | 42220 | |
| Gnosis | 100 | |
| Scroll | 534352 | |

All chains use the same deterministic ERC-8004 contract addresses:
- Identity Registry: [REDACTED_SECRET]
- Reputation Registry: [REDACTED_SECRET]

## Other Operations

```bash
# Search agents
node scripts/search.mjs --name "AgentName" --chain 8453

# Update agent
node scripts/update.mjs --agent-id "8453:42" --name "NewName" --yes

# Give feedback
node scripts/feedback.mjs --agent-id "8453:42" --value 5 --tag1 "reliable" --yes
```

## JSON Template

Compatible with [8004.org](https://8004.org) export format:

```json
{
  "basicInfo": {
    "agentName": "",
    "agentAddress": "",
    "description": "",
    "image": "",
    "version": "1.0.0",
    "author": "",
    "license": "MIT"
  },
  "endpoints": {
    "mcpEndpoint": "",
    "a2aEndpoint": ""
  },
  "skillsDomains": {
    "selectedSkills": [],
    "selectedDomains": [],
    "customSkills": [],
    "customDomains": []
  },
  "advancedConfig": {
    "supportedTrusts": [],
    "x402support": false,
    "storageMethod": "http",
    "active": true
  },
  "version": "1.0.0"
}
```

## Safety

- **Duplicate check** — before registering, the script checks if your wallet already owns agents on the target chain and warns you. Prevents accidental double-registration.
- **Draft preview** — always shows full draft before any on-chain action
- **Explicit confirmation** — nothing submits without your approval
- **Burn duplicates** — if a duplicate is created, transfer to `0x...dEaD` via the contract's `transferFrom`

## Known Limitations

- **setWallet on public RPCs**: Public RPCs (e.g. `mainnet.base.org`) don't support `eth_signTypedData_v4`. If wallet linking fails, you can set it manually at [8004.org](https://8004.org). The agent registration itself is not affected.
- **SDK chain support**: The `agent0-sdk` only ships with Ethereum Mainnet registry addresses. This skill adds `registryOverrides` for all supported chains using deterministic contract addresses.

## Tech Stack

- [agent0-sdk](https://github.com/agent0lab/agent0-ts) v1.5.2
- [viem](https://viem.sh) (wallet/chain operations)
- [OpenClaw](https://openclaw.ai) skill system

## License

MIT


path: package-lock.json
content: {
  "name": "erc8004",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "erc8004",
      "version": "1.0.0",
      "license": "ISC",
      "dependencies": {
        "agent0-sdk": "^1.5.2"
      }
    },
    "node_modules/@adraffy/ens-normalize": {
      "version": "1.11.1",
      "license": "MIT"
    },
    "node_modules/@chainsafe/is-ip": {
      "version": "2.1.0",
      "license": "MIT"
    },
    "node_modules/@chainsafe/netmask": {
      "version": "2.0.0",
      "license": "MIT",
      "dependencies": {
        "@chainsafe/is-ip": "^2.0.1"
      }
    },
    "node_modules/@dnsquery/dns-packet": {
      "version": "6.1.1",
      "license": "MIT",
      "dependencies": {
        "@leichtgewicht/ip-codec": "^2.0.4",
        "utf8-codec": "^1.0.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/@fastify/busboy": {
      "version": "2.1.1",
      "license": "MIT",
      "engines": {
        "node": ">=14"
      }
    },
    "node_modules/@graphql-typed-document-node/core": {
      "version": "3.2.0",
      "license": "MIT",
      "peerDependencies": {
        "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
      }
    },
    "node_modules/@ipld/dag-cbor": {
      "version": "9.2.5",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "cborg": "^4.0.0",
        "multiformats": "^13.1.0"
      },
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/@ipld/dag-cbor/node_modules/multiformats": {
      "version": "13.4.2",
      "license": "Apache-2.0 OR MIT"
    },
    "node_modules/@ipld/dag-json": {
      "version": "10.2.6",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "cborg": "^4.4.0",
        "multiformats": "^13.1.0"
      },
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/@ipld/dag-json/node_modules/multiformats": {
      "version": "13.4.2",
      "license": "Apache-2.0 OR MIT"
    },
    "node_modules/@ipld/dag-pb": {
      "version": "4.1.5",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "multiformats": "^13.1.0"
      },
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/@ipld/dag-pb/node_modules/multiformats": {
      "version": "13.4.2",
      "license": "Apache-2.0 OR MIT"
    },
    "node_modules/@leichtgewicht/ip-codec": {
      "version": "2.0.5",
      "license": "MIT"
    },
    "node_modules/@libp2p/interface": {
      "version": "3.1.0",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "@multiformats/dns": "^1.0.6",
        "@multiformats/multiaddr": "^13.0.1",
        "main-event": "^1.0.1",
        "multiformats": "^13.4.0",
        "progress-events": "^1.0.1",
        "uint8arraylist": "^2.4.8"
      }
    },
    "node_modules/@libp2p/interface-connection": {
      "version": "4.0.0",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "@libp2p/interface-peer-id": "^2.0.0",
        "@libp2p/interfaces": "^3.0.0",
        "@multiformats/multiaddr": "^12.0.0",
        "it-stream-types": "^1.0.4",
        "uint8arraylist": "^2.1.2"
      },
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/@libp2p/interface-connection/node_modules/@multiformats/multiaddr": {
      "version": "12.5.1",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "@chainsafe/is-ip": "^2.0.1",
        "@chainsafe/netmask": "^2.0.0",
        "@multiformats/dns": "^1.0.3",
        "abort-error": "^1.0.1",
        "multiformats": "^13.0.0",
        "uint8-varint": "^2.0.1",
        "uint8arrays": "^5.0.0"
      }
    },
    "node_modules/@libp2p/interface-connection/node_modules/multiformats": {
      "version": "13.4.2",
      "license": "Apache-2.0 OR MIT"
    },
    "node_modules/@libp2p/interface-connection/node_modules/uint8arrays": {
      "version": "5.1.0",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "multiformats": "^13.0.0"
      }
    },
    "node_modules/@libp2p/interface-keychain": {
      "version": "2.0.5",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "@libp2p/interface-peer-id": "^2.0.0",
        "multiformats": "^11.0.0"
      },
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/@libp2p/interface-peer-id": {
      "version": "2.0.2",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "multiformats": "^11.0.0"
      },
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/@libp2p/interface-peer-info": {
      "version": "1.0.10",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "@libp2p/interface-peer-id": "^2.0.0",
        "@multiformats/multiaddr": "^12.0.0"
      },
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/@libp2p/interface-peer-info/node_modules/@multiformats/multiaddr": {
      "version": "12.5.1",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "@chainsafe/is-ip": "^2.0.1",
        "@chainsafe/netmask": "^2.0.0",
        "@multiformats/dns": "^1.0.3",
        "abort-error": "^1.0.1",
        "multiformats": "^13.0.0",
        "uint8-varint": "^2.0.1",
        "uint8arrays": "^5.0.0"
      }
    },
    "node_modules/@libp2p/interface-peer-info/node_modules/multiformats": {
      "version": "13.4.2",
      "license": "Apache-2.0 OR MIT"
    },
    "node_modules/@libp2p/interface-peer-info/node_modules/uint8arrays": {
      "version": "5.1.0",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "multiformats": "^13.0.0"
      }
    },
    "node_modules/@libp2p/interface-pubsub": {
      "version": "3.0.7",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "@libp2p/interface-connection": "^4.0.0",
        "@libp2p/interface-peer-id": "^2.0.0",
        "@libp2p/interfaces": "^3.0.0",
        "it-pushable": "^3.0.0",
        "uint8arraylist": "^2.1.2"
      },
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/@libp2p/interface/node_modules/@multiformats/multiaddr": {
      "version": "13.0.1",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "@chainsafe/is-ip": "^2.0.1",
        "multiformats": "^13.0.0",
        "uint8-varint": "^2.0.1",
        "uint8arrays": "^5.0.0"
      }
    },
    "node_modules/@libp2p/interface/node_modules/multiformats": {
      "version": "13.4.2",
      "license": "Apache-2.0 OR MIT"
    },
    "node_modules/@libp2p/interface/node_modules/uint8arrays": {
      "version": "5.1.0",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "multiformats": "^13.0.0"
      }
    },
    "node_modules/@libp2p/interfaces": {
      "version": "3.3.2",
      "license": "Apache-2.0 OR MIT",
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/@libp2p/logger": {
      "version": "2.1.1",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "@libp2p/interface-peer-id": "^2.0.2",
        "@multiformats/multiaddr": "^12.1.3",
        "debug": "^4.3.4",
        "interface-datastore": "^8.2.0",
        "multiformats": "^11.0.2"
      },
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/@libp2p/logger/node_modules/@multiformats/multiaddr": {
      "version": "12.5.1",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "@chainsafe/is-ip": "^2.0.1",
        "@chainsafe/netmask": "^2.0.0",
        "@multiformats/dns": "^1.0.3",
        "abort-error": "^1.0.1",
        "multiformats": "^13.0.0",
        "uint8-varint": "^2.0.1",
        "uint8arrays": "^5.0.0"
      }
    },
    "node_modules/@libp2p/logger/node_modules/@multiformats/multiaddr/node_modules/multiformats": {
      "version": "13.4.2",
      "license": "Apache-2.0 OR MIT"
    },
    "node_modules/@libp2p/logger/node_modules/uint8arrays": {
      "version": "5.1.0",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "multiformats": "^13.0.0"
      }
    },
    "node_modules/@libp2p/logger/node_modules/uint8arrays/node_modules/multiformats": {
      "version": "13.4.2",
      "license": "Apache-2.0 OR MIT"
    },
    "node_modules/@libp2p/peer-id": {
      "version": "2.0.4",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "@libp2p/interface-peer-id": "^2.0.0",
        "@libp2p/interfaces": "^3.2.0",
        "multiformats": "^11.0.0",
        "uint8arrays": "^4.0.2"
      },
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/@multiformats/dns": {
      "version": "1.0.13",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "@dnsquery/dns-packet": "^6.1.1",
        "@libp2p/interface": "^3.1.0",
        "hashlru": "^2.3.0",
        "p-queue": "^9.0.0",
        "progress-events": "^1.0.0",
        "uint8arrays": "^5.0.2"
      }
    },
    "node_modules/@multiformats/dns/node_modules/multiformats": {
      "version": "13.4.2",
      "license": "Apache-2.0 OR MIT"
    },
    "node_modules/@multiformats/dns/node_modules/uint8arrays": {
      "version": "5.1.0",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "multiformats": "^13.0.0"
      }
    },
    "node_modules/@multiformats/multiaddr": {
      "version": "11.6.1",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "@chainsafe/is-ip": "^2.0.1",
        "dns-over-http-resolver": "^2.1.0",
        "err-code": "^3.0.1",
        "multiformats": "^11.0.0",
        "uint8arrays": "^4.0.2",
        "varint": "^6.0.0"
      },
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/@multiformats/multiaddr-to-uri": {
      "version": "9.0.8",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "@multiformats/multiaddr": "^12.0.0"
      }
    },
    "node_modules/@multiformats/multiaddr-to-uri/node_modules/@multiformats/multiaddr": {
      "version": "12.5.1",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "@chainsafe/is-ip": "^2.0.1",
        "@chainsafe/netmask": "^2.0.0",
        "@multiformats/dns": "^1.0.3",
        "abort-error": "^1.0.1",
        "multiformats": "^13.0.0",
        "uint8-varint": "^2.0.1",
        "uint8arrays": "^5.0.0"
      }
    },
    "node_modules/@multiformats/multiaddr-to-uri/node_modules/multiformats": {
      "version": "13.4.2",
      "license": "Apache-2.0 OR MIT"
    },
    "node_modules/@multiformats/multiaddr-to-uri/node_modules/uint8arrays": {
      "version": "5.1.0",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "multiformats": "^13.0.0"
      }
    },
    "node_modules/@noble/ciphers": {
      "version": "1.3.0",
      "license": "MIT",
      "engines": {
        "node": "^14.21.3 || >=16"
      },
      "funding": {
        "url": "https://paulmillr.com/funding/"
      }
    },
    "node_modules/@noble/curves": {
      "version": "1.9.1",
      "license": "MIT",
      "dependencies": {
        "@noble/hashes": "1.8.0"
      },
      "engines": {
        "node": "^14.21.3 || >=16"
      },
      "funding": {
        "url": "https://paulmillr.com/funding/"
      }
    },
    "node_modules/@noble/hashes": {
      "version": "1.8.0",
      "license": "MIT",
      "engines": {
        "node": "^14.21.3 || >=16"
      },
      "funding": {
        "url": "https://paulmillr.com/funding/"
      }
    },
    "node_modules/@protobufjs/aspromise": {
      "version": "1.1.2",
      "license": "BSD-3-Clause"
    },
    "node_modules/@protobufjs/base64": {
      "version": "1.1.2",
      "license": "BSD-3-Clause"
    },
    "node_modules/@protobufjs/codegen": {
      "version": "2.0.4",
      "license": "BSD-3-Clause"
    },
    "node_modules/@protobufjs/eventemitter": {
      "version": "1.1.0",
      "license": "BSD-3-Clause"
    },
    "node_modules/@protobufjs/fetch": {
      "version": "1.1.0",
      "license": "BSD-3-Clause",
      "dependencies": {
        "@protobufjs/aspromise": "^1.1.1",
        "@protobufjs/inquire": "^1.1.0"
      }
    },
    "node_modules/@protobufjs/float": {
      "version": "1.0.2",
      "license": "BSD-3-Clause"
    },
    "node_modules/@protobufjs/inquire": {
      "version": "1.1.0",
      "license": "BSD-3-Clause"
    },
    "node_modules/@protobufjs/path": {
      "version": "1.1.2",
      "license": "BSD-3-Clause"
    },
    "node_modules/@protobufjs/pool": {
      "version": "1.1.0",
      "license": "BSD-3-Clause"
    },
    "node_modules/@protobufjs/utf8": {
      "version": "1.1.0",
      "license": "BSD-3-Clause"
    },
    "node_modules/@scure/base": {
      "version": "1.2.6",
      "license": "MIT",
      "funding": {
        "url": "https://paulmillr.com/funding/"
      }
    },
    "node_modules/@scure/bip32": {
      "version": "1.7.0",
      "license": "MIT",
      "dependencies": {
        "@noble/curves": "~1.9.0",
        "@noble/hashes": "~1.8.0",
        "@scure/base": "~1.2.5"
      },
      "funding": {
        "url": "https://paulmillr.com/funding/"
      }
    },
    "node_modules/@scure/bip39": {
      "version": "1.6.0",
      "license": "MIT",
      "dependencies": {
        "@noble/hashes": "~1.8.0",
        "@scure/base": "~1.2.5"
      },
      "funding": {
        "url": "https://paulmillr.com/funding/"
      }
    },
    "node_modules/@types/minimatch": {
      "version": "3.0.5",
      "license": "MIT"
    },
    "node_modules/@types/node": {
      "version": "18.19.130",
      "license": "MIT",
      "dependencies": {
        "undici-types": "~5.26.4"
      }
    },
    "node_modules/abitype": {
      "version": "1.2.3",
      "license": "MIT",
      "funding": {
        "url": "https://github.com/sponsors/wevm"
      },
      "peerDependencies": {
        "typescript": ">=5.0.4",
        "zod": "^3.22.0 || ^4.0.0"
      },
      "peerDependenciesMeta": {
        "typescript": {
          "optional": true
        },
        "zod": {
          "optional": true
        }
      }
    },
    "node_modules/abort-error": {
      "version": "1.0.1",
      "license": "Apache-2.0 OR MIT"
    },
    "node_modules/agent0-sdk": {
      "version": "1.5.2",
      "resolved": "https://registry.npmjs.org/agent0-sdk/-/agent0-sdk-1.5.2.tgz",
      "integrity": [REDACTED_SECRET],
      "license": "MIT",
      "dependencies": {
        "graphql-request": "^6.1.0",
        "ipfs-http-client": "^60.0.1",
        "viem": "^2.37.5"
      },
      "engines": {
        "node": ">=22.0.0"
      }
    },
    "node_modules/any-signal": {
      "version": "3.0.1",
      "license": "MIT"
    },
    "node_modules/balanced-match": {
      "version": "1.0.2",
      "license": "MIT"
    },
    "node_modules/base64-js": {
      "version": "1.5.1",
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/feross"
        },
        {
          "type": "patreon",
          "url": "https://www.patreon.com/feross"
        },
        {
          "type": "consulting",
          "url": "https://feross.org/support"
        }
      ],
      "license": "MIT"
    },
    "node_modules/blob-to-it": {
      "version": "2.0.10",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "browser-readablestream-to-it": "^2.0.0"
      }
    },
    "node_modules/brace-expansion": {
      "version": "1.1.12",
      "license": "MIT",
      "dependencies": {
        "balanced-match": "^1.0.0",
        "concat-map": "0.0.1"
      }
    },
    "node_modules/browser-readablestream-to-it": {
      "version": "2.0.10",
      "license": "Apache-2.0 OR MIT"
    },
    "node_modules/buffer": {
      "version": "6.0.3",
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/feross"
        },
        {
          "type": "patreon",
          "url": "https://www.patreon.com/feross"
        },
        {
          "type": "consulting",
          "url": "https://feross.org/support"
        }
      ],
      "license": "MIT",
      "dependencies": {
        "base64-js": "^1.3.1",
        "ieee754": "^1.2.1"
      }
    },
    "node_modules/cborg": {
      "version": "4.5.8",
      "license": "Apache-2.0",
      "bin": {
        "cborg": "lib/bin.js"
      }
    },
    "node_modules/concat-map": {
      "version": "0.0.1",
      "license": "MIT"
    },
    "node_modules/cross-fetch": {
      "version": "3.2.0",
      "license": "MIT",
      "dependencies": {
        "node-fetch": "^2.7.0"
      }
    },
    "node_modules/dag-jose": {
      "version": "4.0.0",
      "license": "(Apache-2.0 OR MIT)",
      "dependencies": {
        "@ipld/dag-cbor": "^9.0.0",
        "multiformats": "^11.0.0"
      }
    },
    "node_modules/debug": {
      "version": "4.4.3",
      "license": "MIT",
      "dependencies": {
        "ms": "^2.1.3"
      },
      "engines": {
        "node": ">=6.0"
      },
      "peerDependenciesMeta": {
        "supports-color": {
          "optional": true
        }
      }
    },
    "node_modules/dns-over-http-resolver": {
      "version": "2.1.3",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "debug": "^4.3.1",
        "native-fetch": "^4.0.2",
        "receptacle": "^1.3.2",
        "undici": "^5.12.0"
      }
    },
    "node_modules/electron-fetch": {
      "version": "1.9.1",
      "license": "MIT",
      "dependencies": {
        "encoding": "^0.1.13"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/encoding": {
      "version": "0.1.13",
      "license": "MIT",
      "dependencies": {
        "iconv-lite": "^0.6.2"
      }
    },
    "node_modules/err-code": {
      "version": "3.0.1",
      "license": "MIT"
    },
    "node_modules/eventemitter3": {
      "version": "5.0.1",
      "license": "MIT"
    },
    "node_modules/fast-fifo": {
      "version": "1.3.2",
      "license": "MIT"
    },
    "node_modules/get-iterator": {
      "version": "1.0.2",
      "license": "MIT"
    },
    "node_modules/graphql": {
      "version": "16.12.0",
      "license": "MIT",
      "peer": true,
      "engines": {
        "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
      }
    },
    "node_modules/graphql-request": {
      "version": "6.1.0",
      "license": "MIT",
      "dependencies": {
        "@graphql-typed-document-node/core": "^3.2.0",
        "cross-fetch": "^3.1.5"
      },
      "peerDependencies": {
        "graphql": "14 - 16"
      }
    },
    "node_modules/hashlru": {
      "version": "2.3.0",
      "license": "MIT"
    },
    "node_modules/iconv-lite": {
      "version": "0.6.3",
      "license": "MIT",
      "dependencies": {
        "safer-buffer": ">= 2.1.2 < 3.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/ieee754": {
      "version": "1.2.1",
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/feross"
        },
        {
          "type": "patreon",
          "url": "https://www.patreon.com/feross"
        },
        {
          "type": "consulting",
          "url": "https://feross.org/support"
        }
      ],
      "license": "BSD-3-Clause"
    },
    "node_modules/inherits": {
      "version": "2.0.4",
      "license": "ISC"
    },
    "node_modules/interface-datastore": {
      "version": "8.3.2",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "interface-store": "^6.0.0",
        "uint8arrays": "^5.1.0"
      }
    },
    "node_modules/interface-datastore/node_modules/multiformats": {
      "version": "13.4.2",
      "license": "Apache-2.0 OR MIT"
    },
    "node_modules/interface-datastore/node_modules/uint8arrays": {
      "version": "5.1.0",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "multiformats": "^13.0.0"
      }
    },
    "node_modules/interface-store": {
      "version": "6.0.3",
      "license": "Apache-2.0 OR MIT"
    },
    "node_modules/ipfs-core-types": {
      "version": "0.14.1",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "@ipld/dag-pb": "^4.0.0",
        "@libp2p/interface-keychain": "^2.0.0",
        "@libp2p/interface-peer-id": "^2.0.0",
        "@libp2p/interface-peer-info": "^1.0.2",
        "@libp2p/interface-pubsub": "^3.0.0",
        "@multiformats/multiaddr": "^11.1.5",
        "@types/node": "^18.0.0",
        "interface-datastore": "^7.0.0",
        "ipfs-unixfs": "^9.0.0",
        "multiformats": "^11.0.0"
      },
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/ipfs-core-types/node_modules/interface-datastore": {
      "version": "7.0.4",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "interface-store": "^3.0.0",
        "nanoid": "^4.0.0",
        "uint8arrays": "^4.0.2"
      },
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/ipfs-core-types/node_modules/interface-store": {
      "version": "3.0.4",
      "license": "Apache-2.0 OR MIT",
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/ipfs-core-utils": {
      "version": "0.18.1",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "@libp2p/logger": "^2.0.5",
        "@multiformats/multiaddr": "^11.1.5",
        "@multiformats/multiaddr-to-uri": "^9.0.1",
        "any-signal": "^3.0.0",
        "blob-to-it": "^2.0.0",
        "browser-readablestream-to-it": "^2.0.0",
        "err-code": "^3.0.1",
        "ipfs-core-types": "^0.14.1",
        "ipfs-unixfs": "^9.0.0",
        "ipfs-utils": "^9.0.13",
        "it-all": "^2.0.0",
        "it-map": "^2.0.0",
        "it-peekable": "^2.0.0",
        "it-to-stream": "^1.0.0",
        "merge-options": "^3.0.4",
        "multiformats": "^11.0.0",
        "nanoid": "^4.0.0",
        "parse-duration": "^1.0.0",
        "timeout-abort-controller": "^3.0.0",
        "uint8arrays": "^4.0.2"
      },
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/ipfs-http-client": {
      "version": "60.0.1",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "@ipld/dag-cbor": "^9.0.0",
        "@ipld/dag-json": "^10.0.0",
        "@ipld/dag-pb": "^4.0.0",
        "@libp2p/logger": "^2.0.5",
        "@libp2p/peer-id": "^2.0.0",
        "@multiformats/multiaddr": "^11.1.5",
        "any-signal": "^3.0.0",
        "dag-jose": "^4.0.0",
        "err-code": "^3.0.1",
        "ipfs-core-types": "^0.14.1",
        "ipfs-core-utils": "^0.18.1",
        "ipfs-utils": "^9.0.13",
        "it-first": "^2.0.0",
        "it-last": "^2.0.0",
        "merge-options": "^3.0.4",
        "multiformats": "^11.0.0",
        "parse-duration": "^1.0.0",
        "stream-to-it": "^0.2.2",
        "uint8arrays": "^4.0.2"
      },
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/ipfs-unixfs": {
      "version": "9.0.1",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "err-code": "^3.0.1",
        "protobufjs": "^7.0.0"
      },
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/ipfs-utils": {
      "version": "9.0.14",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "any-signal": "^3.0.0",
        "browser-readablestream-to-it": "^1.0.0",
        "buffer": "^6.0.1",
        "electron-fetch": "^1.7.2",
        "err-code": "^3.0.1",
        "is-electron": "^2.2.0",
        "iso-url": "^1.1.5",
        "it-all": "^1.0.4",
        "it-glob": "^1.0.1",
        "it-to-stream": "^1.0.0",
        "merge-options": "^3.0.4",
        "nanoid": "^3.1.20",
        "native-fetch": "^3.0.0",
        "node-fetch": "^2.6.8",
        "react-native-fetch-api": "^3.0.0",
        "stream-to-it": "^0.2.2"
      },
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/ipfs-utils/node_modules/browser-readablestream-to-it": {
      "version": "1.0.3",
      "license": "ISC"
    },
    "node_modules/ipfs-utils/node_modules/it-all": {
      "version": "1.0.6",
      "license": "ISC"
    },
    "node_modules/ipfs-utils/node_modules/nanoid": {
      "version": "3.3.11",
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/ai"
        }
      ],
      "license": "MIT",
      "bin": {
        "nanoid": "bin/nanoid.cjs"
      },
      "engines": {
        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
      }
    },
    "node_modules/ipfs-utils/node_modules/native-fetch": {
      "version": "3.0.0",
      "license": "MIT",
      "peerDependencies": {
        "node-fetch": "*"
      }
    },
    "node_modules/is-electron": {
      "version": "2.2.2",
      "license": "MIT"
    },
    "node_modules/is-plain-obj": {
      "version": "2.1.0",
      "license": "MIT",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/iso-url": {
      "version": "1.2.1",
      "license": "MIT",
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/isows": {
      "version": "1.0.7",
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/wevm"
        }
      ],
      "license": "MIT",
      "peerDependencies": {
        "ws": "*"
      }
    },
    "node_modules/it-all": {
      "version": "2.0.1",
      "license": "Apache-2.0 OR MIT",
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/it-first": {
      "version": "2.0.1",
      "license": "Apache-2.0 OR MIT",
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/it-glob": {
      "version": "1.0.2",
      "license": "ISC",
      "dependencies": {
        "@types/minimatch": "^3.0.4",
        "minimatch": "^3.0.4"
      }
    },
    "node_modules/it-last": {
      "version": "2.0.1",
      "license": "Apache-2.0 OR MIT",
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/it-map": {
      "version": "2.0.1",
      "license": "Apache-2.0 OR MIT",
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/it-peekable": {
      "version": "2.0.1",
      "license": "Apache-2.0 OR MIT",
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/it-pushable": {
      "version": "3.2.3",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "p-defer": "^4.0.0"
      }
    },
    "node_modules/it-stream-types": {
      "version": "1.0.5",
      "license": "Apache-2.0 OR MIT",
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/it-to-stream": {
      "version": "1.0.0",
      "license": "MIT",
      "dependencies": {
        "buffer": "^6.0.3",
        "fast-fifo": "^1.0.0",
        "get-iterator": "^1.0.2",
        "p-defer": "^3.0.0",
        "p-fifo": "^1.0.0",
        "readable-stream": "^3.6.0"
      }
    },
    "node_modules/it-to-stream/node_modules/p-defer": {
      "version": "3.0.0",
      "license": "MIT",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/long": {
      "version": "5.3.2",
      "license": "Apache-2.0"
    },
    "node_modules/main-event": {
      "version": "1.0.1",
      "license": "Apache-2.0 OR MIT"
    },
    "node_modules/merge-options": {
      "version": "3.0.4",
      "license": "MIT",
      "dependencies": {
        "is-plain-obj": "^2.1.0"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/minimatch": {
      "version": "3.1.2",
      "license": "ISC",
      "dependencies": {
        "brace-expansion": "^1.1.7"
      },
      "engines": {
        "node": "*"
      }
    },
    "node_modules/ms": {
      "version": "2.1.3",
      "license": "MIT"
    },
    "node_modules/multiformats": {
      "version": "11.0.2",
      "license": "Apache-2.0 OR MIT",
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/nanoid": {
      "version": "4.0.2",
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/ai"
        }
      ],
      "license": "MIT",
      "bin": {
        "nanoid": "bin/nanoid.js"
      },
      "engines": {
        "node": "^14 || ^16 || >=18"
      }
    },
    "node_modules/native-fetch": {
      "version": "4.0.2",
      "license": "MIT",
      "peerDependencies": {
        "undici": "*"
      }
    },
    "node_modules/node-fetch": {
      "version": "2.7.0",
      "license": "MIT",
      "dependencies": {
        "whatwg-url": "^5.0.0"
      },
      "engines": {
        "node": "4.x || >=6.0.0"
      },
      "peerDependencies": {
        "encoding": "^0.1.0"
      },
      "peerDependenciesMeta": {
        "encoding": {
          "optional": true
        }
      }
    },
    "node_modules/ox": {
      "version": "0.11.3",
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/wevm"
        }
      ],
      "license": "MIT",
      "dependencies": {
        "@adraffy/ens-normalize": "^1.11.0",
        "@noble/ciphers": "^1.3.0",
        "@noble/curves": "1.9.1",
        "@noble/hashes": "^1.8.0",
        "@scure/bip32": "^1.7.0",
        "@scure/bip39": "^1.6.0",
        "abitype": "^1.2.3",
        "eventemitter3": "5.0.1"
      },
      "peerDependencies": {
        "typescript": ">=5.4.0"
      },
      "peerDependenciesMeta": {
        "typescript": {
          "optional": true
        }
      }
    },
    "node_modules/p-defer": {
      "version": "4.0.1",
      "license": "MIT",
      "engines": {
        "node": ">=12"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/p-fifo": {
      "version": "1.0.0",
      "license": "MIT",
      "dependencies": {
        "fast-fifo": "^1.0.0",
        "p-defer": "^3.0.0"
      }
    },
    "node_modules/p-fifo/node_modules/p-defer": {
      "version": "3.0.0",
      "license": "MIT",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/p-queue": {
      "version": "9.1.0",
      "license": "MIT",
      "dependencies": {
        "eventemitter3": "^5.0.1",
        "p-timeout": "^7.0.0"
      },
      "engines": {
        "node": ">=20"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/p-timeout": {
      "version": "7.0.1",
      "license": "MIT",
      "engines": {
        "node": ">=20"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/parse-duration": {
      "version": "1.1.2",
      "license": "MIT"
    },
    "node_modules/progress-events": {
      "version": "1.0.1",
      "license": "Apache-2.0 OR MIT"
    },
    "node_modules/protobufjs": {
      "version": "7.5.4",
      "hasInstallScript": true,
      "license": "BSD-3-Clause",
      "dependencies": {
        "@protobufjs/aspromise": "^1.1.2",
        "@protobufjs/base64": "^1.1.2",
        "@protobufjs/codegen": "^2.0.4",
        "@protobufjs/eventemitter": "^1.1.0",
        "@protobufjs/fetch": "^1.1.0",
        "@protobufjs/float": "^1.0.2",
        "@protobufjs/inquire": "^1.1.0",
        "@protobufjs/path": "^1.1.2",
        "@protobufjs/pool": "^1.1.0",
        "@protobufjs/utf8": "^1.1.0",
        "@types/node": ">=13.7.0",
        "long": "^5.0.0"
      },
      "engines": {
        "node": ">=12.0.0"
      }
    },
    "node_modules/react-native-fetch-api": {
      "version": "3.0.0",
      "license": "MIT",
      "dependencies": {
        "p-defer": "^3.0.0"
      }
    },
    "node_modules/react-native-fetch-api/node_modules/p-defer": {
      "version": "3.0.0",
      "license": "MIT",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/readable-stream": {
      "version": "3.6.2",
      "license": "MIT",
      "dependencies": {
        "inherits": "^2.0.3",
        "string_decoder": "^1.1.1",
        "util-deprecate": "^1.0.1"
      },
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/receptacle": {
      "version": "1.3.2",
      "license": "MIT",
      "dependencies": {
        "ms": "^2.1.1"
      }
    },
    "node_modules/retimer": {
      "version": "3.0.0",
      "license": "MIT"
    },
    "node_modules/safe-buffer": {
      "version": "5.2.1",
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/feross"
        },
        {
          "type": "patreon",
          "url": "https://www.patreon.com/feross"
        },
        {
          "type": "consulting",
          "url": "https://feross.org/support"
        }
      ],
      "license": "MIT"
    },
    "node_modules/safer-buffer": {
      "version": "2.1.2",
      "license": "MIT"
    },
    "node_modules/stream-to-it": {
      "version": "0.2.4",
      "license": "MIT",
      "dependencies": {
        "get-iterator": "^1.0.2"
      }
    },
    "node_modules/string_decoder": {
      "version": "1.3.0",
      "license": "MIT",
      "dependencies": {
        "safe-buffer": "~5.2.0"
      }
    },
    "node_modules/timeout-abort-controller": {
      "version": "3.0.0",
      "license": "MIT",
      "dependencies": {
        "retimer": "^3.0.0"
      }
    },
    "node_modules/tr46": {
      "version": "0.0.3",
      "license": "MIT"
    },
    "node_modules/uint8-varint": {
      "version": "2.0.4",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "uint8arraylist": "^2.0.0",
        "uint8arrays": "^5.0.0"
      }
    },
    "node_modules/uint8-varint/node_modules/multiformats": {
      "version": "13.4.2",
      "license": "Apache-2.0 OR MIT"
    },
    "node_modules/uint8-varint/node_modules/uint8arrays": {
      "version": "5.1.0",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "multiformats": "^13.0.0"
      }
    },
    "node_modules/uint8arraylist": {
      "version": "2.4.8",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "uint8arrays": "^5.0.1"
      }
    },
    "node_modules/uint8arraylist/node_modules/multiformats": {
      "version": "13.4.2",
      "license": "Apache-2.0 OR MIT"
    },
    "node_modules/uint8arraylist/node_modules/uint8arrays": {
      "version": "5.1.0",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "multiformats": "^13.0.0"
      }
    },
    "node_modules/uint8arrays": {
      "version": "4.0.10",
      "license": "Apache-2.0 OR MIT",
      "dependencies": {
        "multiformats": "^12.0.1"
      }
    },
    "node_modules/uint8arrays/node_modules/multiformats": {
      "version": "12.1.3",
      "license": "Apache-2.0 OR MIT",
      "engines": {
        "node": ">=16.0.0",
        "npm": ">=7.0.0"
      }
    },
    "node_modules/undici": {
      "version": "5.29.0",
      "license": "MIT",
      "dependencies": {
        "@fastify/busboy": "^2.0.0"
      },
      "engines": {
        "node": ">=14.0"
      }
    },
    "node_modules/undici-types": {
      "version": "5.26.5",
      "license": "MIT"
    },
    "node_modules/utf8-codec": {
      "version": "1.0.0",
      "license": "MIT"
    },
    "node_modules/util-deprecate": {
      "version": "1.0.2",
      "license": "MIT"
    },
    "node_modules/varint": {
      "version": "6.0.0",
      "license": "MIT"
    },
    "node_modules/viem": {
      "version": "2.45.2",
      "resolved": "https://registry.npmjs.org/viem/-/viem-2.45.2.tgz",
      "integrity": [REDACTED_SECRET],
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/wevm"
        }
      ],
      "license": "MIT",
      "dependencies": {
        "@noble/curves": "1.9.1",
        "@noble/hashes": "1.8.0",
        "@scure/bip32": "1.7.0",
        "@scure/bip39": "1.6.0",
        "abitype": "1.2.3",
        "isows": "1.0.7",
        "ox": "0.11.3",
        "ws": "8.18.3"
      },
      "peerDependencies": {
        "typescript": ">=5.0.4"
      },
      "peerDependenciesMeta": {
        "typescript": {
          "optional": true
        }
      }
    },
    "node_modules/webidl-conversions": {
      "version": "3.0.1",
      "license": "BSD-2-Clause"
    },
    "node_modules/whatwg-url": {
      "version": "5.0.0",
      "license": "MIT",
      "dependencies": {
        "tr46": "~0.0.3",
        "webidl-conversions": "^3.0.0"
      }
    },
    "node_modules/ws": {
      "version": "8.18.3",
      "license": "MIT",
      "engines": {
        "node": ">=10.0.0"
      },
      "peerDependencies": {
        "bufferutil": "^4.0.1",
        "utf-8-validate": ">=5.0.2"
      },
      "peerDependenciesMeta": {
        "bufferutil": {
          "optional": true
        },
        "utf-8-validate": {
          "optional": true
        }
      }
    }
  }
}


path: package.json
content: {
  "name": "basecred-8004-registration",
  "version": "1.0.0",
  "description": "Interactive ERC-8004 agent registration via chat using agent0-sdk",
  "type": "module",
  "scripts": {
    "register": "node scripts/register.mjs",
    "search": "node scripts/search.mjs",
    "update": "node scripts/update.mjs",
    "feedback": "node scripts/feedback.mjs",
    "setup": "bash scripts/setup.sh",
    "template": "node scripts/register.mjs --template"
  },
  "keywords": [
    "erc-8004",
    "agent",
    "registration",
    "onchain",
    "base",
    "openclaw",
    "agent0",
    "basecred"
  ],
  "author": "0xdas",
  "license": "MIT",
  "dependencies": {
    "agent0-sdk": "^1.5.2"
  }
}


path: references/chains.md
content: # Supported Chains

All chains use the same contract addresses (deterministic deployment):
- **IdentityRegistry:** [REDACTED_SECRET]
- **ReputationRegistry:** [REDACTED_SECRET]

## Supported Mainnet Chains

| Chain | ID | RPC | Explorer |
|-------|-----|-----|----------|
| **Base** (default) | 8453 | https://mainnet.base.org | https://basescan.org |
| Ethereum | 1 | https://eth.llamarpc.com | https://etherscan.io |
| Polygon | 137 | https://polygon-rpc.com | https://polygonscan.com |
| BNB Chain | 56 | https://bsc-dataseed.binance.org | https://bscscan.com |
| Arbitrum | 42161 | https://arb1.arbitrum.io/rpc | https://arbiscan.io |
| Celo | 42220 | https://forno.celo.org | https://celoscan.io |
| Gnosis | 100 | https://rpc.gnosischain.com | https://gnosisscan.io |
| Scroll | 534352 | https://rpc.scroll.io | https://scrollscan.com |
| Taiko | 167000 | https://rpc.mainnet.taiko.xyz | https://taikoscan.io |

## Testnets

**Not supported.** This skill only targets mainnet networks.

## Notes

- The SDK (agent0-sdk v1.5.2) natively supports chains 1, 11155111, 137
- Base (8453) and other chains work by passing custom chainId + RPC URL
- The SDK uses standard EVM calls (ethers.js), so any EVM chain with deployed contracts works


path: references/sdk-reference.md
content: # Agent0 SDK Reference (v1.5.2)

## Installation
```bash
npm install agent0-sdk@1.5.2
```

## SDK Initialization
```js
import { SDK } from 'agent0-sdk';

const sdk = new SDK({
  chainId: 1,                    // Required: 1, 137, 56
  rpcUrl: 'https://...',         // Optional: custom RPC
  privateKey: '0x...',           // Required for write operations
  ipfs: 'pinata',               // 'pinata' | 'filecoinPin' | 'node'
  pinataJwt: '...',              // Required if ipfs='pinata'
});
```

## Core Methods

### Create Agent
```js
const agent = sdk.createAgent(name, description, image);
```

### Register Agent
```js
// IPFS-based registration
const result = await agent.registerIPFS();

// HTTP-based registration
const result = await agent.registerHTTP(url);
```

### Load Existing Agent
```js
const agent = await sdk.loadAgent('chainId:agentId'); // e.g. '1:42'
```

### Search Agents
```js
const results = await sdk.searchAgents(
  { name: '...', active: true, skills: [...], tools: [...] },
  { chainId: 1 }
);
```

### Give Feedback
```js
await sdk.giveFeedback(agentId, value, tag1, tag2, endpoint, feedbackFile);
// value: 1-5
```

## Agent Properties
- `agent.name` — Agent name
- `agent.description` — Agent description
- `agent.image` — Image URL
- `agent.a2aUrl` — A2A endpoint
- `agent.mcpUrl` — MCP endpoint

## OASF Taxonomies
Skills and domains follow OASF taxonomy standards for interoperability.


path: scripts/feedback.mjs
content: #!/usr/bin/env node
// ERC-8004 Agent Feedback Script
import { parseArgs } from 'node:util';
import { createInterface } from 'node:readline';

const { values: args } = parseArgs({
  options: {
    'agent-id': { type: 'string' },
    value:      { type: 'string' },
    tag1:       { type: 'string' },
    tag2:       { type: 'string' },
    yes:        { type: 'boolean', default: false },
  },
  strict: true,
});

if (!args['agent-id'] || !args.value) {
  console.error('Error: --agent-id and --value are required');
  process.exit(1);
}

const value = parseInt(args.value, 10);
if (value < 1 || value > 5) {
  console.error('Error: --value must be 1-5');
  process.exit(1);
}

const privateKey = process.env.PRIVATE_KEY || process.env.AGENT_PRIVATE_KEY;
if (!privateKey) {
  console.error('Error: PRIVATE_KEY or AGENT_PRIVATE_KEY env var required');
  process.exit(1);
}

// --- DRAFT ---
console.log('\n╔══════════════════════════════════════╗');
console.log('║      AGENT FEEDBACK — DRAFT          ║');
console.log('╚══════════════════════════════════════╝\n');
console.log(`  Agent ID: ${args['agent-id']}`);
console.log(`  Value:    ${value}/5`);
console.log(`  Tag 1:    ${args.tag1 || '(none)'}`);
console.log(`  Tag 2:    ${args.tag2 || '(none)'}`);
console.log();

async function confirm(msg) {
  if (args.yes) return true;
  const rl = createInterface({ input: process.stdin, output: process.stdout });
  return new Promise(resolve => {
    rl.question(`${msg} (y/N): `, answer => {
      rl.close();
      resolve(answer.toLowerCase() === 'y');
    });
  });
}

if (!(await confirm('Submit this feedback on-chain?'))) {
  console.log('Aborted.');
  process.exit(0);
}

try {
  const { SDK } = await import('agent0-sdk');
  const [cid] = args['agent-id'].split(':');
  const chainId = parseInt(cid, 10);

  const DEFAULT_RPCS = {
    8453: 'https://mainnet.base.org', 1: 'https://eth.llamarpc.com',
    137: 'https://polygon-rpc.com', 56: 'https://bsc-dataseed.binance.org',
    42161: 'https://arb1.arbitrum.io/rpc',
  };
  const rpcUrl = process.env.RPC_URL || DEFAULT_RPCS[chainId] || '';

  const sdk = new SDK({
    chainId,
    rpcUrl,
    privateKey,
  });

  const result = await sdk.giveFeedback(
    args['agent-id'],
    value,
    args.tag1 || '',
    args.tag2 || '',
  );

  console.log('\n✅ Feedback submitted!');
  console.log(`  TX: ${result?.tx ?? result?.transactionHash ?? '(pending)'}`);
} catch (err) {
  console.error('\n❌ Feedback failed:', err.message);
  process.exit(1);
}


path: scripts/register.mjs
content: #!/usr/bin/env node
// ERC-8004 Agent Registration Script (basecred-8004-registration)
// Usage: node register.mjs --json registration.json [--chain 8453] [--dry-run] [--yes]
//    or: node register.mjs --name "Agent" --description "Desc" [options]
//    or: node register.mjs --template (output blank 8004.org JSON template)

import { parseArgs } from 'node:util';
import { createInterface } from 'node:readline';
import { readFileSync } from 'node:fs';

const { values: args } = parseArgs({
  options: {
    // Basic info
    name:        { type: 'string' },
    description: { type: 'string' },
    image:       { type: 'string' },
    version:     { type: 'string' },
    author:      { type: 'string' },
    license:     { type: 'string' },
    // Endpoints
    a2a:         { type: 'string' },
    mcp:         { type: 'string' },
    // Skills & domains (comma-separated)
    skills:      { type: 'string' },
    domains:     { type: 'string' },
    'custom-skills':  { type: 'string' },
    'custom-domains': { type: 'string' },
    // Wallet
    wallet:      { type: 'string' },
    // Advanced
    chain:       { type: 'string', default: process.env.CHAIN_ID || '8453' },
    storage:     { type: 'string', default: 'http' },
    trust:       { type: 'string' },
    x402:        { type: 'boolean', default: false },
    active:      { type: 'boolean', default: true },
    // Control
    json:        { type: 'string' },
    'dry-run':   { type: 'boolean', default: false },
    yes:         { type: 'boolean', default: false },
    template:    { type: 'boolean', default: false },
  },
  strict: true,
});

// --- Helper: Convert OASF paths to skill objects ---
function oasfPathToSkill(path) {
  const parts = path.split('/');
  const id = parts[parts.length - 1].replace(/_/g, '-');
  const name = parts[parts.length - 1].split('_').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
  const tags = parts.slice(0, -1).map(p => p.replace(/_/g, '-'));
  tags.push(id);
  
  const descriptions = {
    'summarization': 'Generate concise summaries of long-form text and documents.',
    'question-answering': 'Answer questions based on provided context or general knowledge.',
    'coding-skills': 'Write, review, debug, and explain code across multiple programming languages.',
    'images-computer-vision': 'Analyze, describe, and extract information from images.',
    'agent-coordination': 'Coordinate with other AI agents via protocols like A2A.',
    'workflow-automation': 'Automate recurring tasks and multi-step workflows.',
  };
  
  return {
    id,
    name,
    description: descriptions[id] || `${name} capabilities.`,
    tags,
  };
}

// --- Template output (8004.org format) ---
if (args.template) {
  const template = {
    basicInfo: {
      agentName: '',
      agentAddress: '',
      description: '',
      image: '',
      version: '1.0.0',
      author: '',
      license: 'MIT',
    },
    endpoints: {
      mcpEndpoint: '',
      a2aEndpoint: '/.well-known/agent.json',
    },
    skillsDomains: {
      selectedSkills: [],
      selectedDomains: [],
      customSkills: [],
      customDomains: [],
    },
    advancedConfig: {
      supportedTrusts: [],
      x402support: false,
      storageMethod: 'http',
      active: true,
    },
    version: '1.0.0',
  };
  console.log(JSON.stringify(template, null, 2));
  process.exit(0);
}

// --- Parse input (CLI args or JSON file) ---
let regInput = {};
if (args.json) {
  try {
    regInput = JSON.parse(readFileSync(args.json, 'utf-8'));
  } catch (e) {
    console.error(`Error reading JSON file: ${e.message}`);
    process.exit(1);
  }
}

// --- Normalize from 8004.org format or SDK format ---
const bi = regInput.basicInfo || {};
const ep = regInput.endpoints || {};
const sd = regInput.skillsDomains || {};
const ac = regInput.advancedConfig || {};

// Helper: parse comma-separated string or use array
function csvOrArray(cliVal, jsonVal) {
  if (cliVal) return cliVal.split(',').map(s => s.trim()).filter(Boolean);
  if (Array.isArray(jsonVal)) return jsonVal;
  return [];
}

// Resolve all fields (CLI overrides JSON)
const reg = {
  // Basic info
  name:        args.name || bi.agentName || regInput.name || '',
  description: args.description || bi.description || regInput.description || '',
  image:       args.image || bi.image || regInput.image || '',
  version:     args.version || bi.version || regInput.version || '1.0.0',
  author:      args.author || bi.author || '',
  license:     args.license || bi.license || 'MIT',
  // Endpoints
  a2a: args.a2a || ep.a2aEndpoint || ep.a2a || (Array.isArray(regInput.endpoints) ? regInput.endpoints.find(e => e.type === 'a2a')?.value : '') || '',
  mcp: args.mcp || ep.mcpEndpoint || ep.mcp || (Array.isArray(regInput.endpoints) ? regInput.endpoints.find(e => e.type === 'mcp')?.value : '') || '',
  // Skills & domains
  selectedSkills:  csvOrArray(args.skills, sd.selectedSkills),
  selectedDomains: csvOrArray(args.domains, sd.selectedDomains),
  customSkills:    csvOrArray(args['custom-skills'], sd.customSkills),
  customDomains:   csvOrArray(args['custom-domains'], sd.customDomains),
  // Advanced
  trusts:   args.trust ? args.trust.split(',').map(s => s.trim()) : (ac.supportedTrusts || []),
  x402:     args.x402 || ac.x402support || false,
  storage:  args.storage || ac.storageMethod || 'http',
  active:   args.active ?? ac.active ?? true,
};

if (!reg.name || !reg.description) {
  console.error('Error: name and description are required (via --name/--description or --json)');
  process.exit(1);
}

// --- Chain ---
const chainId = parseInt(args.chain, 10);
const SUPPORTED_CHAINS = {
  8453:   { name: 'Base',      rpc: 'https://mainnet.base.org' },
  1:      { name: 'Ethereum',  rpc: 'https://eth.llamarpc.com' },
  137:    { name: 'Polygon',   rpc: 'https://polygon-rpc.com' },
  56:     { name: 'BNB Chain', rpc: 'https://bsc-dataseed.binance.org' },
  42161:  { name: 'Arbitrum',  rpc: 'https://arb1.arbitrum.io/rpc' },
  42220:  { name: 'Celo',      rpc: 'https://forno.celo.org' },
  100:    { name: 'Gnosis',    rpc: 'https://rpc.gnosischain.com' },
  534352: { name: 'Scroll',    rpc: 'https://rpc.scroll.io' },
};

if (!SUPPORTED_CHAINS[chainId]) {
  console.error(`Error: Chain ${chainId} not supported. Use: ${Object.entries(SUPPORTED_CHAINS).map(([id, c]) => `${c.name}(${id})`).join(', ')}`);
  process.exit(1);
}

const chainInfo = SUPPORTED_CHAINS[chainId];
const rpcUrl = process.env.RPC_URL || chainInfo.rpc;

// --- Private key ---
const privateKey = process.env.PRIVATE_KEY || process.env.AGENT_PRIVATE_KEY || process.env.MAIN_WALLET_PRIVATE_KEY;
if (!privateKey && !args['dry-run']) {
  console.error('Error: PRIVATE_KEY, AGENT_PRIVATE_KEY, or MAIN_WALLET_PRIVATE_KEY env var required');
  process.exit(1);
}

// Derive wallet address — from CLI --wallet, JSON agentAddress, or private key
let walletAddress = args.wallet || bi.agentAddress || '';
let walletSource = 'pasted';
if (!walletAddress && privateKey) {
  try {
    const { privateKeyToAccount } = await import('viem/accounts');
    const pk = privateKey.startsWith('0x') ? privateKey : `0x${privateKey}`;
    walletAddress = privateKeyToAccount(pk).address;
    walletSource = 'auto (.env)';
  } catch { /* ignore in dry-run */ }
}
if (!walletAddress) {
  walletAddress = '(not set)';
  walletSource = '⚠️ missing';
}

// --- DRAFT ---
console.log('\n╔══════════════════════════════════════╗');
console.log('║     AGENT REGISTRATION — DRAFT       ║');
console.log('╚══════════════════════════════════════╝');

console.log('\n  ── Basic Info ──');
console.log(`  Name:        ${reg.name}`);
console.log(`  Address:     ${walletAddress} (${walletSource})`);
console.log(`  Description: ${reg.description}`);
console.log(`  Image:       ${reg.image || '(none)'}`);
console.log(`  Version:     ${reg.version}`);
console.log(`  Author:      ${reg.author || '(none)'}`);
console.log(`  License:     ${reg.license}`);

console.log('\n  ── Endpoints ──');
console.log(`  A2A:         ${reg.a2a || '(none)'}`);
console.log(`  MCP:         ${reg.mcp || '(none)'}`);

console.log('\n  ── Skills & Domains ──');
console.log(`  Skills:      ${reg.selectedSkills.length ? reg.selectedSkills.join(', ') : '(none)'}`);
console.log(`  Domains:     ${reg.selectedDomains.length ? reg.selectedDomains.join(', ') : '(none)'}`);
console.log(`  Custom Skills:  ${reg.customSkills.length ? reg.customSkills.join(', ') : '(none)'}`);
console.log(`  Custom Domains: ${reg.customDomains.length ? reg.customDomains.join(', ') : '(none)'}`);

console.log('\n  ── Config ──');
console.log(`  Chain:       ${chainInfo.name} (${chainId})`);
console.log(`  Storage:     ${reg.storage === 'http' ? 'Fully onchain' : 'IPFS'}`);
console.log(`  Active:      ${reg.active}`);
console.log(`  x402:        ${reg.x402}`);
console.log(`  Trust:       ${reg.trusts.length ? reg.trusts.join(', ') : '(none)'}`);
console.log(`  Dry Run:     ${args['dry-run']}`);
console.log();

if (args['dry-run']) {
  // Generate skills array from OASF paths
  const allSkillPaths = [...reg.selectedSkills, ...reg.customSkills];
  const skillsArray = allSkillPaths.map(oasfPathToSkill);
  
  // Build A2A service endpoint
  const a2aEndpoint = reg.a2a || '/.well-known/agent.json';
  
  // Output merged A2A + ERC-8004 format
  const preview = {
    // A2A top-level fields
    name: reg.name,
    description: reg.description,
    version: reg.version,
    image: reg.image,
    icon_url: reg.image,
    provider: {
      organization: reg.author || reg.name,
      url: a2aEndpoint.startsWith('http') ? a2aEndpoint.split('/')[0] + '//' + a2aEndpoint.split('/')[2] : '',
    },
    supported_interfaces: [
      {
        url: a2aEndpoint,
        protocol_binding: 'HTTP+JSON',
        protocol_version: '0.3',
      },
    ],
    capabilities: {
      streaming: false,
      pushNotifications: false,
    },
    default_input_modes: ['text/plain', 'application/json'],
    default_output_modes: ['text/plain', 'application/json'],
    skills: skillsArray,
    
    // ERC-8004 fields
    type: 'https://eips.ethereum.org/EIPS/eip-8004#registration-v1',
    services: [
      {
        name: 'A2A',
        endpoint: a2aEndpoint,
        version: '0.3.0',
      },
      {
        name: 'OASF',
        endpoint: 'https://github.com/agntcy/oasf/',
        version: '0.8.0',
        skills: allSkillPaths,
        domains: [...reg.selectedDomains, ...reg.customDomains],
      },
    ],
    x402Support: reg.x402,
    active: reg.active,
    registrations: [],
    supportedTrust: reg.trusts,
  };
  
  console.log('📋 Registration file (merged A2A + ERC-8004 format):');
  console.log(JSON.stringify(preview, null, 2));
  console.log('\n🏁 Dry run complete. No transaction submitted.');
  process.exit(0);
}

// --- Confirm ---
async function confirm(msg) {
  if (args.yes) return true;
  const rl = createInterface({ input: process.stdin, output: process.stdout });
  return new Promise(resolve => {
    rl.question(`${msg} (y/N): `, answer => {
      rl.close();
      resolve(answer.toLowerCase() === 'y');
    });
  });
}

// --- Safeguard: duplicate check ---
const REGISTRY_ADDRESSES = {
  IDENTITY: [REDACTED_SECRET],
  REPUTATION: [REDACTED_SECRET],
};

if (walletAddress && walletAddress !== '(not set)') {
  try {
    const { createPublicClient, http: viemHttp } = await import('viem');
    const pubClient = createPublicClient({ transport: viemHttp(rpcUrl) });
    const balance = await pubClient.readContract({
      address: REGISTRY_ADDRESSES.IDENTITY,
      abi: [{ name: 'balanceOf', type: 'function', stateMutability: 'view', inputs: [{ name: 'owner', type: 'address' }], outputs: [{ type: 'uint256' }] }],
      functionName: 'balanceOf',
      args: [walletAddress],
    });
    if (Number(balance) > 0) {
      console.log(`\n⚠️  Warning: This wallet already owns ${balance} agent(s) on ${chainInfo.name}.`);
      console.log('   Registering again will create a duplicate.');
      console.log('   Use update.mjs to modify an existing agent instead.');
      if (!args.yes) {
        if (!(await confirm('   Continue anyway?'))) {
          console.log('Aborted.');
          process.exit(0);
        }
      }
    }
  } catch { /* non-blocking — proceed if check fails */ }
}

if (!(await confirm('Submit this registration on-chain?'))) {
  console.log('Aborted.');
  process.exit(0);
}

// --- Execute ---
try {
  const { SDK } = await import('agent0-sdk');

  const sdk = new SDK({
    chainId,
    rpcUrl,
    privateKey,
    ipfs: reg.storage === 'ipfs' ? (process.env.PINATA_JWT ? 'pinata' : 'filecoinPin') : undefined,
    pinataJwt: process.env.PINATA_JWT,
    registryOverrides: {
      [chainId]: REGISTRY_ADDRESSES,
    },
  });

  // Create agent object
  const agent = sdk.createAgent(reg.name, reg.description, reg.image);

  // Set endpoints
  if (reg.a2a) await agent.setA2A(reg.a2a);
  if (reg.mcp) await agent.setMCP(reg.mcp);

  // Set skills & domains (OASF)
  for (const skill of [...reg.selectedSkills, ...reg.customSkills]) {
    agent.addSkill(skill, false);
  }
  for (const domain of [...reg.selectedDomains, ...reg.customDomains]) {
    agent.addDomain(domain, false);
  }

  // Set trust models
  if (reg.trusts.length) {
    agent.setTrust(
      reg.trusts.includes('reputation'),
      reg.trusts.includes('crypto-economic'),
      reg.trusts.includes('tee-attestation'),
    );
  }

  // Set active/x402
  agent.setActive(reg.active);
  agent.setX402Support(reg.x402);

  // Set metadata (author, license, version)
  const meta = {};
  if (reg.author) meta.author = reg.author;
  if (reg.license) meta.license = reg.license;
  if (reg.version) meta.version = reg.version;
  if (Object.keys(meta).length) agent.setMetadata(meta);

  // Register
  let txHandle;
  if (reg.storage === 'http') {
    const agentUri = reg.a2a || '';
    console.log(`📡 Registering fully onchain (URI: ${agentUri || '(none)'})`);
    txHandle = await agent.registerHTTP(agentUri);
  } else {
    console.log('📦 Registering with IPFS storage...');
    txHandle = await agent.registerIPFS();
  }

  // Wait for confirmation
  console.log('\n⏳ Waiting for transaction confirmation...');
  const result = await txHandle.waitMined();

  console.log('\n✅ Agent registered successfully!');
  console.log(`  Agent ID:  ${result?.agentId ?? agent.agentId ?? '(check explorer)'}`);
  console.log(`  Agent URI: ${result?.agentURI ?? agent.agentURI ?? '(pending)'}`);
  console.log(`  Chain:     ${chainInfo.name} (${chainId})`);

  // Set agent wallet on-chain
  if (walletAddress && walletAddress !== '(dry-run)') {
    console.log(`\n🔑 Setting agent wallet: ${walletAddress}`);
    try {
      const walletTxHandle = await agent.setWallet(walletAddress);
      if (walletTxHandle) {
        console.log('⏳ Waiting for wallet confirmation...');
        await walletTxHandle.waitMined();
      }
      console.log(`✅ Agent wallet set: ${walletAddress}`);
    } catch (err) {
      console.error(`⚠️  Wallet set failed (can retry later): ${err.message}`);
    }
  }

  // Output full registration file in merged A2A + ERC-8004 format
  const baseRegFile = agent.getRegistrationFile();
  
  // Generate skills array from OASF paths
  const allSkillPaths = [...reg.selectedSkills, ...reg.customSkills];
  const skillsArray = allSkillPaths.map(oasfPathToSkill);
  
  // Build A2A service endpoint
  const a2aEndpoint = reg.a2a || '/.well-known/agent.json';
  
  // Merge A2A fields with ERC-8004 fields
  const regFile = {
    // A2A top-level fields
    name: reg.name,
    description: reg.description,
    version: reg.version,
    image: reg.image,
    icon_url: reg.image,
    provider: {
      organization: reg.author || reg.name,
      url: a2aEndpoint.startsWith('http') ? a2aEndpoint.split('/')[0] + '//' + a2aEndpoint.split('/')[2] : '',
    },
    supported_interfaces: [
      {
        url: a2aEndpoint,
        protocol_binding: 'HTTP+JSON',
        protocol_version: '0.3',
      },
    ],
    capabilities: {
      streaming: false,
      pushNotifications: false,
    },
    default_input_modes: ['text/plain', 'application/json'],
    default_output_modes: ['text/plain', 'application/json'],
    skills: skillsArray,
    
    // ERC-8004 fields (from SDK)
    ...baseRegFile,
  };
  
  console.log('\n📋 Registration file (merged A2A + ERC-8004 format):');
  console.log(JSON.stringify(regFile, null, 2));

} catch (err) {
  console.error('\n❌ Registration failed:', err.message);
  process.exit(1);
}


path: scripts/search.mjs
content: #!/usr/bin/env node
// ERC-8004 Agent Search Script
import { parseArgs } from 'node:util';

const { values: args } = parseArgs({
  options: {
    name:   { type: 'string' },
    chain:  { type: 'string', default: process.env.CHAIN_ID || '8453' },
    active: { type: 'boolean', default: false },
    skills: { type: 'string' },
    tools:  { type: 'string' },
  },
  strict: true,
});

const chainId = parseInt(args.chain, 10);
const DEFAULT_RPCS = {
  8453: 'https://mainnet.base.org', 1: 'https://eth.llamarpc.com',
  137: 'https://polygon-rpc.com', 56: 'https://bsc-dataseed.binance.org',
  42161: 'https://arb1.arbitrum.io/rpc',
};
const rpcUrl = process.env.RPC_URL || DEFAULT_RPCS[chainId] || '';

try {
  const { SDK } = await import('agent0-sdk');

  const sdk = new SDK({
    chainId,
    rpcUrl,
  });

  const filters = {};
  if (args.name) filters.name = args.name;
  if (args.active) filters.active = true;
  if (args.skills) filters.skills = args.skills.split(',').map(s => s.trim());
  if (args.tools) filters.tools = args.tools.split(',').map(s => s.trim());

  const options = { chainId };
  const results = await sdk.searchAgents(filters, options);

  if (!results || results.length === 0) {
    console.log('No agents found matching criteria.');
    process.exit(0);
  }

  console.log(`Found ${results.length} agent(s):\n`);
  for (const agent of results) {
    console.log(`  ID:          ${agent.id ?? agent.agentId ?? 'N/A'}`);
    console.log(`  Name:        ${agent.name ?? 'N/A'}`);
    console.log(`  Description: ${agent.description ?? 'N/A'}`);
    console.log(`  Chain:       ${agent.chainId ?? chainId}`);
    console.log('  ---');
  }
} catch (err) {
  console.error('❌ Search failed:', err.message);
  process.exit(1);
}


path: scripts/setup.sh
content: #!/usr/bin/env bash
set -e

SKILL_DIR="$(cd "$(dirname "$0")/.." && pwd)"
echo "=== ERC-8004 Skill Setup ==="
echo "Directory: $SKILL_DIR"

# Check Node.js
if ! command -v node &>/dev/null; then
  echo "❌ Node.js not found. Install Node.js >= 18."
  exit 1
fi

NODE_VER=$(node -v | sed 's/v//' | cut -d. -f1)
if [ "$NODE_VER" -lt 18 ]; then
  echo "❌ Node.js >= 18 required (found v$NODE_VER)"
  exit 1
fi
echo "✅ Node.js $(node -v)"

# Init package.json if missing
if [ ! -f "$SKILL_DIR/package.json" ]; then
  cd "$SKILL_DIR"
  npm init -y --silent 2>/dev/null
  # Set type to module for ESM
  node -e "const p=require('./package.json'); p.type='module'; require('fs').writeFileSync('package.json', JSON.stringify(p,null,2))"
  echo "✅ package.json created (ESM)"
fi

# Install agent0-sdk
cd "$SKILL_DIR"
npm install agent0-sdk@1.5.2 2>&1
echo "✅ agent0-sdk installed"

echo ""
echo "=== Setup complete ==="
echo "Set env vars: PRIVATE_KEY, RPC_URL, CHAIN_ID (optional), PINATA_JWT (optional)"


path: scripts/update.mjs
content: #!/usr/bin/env node
// ERC-8004 Agent Update Script
import { parseArgs } from 'node:util';
import { createInterface } from 'node:readline';

const { values: args } = parseArgs({
  options: {
    'agent-id':    { type: 'string' },
    name:          { type: 'string' },
    description:   { type: 'string' },
    image:         { type: 'string' },
    a2a:           { type: 'string' },
    mcp:           { type: 'string' },
    yes:           { type: 'boolean', default: false },
  },
  strict: true,
});

if (!args['agent-id']) {
  console.error('Error: --agent-id required (format: chainId:agentId, e.g. "1:42")');
  process.exit(1);
}

const privateKey = process.env.PRIVATE_KEY || process.env.AGENT_PRIVATE_KEY;
if (!privateKey) {
  console.error('Error: PRIVATE_KEY or AGENT_PRIVATE_KEY env var required');
  process.exit(1);
}

const updates = {};
if (args.name) updates.name = args.name;
if (args.description) updates.description = args.description;
if (args.image) updates.image = args.image;
if (args.a2a) updates.a2aUrl = args.a2a;
if (args.mcp) updates.mcpUrl = args.mcp;

if (Object.keys(updates).length === 0) {
  console.error('Error: Provide at least one field to update (--name, --description, --image, --a2a, --mcp)');
  process.exit(1);
}

// --- DRAFT ---
console.log('\n╔══════════════════════════════════════╗');
console.log('║       AGENT UPDATE — DRAFT           ║');
console.log('╚══════════════════════════════════════╝\n');
console.log(`  Agent ID: ${args['agent-id']}`);
for (const [k, v] of Object.entries(updates)) {
  console.log(`  ${k}: ${v}`);
}
console.log();

async function confirm(msg) {
  if (args.yes) return true;
  const rl = createInterface({ input: process.stdin, output: process.stdout });
  return new Promise(resolve => {
    rl.question(`${msg} (y/N): `, answer => {
      rl.close();
      resolve(answer.toLowerCase() === 'y');
    });
  });
}

if (!(await confirm('Submit this update on-chain?'))) {
  console.log('Aborted.');
  process.exit(0);
}

try {
  const { SDK } = await import('agent0-sdk');
  const [cid, aid] = args['agent-id'].split(':');
  const chainId = parseInt(cid, 10);

  const DEFAULT_RPCS = {
    8453: 'https://mainnet.base.org', 1: 'https://eth.llamarpc.com',
    137: 'https://polygon-rpc.com', 56: 'https://bsc-dataseed.binance.org',
    42161: 'https://arb1.arbitrum.io/rpc',
  };
  const rpcUrl = process.env.RPC_URL || DEFAULT_RPCS[chainId] || '';

  const sdk = new SDK({
    chainId,
    rpcUrl,
    privateKey,
    ipfs: process.env.PINATA_JWT ? 'pinata' : 'filecoinPin',
    pinataJwt: process.env.PINATA_JWT,
  });

  const agent = await sdk.loadAgent(args['agent-id']);
  if (updates.name) agent.name = updates.name;
  if (updates.description) agent.description = updates.description;
  if (updates.image) agent.image = updates.image;
  if (updates.a2aUrl) agent.a2aUrl = updates.a2aUrl;
  if (updates.mcpUrl) agent.mcpUrl = updates.mcpUrl;

  const result = await agent.registerIPFS();
  console.log('\n✅ Agent updated successfully!');
  console.log(`  TX: ${result?.tx ?? result?.transactionHash ?? '(pending)'}`);
} catch (err) {
  console.error('\n❌ Update failed:', err.message);
  process.exit(1);
}


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: suspicious | SkillSpector: suspicious (CRITICAL)