/** * @module registries/x402 * @description x402 payment flow registry — high-level helpers for * the complete x402 HTTP micropayment lifecycle. * * Implements the x402 payment standard on SAP: * * ┌──────────┐ HTTP 402 ┌──────────┐ * │ Client │ ──────────────→│ Agent │ * └────┬─────┘ └────┬─────┘ * │ 1. Discover pricing │ * │ 2. Create/fund escrow │ * │ 3. Call via x402 header │ * │ │ * │ 4. Agent serves request │ * │ 5. Agent settles onchain │ * │ ← PaymentSettledEvent ← │ * │ 6. Client verifies │ * └───────────────────────────┘ * * This registry provides: * - Pricing estimation with volume curve support * - x402 HTTP header generation * - Escrow lifecycle management * - Settlement verification * - Balance/expiry monitoring * * @category Registries * @since v0.1.0 * * @example * ```ts * const x402 = client.x402; * * // === CLIENT SIDE === * * // 1. Estimate cost before committing * const estimate = x402.estimateCost(agentWallet, 100); * * // 2. Prepare payment (creates escrow + deposits) * const ctx = await x402.preparePayment(agentWallet, { * pricePerCall: 1000, * maxCalls: 100, * deposit: 100_000, * }); * * // 3. Build x402 HTTP headers for API calls * const headers = x402.buildPaymentHeaders(ctx); * * // 4. Check balance * const balance = await x402.getBalance(agentWallet); * * // === AGENT SIDE === * * // 5. Settle after serving calls * const receipt = await x402.settle(depositorWallet, 5, serviceData); * * // 6. Batch settle for efficiency * const batchReceipt = await x402.settleBatch(depositorWallet, settlements); * * // 7. Verify a settlement TX * const verified = await x402.verifySettlement(txSignature); * ``` */ import { type PublicKey, type TransactionSignature } from "@solana/web3.js"; import { BN } from "@coral-xyz/anchor"; import type { SapProgram } from "../modules/base"; import type { SapNetworkId } from "../constants/network"; import type { EscrowAccountV2Data, VolumeCurveBreakpoint } from "../types"; import type { SettleOptions } from "../utils/priority-fee"; export type { SettleOptions } from "../utils/priority-fee"; /** * @interface CostEstimate * @name CostEstimate * @description Cost estimation result from {@link X402Registry.estimateCost} or * {@link X402Registry.calculateCost}. Includes total cost, effective price per call, * and per-tier breakdown when volume curves apply. * @category Registries * @since v0.1.0 */ export interface CostEstimate { /** Total cost in the smallest unit of the escrow token. */ readonly totalCost: BN; /** Number of calls estimated. */ readonly calls: number; /** Effective price per call (weighted average). */ readonly effectivePricePerCall: BN; /** Whether volume curve applies. */ readonly hasVolumeCurve: boolean; /** Breakdown by tier (if volume curve). */ readonly tiers: Array<{ readonly calls: number; readonly pricePerCall: BN; readonly subtotal: BN; }>; } /** * @interface PaymentContext * @name PaymentContext * @description x402 payment context after escrow creation via {@link X402Registry.preparePayment}. * Contains all information needed to build x402 HTTP headers and track the payment flow. * @category Registries * @since v0.1.0 */ export interface PaymentContext { /** Escrow PDA address. */ readonly escrowPda: PublicKey; /** Agent PDA address. */ readonly agentPda: PublicKey; /** Agent wallet. */ readonly agentWallet: PublicKey; /** Depositor (client) wallet. */ readonly depositorWallet: PublicKey; /** Price per call in the smallest unit of the escrow token. */ readonly pricePerCall: BN; /** Max calls allowed. */ readonly maxCalls: BN; /** Escrow nonce used to derive the V2 escrow PDA. */ readonly nonce: BN; /** Escrow creation TX signature. */ readonly txSignature: TransactionSignature; /** * Network identifier for the `X-Payment-Network` header. * Persisted at escrow creation so every subsequent * `buildPaymentHeaders(ctx)` call uses the correct value. * * @default SapNetwork.SOLANA_MAINNET * @since v0.4.3 */ readonly networkIdentifier: string; } /** * @interface PreparePaymentOptions * @name PreparePaymentOptions * @description Options for preparing an x402 payment via {@link X402Registry.preparePayment}. * Defines pricing, deposit, expiry, volume curve, and token configuration. * @category Registries * @since v0.1.0 */ export interface PreparePaymentOptions { /** Base price per call in the smallest unit of the escrow token. */ readonly pricePerCall: number | string | BN; /** Max calls allowed (0 = unlimited). */ readonly maxCalls?: number | string | BN; /** Initial deposit amount in the smallest unit of the escrow token. */ readonly deposit: number | string | BN; /** Expiry timestamp in unix seconds (0 = never). */ readonly expiresAt?: number | string | BN; /** Volume curve breakpoints. */ readonly volumeCurve?: Array<{ afterCalls: number; pricePerCall: number | string | BN; }>; /** SPL token mint (null = native SOL). */ readonly tokenMint?: PublicKey | null; /** Token decimals (default: 9 for SOL). */ readonly tokenDecimals?: number; /** Escrow nonce. Defaults to 0 for the canonical escrow. */ readonly nonce?: number | string | BN; /** Settlement security for the V2 escrow: 1=CoSigned, 2=DisputeWindow. */ readonly settlementSecurity?: 1 | 2; /** Dispute window slots for DisputeWindow escrows. */ readonly disputeWindowSlots?: number | string | BN; /** Required co-signer for CoSigned escrows. */ readonly coSigner?: PublicKey | null; /** Deprecated arbiter field, kept for IDL compatibility. */ readonly arbiter?: PublicKey | null; /** * Network identifier written into the `X-Payment-Network` header. * * Accepts any {@link SapNetworkId} constant or a custom string. * Defaults to `SapNetwork.SOLANA_MAINNET` (`"solana:mainnet-beta"`). * * @example * ```ts * import { SapNetwork } from "@synapse-sap/sdk"; * * // Use genesis-hash form for Kamiyo / Helius x402 * const ctx = await x402.preparePayment(agentWallet, { * pricePerCall: 1000, * deposit: 100_000, * networkIdentifier: SapNetwork.SOLANA_MAINNET_GENESIS, * }); * ``` * * @default SapNetwork.SOLANA_MAINNET * @since v0.4.3 */ readonly networkIdentifier?: SapNetworkId | string; } /** * @interface X402Headers * @name X402Headers * @description x402 HTTP headers for API requests. * Include these headers when calling an agent’s x402 endpoint. * Built by {@link X402Registry.buildPaymentHeaders} or * {@link X402Registry.buildPaymentHeadersFromEscrow}. * @category Registries * @since v0.1.0 */ export interface X402Headers { /** x402 protocol header. */ readonly "X-Payment-Protocol": "SAP-x402"; /** Escrow PDA address (base58). */ readonly "X-Payment-Escrow": string; /** Agent PDA address (base58). */ readonly "X-Payment-Agent": string; /** Client wallet address (base58). */ readonly "X-Payment-Depositor": string; /** Max calls remaining. */ readonly "X-Payment-MaxCalls": string; /** Price per call. */ readonly "X-Payment-PricePerCall": string; /** SAP program ID. */ readonly "X-Payment-Program": string; /** Solana cluster. */ readonly "X-Payment-Network": string; } /** * @interface EscrowBalance * @name EscrowBalance * @description Escrow balance and status returned by {@link X402Registry.getBalance}. * Includes current balance, deposit/settlement totals, remaining calls, * expiry status, and affordable call estimate. * @category Registries * @since v0.1.0 */ export interface EscrowBalance { /** Current balance. */ readonly balance: BN; /** Total deposited. */ readonly totalDeposited: BN; /** Total settled. */ readonly totalSettled: BN; /** Total calls settled. */ readonly totalCallsSettled: BN; /** Calls remaining (maxCalls - settled, or Infinity if unlimited). */ readonly callsRemaining: number; /** Is the escrow expired? */ readonly isExpired: boolean; /** Estimated calls affordable with current balance. */ readonly affordableCalls: number; } /** * @interface SettlementResult * @name SettlementResult * @description Settlement result with verification data from {@link X402Registry.settle}. * Contains the transaction signature, calls settled, amount transferred, * and the service hash used. * @category Registries * @since v0.1.0 */ export interface SettlementResult { /** Transaction signature. */ readonly txSignature: TransactionSignature; /** Calls settled. */ readonly callsSettled: number; /** Amount transferred. */ readonly amount: BN; /** Service hash used. */ readonly serviceHash: number[]; } /** * @interface BatchSettlementResult * @name BatchSettlementResult * @description Batch settlement result from {@link X402Registry.settleBatch}. * Aggregates totals across all individual settlements in the batch. * @category Registries * @since v0.1.0 */ export interface BatchSettlementResult { /** Last transaction signature. */ readonly txSignature: TransactionSignature; /** All transaction signatures emitted by the V2 sequential batch. */ readonly txSignatures?: TransactionSignature[]; /** Total calls settled. */ readonly totalCalls: number; /** Total amount transferred. */ readonly totalAmount: BN; /** Number of individual settlements in batch. */ readonly settlementCount: number; } export interface X402EscrowLookupOptions { /** Escrow nonce. Defaults to 0 for the canonical escrow. */ readonly nonce?: number | string | BN; } export interface X402SettleOptions extends SettleOptions { /** Escrow nonce. Defaults to 0 for the canonical escrow. */ readonly nonce?: number | string | BN; } /** * @name X402Registry * @description x402 payment flow registry for the SAP network. * * Provides the complete x402 HTTP micropayment lifecycle: pricing * estimation, escrow management, HTTP header generation, settlement, * and balance monitoring. Used by both clients (payers) and agents (payees). * * @category Registries * @since v0.1.0 * * @example * ```ts * const x402 = client.x402; * * // Client: prepare payment and build headers * const ctx = await x402.preparePayment(agentWallet, { * pricePerCall: 1000, maxCalls: 100, deposit: 100_000, * }); * const headers = x402.buildPaymentHeaders(ctx); * * // Agent: settle calls after serving * const receipt = await x402.settle(depositorWallet, 5, "service-data"); * ``` */ export declare class X402Registry { private readonly program; private readonly wallet; constructor(program: SapProgram); private nonceBn; private nonceNumber; /** * @name estimateCost * @description Estimate the cost of N calls to an agent. * Reads the escrow data if it exists, falls back to the agent’s pricing. * Supports volume curve pricing for tiered cost calculation. * * @param agentWallet - Agent wallet address. * @param calls - Number of calls to estimate. * @param opts - Optional: provide pricing directly to avoid on-chain fetch. * @param opts.pricePerCall - Base price per call. * @param opts.volumeCurve - Volume curve breakpoints. * @param opts.totalCallsBefore - Total calls already settled (for curve offset). * @returns A {@link CostEstimate} with total cost and per-tier breakdown. * @since v0.1.0 */ estimateCost(agentWallet: PublicKey, calls: number, opts?: { pricePerCall?: BN; volumeCurve?: VolumeCurveBreakpoint[]; totalCallsBefore?: number; }): Promise; /** * @name calculateCost * @description Pure cost calculation (no network calls). * Implements the same tiered pricing logic as the on-chain program. * * @param basePrice - Base price per call in the smallest unit of the escrow token. * @param volumeCurve - Volume curve breakpoints. * @param totalCallsBefore - Total calls already settled (cursor offset). * @param calls - Number of calls to calculate cost for. * @returns A {@link CostEstimate} with total cost and per-tier breakdown. * @since v0.1.0 */ calculateCost(basePrice: BN, volumeCurve: VolumeCurveBreakpoint[], totalCallsBefore: number, calls: number): CostEstimate; /** * @name preparePayment * @description Prepare an x402 payment flow — creates and funds an escrow. * Derives the V2 escrow PDA, sends the `createEscrowV2` instruction, and returns * a {@link PaymentContext} for building x402 headers. * * @param agentWallet - The agent’s wallet public key. * @param opts - Payment options (price, max calls, deposit, etc.). * @returns A {@link PaymentContext} with escrow details and transaction signature. * @since v0.1.0 * * @example * ```ts * const ctx = await x402.preparePayment(agentWallet, { * pricePerCall: 1000, * maxCalls: 100, * deposit: 100_000, * }); * ``` */ preparePayment(agentWallet: PublicKey, opts: PreparePaymentOptions): Promise; /** * @name addFunds * @description Add more funds to an existing escrow. * * @param agentWallet - Agent wallet of the escrow. * @param amount - Amount to deposit in the smallest unit of the escrow token. * @returns The transaction signature. * @since v0.1.0 */ addFunds(agentWallet: PublicKey, amount: number | string | BN, opts?: X402EscrowLookupOptions): Promise; /** * @name withdrawFunds * @description Withdraw remaining funds from an escrow. * * @param agentWallet - Agent wallet of the escrow. * @param amount - Amount to withdraw in the smallest unit of the escrow token. * @returns The transaction signature. * @since v0.1.0 */ withdrawFunds(agentWallet: PublicKey, amount: number | string | BN, opts?: X402EscrowLookupOptions): Promise; /** * @name closeEscrow * @description Close an empty escrow (balance must be 0). * Reclaims the rent-exempt lamports. * * @param agentWallet - Agent wallet of the escrow. * @returns The transaction signature. * @since v0.1.0 */ closeEscrow(agentWallet: PublicKey, opts?: X402EscrowLookupOptions): Promise; /** * @name buildPaymentHeaders * @description Build x402 HTTP headers for API requests. * Include these headers when calling an agent’s x402 endpoint. * * @param ctx - Payment context from {@link X402Registry.preparePayment}. * @param opts - Optional settings. * @param opts.network - Solana cluster name (defaults to `"mainnet-beta"`). * @returns An {@link X402Headers} object ready to merge into HTTP requests. * @since v0.1.0 */ buildPaymentHeaders(ctx: PaymentContext, opts?: { network?: string; }): X402Headers; /** * @name buildPaymentHeadersFromEscrow * @description Build x402 headers directly from an agent wallet (fetches escrow data). * Convenience method that fetches the escrow account on-chain. * * @param agentWallet - Agent wallet to look up the escrow for. * @param opts - Optional settings. * @param opts.network - Network identifier for the `X-Payment-Network` header. * Defaults to `SapNetwork.SOLANA_MAINNET`. * @returns An {@link X402Headers} object, or `null` if no escrow exists. * @since v0.1.0 */ buildPaymentHeadersFromEscrow(agentWallet: PublicKey, opts?: { network?: SapNetworkId | string; nonce?: number | string | BN; }): Promise; /** * @name settle * @description Settle calls — agent claims payment for calls served. * Must be called by the agent owner wallet. Calculates the settlement * amount using the escrow’s pricing and volume curve. * * @param depositorWallet - The client wallet that funded the escrow. * @param callsToSettle - Number of calls to settle. * @param serviceData - Raw service data (auto-hashed to `service_hash`). * @param opts - Optional {@link SettleOptions} for priority fees and RPC tuning. * @returns A {@link SettlementResult} with transaction details and amount. * @since v0.1.0 * @updated v0.6.2 — Added optional `opts` parameter for priority fees. * * @example * ```ts * // Default (no priority fee) * const receipt = await x402.settle(depositor, 1, "data"); * * // Fast settlement with priority fee * import { FAST_SETTLE_OPTIONS } from "@synapse-sap/sdk"; * const receipt = await x402.settle(depositor, 1, "data", FAST_SETTLE_OPTIONS); * * // Custom priority fee * const receipt = await x402.settle(depositor, 1, "data", { * priorityFeeMicroLamports: 10_000, * computeUnits: 100_000, * skipPreflight: true, * }); * ``` */ settle(depositorWallet: PublicKey, callsToSettle: number, serviceData: string | Buffer | Uint8Array, opts?: X402SettleOptions): Promise; /** * @name settleBatch * @description Client-side V2 batch settle. Must be called by the agent owner * wallet. Each entry is settled through the canonical V2 instruction. * * Optionally accepts {@link SettleOptions} to configure priority fees, * compute budget, and RPC behavior for faster confirmation. * * @param depositorWallet - The client wallet that funded the escrow. * @param entries - Array of `{ calls, serviceData }` settlement entries. * @param opts - Optional {@link SettleOptions} for priority fees and RPC tuning. * @returns A {@link BatchSettlementResult} with aggregated totals. * @since v0.1.0 * @updated v0.6.2 — Added optional `opts` parameter for priority fees. * * @example * ```ts * import { FAST_BATCH_SETTLE_OPTIONS } from "@synapse-sap/sdk"; * const receipt = await x402.settleBatch(depositor, entries, FAST_BATCH_SETTLE_OPTIONS); * ``` */ settleBatch(depositorWallet: PublicKey, entries: Array<{ calls: number; serviceData: string | Buffer | Uint8Array; }>, opts?: X402SettleOptions): Promise; /** * @name getBalance * @description Get the current escrow balance and status. * Returns balance, deposit/settlement totals, remaining calls, * expiry status, and affordable call estimate. * * @param agentWallet - Agent wallet of the escrow. * @param depositor - Depositor wallet (defaults to caller). * @returns An {@link EscrowBalance}, or `null` if no escrow exists. * @since v0.1.0 */ getBalance(agentWallet: PublicKey, depositor?: PublicKey, opts?: X402EscrowLookupOptions): Promise; /** * @name hasEscrow * @description Check if an escrow exists for a given agent + depositor pair. * * @param agentWallet - Agent wallet to check. * @param depositor - Depositor wallet (defaults to caller). * @returns `true` if the escrow account exists on-chain. * @since v0.1.0 */ hasEscrow(agentWallet: PublicKey, depositor?: PublicKey, opts?: X402EscrowLookupOptions): Promise; /** * @name fetchEscrow * @description Fetch the raw escrow account data. * * @param agentWallet - Agent wallet of the escrow. * @param depositor - Depositor wallet (defaults to caller). * @returns The raw {@link EscrowAccountV2Data}, or `null` if not found. * @since v0.1.0 */ fetchEscrow(agentWallet: PublicKey, depositor?: PublicKey, opts?: X402EscrowLookupOptions): Promise; /** * @name methods * @description Accessor for the Anchor program methods namespace. * @returns The program methods object for building RPC calls. * @private */ private get methods(); /** * @name fetchNullable * @description Fetch an on-chain account by name and PDA. Returns `null` if not found. * @param name - Anchor account discriminator name. * @param pda - Account public key to fetch. * @returns The deserialized account data, or `null` if the account does not exist. * @private */ private fetchNullable; /** * @name resolveEscrow * @description Try to find a V2 escrow at nonce=0. * Returns the escrow data, PDA, and version indicator. * @private */ private resolveEscrow; } //# sourceMappingURL=x402.d.ts.map