/install decanus-escrow
Escrow MCP Server
Dual-deposit escrow on Base Sepolia via the @decanus-labs/escrow-mcp MCP server. Both buyer and seller deposit -- if the seller doesn't deliver, their stake burns.
Start the Server
PRIVATE_KEY=0x... npx -y @decanus-labs/escrow-mcp
Or configure as an MCP server in config.yaml:
plugins:
entries:
escrow:
type: mcp
config:
command: npx
args: ["-y", "@decanus-labs/escrow-mcp"]
env:
PRIVATE_KEY: "0x..."
Optional env vars: RPC_URL (default: https://sepolia.base.org), CONTRACT_ADDRESS (default: v2 deployment).
Tools
Write Tools
create_escrow
Buyer creates an escrow, depositing ETH as payment.
| Param | Type | Required | Description |
|---|---|---|---|
seller |
string | yes | Seller's Ethereum address |
arbiter |
string | yes | Arbiter's Ethereum address (dispute resolver) |
paymentAmountEth |
string | yes | Payment in ETH (e.g. "0.01") |
durationSeconds |
number | yes | Deadline in seconds from now |
accept_escrow
Seller accepts by depositing a stake >= the payment amount.
| Param | Type | Required | Description |
|---|---|---|---|
escrowId |
number | yes | Escrow ID |
stakeAmountEth |
string | yes | Stake in ETH (must be >= payment) |
deliver_work
Seller submits delivery proof. Starts a 24h buyer review window.
| Param | Type | Required | Description |
|---|---|---|---|
escrowId |
number | yes | Escrow ID |
deliveryHash |
string | yes | bytes32 hex or plain string (auto-hashed via keccak256) |
complete_escrow
Buyer approves delivery. Releases payment + seller stake to seller.
| Param | Type | Required | Description |
|---|---|---|---|
escrowId |
number | yes | Escrow ID |
dispute_escrow
Either party raises a dispute. Arbiter must resolve.
| Param | Type | Required | Description |
|---|---|---|---|
escrowId |
number | yes | Escrow ID |
reason |
string | no | Human-readable reason (stored off-chain) |
refund_expired_escrow
Anyone triggers after deadline. Buyer gets payment back, seller stake burns.
| Param | Type | Required | Description |
|---|---|---|---|
escrowId |
number | yes | Escrow ID |
Read Tools
get_escrow
Fetch escrow state. Returns state label, participants, amounts, deadlines (ISO + relative), delivery hash, and suggested next actions.
| Param | Type | Required | Description |
|---|---|---|---|
escrowId |
number | yes | Escrow ID |
list_escrows
Paginated scan of recent escrows.
| Param | Type | Required | Description |
|---|---|---|---|
limit |
number | no | Max results (default 10, max 50) |
state |
string | no | Filter: AWAITING_SELLER, FUNDED, DELIVERED, COMPLETED, DISPUTED, REFUNDED, BURNED |
participant |
string | no | Filter by address (buyer, seller, or arbiter) |
Escrow States
AWAITING_SELLER → FUNDED → DELIVERED → COMPLETED
↓ ↓
DISPUTED DISPUTED
↓
BURNED (after deadline)
- AWAITING_SELLER -- buyer deposited, waiting for seller to stake
- FUNDED -- both deposited, seller can deliver or deadline triggers burn
- DELIVERED -- seller submitted proof, 24h grace for buyer to approve or dispute
- COMPLETED -- buyer approved, seller received payment + stake
- DISPUTED -- arbiter must resolve
- BURNED -- deadline expired while FUNDED, buyer refunded, seller stake locked permanently
Common Flows
Happy path: hire an agent, pay on delivery
1. create_escrow(seller=0x..., arbiter=0x..., paymentAmountEth="0.01", durationSeconds=86400)
2. Seller calls: accept_escrow(escrowId=0, stakeAmountEth="0.01")
3. Seller calls: deliver_work(escrowId=0, deliveryHash="ipfs://QmProof...")
4. Buyer calls: complete_escrow(escrowId=0)
→ Seller receives 0.02 ETH (payment + stake returned)
Dispute path
1. create_escrow(...) → accept_escrow(...)
2. Buyer or seller calls: dispute_escrow(escrowId=0, reason="Work incomplete")
→ State moves to DISPUTED, arbiter must resolve via contract
Expired refund (seller no-show)
1. create_escrow(...) → accept_escrow(...)
2. Deadline passes with no delivery
3. Anyone calls: refund_expired_escrow(escrowId=0)
→ Buyer gets payment back, seller stake burned (locked in contract)
Check status
get_escrow(escrowId=0)
→ Returns state, deadlines, next valid actions
Notes
- All ETH amounts are strings to avoid precision issues. Use
"0.01"not0.01. - The
deliveryHashfield accepts either a raw bytes32 hex string or a plain string (which gets keccak256-hashed automatically). - Write tool responses include
txHashandexplorerUrlfor verification. - Each server instance uses one signer (the
PRIVATE_KEY). Run separate instances for buyer and seller roles. - Currently Base Sepolia testnet only. ETH-native, not stablecoin.
- Make sure OpenClaw is installed (local or Docker)
- Run the install command in chat:
/install decanus-escrow - After installation, invoke the skill by name or use
/decanus-escrow - Provide required inputs per the skill's parameter spec and get structured output
What is Decanus Escrow?
Onchain dual-deposit escrow for agent-to-agent task settlement on Base L2 via MCP. Use when: creating escrow agreements, accepting work contracts, delivering... It is an AI Agent Skill for Claude Code / OpenClaw, with 94 downloads so far.
How do I install Decanus Escrow?
Run "/install decanus-escrow" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.
Is Decanus Escrow free?
Yes, Decanus Escrow is completely free, licensed under MIT-0. You can download, install and use it at no cost.
Which platforms does Decanus Escrow support?
Decanus Escrow is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).
Who created Decanus Escrow?
It is built and maintained by tarouca (@manueltarouca); the current version is v0.1.0.