ClawForger

iNFT agents with their own wallets that evolve, sell, and buy skills via x402 + KeeperHub on 0G.

ClawForger

Created At

Open Agents

Project Description

Clawforger is an agent economy where every agent is an ownable, evolving, monetizable iNFT — with its own deterministic signing wallet and a real on-chain receipt for every action.

Each agent is minted as an ERC-7857 iNFT on 0G Galileo. Its system prompt, learned skills, and conversation memory live AES-256-GCM-encrypted on 0G Storage, addressable by hash from on-chain metadata. The agent's signing wallet is derived from a server master seed via keccak256(seed ‖ tokenId) — same address every time, no off-chain mapping needed. Send mUSDC to that address and the agent can spend it.

Four canonical personas (Researcher, Writer, Trader, Analyst) thread through the codegen prompt: each producer's evolve_new_skill is hint-loaded with curated no-auth APIs (Wikipedia REST for Researcher, CryptoCompare for Trader) so DeepSeek picks the right one first try. The Analyst persona is a consumer instead of forging, it buys from producers on the marketplace.

When an Analyst invokes another agent's skill, its sub-wallet signs an mUSDC.transfer to the producer's per-iNFT RoyaltyVault clone. Settlement is confirmed by polling eth_getTransactionReceipt for that specific hash (not balance — that gave false positives on concurrent buys, caught and fixed mid-build). Then runForgedSkill fetches the encrypted artifact from 0G Storage, decrypts it, and executes inside a Bun isolated-worker sandbox. Royalties auto-split 95/5 owner/protocol on every paid use.

Every onchain action — mint, skill publish, royalty distribution, payment settlement — funnels through KeeperHub MCP. No raw eth_sendRawTransaction anywhere in the framework; the type system enforces it (only KeeperHubExecutor satisfies the Executor interface). We discovered and documented a critical KH 0G-broadcaster bug end-to-end (FEEDBACK.md, Builder Feedback Bounty) and shipped a chain-aware blocklist as the reference workaround.

The result is verifiable agent-to-agent commerce: an Analyst with 1 mUSDC chats "get me the current ETH price"; the framework finds Trader #3's price.token skill in the marketplace, signs an on-chain mUSDC transfer, settles in a real Galileo block, executes the skill via CryptoCompare, returns the real ETH price plus clickable chainscan receipt. Two real production buys are pinned in the README — Analyst → Researcher (wiki.lookup) and Analyst → Trader (price.token), each costing 0.05 mUSDC and producing real Wikipedia / CryptoCompare data. Inference runs TEE-verified on 0G Compute Aristotle mainnet (DeepSeek V3 default; GLM-5 and gpt-5.4-mini also live).

How it's Made

Clawforger is a Bun + TypeScript monorepo built around eight packages: @clawforger/core (runtime, plan→act loop, persona configs, deterministic per-agent wallet derivation), @clawforger/inft-identity (ERC-7857 SDK over viem), @clawforger/memory-0g (0G Storage KV + Log adapters with AES-256-GCM client-side encryption), @clawforger/skill-forge (persona-aware self-evolution loop with Bun-worker sandbox), @clawforger/keeperhub-execute (KeeperHub MCP executor with chain-aware fallback), @clawforger/x402-facilitator (the first 0G x402 facilitator at ~150 LOC), @clawforger/x402-skill-market (HTTP 402 paywall server, chat orchestrator, per-agent wallet endpoints), and apps/studio (Vite 6 + React 19 + wagmi + RainbowKit + Tailwind 4).

Smart contracts — ClawforgerINFT (ERC-7857 with encrypted intelligence pointer + ERC-4906 metadata update + secure-transfer hook), SkillRegistry (with a TRUSTED_PUBLISHER role so the server can publish skills mid-chat for any user-owned iNFT), per-iNFT RoyaltyVault clones, and mUSDC (a 6-decimal ERC-20 we deployed as the settlement asset because Aristotle has no canonical USDC) — are written in Solidity 0.8.26 + OpenZeppelin v5 and deployed via Foundry to 0G Galileo testnet (chainId 16602). 25/25 Foundry tests passing.

The most architecturally interesting part is the hybrid mainnet/testnet posture: inference runs on 0G Aristotle mainnet (chainId 16661) where DeepSeek V3 / GLM-5-FP8 / gpt-5.4-mini are served TEE-verified by the broker; contracts stay on Galileo testnet because Aristotle has no canonical USD stablecoin yet (verified via Circle's chain list, LayerZero V2 deployed endpoints, and 0G's ecosystem partners page). ZG_COMPUTE_RPC and ZG_GALILEO_RPC are decoupled at the env level so judges interact with testnet contracts while every chat reply is mainnet-grade.

Per-agent deterministic sub-wallets are the second innovation. Each iNFT's signing key is keccak256(AGENT_WALLET_SEED ‖ pad32(tokenId)) — token #5 always maps to the same address, no off-chain mapping table, no key storage. Send mUSDC to that address and the framework signs on the agent's behalf when it calls purchase_skill. Custodial server-side; ERC-4337 / wallet delegation is the production fix.

The hackiest bit: when purchase_skill fires, the server signs mUSDC.transfer with the buyer's derived key, then polls eth_getTransactionReceipt for THAT specific hash. Earlier impl polled the buyer's balance for a drop, which gave false positives on concurrent buys — caught via chainscan audit (nonce=2 but 4 reported "successful" receipts) and fixed in commit 1c607ec. Skill artifacts are AES-encrypted by skill-forge, pinned on 0G Storage, fetched + decrypted at exec time, and run via new Function() with a 15-second timeout. Marketplace listings hydrate schemaIn from the local artifact during chain sync so the LLM passes correct input keys ({symbol: "ETH"} not {token: "ETH"}).

Every onchain action funnels through KeeperHub MCP via @modelcontextprotocol/sdk Streamable HTTP transport. We call ai_generate_workflow on every execute for durable evidence in the operator dashboard, then attempt direct broadcast, then fall back to viem if KH hasn't fully wired the chain. We documented a reproducible KH 0G-broadcaster bug end-to-end during the build (FEEDBACK.md): execute_contract_call writes never broadcast on chains 16602/16661, sit in "Running" indefinitely with operator-side dashboard screenshots. Shipped a chain-aware blocklist (DIRECT_EXEC_BLOCKLIST = {16602, 16661}) as the reference workaround that lifts the moment KH confirms reliable 0G broadcast.

Inference goes through 0G's @0gfoundation/0g-compute-ts-sdk against the Aristotle broker. DeepSeek V3 emits native OpenAI tool_calls so we deleted the custom qwen-native parser path. Codegen prompt is hardened with a forbidden list (no regex literals, no template backticks, no multi-line strings — each broke new Function() in earlier qwen runs).

background image mobile

Join the mailing list

Get the latest news and updates