Ava

Ava is the control plane for agents that move capital.

Claude, Cursor, Codex, OpenClaw connect over MCP. They never hold the key. Nothing spends outside a mandate. A receipt without chain-confirmed standing is not a fill.

“Supply 5 USDC to Morpho on Base”
A same-chain Morpho USDC supply on Base, under a mandate, then a chain-confirmed receipt. One route, proven, is the claim. n=1 is first-class.
Connect your agentnpx @getava-xyz/connect

OpenClaw openclaw skills install @kamalbuilds/ava

MCP https://www.getava.xyz/mcp

The refusal is real, read from the live API when this was cut.

What people say about Ava, posted on X

Live posts from X. Third-party posts first, then the founders, each labelled by who wrote it.

Third party@monad_dev
Third party@PauChan23
Founder@kamalbuilds
Founder@kamalbuilds
Founder@kamalbuilds
Founder@kamalbuilds

One-click deposit is not the hard part. Bounding it is.

An MCP server that deposits to Morpho already exists. So does an unauthed Morpho MCP. What neither can tell you is whether the agent stayed inside what you authorised, or whether the thing it reported actually happened.

Caps the model cannot widen

A mandate names the asset, the chain, the amount and the allowed kinds. Those bytes are hashed at creation, and the hash is carried inside the artifact the signer commits to. A swap submitted under a lend mandate comes back MANDATE_KIND_NOT_ALLOWED with the offending values attached.

capital, constraints.allowedKinds, mandateHash

A preview the agent cannot skip

The first execute call never fills. It returns the exact artifact plus previewHash = sha256(RFC8785(preImage)), and refuses. Only a re-send carrying that hash proceeds. The preImage includes the mandate hash, so what gets signed is bound to what was authorised. A stale hash is refused before any signature is requested.

previewHash

A receipt that grades itself

chain-confirmed, unconfirmed, or no proof. Only the chain-confirmed arm can carry a transaction hash. A track record counts only that arm as proven, and it ships the counting rule with the data. A receipt without chain-confirmed standing is not a fill.

proof.standing

A wallet per agent, not per human

Each agent instance gets its own Turnkey wallet and its own mandate, so sessions do not share risk. A limit set for one does not travel to another, and the receipt names which one spent. The agent never holds the key.

ava_provision_wallet

Unattended spending inside those bounds is the wedge being shipped. Nothing currently ticks a standing envelope on a schedule, so do not treat a standing plan as a running strategy.

The first call to spend money is always a refusal

An MCP call is not a human saying yes. So the first execute returns the artifact a human has to approve, plus its hash, and stops. Nothing was signed and nothing moved.

The first call to spend moneyPOST /v1/lend/execute
$ curl -sX POST https://www.getava.xyz/v1/lend/execute \
    -H 'authorization: Bearer ava_st_…' \
    -d '{"mandateId":"mdt_b6156a74e5224ca9","op":"supply","amount":"5"}'

POLICY_HUMAN_CONFIRMATION_REQUIRED
  signed        false
  liveSubmit    false
  filled        false
  venue         morpho_blue        chain base (8453)
  owner         0x15ab\u2026Bb2a        Turnkey, this agent
  amount        5 USDC             5000000 base units
  previewHash   cbdcce36\u2026e243a09f
  gate          sha256(RFC8785(preImage))
  preImage      { venue, chainId, marketId, owner, receiver,
                  op, assetSymbol, amountBaseUnits,
                  mandateId, mandateHash }

Recorded against the public API on 2026-08-25. Re-send with that hash and it proceeds. Send a different one and it refuses again without asking the signer for anything. Recompute the digest yourself from the preImage. The LLM is not the signer, the policy, or the verifier.

Signed by Ava. Confirmed by the chain.

Ava builds the calldata, signs it in a Turnkey enclave and broadcasts it to mainnet. Each transaction below is re-read from its chain's own node before this page builds, and the contract it called is checked against the venue named beside it.

ChainVenueActionTransactionBlock
BaseMorpho gtUSDCpsupply USDC0x97b78540…36bbba49315911
BaseMorpho gtUSDCpwithdraw USDC0xce4109e4…6b0a7f49327027
AvalancheAave v3supply USDC0x12990c11…f4209f92231544
BNB ChainAave v3supply USDC0x7737cf5c…08b9de114508635
MonadAave v3supply USDC0x50940c95…8715cf92954146
MonadAave v3supply USDC0x1b23c35d…628af793291520
BNB ChainSushiSwap via LI.FIswap, no venue adapter0x14850931…de0542114518492

A block explorer proves the transaction happened. It does not prove the transaction was the one you authorised. For that, read Ava’s own re-read of the Monad row, which compares what settled against what was authorised and needs no credential to open. These are small amounts on purpose. They show the path executing, not a claim that it is ready for unattended capital.

callable today

  • Aave v3 on Arbitrumwired, no settlement yet
  • Aave v3 on Avalanche
  • Morpho Blue on Base
  • Aave v3 on BNB Chain
  • Aave v3 on Monad

Lending routes that report implemented, apiReachable and operatorEnabled on the live registry accept a live execution through the authenticated API. Every other venue carries a machine-readable reason it does not: no executor implemented, an executor no public route imports, operator disabled, or proven by direct script only. SushiSwap and LI.FI are in the settlements table because they settled through a script. They are not callable from the API. The registry is the same object the executor consults, so the list on this page and the answer at signing time cannot disagree.

A receipt without chain-confirmed standing is not a fill

Most agent tooling logs what it meant to do. A receipt with no standing turns a ledger of evidence into a ledger of claims, and by the time anyone checks, the two look identical.

GET /v1/receipts/exe_5f1c0a7d94b2NO PROOF
receiptVersion
"ava.exec.v1"
executionId
"exe_5f1c0a7d94b2"
mandateId
"mdt_fc3dfbf28fc74945"
mandateHash
"4bd430490ee29e38811275c3c4689e573fed2e435ef57f965d5852b452d2b44f"
venue
"morpho"
status
"rejected"
venueOrderId
null
txHash
null
llmUsedInHotPath
false
timestamps.createdAt
"2026-07-29T12:28:16.555Z"

MANDATE_KIND_NOT_ALLOWED Intent kind "swap" is not in the mandate's allowedKinds [lend, strategy]. The execution stopped at the gate, so the receipt carries no order id and no transaction hash, and it does not pretend to.

Three standings, never collapsed into one

  • chain confirmed

    A public RPC confirmed the transaction. This is the only standing that counts as proven anywhere in Ava.

  • unconfirmed

    An identifier exists, supplied by an external signer, and nothing independent has checked it yet. A claim, not a proof.

  • no proof

    Nothing was ever submitted to a venue or a chain. The receipt says so rather than going quiet.

"receiptsProven counts only receipts whose proofStanding is chain-confirmed"

Served verbatim in the verification block of every agent record. The rule ships with the data so a reader does not have to take Ava's word for how the number was counted.

Recompute the digest yourself over the canonical unsigned receipt, or ask the API at GET /v1/receipts/:executionId/verify, no credential required. Open a chain-confirmed one.

A mandate is not a spend limit

A spend limit answers one question: how much can leave. It has no opinion about whether the agent is doing the job you hired it for, and nothing to say when the agent quietly starts doing something else.

How much capital
SPEND LIMITAn allowance per period, shared by everything the key can do.
AVA MANDATEAsset, amount and chain, scoped to one agent instance. Two agents under the same person cannot spend each other's budget.capital
What it may do with it
SPEND LIMITAny call the key is permitted to make.
AVA MANDATEAn explicit list of kinds. A swap submitted under a lend mandate is refused, even when the swap itself is a perfectly safe transaction.constraints.allowedKinds
How much may be lost
SPEND LIMITNot represented. A limit cannot tell a good fill from a bad one.
AVA MANDATEA drawdown ceiling and a notional ceiling, enforced against whichever binds tighter, the explicit cap or the capital actually funded.constraints.maxDrawdownPct
At what execution quality
SPEND LIMITNot represented.
AVA MANDATEA slippage ceiling in basis points and an optional venue preference, carried into the plan before a quote is accepted.constraints.maxSlippageBps
When it should act
SPEND LIMITWhenever it is asked.
AVA MANDATENamed conditions (asset, venue, bounds) on the mandate. Unattended evaluation of those conditions is the wedge being shipped. Nothing currently ticks a standing envelope on a schedule.conditions
Who can widen it
SPEND LIMITWhoever holds the key.
AVA MANDATENobody at runtime. Not the model, not the user message, not a tool call. The terms are fixed at creation and hashed, and that hash is carried into the artifact the signer commits to.mandateHash
What the signer commits to
SPEND LIMITNothing. The key signs whatever it is handed.
AVA MANDATEThe mandate hash is inside the preImage of the preview digest, so a signature cannot cover terms other than the ones authorised.gate.preImage.mandateHash

Where a mandate can operate

A mandate names its own chain, and Ava refuses an action on any venue it cannot execute. These are the routes the live registry reports as implemented, reachable, and operator-enabled. SushiSwap and LI.FI are not on this list.

  • Aave v3 on Arbitrum
  • Aave v3 on Avalanche
  • Morpho Blue on Base
  • Aave v3 on BNB Chain
  • Aave v3 on Monad

The live lending routes enforce these numeric caps from the mandate record. A user signature over the same terms is available at POST /v1/mandates/:id/signature and is required on the routes that carry the identity gate. The settled lending routes enforce the caps without it today.

Ava fails closed

When an action falls outside the mandate, or a venue is missing, or a signature never arrives, Ava stops and records the refusal. It does not invent a fill, and there is no path that turns a refused execution into a success receipt. Refusals are counted in the track record next to the wins, because an agent that never refuses anything is not being held to anything.

Typed refusal codes

  • MANDATE_KIND_NOT_ALLOWED
  • MANDATE_NOTIONAL_EXCEEDED
  • MANDATE_DRAWDOWN_BREACH
  • MANDATE_PAUSED
  • MANDATE_CANCELLED
  • MANDATE_COMPLETED

Your agent branches on the code. It never has to parse an apology.

Every agent instance getsits own wallet.

Three Claude Code windows, a Cursor tab and a Codex run are separate actors, not one user. Register each as its own agent instance and it gets its own Turnkey wallet and its own mandate, so a limit you set for the agent refactoring your billing code does not travel to the one reading your inbox.

When one of them spends, the receipt names which agent instance did it. That is the difference between an audit trail and a shrug.

Scoped, not shared
A mandate binds to one agent instance. Revoking it stops that agent and leaves the others running.
Attributable by default
Every receipt carries the agent that requested it, so “which one did this” is a lookup, not an investigation.
ava_session -> usr_ff7f… / agent_a3f1
ava_provision_wallet -> 0x340340…F1db active
ava_create_mandate -> 250 USDC on Base, lend only
$ cursor # agent instance B, same human
ava_session -> usr_ff7f… / agent_b7c2
ava_provision_wallet -> 0x9c1b22…7ae0 active
instance B tries instance A's mandate
MANDATE_NOT_FOUND refused. not yours.

Ava runs inside the agent you already use

Claude, Cursor and Codex run npx @getava-xyz/connect. OpenClaw installs the skill pack. Anything else uses plain REST. The agent does not install a wallet, a browser extension, or a new app. It points at one URL and gets a session, a mandate, and a receipt.

Claude Code

npx @getava-xyz/connect

one command

Cursor

npx @getava-xyz/connect

one command

Codex

npx @getava-xyz/connect

writes config

OpenClaw

openclaw skills install @kamalbuilds/ava

skill pack

Grok

~/.grok/mcp.json

config file

Anything else

plain REST

no MCP client required

https://www.getava.xyz/mcp

What an agent can execute through it today:

  • Aave v3 on Arbitrum
  • Aave v3 on Avalanche
  • Morpho Blue on Base
  • Aave v3 on BNB Chain
  • Aave v3 on Monad

The agent brings no key. Ava provisions a policy-gated wallet in a Turnkey enclave, files the mandate against it, and refuses anything the mandate does not cover. Call tools/list on that URL for the current tool surface rather than trusting a number on a marketing page.

The last transaction routed through SushiSwap. There is no SushiSwap code in this repository.

No adapter, no address book, no ABI. It touched six contracts across seventeen logs, none of which Ava can decode. It executed inside its mandate and was verified against the chain anyway, because the gate reads what the bytes will move rather than which protocol wrote them.

25

adapters written the venue-by-venue way

4

live venues those 25 adapters actually produced

1

generic integration, reaching every venue an aggregator can route to

An adapter is a bet that a venue will not change. Every new protocol costs another one, every upgrade breaks the last one, and the list of things an agent may safely do stays pinned to the size of an engineering team. Bounding the calldata removes that ceiling: the work is done once, and a venue nobody has heard of yet is already covered on the day an aggregator learns to route to it.

This is also the part that does not commoditise. Routing is already free and getting cheaper. Proof that the money did what was authorised is the thing that has to be built once and stays built.

the transaction in question
0x14850931…de0542
chain
BNB Chain
routed by
LI.FI
filled at
SushiSwap
adapter in repo
none
callable from the API
not yet

This one settled through a direct script. The generic route is registered prepare-only until the API path is wired, because a registry that advertises a route the API cannot execute is worse than one that admits the gap.

What a plan looks like, and where the API stops

ava_plan_workflow decomposes one sentence into dependent legs. Execution admits a plan only if every leg is executable. A bridge leg is not, so this plan is refused before anything moves.

A sentence the planner accepts
“Supply 300 USDC to Morpho on Base, bridge no more than 200 to Avalanche, then supply what arrives to Aave”
What Ava returnsava_plan_workflow
leg_1  lend    base       morpho   USDC  300
leg_2  bridge  base -> avalanche   USDC  max 200
leg_3  lend    avalanche  aave     USDC  amount from leg_2
  • leg_3 waits for leg_2. Dependency, not a list.
  • leg_2 is not executable today. Admission is whole-plan-or-none, so the API refuses the plan rather than running the Morpho leg and stopping mid-flight.
  • The live loop is a same-chain Morpho supply on Base. Cross-chain dependent execution has not run.

Who this is for

Two people meet at the same sentence. One is giving an agent the one thing it cannot do on its own, one is putting up the money, and both need the plan to say what it will really do before it does it.

You are giving an agent onchain reach

Your agent already writes the code and does the research. What it cannot do is hold a key, stay inside a mandate, and prove the fill on chain. It connects to Ava over MCP and gets a wallet, a mandate and a receipt. The model never signs, never sets policy, and never verifies.

One POST gets a session, and from there the agent provisions its own wallet and files its own mandate on the same public API. Call tools/list on /mcp for the tools an agent sees. What Ava cannot execute comes back as a typed refusal with the offending values attached, never as a plausible substitute action.

Install the MCP server

It is your capital moving

You type what you want in one sentence. Ava reads back the plan, with the amount, the venue and the chain, and a missing chain is a question it asks rather than a detail it invents. Nothing moves until the exact artifact has been previewed and its hash re-sent.

Run several agents at once and each gets its own wallet and its own isolated risk budget, so a bad week from one of them cannot reach the others. Pause any of them, or all of them, in one call.

Write your first mandate

Whitepaper · v1.0 · November 2026

The whole argument, with the proofs.

How a mandate binds an agent, why a preview hash cannot be confirmed on a human’s behalf, how one idempotency key yields at most one signature, and how every receipt is re-read from the chain. Checked against the code at commit eff936c.

pages
45pages
diagrams
15diagrams
sections
17sections
Cover of the Ava whitepaper: A mandate-bounded execution layer for autonomous agents

Where Ava started

Before it was a control plane, Ava was a multichain DeFAI agent built in the open at hackathons in early 2025. It took first place on the Avalanche track at the Cookie DeFAI Hackathon, and it was demoed for Sui and voted on at ETHDenver. These are the posts from that time. Each card links to the original.

Cookie DeFAI Hackathon, Avalanche track
1st
Cookie DeFAI Hackathon, Avalanche track
votes and 6 attestations in ETHDenver 2025 quadratic voting
212
votes and 6 attestations in ETHDenver 2025 quadratic voting
presented to the judges of the Sui AI Agent Hackathon
Demo Day
presented to the judges of the Sui AI Agent Hackathon

Give your agent a wallet it cannot misuse.

One session, one mandate, one receipt. No key to hand over, no signup, no wallet popup. Start on the public API and check every claim on this page before you write a line of code.

Check that any of this is live before you write a line of code.

$ curl -s https://www.getava.xyz/health
{ "ok": true, "productionMode": true }