Escrow API
V2 escrow system with dispute resolution, settlement security, staking, and subscriptions. SDK v0.20.0 aligned.
Escrow API
SDK Version: v0.20.0
The SDK provides three escrow-related modules:
| Module | Access | Status | Description |
|---|---|---|---|
EscrowV2Module | client.escrowV2 | Current | Full escrow with dispute resolution & settlement security |
X402Registry | client.x402 | Current | High-level payment flow (cost estimation, headers, settlement) |
EscrowModule | client.escrow | Deprecated | V1 escrow without disputes - use V2 instead |
EscrowV2Module (v0.20.0)
Access via client.escrowV2. Supports settlement security modes, dispute resolution, and pending settlements.
Settlement Security Modes
V2 escrows require a security mode that determines how settlements are validated:
| Mode | Enum Value | Description |
|---|---|---|
SettlementSecurity.SelfReport | 0 | Agent settles unilaterally - no co-sign needed |
SettlementSecurity.CoSigned | 1 | Both depositor and agent must co-sign every settlement |
SettlementSecurity.DisputeWindow | 2 | Agent proposes settlement, depositor has time window to dispute |
Create V2 Escrow
import { SettlementSecurity } from "@oobe-protocol-labs/synapse-sap-sdk";
await client.escrowV2.create(agentWallet, {
deposit: new BN(100_000),
pricePerCall: new BN(1_000),
maxCalls: new BN(100),
expiresAt: new BN(Math.floor(Date.now() / 1000) + 86400),
securityMode: SettlementSecurity.CoSigned,
});| Field | Type | Description |
|---|---|---|
deposit | BN | Initial deposit in lamports |
pricePerCall | BN | Lamports per call |
maxCalls | BN | Maximum calls (0 = unlimited) |
expiresAt | BN | Unix timestamp (0 = never) |
securityMode | SettlementSecurity | Settlement validation mode |
Deposit / Withdraw / Close
// Top up escrow
await client.escrowV2.deposit(agentWallet, nonce, new BN(50_000));
// Withdraw unused funds (depositor only)
await client.escrowV2.withdraw(agentWallet, nonce, new BN(30_000));
// Close empty escrow (reclaims rent)
await client.escrowV2.close(agentWallet, nonce);Settlement (SelfReport Mode)
import { sha256, hashToArray } from "@oobe-protocol-labs/synapse-sap-sdk";
const serviceHash = hashToArray(sha256("service-proof-001"));
await client.escrowV2.settle(depositorWallet, nonce, new BN(5), serviceHash);Dispute Flow (DisputeWindow Mode)
When using DisputeWindow security, settlements go through a pending state:
// 1. Agent creates pending settlement
await client.escrowV2.createPendingSettlement(
agentWallet, depositorWallet, nonce,
settlementIdx, new BN(5), new BN(5000), serviceHash,
);
// 2. Depositor can dispute within the window
await client.escrowV2.fileDispute(agentWallet, nonce, settlementIdx, evidenceHash);
// 3. Arbiter resolves dispute
await client.escrowV2.resolveDispute(
depositorWallet, agentWallet, nonce, settlementIdx,
DisputeOutcome.DepositorWins,
);
// 4. Or if no dispute, finalize after window expires
await client.escrowV2.finalizeSettlement(agentWallet, depositorWallet, nonce, settlementIdx);
// 5. Cleanup
await client.escrowV2.closeDispute(pendingSettlementPda);
await client.escrowV2.closePendingSettlement(pendingSettlementPda);Dispute Outcomes
| Outcome | Value | Description |
|---|---|---|
DisputeOutcome.Pending | 0 | Dispute filed, awaiting resolution |
DisputeOutcome.DepositorWins | 1 | Funds returned to depositor |
DisputeOutcome.AgentWins | 2 | Agent receives the disputed amount |
DisputeOutcome.AutoReleased | 3 | Window expired - auto-released to agent |
X402Registry (High-Level)
Access via client.x402. Handles cost estimation, payment preparation, header generation, settlement, and balance tracking.
Estimate Cost
const estimate = await client.x402.estimateCost(
agentWallet, // PublicKey: the agent you want to pay
100, // number of calls you plan to make
);
console.log(estimate.totalCost.toString()); // BN → string
console.log(estimate.effectivePricePerCall.toString()); // weighted average
console.log(estimate.hasVolumeCurve); // has tiered pricing?Prepare Payment
Creates escrow and deposits funds in a single transaction:
const ctx = await client.x402.preparePayment(agentWallet, {
pricePerCall: 1_000, // lamports per call (number, string, or BN)
maxCalls: 500, // max calls allowed (0 = unlimited)
deposit: 500_000, // initial deposit in lamports
expiresAt: 0, // Unix timestamp (0 = never expires)
volumeCurve: [ // optional: tiered pricing breakpoints
{ afterCalls: 100, pricePerCall: 800 }, // 20% discount after 100 calls
],
});Build Headers
// From a PaymentContext (returned by preparePayment)
const headers = client.x402.buildPaymentHeaders(ctx);
// From an existing escrow (looks up the PDA on-chain)
const headers = await client.x402.buildPaymentHeadersFromEscrow(agentWallet);Settle
const receipt = await client.x402.settle(depositorWallet, 5, "service-data-v1");Batch Settle
const batch = await client.x402.settleBatch(depositorWallet, [
{ calls: 3, serviceData: "batch-1" },
{ calls: 7, serviceData: "batch-2" },
]);Balance
const balance = await client.x402.getBalance(agentWallet);| Field | Type | Description |
|---|---|---|
balance | BN | Current remaining balance |
totalDeposited | BN | Cumulative deposits |
totalSettled | BN | Cumulative settlements |
callsRemaining | number | Remaining calls |
isExpired | boolean | Expiry check |
affordableCalls | number | Calls the budget allows |
StakingModule (v0.20.0)
Access via client.staking. Agent collateral staking - not yield, but a trust signal and slashing mechanism.
Constants
| Constant | Value | Description |
|---|---|---|
MIN_STAKE | 100,000,000 lamports (0.1 SOL) | Minimum stake amount |
UNSTAKE_COOLDOWN_SLOTS | 1,512,000 (~7 days) | Cooldown before withdrawal |
SLASH_BPS | 5,000 (50%) | Slash penalty for lost disputes |
Lifecycle
// Initialize stake (minimum 0.1 SOL)
await client.staking.initStake(agentWallet, new BN(1_000_000_000));
// Add more stake
await client.staking.deposit(agentWallet, new BN(500_000_000));
// Request unstake (starts 7-day cooldown)
await client.staking.requestUnstake(agentWallet, new BN(500_000_000));
// Complete unstake after cooldown expires
await client.staking.completeUnstake(agentWallet);SubscriptionModule (v0.20.0)
Access via client.subscription. Recurring payment subscriptions with configurable billing intervals.
Billing Intervals
| Interval | Value | Description |
|---|---|---|
BillingInterval.Daily | 0 | Daily billing cycle |
BillingInterval.Weekly | 1 | Weekly billing cycle |
BillingInterval.Monthly | 2 | Monthly billing cycle |
Lifecycle
import { BillingInterval } from "@oobe-protocol-labs/synapse-sap-sdk";
// Create a subscription
await client.subscription.create(agentWallet, {
subId: 1,
amount: new BN(100_000),
interval: BillingInterval.Monthly,
});
// Fund subscription
await client.subscription.fund(agentWallet, 1, new BN(100_000));
// Cancel subscription (stops future billing)
await client.subscription.cancel(agentWallet, 1);
// Close subscription PDA (reclaim rent)
await client.subscription.close(agentWallet, 1);Next Steps
- x402 Payments — Payment flow diagrams
- Security — Escrow safety patterns
- Troubleshooting — Common errors
Last Updated: June 2026
SDK Version: 0.20.0