import { k as BatchPayload, l as BatchEvmSigner, m as BeforePaymentCreationHook, n as AfterPaymentCreationHook, o as OnPaymentCreationFailureHook, p as OnPaymentResponseHook, q as PaymentResponseContext } from '../hooks-BKkPP7ic.mjs'; export { G as GATEWAY_AUTH_VALIDITY_WINDOW_SECONDS } from '../hooks-BKkPP7ic.mjs'; import { Chain, Address, PublicClient, Transport, WalletClient, Account, Hex } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; /** * PaymentRequirements interface (minimal subset needed). */ interface PaymentRequirements$1 { scheme: string; network: string; asset: string; amount: string; payTo: string; maxTimeoutSeconds: number; extra?: Record; } /** * PaymentPayload interface (minimal subset needed). */ interface PaymentPayload$1 { x402Version: number; payload: BatchPayload; } /** * SchemeNetworkClient interface from @x402/core. */ interface SchemeNetworkClient$1 { readonly scheme: string; createPaymentPayload(x402Version: number, paymentRequirements: PaymentRequirements$1): Promise>; } /** * Circle Batching EVM Scheme Client. * * A SchemeNetworkClient implementation for Circle Gateway batched payments. * Signs EIP-3009 TransferWithAuthorization against the GatewayWallet contract * (from `extra.verifyingContract`) instead of the USDC token contract. * * Lifecycle hooks (`onBeforePaymentCreation`, `onAfterPaymentCreation`, * `onPaymentCreationFailure`, `onPaymentResponse`) mirror the standard SDK's * `x402Client` semantics — see https://docs.x402.org/advanced-concepts/lifecycle-hooks. * * Hooks fire inside `createPaymentPayload` so that this scheme can be used * standalone (without `x402Client`). When wrapped by an `x402Client`, register * hooks at that level instead — running them in both places would double-fire. * * @example * ```typescript * import { BatchEvmScheme } from "@circle-fin/x402-batching/client"; * * const scheme = new BatchEvmScheme(evmSigner) * .onBeforePaymentCreation(async (ctx) => { * if (BigInt(ctx.selectedRequirements.amount) > 10_000_000n) { * return { abort: true, reason: "Payment exceeds spending limit" }; * } * }) * .onAfterPaymentCreation(async (ctx) => { * console.log("Signed payment", ctx.paymentPayload); * }); * ``` */ declare class BatchEvmScheme implements SchemeNetworkClient$1 { private readonly signer; readonly scheme = "exact"; private beforePaymentCreationHooks; private afterPaymentCreationHooks; private onPaymentCreationFailureHooks; private paymentResponseHooks; /** * Creates a new BatchEvmScheme. * * @param signer - The EVM signer for signing payment authorizations */ constructor(signer: BatchEvmSigner); /** * Register a hook that runs before payment payload creation. Returning * `{ abort: true, reason }` causes `createPaymentPayload` to throw * `Error("Payment creation aborted: ")`. */ onBeforePaymentCreation(hook: BeforePaymentCreationHook): this; /** * Register a hook that runs after a successful payment payload creation. */ onAfterPaymentCreation(hook: AfterPaymentCreationHook): this; /** * Register a hook that runs when payload creation throws. Return * `{ recovered: true, payload }` to swallow the error and use the * provided payload as the result instead. */ onPaymentCreationFailure(hook: OnPaymentCreationFailureHook): this; /** * Register a hook that runs after the buyer's paid HTTP request completes. * Hooks fire when {@link dispatchPaymentResponse} is called by the * transport. Return `{ recovered: true }` to instruct the transport to * retry with a fresh payload. */ onPaymentResponse(hook: OnPaymentResponseHook): this; /** * Fire all registered `onPaymentResponse` hooks in order. Returns * `{ recovered: true }` if any hook signals recovery (first wins). * * Transport wrappers should call this after the paid HTTP request settles * — see `x402HTTPClient.processPaymentResult` in the standard SDK. */ dispatchPaymentResponse(context: PaymentResponseContext): Promise<{ recovered: true; } | undefined>; /** * Creates a payment payload for Circle batching. * * @param x402Version - The x402 protocol version * @param paymentRequirements - The payment requirements (must be a Circle batching option) * @returns Promise resolving to the payment payload * @throws Error if requirements are not a Circle batching option */ createPaymentPayload(x402Version: number, paymentRequirements: PaymentRequirements$1): Promise>; /** * Sign the EIP-3009 authorization using EIP-712. * Uses the GatewayWallet contract as verifyingContract instead of USDC. */ private signAuthorization; /** * When `createPaymentPayload` is called directly (not through an x402Client), * we don't have a real PaymentRequired response. Synthesize a minimal one * so the hook context still carries the standard SDK's shape. */ private synthesizePaymentRequired; } /** * PaymentRequirements interface (minimal subset needed). */ interface PaymentRequirements { scheme: string; network: string; asset: string; amount: string; payTo: string; maxTimeoutSeconds: number; extra?: Record; } /** * PaymentPayload interface (minimal subset needed). */ interface PaymentPayload { x402Version: number; payload: unknown; } /** * SchemeNetworkClient interface from @x402/core. */ interface SchemeNetworkClient { readonly scheme: string; createPaymentPayload(x402Version: number, paymentRequirements: PaymentRequirements): Promise>; } /** * Composite EVM Scheme that dispatches between BatchEvmScheme and a fallback. * * When both BatchEvmScheme and ExactEvmScheme register for the same `scheme` * ("exact") on the same network wildcard ("eip155:*"), x402Client uses * first-registered-wins. This means one scheme always shadows the other. * * CompositeEvmScheme solves this by registering once and dispatching at * runtime: if the payment requirements include batching metadata * (`supportsBatching()`), it delegates to BatchEvmScheme; otherwise it * delegates to the fallback (typically ExactEvmScheme). * * @example * ```typescript * import { CompositeEvmScheme, BatchEvmScheme } from "@circle-fin/x402-batching/client"; * import { ExactEvmScheme } from "@x402/evm/exact/client"; * * const composite = new CompositeEvmScheme( * new BatchEvmScheme(signer), * new ExactEvmScheme(signer), * ); * client.register("eip155:*", composite); * ``` */ declare class CompositeEvmScheme implements SchemeNetworkClient { private readonly batchScheme; private readonly fallbackScheme; readonly scheme = "exact"; constructor(batchScheme: BatchEvmScheme, fallbackScheme: SchemeNetworkClient); createPaymentPayload(x402Version: number, paymentRequirements: PaymentRequirements): Promise>; } /** * x402Client-like interface (minimal subset needed for registration). */ interface X402ClientLike { register(network: string, client: { readonly scheme: string; }): unknown; } /** * SchemeNetworkClient-like interface (minimal subset for fallback). */ interface SchemeNetworkClientLike { readonly scheme: string; createPaymentPayload(x402Version: number, paymentRequirements: { scheme: string; network: string; asset: string; amount: string; payTo: string; maxTimeoutSeconds: number; extra?: Record; }): Promise<{ x402Version: number; payload: unknown; }>; } /** * Configuration for registering batch scheme. */ interface RegisterBatchSchemeConfig { /** The EVM signer for signing payment authorizations */ signer: BatchEvmSigner; /** Networks to register for (default: all EVM networks via wildcard) */ networks?: string[]; /** * Optional fallback SchemeNetworkClient for non-batching "exact" payments. * * When provided, a CompositeEvmScheme is registered that dispatches to * BatchEvmScheme for Gateway payments and to the fallback for standard * on-chain payments. This avoids the scheme collision where x402Client's * first-registered-wins policy causes one scheme to shadow the other. * * @example * ```typescript * import { ExactEvmScheme } from "@x402/evm/exact/client"; * * registerBatchScheme(client, { * signer: evmSigner, * fallbackScheme: new ExactEvmScheme(evmSigner), * }); * ``` */ fallbackScheme?: SchemeNetworkClientLike; } /** * Register batch scheme with an x402Client. * * This registers a BatchEvmScheme that can handle payment requirements * with `extra.name === "GatewayWalletBatched"`. The scheme signs EIP-3009 * authorizations against the batch wallet contract instead of USDC. * * When `fallbackScheme` is provided, a CompositeEvmScheme is registered * instead, which handles both batch and standard payments in a single * registration — no need to separately register ExactEvmScheme. * * @param client - The x402Client to register with * @param config - Configuration including the EVM signer * @returns The registered scheme instance * * @example * ```typescript * import { x402Client } from "@x402/core/client"; * import { registerBatchScheme } from "@circle-fin/x402-batching/client"; * import { ExactEvmScheme } from "@x402/evm/exact/client"; * import { privateKeyToAccount } from "viem/accounts"; * * const account = privateKeyToAccount("0x..."); * const client = new x402Client(); * * // Handles both batch and standard EVM payments: * registerBatchScheme(client, { * signer: account, * fallbackScheme: new ExactEvmScheme(account), * }); * ``` */ declare function registerBatchScheme(client: X402ClientLike, config: RegisterBatchSchemeConfig & { fallbackScheme: SchemeNetworkClientLike; }): CompositeEvmScheme; declare function registerBatchScheme(client: X402ClientLike, config: Omit): BatchEvmScheme; declare function registerBatchScheme(client: X402ClientLike, config: RegisterBatchSchemeConfig): BatchEvmScheme | CompositeEvmScheme; /** * Gateway domain identifiers for supported chains. * See: https://developers.circle.com/gateway/gateway-supported-blockchains */ declare const GATEWAY_DOMAINS: { readonly arbitrumSepolia: 3; readonly arcTestnet: 26; readonly avalancheFuji: 1; readonly baseSepolia: 6; readonly sepolia: 0; readonly hyperEvmTestnet: 19; readonly optimismSepolia: 2; readonly polygonAmoy: 7; readonly seiAtlantic: 16; readonly sonicTestnet: 13; readonly unichainSepolia: 10; readonly worldChainSepolia: 14; readonly arbitrum: 3; readonly avalanche: 1; readonly base: 6; readonly ethereum: 0; readonly hyperEvm: 19; readonly optimism: 2; readonly polygon: 7; readonly sei: 16; readonly sonic: 13; readonly unichain: 10; readonly worldChain: 14; readonly arc: 26; }; /** * Supported chain names type. */ type SupportedChainName = keyof typeof GATEWAY_DOMAINS; /** * Chain configuration with contract addresses. */ interface ChainConfig { chain: Chain; domain: number; usdc: Address; gatewayWallet: Address; gatewayMinter: Address; rpcUrl?: string; } /** * Chain configurations for supported chains. */ declare const CHAIN_CONFIGS: Record; /** * Configuration for creating a GatewayClient. */ interface GatewayClientConfig { /** The chain to connect to */ chain: SupportedChainName; /** Private key for signing transactions */ privateKey: Hex; /** * Custom RPC URL. Optional for all chains (a public default is used). */ rpcUrl?: string; /** Additional headers merged into every outbound Gateway API request. */ headers?: Record; } /** * Result of a deposit operation. */ interface DepositResult { /** Transaction hash of the approval (if needed) */ approvalTxHash?: Hex; /** Transaction hash of the deposit */ depositTxHash: Hex; /** Amount deposited in USDC atomic units */ amount: bigint; /** Formatted amount deposited */ formattedAmount: string; /** Depositor address */ depositor: Address; } /** * Result of a withdraw operation (instant transfer). */ interface WithdrawResult { /** Transaction hash of the mint on destination chain */ mintTxHash: Hex; /** Amount withdrawn in USDC atomic units */ amount: bigint; /** Formatted amount withdrawn */ formattedAmount: string; /** Source chain name */ sourceChain: string; /** Destination chain name */ destinationChain: string; /** Recipient address */ recipient: Address; } /** * Result of a pay operation. */ interface PayResult { /** The response data from the resource */ data: T; /** Amount paid in USDC atomic units */ amount: bigint; /** Formatted amount paid */ formattedAmount: string; /** Transaction hash from settlement */ transaction: string; /** HTTP status code */ status: number; } /** * All balances in one object. */ interface Balances { /** Regular wallet USDC balance */ wallet: { balance: bigint; formatted: string; }; /** Gateway balances */ gateway: { total: bigint; available: bigint; withdrawing: bigint; withdrawable: bigint; formattedTotal: string; formattedAvailable: string; formattedWithdrawing: string; formattedWithdrawable: string; }; } /** * Result of checking if a URL supports batching. */ interface SupportsResult { /** Whether the URL supports Gateway batching */ supported: boolean; /** Payment requirements if supported */ requirements?: Record; /** Error message if not supported */ error?: string; } /** * Result of a trustless withdrawal initiation. * * NOTE: Trustless withdrawals are for emergency use only when Circle's API is unavailable. * For normal withdrawals, use `transfer()` with the same source and destination chain. */ interface TrustlessWithdrawalInitResult { /** Transaction hash */ txHash: Hex; /** Amount being withdrawn in USDC atomic units */ amount: bigint; /** Formatted amount being withdrawn */ formattedAmount: string; /** Block number at which withdrawal becomes available (~7 days) */ withdrawalBlock: bigint; } /** * Result of a trustless withdrawal completion. * * NOTE: Trustless withdrawals are for emergency use only when Circle's API is unavailable. */ interface TrustlessWithdrawalResult { /** Transaction hash */ txHash: Hex; /** Amount withdrawn in USDC atomic units */ amount: bigint; /** Formatted amount withdrawn */ formattedAmount: string; } /** * Gateway balance information. */ interface GatewayBalance { /** Total balance in Gateway */ total: bigint; /** Available balance (can be used) */ available: bigint; /** Balance in withdrawal process */ withdrawing: bigint; /** Balance ready to be withdrawn */ withdrawable: bigint; /** Formatted total balance */ formattedTotal: string; /** Formatted available balance */ formattedAvailable: string; /** Formatted withdrawing balance */ formattedWithdrawing: string; /** Formatted withdrawable balance */ formattedWithdrawable: string; } type TransferStatus = 'received' | 'batched' | 'confirmed' | 'completed' | 'failed'; /** * Shape may evolve; preserve all fields as returned by the API. */ interface TransferResponse { id: string; status: TransferStatus; token: 'USDC'; sendingNetwork: string; recipientNetwork: string; fromAddress: string; toAddress: string; amount: string; createdAt: string; updatedAt: string; [key: string]: unknown; } interface SearchTransfersParams { from?: Hex; to?: Hex; nonce?: Hex; network?: string; status?: TransferStatus; token?: 'USDC'; startDate?: string; endDate?: string; pageSize?: number; pageAfter?: string; pageBefore?: string; } interface CursorPagination { self?: string; first?: string; prev?: string; next?: string; pageAfter?: string; pageBefore?: string; } interface SearchTransfersResponse { transfers: TransferResponse[]; pagination?: CursorPagination; } /** * Gateway Client for gasless payments and cross-chain USDC via Circle Gateway. * * This client provides a simple interface for buyers to: * - **Deposit**: Move USDC into Gateway for gasless payments * - **Pay**: Pay for x402-protected resources (handles 402 automatically) * - **Withdraw**: Get USDC back (same-chain or cross-chain, instant) * - **GetBalances**: Check all balances in one call * * ## Typical Flow * ```typescript * const gateway = new GatewayClient({ chain: 'arcTestnet', privateKey }); * * // 1. Deposit (one-time setup) * await gateway.deposit('100'); * * // 2. Pay for resources (many times, gasless!) * const { data } = await gateway.pay('https://api.example.com/resource'); * * // 3. Check balances * const balances = await gateway.getBalances(); * * // 4. Withdraw when done * await gateway.withdraw('50'); * // Or withdraw to a different chain (requires gas on destination) * await gateway.withdraw('25', { chain: 'baseSepolia' }); * ``` * * ## Emergency Flow (when Circle's API is down) * Use `initiateTrustlessWithdrawal()` and `completeTrustlessWithdrawal()` (7-day delay). */ declare class GatewayClient { readonly chainConfig: ChainConfig; readonly account: ReturnType; readonly publicClient: PublicClient; readonly walletClient: WalletClient; private readonly _headers; /** * The scheme that builds and signs the batched payment payload. `pay()` * delegates to this so the buyer flow runs the same lifecycle hooks as the * standalone `BatchEvmScheme` / `x402Client` paths. */ private readonly batchScheme; /** * Creates a new GatewayClient. * * @param config - Configuration including chain and private key */ constructor(config: GatewayClientConfig); /** * Register a hook that runs before the payment payload is created. Returning * `{ abort: true, reason }` causes `pay()` to throw before signing. */ onBeforePaymentCreation(hook: BeforePaymentCreationHook): this; /** * Register a hook that runs after the payment payload is successfully created. */ onAfterPaymentCreation(hook: AfterPaymentCreationHook): this; /** * Register a hook that runs when payload creation throws. Return * `{ recovered: true, payload }` to recover with the provided payload. */ onPaymentCreationFailure(hook: OnPaymentCreationFailureHook): this; /** * Register a hook that runs after the buyer's paid HTTP request completes. * Return `{ recovered: true }` to have `pay()` retry once with a fresh payload. */ onPaymentResponse(hook: OnPaymentResponseHook): this; /** * Get the account address. */ get address(): Address; /** * Get the chain name. */ get chainName(): string; /** * Get the Gateway domain for this chain. */ get domain(): number; /** * Get the chain name key for this client. */ getChainName(): SupportedChainName; /** * Get the USDC balance of the account (not in Gateway). * * @param address - Optional address to check (defaults to account address) * @returns USDC balance in atomic units and formatted */ getUsdcBalance(address?: Address): Promise<{ balance: bigint; formatted: string; }>; /** * Get all balances (wallet + gateway) in one call. * * @param address - Optional address to check (defaults to account address) * @returns All balances */ getBalances(address?: Address): Promise; /** * Get the Gateway balance for an address. * * @param address - Optional address to check (defaults to account address) * @returns Gateway balance information * @deprecated Use `getBalances()` instead for a unified view */ getBalance(address?: Address): Promise; /** * Get the Gateway balance for an address via Gateway API. */ private getGatewayBalance; /** * Deposit USDC into the Gateway Wallet. * * This method first approves the Gateway Wallet contract to spend USDC, * then deposits the specified amount. * * @param amount - Amount of USDC to deposit (as a decimal string, e.g., "10.5") * @param options - Optional deposit options * @returns Deposit result with transaction hashes */ deposit(amount: string, options?: { /** Amount to approve (defaults to amount) */ approveAmount?: string; /** Skip approval if already approved */ skipApprovalCheck?: boolean; }): Promise; /** * Deposit USDC into the Gateway Wallet on behalf of another address. * * The resulting balance belongs to the specified depositor address, * not the caller. * * @param amount - Amount of USDC to deposit (as a decimal string) * @param depositor - Address that will own the resulting balance * @param options - Optional deposit options * @returns Deposit result with transaction hashes */ depositFor(amount: string, depositor: Address, options?: { /** Amount to approve (defaults to amount) */ approveAmount?: string; /** Skip approval if already approved */ skipApprovalCheck?: boolean; }): Promise; /** * Check if a URL supports Gateway batching before paying. * * @param url - The URL to check * @returns Whether batching is supported and payment requirements */ supports(url: string): Promise; /** * Pay for an x402-protected resource. * * This method handles the full 402 payment flow automatically: * 1. Makes initial request * 2. If 402, finds Gateway batching option * 3. Signs payment authorization * 4. Retries with Payment-Signature header * * @param url - The URL to pay for * @param options - Optional request options * @returns The response data and payment info * * @example * ```typescript * const { data, amount } = await gateway.pay('https://api.example.com/resource'); * console.log('Paid', amount, 'USDC for:', data); * ``` */ pay(url: string, options?: { /** HTTP method (default: GET) */ method?: 'GET' | 'POST' | 'PUT' | 'DELETE'; /** Request body for POST/PUT */ body?: unknown; /** Additional headers */ headers?: Record; }): Promise>; /** * Withdraw USDC from Gateway to your wallet. * * By default, withdraws to the same chain (instant, no 7-day delay). * Optionally, withdraw to a different chain (requires gas on destination). * * @param amount - Amount of USDC to withdraw (as a decimal string) * @param options - Optional withdrawal options * @returns Withdrawal result with transaction hash * * @example * ```typescript * // Withdraw to same chain (instant!) * await gateway.withdraw('50'); * * // Withdraw to Base Sepolia (requires ETH on Base for gas) * await gateway.withdraw('25', { chain: 'baseSepolia' }); * ``` */ withdraw(amount: string, options?: { /** Destination chain (defaults to same chain) */ chain?: SupportedChainName; /** Recipient address (defaults to your address) */ recipient?: Address; /** Max fee willing to pay in USDC (defaults to 2.01) */ maxFee?: string; }): Promise; /** * Transfer USDC to any supported chain (alias for withdraw with destination chain). * @deprecated Use `withdraw({ chain })` instead */ transfer(amount: string, destinationChain: SupportedChainName, recipient?: Address): Promise; /** * Create a burn intent for a transfer. */ private createBurnIntent; /** * Get a single x402 transfer by ID. * * @param id - The transfer UUID * @returns Transfer object */ getTransferById(id: string): Promise; /** * Search x402 transfers with optional filters. * * Supports cursor-based pagination via `pageAfter` / `pageBefore`. * When `network` is omitted, defaults to the client's chain (e.g., `eip155:84532`). * When `status` is provided, also provide `from`, `to`, or `nonce`. * * @param params - Optional transfer search filters * @returns Paginated transfer search response */ searchTransfers(params?: SearchTransfersParams): Promise; private gatewayApiHeaders; /** * Check if this client is connected to a testnet. */ private isTestnet; /** * Parse pagination from an RFC 5988 Link header. * Could be replaced with 'http-link-header' library * * Example: * ; rel="next", <...>; rel="self" */ private parseLinkHeader; private getQueryParam; /** * Get the trustless withdrawal delay in blocks (~7 days). * * NOTE: This is for the emergency trustless withdrawal flow only. * For normal withdrawals, use `transfer()` to the same chain. * * @returns Number of blocks to wait after initiating trustless withdrawal */ getTrustlessWithdrawalDelay(): Promise; /** * Get the block at which a pending trustless withdrawal becomes available. * * @param address - Optional address to check (defaults to account address) * @returns Block number, or 0n if no pending withdrawal */ getTrustlessWithdrawalBlock(address?: Address): Promise; /** * Initiate a trustless withdrawal from the Gateway Wallet. * * ⚠️ **WARNING: This is for emergency use only!** * * Use this only when Circle's Gateway API is unavailable. For normal * withdrawals, use `transfer()` to the same chain - it's instant. * * After calling this, you must wait ~7 days (`withdrawalDelay` blocks) * before calling `completeTrustlessWithdrawal()`. * * @param amount - Amount of USDC to withdraw (as a decimal string) * @returns Withdrawal initiation result */ initiateTrustlessWithdrawal(amount: string): Promise; /** * Complete a trustless withdrawal after the ~7-day delay period. * * ⚠️ **WARNING: This is for emergency use only!** * * Use this only when Circle's Gateway API is unavailable. For normal * withdrawals, use `transfer()` to the same chain - it's instant. * * @returns Withdrawal result */ completeTrustlessWithdrawal(): Promise; } export { type Balances, BatchEvmScheme, CHAIN_CONFIGS, type ChainConfig, CompositeEvmScheme, type CursorPagination, type DepositResult, GATEWAY_DOMAINS, type GatewayBalance, GatewayClient, type GatewayClientConfig, type PayResult, type RegisterBatchSchemeConfig, type SearchTransfersParams, type SearchTransfersResponse, type SupportedChainName, type SupportsResult, type TransferResponse, type TransferStatus, type TrustlessWithdrawalInitResult, type TrustlessWithdrawalResult, type WithdrawResult, registerBatchScheme };