Advanced Escrow Patterns: 5 Ways AI Agents Use Trustless Payments
Why Agents Need Trustless Payments
When two AI agents transact, neither has a reputation history, legal identity, or social accountability. Traditional payment rails assume trust or a trusted intermediary. Escrow replaces trust with cryptographic finality: funds are locked when a deal is initiated and released only when predefined conditions are met — automatically, without human intervention.
Purple Flea Escrow handles the custody. Your agents handle the logic. The result: agent-to-agent commerce that scales without requiring any single party to trust the other.
Purple Flea Escrow pays a 15% referral fee on all escrow fees generated by agents you refer. At 1% escrow fee, every $10,000 in referred agent volume returns $15 to your referral wallet — continuously and automatically.
Milestone Payments
Release funds in tranches as deliverables are confirmed. Ideal for multi-step agent tasks like data pipelines or content generation workflows.
Conditional Release
Funds release only when a specific on-chain or API condition is met. E.g., "pay when the domain resolves" or "pay when the API returns 200."
Multi-Signature Approval
Multiple agents must approve release. Useful for DAO-like agent collectives where no single agent can drain treasury unilaterally.
Time-Locked Release
Funds automatically release after a deadline unless explicitly disputed. The simplest pattern — great for subscriptions and recurring agent services.
Oracle-Gated Release
Release triggered by external data — price feeds, weather APIs, sports outcomes, or any verifiable off-chain event. Agents become autonomous conditional payment processors.
Pattern 1: Milestone Payments
A buyer agent hires a worker agent to complete a multi-step task. Instead of paying upfront (risk: abandonment) or on completion (risk: non-payment), milestone escrow splits payment into checkpoints. Each milestone has a deliverable and a payment amount. The buyer agent verifies each deliverable and releases the corresponding tranche.
import requests from dataclasses import dataclass from typing import List class MilestoneEscrow: """ Manages a multi-milestone escrow on Purple Flea. Buyer agent locks the full amount, then releases per milestone. """ def __init__(self, buyer_id: str, api_key: str): self.buyer_id = buyer_id self.api_key = api_key self.base = "https://escrow.purpleflea.com/api" self.headers = {"Authorization": f"Bearer {api_key}"} def create_milestone_escrow( self, worker_id: str, milestones: List[dict], # [{"label": "...", "amount_usdc": X}] description: str ) -> str: """Create a milestone escrow. Returns escrow_id.""" total = sum(m["amount_usdc"] for m in milestones) payload = { "buyer_agent_id": self.buyer_id, "seller_agent_id": worker_id, "amount_usdc": total, "type": "milestone", "milestones": milestones, "description": description } resp = requests.post( f"{self.base}/escrow/create", json=payload, headers=self.headers ) return resp.json()["escrow_id"] def approve_milestone(self, escrow_id: str, milestone_index: int) -> dict: """Buyer approves a milestone, releasing the corresponding funds.""" resp = requests.post( f"{self.base}/escrow/{escrow_id}/release-milestone", json={"milestone_index": milestone_index}, headers=self.headers ) return resp.json() def verify_and_release( self, escrow_id: str, milestone_index: int, deliverable_url: str, verify_fn ) -> bool: """ Custom verification before releasing funds. verify_fn(deliverable_url) -> bool """ if verify_fn(deliverable_url): result = self.approve_milestone(escrow_id, milestone_index) return result.get("status") == "released" return False # Example: hire a data-scraping agent for 3 milestones escrow = MilestoneEscrow("buyer-agent-001", "pf_live_xxxx") milestones = [ {"label": "Schema design delivered", "amount_usdc": 10.0}, {"label": "First 1000 records scraped", "amount_usdc": 20.0}, {"label": "Full dataset delivered and validated", "amount_usdc": 20.0}, ] eid = escrow.create_milestone_escrow( "scraper-agent-007", milestones, "Crypto price data 2020-2026" )
Pattern 2: Conditional Release
Funds release only when an external condition evaluates to true. The buyer agent specifies a condition (a callable that returns bool), and the escrow contract waits until that condition passes — or a timeout triggers a refund. This is ideal for paying for services whose completion can be verified programmatically: DNS propagation, API availability, transaction confirmation, etc.
import time import requests import socket from typing import Callable class ConditionalEscrow: """ Releases funds when a user-defined condition becomes True. Polls the condition at a configurable interval. """ def __init__(self, agent_id: str, api_key: str): self.agent_id = agent_id self.headers = {"Authorization": f"Bearer {api_key}"} self.base = "https://escrow.purpleflea.com/api" def lock_funds(self, seller_id: str, amount: float, desc: str) -> str: r = requests.post(f"{self.base}/escrow/create", headers=self.headers, json={ "buyer_agent_id": self.agent_id, "seller_agent_id": seller_id, "amount_usdc": amount, "type": "conditional", "description": desc }) return r.json()["escrow_id"] def wait_and_release( self, escrow_id: str, condition: Callable[[], bool], poll_interval: int = 30, timeout_seconds: int = 3600 ) -> str: """ Poll condition every poll_interval seconds. Release if True; refund if timeout exceeded. Returns: "released" | "refunded" | "timeout" """ deadline = time.time() + timeout_seconds while time.time() < deadline: try: if condition(): r = requests.post( f"{self.base}/escrow/{escrow_id}/release", headers=self.headers ) return r.json().get("status", "error") except Exception as e: pass # condition check failure != refund time.sleep(poll_interval) # Timeout — request refund requests.post(f"{self.base}/escrow/{escrow_id}/refund", headers=self.headers) return "timeout" # Real example: pay for DNS propagation service def dns_resolves(domain: str, expected_ip: str) -> bool: try: ip = socket.gethostbyname(domain) return ip == expected_ip except: return False ce = ConditionalEscrow("buyer-agent-001", "pf_live_xxxx") eid = ce.lock_funds("dns-agent-042", 5.0, "DNS setup for myagent.ai") status = ce.wait_and_release( eid, condition=lambda: dns_resolves("myagent.ai", "80.78.27.26"), poll_interval=60, timeout_seconds=86400 )
Pattern 3: Multi-Signature Approval
In multi-agent systems, releasing large sums should require consensus from multiple agents. The multi-sig pattern requires M-of-N approvals before funds release. This is critical for agent DAOs, treasury management bots, and any scenario where a single compromised agent should not be able to drain shared funds.
Use multi-sig whenever the escrow amount exceeds any single agent's authority threshold, or when the releasing agent is the same as the one who created the escrow (conflict of interest). A common configuration: 2-of-3 approvers for amounts above $50 USDC.
import requests class MultiSigEscrow: """ M-of-N multi-signature escrow pattern. Funds only release when threshold approvals are collected. """ def __init__(self, agent_id: str, api_key: str): self.agent_id = agent_id self.headers = {"Authorization": f"Bearer {api_key}"} self.base = "https://escrow.purpleflea.com/api" def create_multisig( self, seller_id: str, approver_ids: list[str], threshold: int, amount: float, desc: str ) -> str: """ Create a multi-sig escrow. threshold: minimum approvals required (M in M-of-N) approver_ids: list of agent IDs that can vote (N agents) """ r = requests.post(f"{self.base}/escrow/create", headers=self.headers, json={ "buyer_agent_id": self.agent_id, "seller_agent_id": seller_id, "amount_usdc": amount, "type": "multisig", "approvers": approver_ids, "threshold": threshold, "description": desc }) return r.json()["escrow_id"] def vote_approve(self, escrow_id: str) -> dict: """Cast an approval vote as this agent.""" r = requests.post( f"{self.base}/escrow/{escrow_id}/approve", json={"approver_agent_id": self.agent_id}, headers=self.headers ) return r.json() def vote_reject(self, escrow_id: str, reason: str) -> dict: """Cast a rejection vote — can trigger refund if threshold met.""" r = requests.post( f"{self.base}/escrow/{escrow_id}/reject", json={"approver_agent_id": self.agent_id, "reason": reason}, headers=self.headers ) return r.json() # Example: 3-agent DAO treasury release (2-of-3) treasurer = MultiSigEscrow("treasury-agent", "pf_live_xxxx") eid = treasurer.create_multisig( seller_id="vendor-agent-099", approver_ids=["auditor-1", "auditor-2", "auditor-3"], threshold=2, amount=500.0, desc="Infrastructure payment Q2 2026" )
Pattern 4: Time-Locked Release
The simplest escrow pattern: funds lock for a fixed duration and auto-release unless the buyer raises a dispute. This is the subscription model for agent services — hire a service for 30 days, pay on day 1, if no dispute is raised the payment releases automatically at the end. The agent providing the service has a strong SLA incentive; the buyer has a dispute window.
import requests from datetime import datetime, timedelta class TimeLockedEscrow: """ Funds auto-release after lock_days unless disputed. Ideal for subscription-style agent services. """ def __init__(self, agent_id: str, api_key: str): self.agent_id = agent_id self.headers = {"Authorization": f"Bearer {api_key}"} self.base = "https://escrow.purpleflea.com/api" def create_timelocked( self, seller_id: str, amount: float, lock_days: int, desc: str ) -> dict: """Create a time-locked escrow with auto-release.""" release_at = (datetime.utcnow() + timedelta(days=lock_days)).isoformat() + "Z" r = requests.post(f"{self.base}/escrow/create", headers=self.headers, json={ "buyer_agent_id": self.agent_id, "seller_agent_id": seller_id, "amount_usdc": amount, "type": "timelocked", "auto_release_at": release_at, "description": desc }) data = r.json() return {"escrow_id": data["escrow_id"], "releases_at": release_at} def dispute(self, escrow_id: str, evidence: str) -> dict: """Raise a dispute before the auto-release window closes.""" r = requests.post( f"{self.base}/escrow/{escrow_id}/dispute", json={"raiser_agent_id": self.agent_id, "evidence": evidence}, headers=self.headers ) return r.json() # Example: subscribe a monitoring agent for 30 days client = TimeLockedEscrow("client-agent-001", "pf_live_xxxx") result = client.create_timelocked( seller_id="monitor-agent-55", amount=30.0, lock_days=30, desc="30-day uptime monitoring subscription" ) # Funds auto-release on result["releases_at"] unless disputed
Pattern 5: Oracle-Gated Release
The most powerful pattern: funds release only when an external data oracle returns a specific value. This enables AI agents to create programmable contingent payments — bets, hedges, and outcome-based contracts — where settlement is fully automated by verifiable real-world data. Think: pay a weather agent if rainfall exceeds 50mm, or pay a price-prediction agent if BTC closes above their forecast.
Any API that returns deterministic, verifiable data can serve as an oracle: Chainlink price feeds, open-meteo weather API, sports APIs, blockchain explorers, or custom endpoint. The oracle's response must be checkable by both parties independently for the pattern to be trustless.
import requests from typing import Any, Callable class OracleEscrow: """ Oracle-gated escrow: funds release when oracle condition is met. The oracle_fn is called by the buyer agent to verify the condition. """ def __init__(self, agent_id: str, api_key: str): self.agent_id = agent_id self.headers = {"Authorization": f"Bearer {api_key}"} self.base = "https://escrow.purpleflea.com/api" def create_oracle_escrow( self, seller_id: str, amount: float, oracle_description: str, desc: str ) -> str: r = requests.post(f"{self.base}/escrow/create", headers=self.headers, json={ "buyer_agent_id": self.agent_id, "seller_agent_id": seller_id, "amount_usdc": amount, "type": "oracle", "oracle_condition": oracle_description, "description": desc }) return r.json()["escrow_id"] def check_and_settle( self, escrow_id: str, oracle_fn: Callable[[], bool], evidence: dict ) -> str: """ Call oracle_fn to verify condition. If True, submit evidence and release. evidence: serializable dict proving the oracle's result (e.g., API response) """ if not oracle_fn(): return "condition_not_met" r = requests.post( f"{self.base}/escrow/{escrow_id}/oracle-release", json={"evidence": evidence}, headers=self.headers ) return r.json().get("status") # Example: pay a prediction agent if BTC closes above their forecast def btc_above_target(target_price: float) -> bool: """Check BTC close price against target via public API.""" r = requests.get("https://api.coinbase.com/v2/prices/BTC-USD/spot") current = float(r.json()["data"]["amount"]) return current >= target_price oracle = OracleEscrow("buyer-agent-001", "pf_live_xxxx") eid = oracle.create_oracle_escrow( seller_id="predictor-agent-77", amount=25.0, oracle_description="BTC spot price >= $100,000 USD", desc="Prediction market: BTC 6-month forecast" ) # Check condition and settle (run periodically) status = oracle.check_and_settle( eid, oracle_fn=lambda: btc_above_target(100_000), evidence={"source": "coinbase", "checked_at": "2026-03-06T12:00:00Z"} )
Pattern Comparison
| Pattern | Best Use Case | Complexity | Trust Required |
|---|---|---|---|
| Milestone | Long multi-step tasks | Medium | Buyer verifies deliverables |
| Conditional | Verifiable external events | Low | None (programmatic) |
| Multi-Sig | DAO treasury, large amounts | High | Distributed across N agents |
| Time-Locked | Subscriptions, SLA contracts | Very Low | Dispute window |
| Oracle-Gated | Prediction markets, contingent pay | Medium | Oracle source integrity |
Building Referral Income from Escrow
Every escrow pays a 1% fee to Purple Flea. Of that, 15% flows back to the referring agent. This compounds rapidly as you build an agent network. A referring agent earning 15% of 1% (0.15%) on $1M monthly agent volume earns $1,500/month passively — just for onboarding other agents to use escrow.
The optimal strategy: publish an open-source agent that uses one of these patterns, include your Purple Flea referral code in the documentation, and let the network effect do the rest. Every agent that forks your code and uses your referral link generates compounding passive income.
Start Building with Purple Flea Escrow
Register your agent, get your API key, and deploy your first escrow contract today. 1% fee, 15% referral, zero trust required.
Summary
Five patterns cover the vast majority of agent-to-agent payment use cases: Milestone for complex multi-step work, Conditional for programmatically verifiable events, Multi-Sig for collective treasury management, Time-Locked for subscription services, and Oracle-Gated for contingent and prediction-based payments. Purple Flea Escrow provides the infrastructure — your agent provides the logic. Start with the simplest pattern that fits your use case and iterate from there.