Python SDK for Arbitova — non-custodial on-chain escrow + AI arbitration for agent-to-agent payments on Base
Project description
arbitova
Non-custodial USDC escrow for agent-to-agent payments on Base.
Two agents lock USDC into a contract, one delivers, the other confirms or disputes, and a neutral arbiter resolves. Arbitova never holds the money — the contract does.
No API keys. No registration. No custody. Your Ethereum address is your identity.
pip install arbitova
Contract: 0xA8a031bcaD2f840b451c19db8e43CEAF86a088fC on Base Sepolia (mainnet launching after audit)
Spec: A2A-ESCROW-RFC-v0.1
Live UI: arbitova.com/pay
Why this exists
Every A2A / agent-commerce spec in the wild — MCP, Google's A2A, ERC-7683, Coinbase's Agent Commerce — defines how agents talk. None of them define how money moves when the agents don't trust each other.
Arbitova is the missing settlement primitive:
- Deterministic state machine.
createEscrow → markDelivered → {confirmDelivery | dispute → resolve | cancel}. No hidden branches, no admin override. - No auto-release after timeout. Review windows expire into
DISPUTED, not into seller payout. Silence is safer than a wrong confirmation. - Content-hash pinned on-chain. Sellers can't swap the delivery file after the buyer inspects.
- Verdict transparency. Every arbiter decision, its reasoning, the ensemble vote breakdown, and the content-hash integrity data is published per-case at arbitova.com/verdicts.
This is not a marketplace. There is no Arbitova account, no listing fee, no Arbitova Pro tier. The protocol is the whole product.
Dispute publicity
If an escrow is disputed and resolved by Arbitova arbitration, the verdict, reasoning, and ensemble vote breakdown are published per-case at arbitova.com/verdicts. The delivery payload itself is not published (only its keccak256 hash). Your wallet address is already public on-chain. See the transparency policy.
30-second quickstart
Both sides need a Base Sepolia private key with some test USDC + a pinch of ETH for gas. Faucet: https://faucet.circle.com/ (Base Sepolia USDC) · gas: https://www.alchemy.com/faucets/base-sepolia
Buyer
import os
from arbitova import path_b
os.environ["ARBITOVA_RPC_URL"] = "https://sepolia.base.org"
os.environ["ARBITOVA_CHAIN_ID"] = "84532"
os.environ["ARBITOVA_ESCROW_ADDRESS"] = "0xA8a031bcaD2f840b451c19db8e43CEAF86a088fC"
os.environ["ARBITOVA_USDC_ADDRESS"] = "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
os.environ["ARBITOVA_PRIVATE_KEY"] = "<buyer_private_key>"
result = path_b.arbitova_create_escrow(
seller_address="0xSellerAddressHere",
amount_usdc="5.00",
delivery_hours=24,
review_hours=24,
verification_uri="https://example.com/spec.json",
)
print(f"Escrow #{result['escrow_id']} — tx {result['tx_hash']}")
Seller
import os
from arbitova import path_b
os.environ["ARBITOVA_PRIVATE_KEY"] = "<seller_private_key>"
# (other env vars same as buyer)
result = path_b.arbitova_mark_delivered(
escrow_id=1,
delivery_payload_uri="https://example.com/receipt.json",
delivery_content_bytes=b"hello, buyer", # content-hash pinned on-chain
)
print(f"Delivered — tx {result['tx_hash']}")
Buyer confirms (happy path)
path_b.arbitova_confirm_delivery(escrow_id=1)
# Contract pays seller (amount − 0.5% release fee) atomically.
Or: buyer disputes → Arbitova resolves
path_b.arbitova_dispute(escrow_id=1, reason="Delivery did not match spec section 3.2")
# Arbitova signer runs AI arbitration off-chain, then calls resolve() with the split.
API reference (Path B — on-chain)
| Function | Description |
|---|---|
arbitova_create_escrow(seller, amount, delivery_hours, review_hours, verification_uri) |
Buyer locks USDC into the escrow contract |
arbitova_mark_delivered(escrow_id, delivery_payload_uri, delivery_content_bytes) |
Seller signals delivery + pins keccak256(delivery_content_bytes) on-chain |
arbitova_confirm_delivery(escrow_id) |
Buyer releases funds; contract pays seller (minus 0.5% release fee) |
arbitova_dispute(escrow_id, reason) |
Buyer opens dispute; bond is locked; Arbitova arbiter resolves |
arbitova_resolve(escrow_id, buyer_bps, seller_bps, verdict_hash) |
Arbiter-only — posts final split to chain |
arbitova_get_escrow(escrow_id) |
Read current state |
arbitova_cancel_if_not_delivered(escrow_id) |
Buyer safety valve — reclaim funds after delivery deadline |
arbitova_escalate_if_expired(escrow_id) |
Permissionless — anyone can push a silent review window into DISPUTED |
verify_delivery_hash(delivery_content_bytes, on_chain_delivery_hash) |
Buyer verification: recompute the hash and compare to what's on-chain |
Fees (contract-level)
| On | Rate | Paid by | Source |
|---|---|---|---|
confirmDelivery / escalateIfExpired |
0.5% (releaseFeeBps = 50) |
Seller (deducted from payout) | Contract |
resolve (after dispute) |
2% (resolveFeeBps = 200) |
Losing party (from their share) | Contract |
No Arbitova balance to top up. No invoices. Fees are collected on-chain in USDC when the contract releases funds.
Links
- Website: https://arbitova.com
- Pay UI: https://arbitova.com/pay
- Verdicts dashboard: https://arbitova.com/verdicts
- Spec (RFC v0.1): https://github.com/jiayuanliang0716-max/Arbitova/blob/master/spec/A2A-ESCROW-RFC-v0.1.md
- GitHub: https://github.com/jiayuanliang0716-max/Arbitova
- Transparency policy: https://github.com/jiayuanliang0716-max/Arbitova/blob/master/docs/transparency-policy.md
- npm (JS SDK): https://www.npmjs.com/package/@arbitova/sdk
- MCP server: https://www.npmjs.com/package/@arbitova/mcp-server
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file arbitova-2.5.4.tar.gz.
File metadata
- Download URL: arbitova-2.5.4.tar.gz
- Upload date:
- Size: 36.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
38cef24568154aab84fe3868d2ed0147f9a3ed4a7b400a38e8c565e7ab4d702e
|
|
| MD5 |
b32275cb70de7fbaa45baf73243306b8
|
|
| BLAKE2b-256 |
090601b852112e7fe3818f8765f80ddd751cf5dbf885b6a9287b75087fde2d0b
|
File details
Details for the file arbitova-2.5.4-py3-none-any.whl.
File metadata
- Download URL: arbitova-2.5.4-py3-none-any.whl
- Upload date:
- Size: 30.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
06a36e8897190b79b3b506768fda516fa34795be50e5e5928954dcfe6ac3f071
|
|
| MD5 |
5d4fd9cf5aa48fa25c931ec970b6cd57
|
|
| BLAKE2b-256 |
dbbe21cf606da34ea989203c3ebf4fcc3df0a5bc0769612586cd810fbdcb363d
|