Thesettlementlayerforthemachineeconomy.

LayerX agent domain

Pay on delivery, not up front

Escrow holds, capture and disputes

Move funds into a protocol account, then capture, release, time out or let an arbiter split.

Open a hold that names the beneficiary, the arbiter, the asset, an expiry and a dispute window, and the amount leaves your spending account so the provider can see it. The beneficiary captures all of it or part of it, and you release the rest at any time. Expired holds sweep back to their owners at the start of an epoch. Either side opens a dispute, and only the named arbiter splits the remaining balance.

What it does

Escrow is a module in the LayerX agent domain that moves an amount out of an agent's main account into a dedicated escrow account and records who may take it, by when, and who arbitrates if the two sides disagree. Seven activity types drive one state machine: open, capture, partial capture, release, timeout, dispute open and dispute resolve. A hold is open or partially captured while it is live, and captured, released, resolved or timed out once it is finished. Every settling activity carries a 32-byte idempotency key, and the settled result is stored so a resubmission rebuilds the same receipt instead of moving funds twice.

Key capabilities

  • Open a hold that names owner, beneficiary, arbiter, asset, expiry and dispute window.
  • Capture the whole remaining balance, or capture part and leave the rest held.
  • Owner releases the remaining balance back to the main account at any time.
  • Expired holds are swept back to their owners at the start of an epoch.
  • Either party opens a dispute; only the named arbiter resolves it.
  • Arbiter splits the remaining balance by basis points, remainder to the owner.

Who it's for

Agent developers and service operators who need payment on delivery rather than payment up front.

Why it matters

The money leaves the payer's spending account when the hold opens, so the provider can see it is there before doing the work. The provider can never take more than the hold, never after expiry and never while a dispute is open. If the work is contested, a named arbiter divides the remaining balance instead of one side keeping all of it.

Differentiators

The escrow account is a separate account kind that only the escrow module can debit, and only for a capture, release or resolve reason; owner authority and session keys cannot spend it. The expiry sweep runs inside epoch processing, so a hold times out without anyone sending a transaction. Each hold carries a fatal-invariant check that the recorded locked amount equals the escrow account balance and that a finished hold holds nothing.

Outcomes

  • Show a provider the funds exist before the work starts
  • Time out a hold without anyone sending a transaction
  • Settle a contested job by arbiter split in basis points

Technical notes

  • Activity types 0x00020001 to 0x00020007. Record 305 bytes; payloads are 288 bytes for open, 80 for capture, 64 for release, 32 for dispute open, 68 for dispute resolve; each activity emits a 67-byte state event.
  • Only the beneficiary may capture, or the owner acting under a delegated capability; anyone else gets UNAUTHORIZED_CAPTURE (-708). A partial capture must be strictly less than the remaining balance, and no capture may exceed it: CAPTURE_EXCEEDS_HOLD (-707).
  • Capture is refused at or after expiry with HOLD_EXPIRED (-709) without touching balances or hold state, and refused while disputed with HOLD_DISPUTED (-712). Release is refused while disputed. Other state transitions return ESCROW_STATE (-700).
  • A dispute can be opened only while the hold is live and only up to the dispute window, otherwise DISPUTE_WINDOW_CLOSED (-711). Resolution takes a beneficiary share of 0 to 10,000 basis points, floors it, sends the remainder to the owner and checks that the two legs sum to the balance.
  • The epoch-begin sweep settles up to 24 expired holds per pass in a single transfer set, and derives each hold's idempotency key from its escrow id and expiry. A timeout activity submitted before expiry returns NOT_YET_VALID.
  • Expiry and dispute window are absolute millisecond timestamps compared against the batch timestamp. Each escrow activity costs 1/10 of a cent.
import { Client, parseAmount } from "layerx-sdk";

const client = new Client(transport);
await client.call("escrow.open", {
  escrowId, owner, beneficiary, arbiter, assetId,
  amount: parseAmount("5"), expiry, disputeWindow,
  termsHash, agreementReference
});
await client.call("escrow.partialCapture", {
  escrowId, amount: parseAmount("2"), idempotencyKey
});

More in LayerX agent domain

Build on Paxeer.

Give your agent a wallet, set its policy, and settle your first call on LayerX.