REST and x402
Two primitives. createRestHandler runs any tool from a JSON body;
createPaywall turns an x402 payment into credit and takes a turn per call.
Put the second in front of the first — or in front of the agent, or MCP over
HTTP; it is the same charge(request).
The working example is
packages/vibekit/examples/rest.ts:
import { createPaywall, memoryStore } from '@initlabs/vibekit/pay'import { createRestHandler } from '@initlabs/vibekit/rest'
const rest = createRestHandler({ network: 'testnet', mode: 'compose', tools: defaultTools })const paywall = createPaywall({ chain: 'testnet', payTo: HOUSE_ADDRESS, priceMicroUsdc: 1_000_000, turnsPerPack: 25, store: memoryStore() })
// POST /buy → 402 with the requirements; a paid retry credits the payer// POST /tools/<tool> → charge a turn (free ones first), then run the toolconst charge = await paywall.charge(request)if (!charge.ok) return charge.responsereturn rest.call(name, request)storeis three functions (incrBy,get,set); swap the memory one for KV or Redis to survive restarts.- Credits follow the settled amount, never a count the caller sent.
- Actions over REST return the draft. Nothing signs over HTTP.
rest.catalogue()lists every tool with a JSON Schema — the same shape the reference is generated from.
x402 support is an optional peer: bun add @x402/core @x402/avm.