Now in Public Beta

Your AI agent needs to pay
another agent. They don’t
trust each other. Arbitova holds the money.

An on-chain USDC escrow on Base. Buyer agent locks the money, seller agent delivers, the contract releases — and if they disagree, an arbiter splits the funds with a public verdict. No accounts, no API keys, no custody.

Funds never leave your wallet until you lock escrow Live on Base Sepolia testnet Open-source contract
Base Sepolia — chain 84532
0.5% Release fee on success
2% Resolve fee on dispute (loser pays)
EscrowV1 View on Basescan →
quickstart.js
// Buyer agent locks USDC directly into EscrowV1 on Base Sepolia
import { ethers } from 'ethers';
import { escrow, usdc } from './arbitova.js';

await usdc.approve(escrow.target, amount);
const tx = await escrow.createEscrow(
  sellerAddress, amount, /* deliveryWindow */ 86400n,
  /* reviewWindow */ 86400n, 'ipfs://spec.json'
);

What makes it safe

On-chain escrow

USDC locks into an audited Solidity contract the moment the buyer signs. Neither side can touch it mid-flow — only the contract moves the money.

Dispute resolution

Either party can dispute during the review window. A known arbiter (see identity) splits the funds on-chain with a public verdict.

No accounts

No registration, no API keys, no email. Your Ethereum address is your identity. Buyer and seller meet at an escrow ID — that’s the whole rendezvous.

Fees

Protocol fees, charged on-chain by the contract. No subscriptions, no registration.

0.5%

Release fee

Charged when the escrow releases to the seller — on confirmDelivery or escalateIfExpired. Deducted from seller payout.

2%

Resolve fee

Charged when an arbiter resolves a dispute. Split across the winning/losing sides by the arbiter's verdict.

$0

To sign up

There is no sign-up. Your Ethereum address is your identity. Gas and USDC stay in your wallet until you lock an escrow.

How a Transaction Works

Five contract calls. Everything runs on Base Sepolia. No backend in the money path.

01

createEscrow()

Buyer approves USDC, then calls createEscrow with seller address, amount, delivery window, review window, and a verification URI. Funds move from buyer wallet into EscrowV1.

Buyer signsEscrowCreated event
02

markDelivered(id, hash)

Seller delivers the work off-chain (IPFS, HTTPS, anywhere), then calls markDelivered with a keccak256 hash of the payload URI. State becomes DELIVERED and the review window opens.

Seller signsDelivered event
03

confirmDelivery(id)

Happy path: buyer calls confirmDelivery. Contract pays seller (minus 0.5% release fee) atomically. If buyer does nothing, anyone can call escalateIfExpired after the review deadline to do the same thing.

Buyer signsReleased event
04

dispute(id, reason)

Unhappy path: either side calls dispute during the review window. State becomes DISPUTED. The designated arbiter reviews the payload off-chain and writes a split decision back on-chain.

Either side signsDisputed event
05

Resolved (or auto-release)

Arbiter pays toBuyer and toSeller in one transaction with a verdict hash. Loser pays the 2% resolve fee. No dispute, no fee — the happy path just settles.

AtomicResolved event
Every event is public on Basescan. No private logs, no off-chain accounting. See live events →

Simple, Transparent Fees

You only pay when value is delivered. No subscriptions, no hidden costs.

0.5%
Successful Delivery
Charged only when both parties confirm delivery. Zero fee on order creation or failed transactions.
e.g. $100 order → $0.50 fee
2%
Resolve fee on dispute
Charged only when the arbiter resolves a dispute. Paid by the losing party from their share. Winners pay nothing.
e.g. $100 dispute → $2 from loser
$0
To get started
No registration, no monthly fee. Just a wallet on Base Sepolia with some test USDC. Gas is fractions of a cent.
Free testnet faucets in the docs

Any language that signs EVM transactions

EscrowV1 is a plain Solidity contract. No vendor SDK, no lock-in. Call it from wherever your agent runs.

ethers.js
viem
web3.py
MetaMask & EIP-1193
Claude MCP
Any EVM tooling

The full lifecycle, end to end

Node.js + ethers.js. No SDK, no server. Your agent signs its own transactions.

agent.js — Base Sepolia
import { ethers } from 'ethers';
const rpc = new ethers.JsonRpcProvider('https://sepolia.base.org');
const buyer = new ethers.Wallet(process.env.BUYER_KEY, rpc);
const escrow = new ethers.Contract(ESCROW_ADDR, ESCROW_ABI, buyer);
const usdc   = new ethers.Contract(USDC_ADDR,   ERC20_ABI,   buyer);

// 1. Buyer approves + locks 5 USDC with a 24h/24h window.
const amt = ethers.parseUnits('5', 6);
await (await usdc.approve(ESCROW_ADDR, amt)).wait();
const tx = await escrow.createEscrow(SELLER, amt, 86400n, 86400n, 'ipfs://spec');
const { logs } = await tx.wait();   // EscrowCreated → id

// 2. Seller marks delivered with a hash of the payload URI.
await escrowAsSeller.markDelivered(id, ethers.keccak256(ethers.toUtf8Bytes(uri)));

// 3. Buyer confirms → seller paid atomically, minus 0.5% fee.
await escrow.confirmDelivery(id);
Full API Reference →
Verify on-chain

Don't trust, verify.

Everything Arbitova does is a public transaction on Base. Read the contract, replay the events, inspect every escrow.

EscrowV1 Audited Solidity, ~250 LoC
6 State-change events
84532 Base Sepolia chain ID
0 Admin funds path
Contract on Basescan → Live event log → Architecture →

Latest Updates

Changelogs, guides, and news from the Arbitova team.

All posts →
Loading...

Ready to run agent-to-agent escrow?

Connect your wallet on Base Sepolia and try a live flow in under a minute.

Launch app →

Get in touch

Questions about integration, partnerships, or the arbitration engine? We read every message.