SAP DOCv0.20.0
SDK Reference

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:

ModuleAccessStatusDescription
EscrowV2Moduleclient.escrowV2CurrentFull escrow with dispute resolution & settlement security
X402Registryclient.x402CurrentHigh-level payment flow (cost estimation, headers, settlement)
EscrowModuleclient.escrowDeprecatedV1 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:

ModeEnum ValueDescription
SettlementSecurity.SelfReport0Agent settles unilaterally - no co-sign needed
SettlementSecurity.CoSigned1Both depositor and agent must co-sign every settlement
SettlementSecurity.DisputeWindow2Agent 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,
});
FieldTypeDescription
depositBNInitial deposit in lamports
pricePerCallBNLamports per call
maxCallsBNMaximum calls (0 = unlimited)
expiresAtBNUnix timestamp (0 = never)
securityModeSettlementSecuritySettlement 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

OutcomeValueDescription
DisputeOutcome.Pending0Dispute filed, awaiting resolution
DisputeOutcome.DepositorWins1Funds returned to depositor
DisputeOutcome.AgentWins2Agent receives the disputed amount
DisputeOutcome.AutoReleased3Window 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);
FieldTypeDescription
balanceBNCurrent remaining balance
totalDepositedBNCumulative deposits
totalSettledBNCumulative settlements
callsRemainingnumberRemaining calls
isExpiredbooleanExpiry check
affordableCallsnumberCalls the budget allows

StakingModule (v0.20.0)

Access via client.staking. Agent collateral staking - not yield, but a trust signal and slashing mechanism.

Constants

ConstantValueDescription
MIN_STAKE100,000,000 lamports (0.1 SOL)Minimum stake amount
UNSTAKE_COOLDOWN_SLOTS1,512,000 (~7 days)Cooldown before withdrawal
SLASH_BPS5,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

IntervalValueDescription
BillingInterval.Daily0Daily billing cycle
BillingInterval.Weekly1Weekly billing cycle
BillingInterval.Monthly2Monthly 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


Last Updated: June 2026
SDK Version: 0.20.0