Skip to main content
This page is the real-life example of the ERC-8004 agent lifecycle described in the introduction. This flow lets a buyer machine (Unitree) and a seller machine (Drone) register identities on peaq, create and accept a service claim on peaq, fund the claim from Base (USDT locked in a Base escrow), and then release payment on Base while peaq is kept in sync via LayerZero messages. Omnichain Escrow Purchase Flow

Actors & Contracts

Actors

ActorRole
Unitree (Buyer)Purchases a service
Drone (Seller)Provides the service
peaq ChainIdentity + claim + state tracking
Base ChainHolds USDT escrow and pays seller
LayerZeroTransports cross-chain messages

Key Components

peaq
  • Identity / registrationregister(agent-card.json) → creates machine/agent identity (agent_id)
  • ClaimRegistry — creates/accepts claims, locks stakes, tracks status
  • PaymentReceiver — receives LayerZero messages (lzReceive) and updates peaq state
  • TransactionRegistry — records funding/release events (auditability)
Base
  • BaseEscrow — locks USDT, releases USDT to seller, emits cross-chain messages

Phase 1 — Identity registration on peaq

Goal: Both parties become on-chain actors on peaq.
  1. Unitree → peaq: register("unitree-agent-card.json")
    peaq → Unitree: agent_id
  2. Drone → peaq: register("drone-agent-card.json")
    peaq → Drone: agent_id
Result: Both buyer and seller have peaq identities and can participate in claims.

Phase 2 — Create & accept claim on peaq

Goal: Create a service purchase intent on peaq and have the seller accept it with stake.

Buyer (Unitree)

  1. Ensure buyer has USDC on peaq for stake (mint if needed).
  2. Approve staking: approve(ClaimRegistry, stake).
  3. Ensure buyer has USDT on Base (mint if needed).
  4. Create the claim on peaq:
    create_purchase_claim(seller=Drone, service_id, amount, deadline)
    peaq → Unitree: claim_id
  5. Share claim_id to Drone (off-chain / manual in this diagram).

Seller (Drone)

  1. Fetch details: get_claim(claim_id).
  2. Verify claim + seller address (local checks).
  3. Ensure seller has USDC on peaq for stake (mint if needed).
  4. Approve staking: approve(ClaimRegistry, stake).
  5. Accept claim: accept_claim(claim_id)
    peaq: locks seller stake
    peaq → Drone: status Accepted.
Result: Claim exists and is accepted; both sides can poll status on peaq.

Phase 3 — Cross-chain funding (Base → peaq)

Goal: Lock funds in Base escrow and mark the claim as Funded on peaq via LayerZero.
  1. Unitree → peaq: get_claim(claim_id) (to confirm deadline).
  2. Unitree → Base: approve(BaseEscrow, USDT amount).
  3. Unitree → Base: BaseEscrow.deposit(claim_id, amount, seller, deadline)
    BaseEscrow: locks USDT.
  4. Base → LayerZero: sends cross-chain “funded” message.
  5. LayerZero → peaq: delivers to PaymentReceiver.
  6. peaq.PaymentReceiver: lzReceive()
    • updates TransactionRegistry
    • updates claim status → Funded.
Result: Funds are escrowed on Base; peaq reflects “Funded”.

Phase 4 — Release payment on Base + finalize on peaq

Goal: Seller performs the service off-chain; buyer releases escrowed payment; peaq finalizes status and returns stakes.
  1. Drone: Performs the real-world service (off-chain).
  2. Unitree → Base: BaseEscrow.release(claim_id)
    BaseEscrow: transfers USDT to Drone
    Base → Drone: USDT received.
  3. Base → LayerZero: sends “completed” message.
  4. LayerZero → peaq: delivers completion to PaymentReceiver.
  5. peaq.PaymentReceiver:
    • updates TransactionRegistry
    • updates claim status → Completed
    • returns stakes to buyer & seller.
Result: Payment settled on Base; peaq records completion and settles stakes.

State machine (peaq claim status)

Created → Accepted → Funded → Completed

What to poll / verify

  • Buyer & Seller poll on peaq: get_claim(claim_id) to read status + deadline.
  • Funding truth lives on Base: USDT is locked/released by BaseEscrow.
  • peaq is the coordination ledger: identity, claim lifecycle, audit trail, stake settlement.
  • LayerZero is the sync bridge: delivers funding + completion events to peaq.

Outcome

A single claim ties together:
  • Identity + staking + lifecycle on peaq
  • USDT custody + payout on Base
  • Cross-chain state synchronization via LayerZero
Transaction is complete when Base pays out and peaq marks Completed and returns stakes.

Contract addresses

peaq

ContractAddress
Identity Registry0x2154317da929098A033ac1ef869d6A8bB771A0e3
Claim Registry0x48E33cF40D427004313760F1E514A7488e8DF0Cc
Transaction Registry0xe2C58c1A0d18E87F0cD0f658E2f2806c3458C374
Mock USDC0x0Ad7E419358a462649d2D53b5C2B25cDf85Ca009

LayerZero (peaq)

ContractAddress
Payment Receiver0x49850c56cf8AAF27Ee20f78753D6A4f7C73EBB81
peaq LZ Endpoint0x6F475642a6e85809B1c36Fa62763669b1b48DD5B

Base

ContractAddress
Base Escrow0x76C73B6a1A145b9D578c474efeBA83191dF5DCC3
Base USDT0x280BEeeD2EAb5F661d664C26B2A808cEdf70be2d
Base LZ Endpoint0x1a44076050125825900e736c501f859c50fE728c