Bounded autonomy and auditable settlement for agent-initiated payments — two AI agents transact over a priced API, every payment passing through a policy engine (spending caps, allowed counterparties, mandate expiry) that logs an allow/deny decision and emits a signed receipt. Runs on Base Sepolia testnet only. Zero real money.
This repository is currently scaffolding only — no x402/ERC-8004 protocol logic, policy engine, or database schema has been implemented yet.
apps/web Next.js 15 App Router, TypeScript, Tailwind
packages/contracts Foundry project (trivial placeholder contract)
packages/shared Shared TS types, zod schemas, chain config
services/agent-buyer Standalone Node/TS process (buyer agent)
services/agent-seller Standalone Node/TS process (seller agent)
services/indexer Ponder — installed, not yet configured
- Node.js >= 20.9 (check with
node --version) - npm (ships with Node)
- Foundry (
forge,cast,anvil) - A Neon Postgres database
- A Base Sepolia RPC URL (public default works; see
.env.example)
-
Install Foundry (skip if already installed):
curl -L https://foundry.paradigm.xyz | bash foundryup -
Fetch the forge-std submodule used by
packages/contracts:git submodule update --init --recursive
-
Install JS/TS dependencies (installs every workspace: apps, packages, services):
npm install
-
Copy the env file and fill in real values:
cp .env.example .env
See the comments in
.env.examplefor where to obtain each value. At minimum, setDATABASE_URL(Neon) to run the web app with database access;BASE_SEPOLIA_RPC_URLalready defaults to the public endpoint so the health check works out of the box.Next.js only reads
.env*files fromapps/web, so also copy it there:cp .env.example apps/web/.env.local
For the agent services, copy it into each service directory as well:
cp .env.example services/agent-buyer/.env cp .env.example services/agent-seller/.env
-
Verify the contracts package compiles and its test passes:
cd packages/contracts forge test cd ../..
-
Run the web app:
npm run dev --workspace=web
Then confirm the RPC path works end to end:
curl http://localhost:3000/api/health # => {"ok":true,"chain":"base-sepolia","blockNumber":"<current block>"} -
Run an agent service (each is a bare heartbeat loop for now):
npm run dev --workspace=@writ/agent-buyer npm run dev --workspace=@writ/agent-seller
packages/shared and apps/web are wired for Drizzle ORM against Postgres (Neon), but
apps/web/src/db/schema.ts is intentionally empty — the schema is being designed separately.
Once tables are added there:
npm run db:generate --workspace=web # generate a migration from the schema
npm run db:push --workspace=web # push schema directly (dev convenience)Run from the repo root — these apply across all workspaces:
npm run lint
npm run format # writes changes
npm run format:check # CI-style check, no writes
npm run typecheck- Package manager is npm workspaces (not pnpm), despite this being a common choice in similar stacks — chosen explicitly for this project.
services/indexeronly hasponderinstalled as a dependency; there is noponder.config.tsor schema yet.- All contract/agent private keys in
.env.exampleshould be freshly generated burner wallets funded only with Base Sepolia testnet ETH from a faucet — never a real key.