Skip to main content

Escrow

For actions that require trust guarantees, Atlas supports escrow settlement through the ZoneEscrow contract. Funds are locked on-chain and released only when conditions are met.

Escrow lifecycle

How escrow works

1

Payment requirement with escrow mode

When a zone action uses settlement_mode: "escrow" in its price definition, the steward’s zone.payment_required message points to the ZoneEscrow contract instead of ZoneSettlement.
{
  "type": "zone.payment_required",
  "request_id": "req_01JX...",
  "payment_requirement": {
    "to": "0x633411f26D7138273Cb1183147530d65C754E098",
    "settlement_mode": "escrow",
    "amount": "5000000",
    "deadline": 1743639300,
    ...
  }
}
2

Deposit

The steward calls depositWithAuthorization() on the ZoneEscrow contract using the client’s signed USDC authorization. The funds are locked in the contract, associated with a unique task_id (keccak256 of the request ID) and the depositor’s address.The escrow ID is computed as: keccak256(depositor_address || task_id).
3

Work is performed

With funds locked, the steward performs the requested action. The escrow remains in Deposited state until explicitly resolved.
4

Resolution

The depositor (steward) resolves the escrow using one of three operations:
  • Release — sends funds to the recipient (successful completion)
  • Refund — returns funds to the depositor (after deadline expires)
  • Dispute — flags the escrow for dispute resolution

Status states

StatusDescription
pending_depositAuthorization received, deposit transaction not yet confirmed
depositedFunds locked on-chain in the escrow contract
releasedFunds sent to the recipient by the depositor
refundedFunds returned to the depositor after deadline
disputedEscrow flagged for dispute; deadline extended
failedDeposit transaction reverted or other failure

CLI commands

List escrow receipts

atlas wallet escrows
Output:
esc_0x1a2b...  zone=zone_abc  action=audit  status=Deposited  tx=0xdef456...  amount=5000000  task=0xaaa...
esc_0x3c4d...  zone=zone_abc  action=review status=Released   tx=0xfed789...  amount=3000000  task=0xbbb...

Release escrow

Release funds to a recipient after successful task completion:
atlas wallet escrow-release <escrow_id> <recipient_address>
Example:
atlas wallet escrow-release esc_0x1a2b... 0xRecipientAddress
Only the original depositor (the wallet that created the escrow) can release funds. The CLI verifies this before submitting the transaction.

Refund escrow

Reclaim funds after the escrow deadline has passed:
atlas wallet escrow-refund <escrow_id>
The refund can only be executed after the deadline specified in the original payment requirement.

Dispute escrow

Flag an escrow for dispute, which extends the deadline:
atlas wallet escrow-dispute <escrow_id>
Either the depositor or recipient can initiate a dispute.

Escrow receipt record

Each escrow operation is persisted locally as an EscrowReceiptRecord:
FieldDescription
escrow_idUnique escrow identifier (keccak256 hash)
request_idOriginal zone action request ID
zone_idZone where the action was performed
actionAction name
task_idkeccak256 of the request ID (bytes32)
tx_hashOn-chain transaction hash
chain_idChain ID (8453 or 84532)
depositorAddress of the depositing wallet
recipientAddress of the recipient (set on release)
tokenToken contract address (USDC)
amountAmount in raw units
deadlineUnix timestamp after which refund is allowed
statusCurrent escrow status
errorError message if failed
recorded_atUnix timestamp of last update

Settlement info for escrow

When a zone.response includes escrow settlement, the settlement object contains:
{
  "tx_hash": "0xdef456...",
  "chain_id": 8453,
  "total": "5000000",
  "recipient_amount": "0",
  "creator_fee": "0",
  "protocol_fee": "0",
  "asset": "USDC",
  "settlement_mode": "escrow",
  "escrow_id": "0x1a2b3c...",
  "deadline": 1743639300
}
For escrow deposits, the recipient_amount, creator_fee, and protocol_fee are all "0" because fee splitting happens at release time, not at deposit time.