Skip to content

1clawAI/scaffold-agent

Repository files navigation

scaffold-agent

Interactive CLI to scaffold monorepo projects for onchain AI agents.

AI / agent tools: see AGENTS.md (shared instructions). Claude Code uses CLAUDE.md (imports AGENTS.md). Cursor skill: .cursor/skills/scaffold-agent/.

Prerequisites

  • Node.js and npm — for npx scaffold-agent@latest and the generated workspace.
  • just — installed separately (not an npm dependency). Generated repos use a root justfile for just chain, just deploy, just start, etc. See installation (e.g. brew install just, or a prebuilt binary).

Without just, you can still run the underlying npm run / npx scripts from the generated README.md, but the docs and defaults assume just is on your PATH.

Basic flow

Typical path when you picked Foundry or Hardhat and want a local node on http://127.0.0.1:8545:

  1. Scaffold the monorepo

    npx scaffold-agent@latest
    # or create `my-agent/` directly (skips the project name prompt):
    npx scaffold-agent@latest my-agent
  2. Enter the project (replace my-agent with the folder name you chose)

    cd my-agent
  3. Run the local chain — use a second terminal; the node must be up before just fund / just deploy.

    just chain
  4. Fund the deployer (and optional agent address from .env)

    just fund
  5. Deploy contracts and refresh generated ABI types

    just deploy
  6. Start the app

    just start
  7. Open the UI — Next.js / Vite dev server is usually http://localhost:3000.

Shortcut: with a local chain, you can run just quickstart instead of steps 3–6 (starts chain in the background, funds, deploys, then starts the app).

Health check: run just doctor anytime to validate tools, .env, encrypted secrets, 1Claw IDs, and package installs.

If you skipped a chain in the wizard, omit steps 3–5 and point scaffold.config.ts (and RPC env vars) at the network you use, then just deploy / just start as your project README describes. If npm install didn’t run during scaffold, run it once at the repo root before just start. Python (A2A) projects follow the same just commands where applicable; see the generated README.

Usage

Published on npm as scaffold-agent. The CLI binary is also scaffold-agent.

npx scaffold-agent@latest
npx scaffold-agent@latest my-agent   # creates ./my-agent (skips project name prompt)

(@latest is the default dist-tag — you can omit it.)

CLI flags: Run scaffold-agent --help / -h for the full list (every wizard step has a flag; unknown options error). --version / -V. Optional argument: project-name — directory to create (same rules as the interactive prompt: letters, numbers, -, _), or use --project <name>.

Non-interactive / automation: --non-interactive / -y runs with no prompts. Set --env-password when --secrets is oneclaw or encrypted (min 6 characters). Omitted choices use documented defaults in --help (e.g. Foundry + Next.js + 1Claw Shroud token billing). Use --skip-npm-install and --skip-auto-fund to match the env vars below. With Intents: --oneclaw-intents and optional --oneclaw-signing-chains ethereum,solana (see --help).

Config file: --from-config agent.json merges JSON into the wizard (CLI flags override the file). Use --dump-config or --dump-config-out <file> to print or save that shape; secret values are omitted from the dump. --swarm <n> (1–64) generates multiple agent wallets; Next/Vite apps get a public agents.json roster, header agent picker, and /swarm page. Details: AGENTS.md.

After the project is written, the CLI runs npm install at the monorepo root (workspaces install all packages). Set SCAFFOLD_SKIP_NPM_INSTALL=1 or --skip-npm-install to skip (e.g. offline or you use another package manager).

The wizard walks through:

  1. Project name — directory to create (skipped if you pass it as the first argument, e.g. scaffold-agent my-agent)
  2. Secrets management — 1Claw (HSM-backed vault), encrypted secrets file, or plain .env
  3. Agent identity — generate one or more Ethereum wallets (--swarm for many)
  4. Ampersend SDK — optional; adds @ampersend_ai/ampersend-sdk + AMPERSEND.md (docs.ampersend.ai, GitHub). Prompts for your Ampersend signing key and stores it in the 1Claw vault (private-keys/ampersend-signing) or encrypted .env; generated apps fetch it at runtime for x402 payments.
  5. LLM Provider — 1Claw, Gemini, OpenAI, or Anthropic
  6. Chain framework — Foundry, Hardhat, or none
  7. App framework — Next.js, Vite, or Python (Google A2A)

At the end it displays QR codes for the Deployer and Agent addresses. If you picked a chain, the CLI also runs scripts/fund-deployer.mjs (same as just fund). Order matters: auto-fund only succeeds if a node is already listening on RPC_URL (default http://127.0.0.1:8545). Most people run just chain first, then scaffold in another terminal—or run just fund after cd into the project. Set SCAFFOLD_SKIP_AUTO_FUND=1 or --skip-auto-fund to skip. just generate tries the same auto-fund when you create a deployer.

What gets created

my-agent/
├── justfile                      # just chain / deploy / start / generate
├── scripts/
│   ├── secrets-crypto.mjs        # encrypt/decrypt .env.secrets.encrypted
│   ├── with-secrets.mjs          # prompt password, run deploy/start with env
│   ├── secret-add.mjs            # just env / enc / vault / reown
│   ├── deploy-foundry.mjs        # or deploy-hardhat.mjs
│   ├── generate-abi-types.mjs    # auto-gen TypeScript from contract ABIs
│   ├── generate-deployer.mjs     # create deployer wallet if missing (+ auto-fund if RPC up)
│   ├── fund-deployer.mjs         # fund deployer + agents (incl. swarm roster in public/agents.json)
│   ├── check-network.mjs         # validate targetNetwork has deployed contracts
│   ├── doctor.mjs                # just doctor — health check
│   └── swarm-agents.mjs          # just swarm — append wallets (Next/Vite)
├── packages/
│   ├── foundry/                  # or hardhat/ (Solidity contracts)
│   └── nextjs/                   # or vite/ or python/ (frontend / agent)
│       ├── public/agents.json    # swarm roster (addresses only; Next/Vite)
│       ├── app/
│       │   ├── layout.tsx        # root layout + shared Header nav
│       │   ├── page.tsx          # chat UI (suggested prompts, no inline header)
│       │   ├── identity/page.tsx # ERC-8004 / Agent0 identity + register
│       │   ├── balances/page.tsx # deployer + agent balances
│       │   ├── ens/page.tsx      # ENS resolution + registration links
│       │   ├── swarm/page.tsx    # swarm list + local keygen hints
│       │   ├── debug/page.tsx    # deployed contracts (Next only)
│       │   └── api/
│       │       ├── chat/route.ts # LLM streaming API
│       │       └── agent0/lookup/route.ts # server-side registry search
│       ├── components/
│       │   ├── Header.tsx        # shared nav (Chat, Balances, ENS, Identity, Swarm, Debug)
│       │   └── ui/               # shadcn Button, Input
│       ├── contracts/            # auto-generated ABI types
│       └── ...
├── .cursor/mcp.json              # 1Claw MCP for Cursor (when 1Claw is selected)
├── .mcp.json                     # 1Claw MCP for Claude Code (same server config)
├── .env                          # non-sensitive config (gitignored)
├── .env.secrets.encrypted        # AES-256-GCM encrypted API keys & private keys (gitignored)
├── .gitignore
├── package.json                  # monorepo root
└── README.md

Commands (via just)

Command Description
just chain Start local blockchain (Foundry/Hardhat)
just fund Fund DEPLOYER_ADDRESS, AGENT_ADDRESS, and swarm addresses in packages/*/public/agents.json (100 ETH each from account #0)
just deploy Deploy contracts & auto-gen ABIs (prompts for secrets password if encrypted)
just start Start frontend or agent (runs check-network first as a warning)
just quickstart One-command local setup: chain (background) → fund → deploy → start (Foundry/Hardhat + UI)
just doctor Health check: validate env, tools, 1Claw IDs, and package installs
just check-network Validate targetNetwork chainId has contracts in deployedContracts.ts
just use-network KEY Switch targetNetwork in scaffold.config.ts and run check (keys: ethereum, base, sepolia, baseSepolia, polygon, bnb, localhost)
just accounts Show QR codes for DEPLOYER_ADDRESS + agent address (repo-root .env)
just balances Native balance on all chains in network-definitions (deployer + agent; rpcOverrides)
just generate Generate deployer wallet (password prompt if encrypted)
just swarm agents=N Add N swarm wallets (public/agents.json + SWARM_AGENT_KEYS_JSON; Next/Vite; default agents=1)
just env KEY VALUE Upsert repo-root .env (e.g. NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID)
just enc KEY VALUE Update .env.secrets.encrypted (password prompt)
just vault PATH VALUE Store a secret in the 1Claw vault (wraps with-secrets)
just list-1claw Print vault + agent UUIDs from the 1Claw API (ONECLAW_API_KEY)
just sync-1claw-env List + write first vault + agent UUID into repo-root .env
just reset Re-bootstrap 1Claw (new vault + agent; read warning first)
just reown PROJECT_ID WalletConnect Cloud id → .env (Next: NEXT_PUBLIC_…, Vite: VITE_…)

ABI type generation

just deploy automatically parses compiled contract artifacts and generates deployedContracts.ts — the same pattern used by Scaffold-ETH 2. This gives you type-safe contract addresses and ABIs in your frontend code.

Next.js apps get a shared Header with nav tabs (Chat, Balances, ENS, Identity, Swarm, Debug) and /debug: read-only view of deployed addresses and ABI via Scaffold UI, similar to Scaffold-ETH 2 Debug Contracts.

Unified network model

Generated projects use a single source of truth for the active EVM network:

  • scaffold.config.ts defines targetNetwork (e.g. "localhost", "base", "sepolia") and optional rpcOverrides.
  • getActiveNetwork() resolves the full NetworkDefinition (chainId, RPC, block explorer) with overrides applied.
  • AI agent tools (lib/agent-onchain-tools.ts) default chainId and chain parameters to the active network — the model doesn't need to guess.
  • just check-network validates that deployedContracts.ts has entries for targetNetwork's chainId.
  • just use-network <key> rewrites targetNetwork and runs the check in one step.
  • just start runs check-network as a precheck (warns if contracts are missing, but doesn't block the dev server).

Agent on-chain tools

Next.js and Vite projects include lib/agent-onchain-tools.ts — preset Vercel AI SDK tools wired into the chat route:

  • list_deployed_contracts — enumerate addresses from deployedContracts.ts (hints active chain).
  • contract_read — call any view/pure function via RPC using the deployed ABI (defaults to active network).
  • oneclaw_intent_simulate — simulate a transaction via 1Claw Intents + Tenderly (when 1Claw SDK is included).
  • oneclaw_intent_submit — submit a signed transaction intent to 1Claw's HSM/TEE (keys never in the model).
  • oneclaw_intent_sign_only — sign a transaction without broadcasting (BYORPC — for MEV protection, Flashbots, custom relayers).
  • oneclaw_list_signing_keys — list the agent's HSM-backed signing keys (address, chain, status).
  • oneclaw_list_transactions — list recent Intents API transactions for this agent.

When Ampersend is enabled, the chat route also exposes x402_paid_fetch for paid HTTP requests over x402.

The 1Claw intent tools default the chain parameter to the active network's 1Claw slug via ONECLAW_CHAIN_NAMES — covering all 29 EVM mainnets, testnets, plus non-EVM chains (Bitcoin, Solana, XRP, Cardano, Tron).

Route loading & frontend performance

Next.js: app/loading.tsx plus per-route loading.tsx under /identity, /balances, /debug, /ens, /swarm show a header + card skeleton as soon as you navigate, while the route’s JavaScript loads (especially noticeable in dev). npm run dev uses next dev --turbo. next.config.js sets experimental.optimizePackageImports: ["lucide-react"] so icon imports tree-shake instead of pulling the whole package. Wagmi’s React Query client uses 30s staleTime to reduce background refetching.

Vite: /identity, /ens, /balances, and /swarm are loaded with React.lazy and a shared PageLoading skeleton so those chunks download only when you open those routes (home Chat stays eager).

UX / a11y (both stacks): 1Claw-inspired dark theme (crimson accent, Inter font, sticky glass header), skip to main content link (keyboard), visible :focus-visible rings on interactive controls, chat role landmarks, suggested prompts on the empty chat state, and context-aware error hints (Gemini quota vs 1Claw vs generic env). Local faucet uses an in-app toast instead of window.alert; Balances explains when no ERC-20 tokens are configured for the chain.

1Claw IDs programmatically

With your user ONECLAW_API_KEY you can call the same REST API the CLI uses:

  • POST /v1/auth/api-key-token → Bearer token
  • GET /v1/vaults → vault UUIDs (ONECLAW_VAULT_ID)
  • GET /v1/agents → agent UUIDs (ONECLAW_AGENT_ID)

Scaffolded 1Claw projects include just list-1claw (runs scripts/list-1claw-ids.mjs under with-secrets when needed) and just sync-1claw-env to write the first listed vault + agent UUIDs into repo-root .env.

Agent API keys (ONECLAW_AGENT_API_KEY / ocv_…) are not returned by list endpoints — only when you create an agent (POST /v1/agents, as in setupOneClaw) or rotate via @1claw/sdk client.agents.rotateKey(id).

1Claw integration

When you choose 1Claw (1claw.xyz), the CLI:

  • Authenticates with your ONECLAW_API_KEY
  • Creates a vault for the project and writes ONECLAW_VAULT_ID into .env when you enter the API key during setup and vault creation succeeds. If you skip the key (“add later”) or setup fails, ONECLAW_VAULT_ID stays blank — then run just sync-1claw-env (with your key loaded) or just list-1claw and paste IDs (or copy from the dashboard).
  • Stores the deployer private key at private-keys/deployer in the vault (not on disk)
  • If agent identity is generated, stores it at private-keys/agent and registers the agent
  • If you pick Gemini, OpenAI, or Anthropic as the LLM, the CLI can store that provider’s API key in the vault as llm-api-key (optional — you can add it later in the dashboard)
  • If you pick 1Claw as the LLM, chat uses Shroud. During setup the CLI registers a 1Claw agent (unless you already get one from generating an on-chain agent wallet) and writes ONECLAW_AGENT_ID + ONECLAW_AGENT_API_KEY to your env when vault creation succeeds — you don’t need to paste them manually. The Shroud agent UUID is not your Ethereum AGENT_ADDRESS. With vault BYOK, set ONECLAW_VAULT_ID too or Shroud’s vault://… header is invalid. You choose an upstream provider — openai, anthropic, google / gemini, mistral, cohere, openrouter, darkbloom (E2E encrypted Apple Silicon TEE), or venice (zero-retention + optional TEE/E2EE) (SHROUD_LLM_PROVIDER); Shroud proxies to it. The CLI asks how upstream LLM usage is paid:
    • LLM Token Billing on 1claw.xyz — set SHROUD_BILLING_MODE=token_billing; no provider key.
    • Your own API key — set SHROUD_BILLING_MODE=provider_api_key. With 1Claw secrets, the key can live in the vault at api-keys/openai, api-keys/gemini, etc. (the chat route sends vault://… as X-Shroud-Api-Key). Without 1Claw vault, use SHROUD_PROVIDER_API_KEY in .env.

HSM signing key provisioning

When 1Claw Intents is enabled (--oneclaw-intents), the CLI provisions HSM signing keys via POST /v1/agents/:id/signing-keys for each chain you select. Interactive runs show a multi-select; non-interactive runs use --oneclaw-signing-chains (comma-separated: ethereum, bitcoin, solana, xrp, cardano, tron; default ethereum). Keys are generated inside the __agent-keys vault — never exposed. The CLI prints each address with a testnet faucet link and dashboard deep links (https://1claw.xyz/vaults, https://1claw.xyz/agents/<id>). Additional chains can be provisioned later via the 1Claw dashboard or SDK.

MCP server

When 1Claw is selected (secrets or LLM), the scaffold generates .cursor/mcp.json (Cursor) and .mcp.json (Claude Code) with the @1claw/mcp server pre-configured. This gives AI agents access to 44 MCP tools: vault secrets, Intents API (simulate, submit, sign), signing key management, treasury proposals, and execution intents. Only ONECLAW_AGENT_API_KEY is required — agent ID and vault are auto-discovered.

LLM providers

Choice Auth / keys Notes
1Claw (LLM) .env: agent + SHROUD_LLM_PROVIDER, SHROUD_BILLING_MODE Shroud; optional SHROUD_BASE_URL, SHROUD_DEFAULT_MODEL. If BYOK + vault: SHROUD_PROVIDER_VAULT_PATH / api-keys/…; if BYOK + no vault: SHROUD_PROVIDER_API_KEY
Gemini / OpenAI / Anthropic + 1Claw secrets Vault: llm-api-key Fetched by the app’s chat route (not Shroud path)
Gemini / OpenAI / Anthropic + no 1Claw secrets .env provider env vars CLI can prompt to fill .env

Shroud upstreams and default models

Supported SHROUD_LLM_PROVIDER values match scaffold-agent --shroud-upstream: openai, anthropic, google, gemini, mistral, cohere, openrouter, darkbloom, venice. The scaffold writes SHROUD_DEFAULT_MODEL into repo-root .env using this table; change it anytime (ids must be valid for that upstream and for Shroud; OpenRouter uses provider/model slugs from openrouter.ai/models).

SHROUD_LLM_PROVIDER Default SHROUD_DEFAULT_MODEL
openai gpt-4o
anthropic claude-sonnet-4-6-20250217
google or gemini gemini-2.5-flash
mistral mistral-large-latest
cohere command-a-03-2025
openrouter openai/gpt-4o
darkbloom gpt-4o
venice llama-3.3-70b

Direct LLM (Gemini / OpenAI / Anthropic, not Shroud)

When the app calls the provider SDK directly (vault llm-api-key or plain .env keys, no Shroud), the generated chat route uses these defaults:

Provider Default model Override
Gemini gemini-2.5-flash GOOGLE_GENERATIVE_AI_MODEL
OpenAI gpt-4o No env var in the template — edit the generated chat route (app/api/chat/route.ts for Next.js, or the Vite /api/chat handler) to pass another model id.
Anthropic claude-sonnet-4-6-20250217 Same as OpenAI (edit the route).

All chat routes use the Vercel AI SDK for streaming. Shroud + Google/Gemini upstream: if SHROUD_BILLING_MODE=token_billing, chat uses Shroud for Gemini (no Google API key in your app) so 1Claw token billing can apply — enable billing for the agent on 1claw.xyz. If a key is present (SHROUD_PROVIDER_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY, or vault api-keys/google with ONECLAW_VAULT_ID), the route prefers the direct Google Generative AI API (better compatibility than some Shroud↔Gemini paths). With SHROUD_BILLING_MODE=provider_api_key and no Google key resolvable, the route returns 503 (BYOK required for that mode). Direct Google API default is gemini-2.5-flash (GOOGLE_GENERATIVE_AI_MODEL). Shroud path default for Gemini is gemini-2.5-flash (SHROUD_DEFAULT_MODEL) — token billing uses Stripe’s AI gateway, and unsupported model ids can return 404 with Stripe doc links in the error body. The generated chat route sends X-Shroud-Model (per Shroud docs) as well as the JSON model field so the gateway picks the right id. See Gemini rate limits for BYOK. Set SHROUD_DISABLE_GEMINI_DIRECT=1 to always use Shroud POST …/chat/completions even when a Google key exists. Other Shroud upstreams use minimal non-streaming Shroud + createDataStreamResponse / formatDataStreamPart (or pipeDataStreamToResponse on Vite). Do not send Authorization: Bearer … to Shroud — use X-Shroud-Agent-Key. Optional: SHROUD_STREAM_CHUNK_CHARS (default 40) for non-Gemini Shroud chunking.

Publishing to npm

Package name: scaffold-agent (unscoped). Listing: npmjs.com/package/scaffold-agent.

Manual publish — any npm user with rights to the scaffold-agent package name:

npm login
npm run build
npm publish --tag latest

Optional: npm publish --provenance --tag latest if you use npm provenance from your environment.

Acknowledgements

This project builds on ideas and tooling from the Ethereum builder community:

Developer Documentation

To build and run this CLI locally from a clone (test changes before publishing or using npx):

npm install
npm run build
node dist/cli.js

That runs the same entry as scaffold-agent / npx scaffold-agent after a successful build. npm start is equivalent to node dist/cli.js. Use node dist/cli.js --help for the full flag list.

While iterating on src/, npm run dev runs tsup --watch so dist/cli.js stays rebuilt on save. After touching src/cli.ts, src/cli-argv.ts, src/cli-wizard.ts, src/agent-project-config.ts, or src/actions/scaffold.ts, run npm run build (or keep npm run dev running) before testing the CLI.

Contributor-oriented details: AGENTS.md.

License

MIT — see LICENSE in the repo.

About

Interactive CLI to scaffold monorepo projects for onchain AI agents

Resources

License

Stars

2 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors