A daily spending limit for your AI agent.

The agent is deliberately gullible. The contract isn't.

How it works

  1. Deposit USDG (or any ERC-20) into a vault on Robinhood Chain, name your agent's address, set a daily cap and a list of allowed recipients.
  2. The agent can only call spend(to, amount, memo). Inside the cap and to a listed recipient, the money moves. Anything else is refused by the contract and recorded as a Refused event.
  3. Change the cap, swap or revoke the agent, withdraw — any time. Only the vault owner can.

Your agent only needs gas. The money stays in the vault. About 0.001 ETH covers roughly 1,000 spends. Every refusal is a transaction on Robinhood Chain; see /proof.

Works with USDG or any standard ERC-20 on Robinhood Chain, including tokenized stocks. Tokens that charge the sender extra or rebase downward aren't supported.

Numbers

What the contract guarantees vs what the team does

The contract guarantees

  • A vault, its daily cap and its allowlist.
  • Revoking the agent and withdrawing, by the owner, any time.
  • A Refused event for every refused spend, with the reason.
  • The token has no function in the contract.

The team does, by hand

  • The demo agent tries every payment request it is given. That is its system prompt, and you can test it on the home page.
  • Paid sinks are swept back into the demo vault by hand. Refills are public transactions. Nothing is promised.
  • Creator fees pay for the server, the model and the demo vault's refills.

Contract

Source verified on Sourcify (exact match).

Functions

FunctionWhoWhat
createVault(asset, agent, dailyCap, recipients[])anyoneNew vault, you are the owner. The agent may be empty (zero) and set later, but cannot be you.
deposit(id, amount)anyoneAdds the amount actually received to the vault. Send funds with deposit only: tokens sent directly to the contract can't be recovered.
withdraw(id, amount)ownerSends the amount back to the owner's own address only. If the token issuer blacklists the owner, the withdraw fails.
setAgent(id, agent)ownerSwap the agent. Zero revokes it.
setDailyCap(id, cap)ownerChange the cap. Zero pauses the agent.
setRecipient(id, to, ok)ownerAllow or remove a recipient.
spend(id, to, amount, memo)agentReturns true and moves the money, or returns false and emits Refused. It does not revert on refusal.
remaining(id)viewCap minus spent today.
canSpend(id, to, amount)view0 means it would pass; otherwise the reason code below, or 4 when the vault has no agent.

Events

VaultCreated, Deposited, Withdrawn, AgentSet, CapSet, RecipientSet, Spent, Refused.

Refusal reasons

CodeNameMeaning
1RECIPIENT_NOT_ALLOWEDThe recipient is not on the allowlist.
2OVER_DAILY_CAPThe amount is more than what is left of today's cap.
3INSUFFICIENT_VAULT_BALANCEThe vault holds less than the amount.

Demo agent

The hot key. The demo agent's key lives on our server and can only call spend() on vault #1. If it leaked, the most anyone could do is spend what is left of that day's cap, to the three allowed recipients. That is the point of the contract.

Transaction status OK does not mean money moved

A refused spend is a successful transaction that moves no tokens. Look for Spent versus Refused in the logs. On Blockscout a refusal shows status OK with no token transfer.

The daily window

The window is the UTC calendar day. It resets at 00:00 UTC. A midnight burst can reach twice the cap across two UTC days: an agent can spend what is left of today, then the next day's cap, within minutes of 00:00 UTC.

For agents

Read how much is left, then pay from the agent key. Amounts are in the asset's smallest unit (USDG has 6 decimals).

cast

curl

viem

spend returns ok: false instead of throwing when the vault refuses; check it. Call canSpend first if you want to know without sending a transaction.

Download heelwick.mjs

Token

The token is the project's coin on Pons. It does nothing inside the contract. Creator fees pay for the server, the model, and the demo vault's refills — by hand, with public transactions, nothing promised.

FAQ

What happens when my agent asks for too much?

The contract refuses, emits Refused with the reason, and no funds move.

Can I get my money out if the agent misbehaves?

Yes. Only you, as owner, can withdraw, and you can revoke the agent or set the cap to zero at any time.

Which assets work?

USDG, or any standard ERC-20 on Robinhood Chain, including tokenized stocks. One asset per vault. Tokens that charge the sender extra or rebase downward aren't supported.

When does the cap reset?

At 00:00 UTC, every day.

Does my agent need ETH?

Only for gas. The money stays in the vault.

Is the demo agent's key safe?

It lives on our server and can only call spend() on vault #1, which is limited by the contract. See the hot key note above.

Experimental software. Use amounts you can afford to lose. Nothing here is financial advice.