Tutorial · 10 minutes
Give your agent its first allowance.
Six steps, every command actually works on your laptop. No wallet, no chain, no API keys, nothing to buy. By the last step you'll have watched an AI agent pay x402 APIs by itself — and watched your guardrails stop it from going rogue.
Make sure Node ≥ 24 is installed
This tutorial runs Wallie from a clone, as plain TypeScript that Node executes directly — no build step. That needs Node ≥ 24. If you would rather not clone anything, npx wallie works on Node ≥ 20.11 and needs no checkout at all.
node --version
You should see
v24.x.x
Run the full story once
Before understanding parts, watch the whole movie: five priced APIs come up on localhost, an agent spends within a $5 allowance, a runaway loop trips the breaker, attacks get blocked, the kill switch freezes everything.
git clone https://github.com/fskroes/AllowanceKit.git wallie cd wallie npm run demo
You should see (abridged)
PAID weather?city=lisbon $0.001000 0xcddcb9a6… PAID research?topic=… $0.250000 0x4e5bc352… BLOCKED loop #150 velocity_circuit_breaker BLOCKED evil-api.example.com host_not_allowlisted BLOCKED feed?key=pro per_call_cap spent $1.99 across 154 settled payments · 5 blocks enforced
Understand what just happened
Every line maps to a real event in the append-only ledger at .allowance/ledger.jsonl. This file is deliberately boring: JSON lines, one decision each — which is exactly what an auditor wants.
Peek at the raw evidence
tail -5 .allowance/ledger.jsonl
| LEDGER EVENT | MEANING |
|---|---|
| topup | human funded the allowance — the ceiling exists |
| payment | policy said yes → signed → settled → receipt stored |
| blocked | policy said no — rule, reason and attempted price recorded |
| policy_change | someone touched the rules (e.g. kill switch flipped) |
Fund a fresh allowance yourself
This time you're the human. Provision the wallet, load it, set one policy. These three commands are the entire "setup" experience — that's the point.
node src/cli.ts status node src/cli.ts topup 2.00 node src/cli.ts policy perCallMaxUsd 0.25
You should see
topped up $2.000000 → remaining $5.007000
{ "perCallMaxUsd": 0.25, … }
Write your own paying agent
One import replaces fetch. Save this as my-agent.ts in the repo root and run it — you just wrote an autonomous purchasing agent.
import { createAgent } from "./src/wallet.ts"; import { payingFetch } from "./src/payer.ts"; import { startSellerApis } from "./src/demo-servers.ts"; import { fmtUsdExact } from "./src/money.ts"; const rt = createAgent(new URL("./.allowance/", import.meta.url).pathname); const apis = await startSellerApis(rt.chain); const r = await payingFetch(rt.ctx, apis.weatherUrl("reykjavik")); console.log("status:", r.status); console.log("cost: ", fmtUsdExact(r.costMicro)); console.log("tx: ", r.txHash); console.log("data: ", r.body); if (r.blockedBy) console.log("blocked by policy:", r.blockedBy.rule);
node my-agent.ts
You should see
status: 200
cost: $0.001000
tx: 0x9f21ab77…
data: { city: 'reykjavik', tempC: 1.2, conditions: 'rainy' }
Watch it live, then hit the big red button
The dashboard reads the same ledger your agent writes. Open it in one tab, run spending in another, then flip the kill switch mid-flight and watch the next call die instantly.
node src/cli.ts dashboard
node my-agent.ts
Then, in the dashboard
→ http://localhost:4030 → press [ KILL SWITCH: OFF ] → becomes KILL SWITCH: ON — spending frozen → re-run node my-agent.ts → blocked: kill_switch · human paused all spending for this agent
You did it — here's the road to real money
Everything so far settled on Wallie's deterministic mock ledger — on purpose, so you learned with zero risk. The included live buyer runtime handles signing. Seller integrations use a facilitator behind this interface:
interface Facilitator { verify(payment: PaymentPayload): Promise<VerifyResult>; settle(payment: PaymentPayload): Promise<SettleResult>; }
Go live on Base Sepolia
Same runtime, same rails — but now payments settle in real USDC on a real chain. Base Sepolia is a free testnet, so you prove the whole path with faucet money before risking a cent. Your wallet key is read from the environment and never written to disk.
# your wallet key — read from the env, never written to disk
export AGENT_PRIVATE_KEY=0x...
allowance-kit init --live --network base-sepolia
allowance-kit topup 5.00
allowance-kit policy perCallMaxUsd 0.10
allowance-kit pay https://some-live-x402-api.com/dataYou should see
REAL MONEY — payments settle in USDC on base-sepolia
topped up $5.000000 → ceiling raised (nothing moved on-chain)
{ "perCallMaxUsd": 0.10, … }
PAID /data $0.001000 0x… (exit 0)
Mainnet is one flag and a confirmation — allowance-kit init --live --network base (it asks you to type base back). This is not theoretical: Wallie settled a real USDC payment on Base mainnet on 2026-09-07 — see the transaction on BaseScan.
Get told when it stops
A dashboard only helps someone who is looking at it — the runs that hurt happen overnight. Connect the agent to Wallie Cloud and every decision plus a 60-second heartbeat streams up. If the heartbeats stop, the cloud tells you the agent went silent.
allowance-kit notify cloud wk_live_... export WALLIE_CLOUD_KEY=wk_live_... allowance-kit notify test
You should see
cloud set — every decision and a heartbeat go to api.onewallie.com delivered cloud connected as your workspace
That's the whole piggy bank. 🐷✨
You provisioned an allowance, wrote an agent that pays x402 APIs autonomously, enforced six rails, and kept the receipts.