@bankofai/x402-core 1.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +294 -0
- package/dist/cjs/client/index.d.ts +149 -0
- package/dist/cjs/client/index.js +909 -0
- package/dist/cjs/client/index.js.map +1 -0
- package/dist/cjs/facilitator/index.d.ts +206 -0
- package/dist/cjs/facilitator/index.js +431 -0
- package/dist/cjs/facilitator/index.js.map +1 -0
- package/dist/cjs/http/index.d.ts +50 -0
- package/dist/cjs/http/index.js +1452 -0
- package/dist/cjs/http/index.js.map +1 -0
- package/dist/cjs/index.d.ts +3 -0
- package/dist/cjs/index.js +31 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/schemas/index.d.ts +891 -0
- package/dist/cjs/schemas/index.js +216 -0
- package/dist/cjs/schemas/index.js.map +1 -0
- package/dist/cjs/server/index.d.ts +79 -0
- package/dist/cjs/server/index.js +2568 -0
- package/dist/cjs/server/index.js.map +1 -0
- package/dist/cjs/types/index.d.ts +1 -0
- package/dist/cjs/types/index.js +97 -0
- package/dist/cjs/types/index.js.map +1 -0
- package/dist/cjs/types/v1/index.d.ts +1 -0
- package/dist/cjs/types/v1/index.js +19 -0
- package/dist/cjs/types/v1/index.js.map +1 -0
- package/dist/cjs/utils/index.d.ts +77 -0
- package/dist/cjs/utils/index.js +179 -0
- package/dist/cjs/utils/index.js.map +1 -0
- package/dist/cjs/x402Client-BgegfQgE.d.ts +1807 -0
- package/dist/cjs/x402Client-TQHctrG7.d.ts +1807 -0
- package/dist/esm/chunk-ABS7D6VX.mjs +145 -0
- package/dist/esm/chunk-ABS7D6VX.mjs.map +1 -0
- package/dist/esm/chunk-AGOUMC4P.mjs +68 -0
- package/dist/esm/chunk-AGOUMC4P.mjs.map +1 -0
- package/dist/esm/chunk-BJTO5JO5.mjs +11 -0
- package/dist/esm/chunk-BJTO5JO5.mjs.map +1 -0
- package/dist/esm/chunk-FPXAE3OS.mjs +161 -0
- package/dist/esm/chunk-FPXAE3OS.mjs.map +1 -0
- package/dist/esm/chunk-IL77TMJL.mjs +1275 -0
- package/dist/esm/chunk-IL77TMJL.mjs.map +1 -0
- package/dist/esm/chunk-VE37GDG2.mjs +7 -0
- package/dist/esm/chunk-VE37GDG2.mjs.map +1 -0
- package/dist/esm/client/index.d.mts +149 -0
- package/dist/esm/client/index.mjs +504 -0
- package/dist/esm/client/index.mjs.map +1 -0
- package/dist/esm/facilitator/index.d.mts +206 -0
- package/dist/esm/facilitator/index.mjs +399 -0
- package/dist/esm/facilitator/index.mjs.map +1 -0
- package/dist/esm/http/index.d.mts +50 -0
- package/dist/esm/http/index.mjs +35 -0
- package/dist/esm/http/index.mjs.map +1 -0
- package/dist/esm/index.d.mts +3 -0
- package/dist/esm/index.mjs +8 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/schemas/index.d.mts +891 -0
- package/dist/esm/schemas/index.mjs +70 -0
- package/dist/esm/schemas/index.mjs.map +1 -0
- package/dist/esm/server/index.d.mts +79 -0
- package/dist/esm/server/index.mjs +1318 -0
- package/dist/esm/server/index.mjs.map +1 -0
- package/dist/esm/types/index.d.mts +1 -0
- package/dist/esm/types/index.mjs +14 -0
- package/dist/esm/types/index.mjs.map +1 -0
- package/dist/esm/types/v1/index.d.mts +1 -0
- package/dist/esm/types/v1/index.mjs +1 -0
- package/dist/esm/types/v1/index.mjs.map +1 -0
- package/dist/esm/utils/index.d.mts +77 -0
- package/dist/esm/utils/index.mjs +28 -0
- package/dist/esm/utils/index.mjs.map +1 -0
- package/dist/esm/x402Client-BgegfQgE.d.mts +1807 -0
- package/dist/esm/x402Client-TQHctrG7.d.mts +1807 -0
- package/package.json +142 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/client/index.ts","../../../src/index.ts","../../../src/utils/index.ts","../../../src/client/x402Client.ts","../../../src/schemas/index.ts","../../../src/http/httpFacilitatorClient.ts","../../../src/http/index.ts","../../../src/http/x402HTTPClient.ts"],"sourcesContent":["export * from \"./x402Client\";\nexport * from \"../http/x402HTTPClient\";","export const x402Version = 2;\n","import { Network } from \"../types\";\n\n/**\n * Converts a JavaScript number to a plain decimal string, expanding scientific notation\n * via string manipulation rather than parseFloat round-tripping.\n *\n * e.g. 1e-7 → \"0.0000001\", 4.02 → \"4.02\"\n *\n * @param n - The number to convert\n * @returns A plain decimal string representation with no scientific notation\n */\nexport function numberToDecimalString(n: number): string {\n const str = n.toString();\n if (!/[eE]/.test(str)) return str;\n\n const [significand, exponentStr] = str.split(/[eE]/);\n const exp = parseInt(exponentStr, 10);\n const negative = significand.startsWith(\"-\");\n const abs = negative ? significand.slice(1) : significand;\n const [intDigits, fracDigits = \"\"] = abs.split(\".\");\n const allDigits = intDigits + fracDigits;\n const decimalPos = intDigits.length + exp;\n\n let result: string;\n if (decimalPos <= 0) {\n result = \"0.\" + \"0\".repeat(-decimalPos) + allDigits;\n } else if (decimalPos >= allDigits.length) {\n result = allDigits + \"0\".repeat(decimalPos - allDigits.length);\n } else {\n result = allDigits.slice(0, decimalPos) + \".\" + allDigits.slice(decimalPos);\n }\n return (negative ? \"-\" : \"\") + result;\n}\n\n/**\n * Parses a money string into a finite, non-negative decimal number.\n * Accepts plain decimal strings with an optional leading dollar sign.\n *\n * @param money - The money string to parse\n * @returns Decimal number\n */\nexport function parseMoneyString(money: string): number {\n const cleaned = money.replace(/^\\$/, \"\").trim();\n if (!/^-?\\d+(?:\\.\\d+)?$/.test(cleaned) || /[eE]/.test(cleaned)) {\n throw new Error(`Invalid money format: ${money}`);\n }\n\n const amount = Number(cleaned);\n if (!Number.isFinite(amount) || amount < 0) {\n throw new Error(`Invalid money format: ${money}`);\n }\n return amount;\n}\n\n/**\n * Convert a decimal amount to token smallest units.\n * Accepts only plain decimal strings — scientific notation is not allowed.\n * Throws if the amount is non-zero but too small to represent with the given decimal precision.\n *\n * @param decimalAmount - The decimal amount as a plain string (e.g., \"0.10\")\n * @param decimals - The number of decimals for the token (e.g., 6 for USDC)\n * @returns The amount in smallest units as a string\n */\nexport function convertToTokenAmount(decimalAmount: string, decimals: number): string {\n if (/[eE]/.test(decimalAmount)) {\n throw new Error(\n `Invalid amount: ${decimalAmount} — use decimal notation, not scientific notation`,\n );\n }\n if (!/^-?\\d+\\.?\\d*$/.test(decimalAmount)) {\n throw new Error(`Invalid amount: ${decimalAmount}`);\n }\n const [intPart, decPart = \"\"] = decimalAmount.split(\".\");\n const paddedDec = decPart.padEnd(decimals, \"0\").slice(0, decimals);\n const tokenAmount = (intPart + paddedDec).replace(/^0+/, \"\") || \"0\";\n if (tokenAmount === \"0\" && /[1-9]/.test(decimalAmount)) {\n throw new Error(\n `Amount ${decimalAmount} is too small to represent with ${decimals} decimal places`,\n );\n }\n return tokenAmount;\n}\n\n/**\n * Scheme data structure for facilitator storage\n */\nexport interface SchemeData<T> {\n facilitator: T;\n networks: Set<Network>;\n pattern: Network;\n}\n\nconst escapeRegExp = (value: string): string => value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\nconst networkPatternToRegExp = (pattern: Network): RegExp => {\n const source = escapeRegExp(pattern).replace(/\\\\\\*/g, \".*\");\n return new RegExp(`^${source}$`);\n};\n\nexport const networkMatchesPattern = (pattern: Network, network: Network): boolean => {\n return networkPatternToRegExp(pattern).test(network);\n};\n\nexport const findSchemesByNetwork = <T>(\n map: Map<string, Map<string, T>>,\n network: Network,\n): Map<string, T> | undefined => {\n // Direct match first\n let implementationsByScheme = map.get(network);\n\n if (!implementationsByScheme) {\n // Try pattern matching for registered network patterns\n for (const [registeredNetworkPattern, implementations] of map.entries()) {\n if (networkMatchesPattern(registeredNetworkPattern as Network, network)) {\n implementationsByScheme = implementations;\n break;\n }\n }\n }\n\n return implementationsByScheme;\n};\n\nexport const findByNetworkAndScheme = <T>(\n map: Map<string, Map<string, T>>,\n scheme: string,\n network: Network,\n): T | undefined => {\n return findSchemesByNetwork(map, network)?.get(scheme);\n};\n\n/**\n * Finds a facilitator by scheme and network using pattern matching.\n * Works with new SchemeData storage structure.\n *\n * @param schemeMap - Map of scheme names to SchemeData\n * @param scheme - The scheme to find\n * @param network - The network to match against\n * @returns The facilitator if found, undefined otherwise\n */\nexport const findFacilitatorBySchemeAndNetwork = <T>(\n schemeMap: Map<string, SchemeData<T>>,\n scheme: string,\n network: Network,\n): T | undefined => {\n const schemeData = schemeMap.get(scheme);\n if (!schemeData) return undefined;\n\n // Check if network is in the stored networks set\n if (schemeData.networks.has(network)) {\n return schemeData.facilitator;\n }\n\n // Try pattern matching\n if (networkMatchesPattern(schemeData.pattern, network)) {\n return schemeData.facilitator;\n }\n\n return undefined;\n};\n\nexport const Base64EncodedRegex = /^[A-Za-z0-9+/]*={0,2}$/;\n\n/**\n * Encodes a string to base64 format\n *\n * @param data - The string to be encoded to base64\n * @returns The base64 encoded string\n */\nexport function safeBase64Encode(data: string): string {\n if (typeof globalThis !== \"undefined\" && typeof globalThis.btoa === \"function\") {\n const bytes = new TextEncoder().encode(data);\n const binaryString = Array.from(bytes, byte => String.fromCharCode(byte)).join(\"\");\n return globalThis.btoa(binaryString);\n }\n return Buffer.from(data, \"utf8\").toString(\"base64\");\n}\n\n/**\n * Decodes a base64 string back to its original format\n *\n * @param data - The base64 encoded string to be decoded\n * @returns The decoded string in UTF-8 format\n */\nexport function safeBase64Decode(data: string): string {\n if (typeof globalThis !== \"undefined\" && typeof globalThis.atob === \"function\") {\n const binaryString = globalThis.atob(data);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n const decoder = new TextDecoder(\"utf-8\");\n return decoder.decode(bytes);\n }\n return Buffer.from(data, \"base64\").toString(\"utf-8\");\n}\n\n/**\n * Deep equality comparison for payment requirements\n * Uses a normalized JSON.stringify for consistent comparison\n *\n * @param obj1 - First object to compare\n * @param obj2 - Second object to compare\n * @returns True if objects are deeply equal\n */\nexport function deepEqual(obj1: unknown, obj2: unknown): boolean {\n // Normalize and stringify both objects for comparison\n // This handles nested objects, arrays, and different property orders\n const normalize = (obj: unknown): string => {\n // Handle primitives and null/undefined\n if (obj === null || obj === undefined) return JSON.stringify(obj);\n if (typeof obj !== \"object\") return JSON.stringify(obj);\n\n // Handle arrays\n if (Array.isArray(obj)) {\n return JSON.stringify(\n obj.map(item =>\n typeof item === \"object\" && item !== null ? JSON.parse(normalize(item)) : item,\n ),\n );\n }\n\n // Handle objects - sort keys and recursively normalize values\n const sorted: Record<string, unknown> = {};\n Object.keys(obj as Record<string, unknown>)\n .sort()\n .forEach(key => {\n const value = (obj as Record<string, unknown>)[key];\n sorted[key] =\n typeof value === \"object\" && value !== null ? JSON.parse(normalize(value)) : value;\n });\n return JSON.stringify(sorted);\n };\n\n try {\n return normalize(obj1) === normalize(obj2);\n } catch {\n // Fallback to simple comparison if normalization fails\n return JSON.stringify(obj1) === JSON.stringify(obj2);\n }\n}\n","import { x402Version } from \"..\";\nimport { SchemeNetworkClient } from \"../types/mechanisms\";\nimport { PaymentPayload, PaymentRequirements } from \"../types/payments\";\nimport { Network, PaymentRequired, SettleResponse } from \"../types\";\nimport { findByNetworkAndScheme, findSchemesByNetwork } from \"../utils\";\n\n/**\n * Client Hook Context Interfaces\n */\n\nexport interface PaymentCreationContext {\n paymentRequired: PaymentRequired;\n selectedRequirements: PaymentRequirements;\n}\n\nexport interface PaymentCreatedContext extends PaymentCreationContext {\n paymentPayload: PaymentPayload;\n}\n\nexport interface PaymentCreationFailureContext extends PaymentCreationContext {\n error: Error;\n}\n\n/**\n * Client Hook Type Definitions\n */\n\nexport type BeforePaymentCreationHook = (\n context: PaymentCreationContext,\n) => Promise<void | { abort: true; reason: string }>;\n\nexport type AfterPaymentCreationHook = (context: PaymentCreatedContext) => Promise<void>;\n\nexport type OnPaymentCreationFailureHook = (\n context: PaymentCreationFailureContext,\n) => Promise<void | { recovered: true; payload: PaymentPayload }>;\n\n/**\n * Context provided to payment response hooks after the paid request completes.\n *\n * Discriminate by what's present:\n * - `settleResponse` with `success: true` → settle succeeded\n * - `settleResponse` with `success: false` → settle failed\n * - `paymentRequired` (no `settleResponse`) → verify failed\n * - `error` → transport or parse error\n */\nexport interface PaymentResponseContext {\n paymentPayload: PaymentPayload;\n requirements: PaymentRequirements;\n settleResponse?: SettleResponse;\n paymentRequired?: PaymentRequired;\n error?: Error;\n}\n\n/**\n * Hook fired after a paid request completes.\n * Return `{ recovered: true }` to signal the transport should retry with a fresh payload.\n */\nexport type OnPaymentResponseHook = (\n ctx: PaymentResponseContext,\n) => Promise<void | { recovered: true }>;\n\nexport type SelectPaymentRequirements = (x402Version: number, paymentRequirements: PaymentRequirements[]) => PaymentRequirements;\n\ntype ClientHookAdapterHandles = {\n beforePaymentCreation?: BeforePaymentCreationHook;\n afterPaymentCreation?: AfterPaymentCreationHook;\n onPaymentCreationFailure?: OnPaymentCreationFailureHook;\n onPaymentResponse?: OnPaymentResponseHook;\n};\n\ntype ClientHookPhase = keyof ClientHookAdapterHandles;\n\nexport interface ClientExtensionHooks {\n onBeforePaymentCreation?: (\n declaration: unknown,\n context: PaymentCreationContext,\n ) => Promise<void | { abort: true; reason: string }>;\n onAfterPaymentCreation?: (\n declaration: unknown,\n context: PaymentCreatedContext,\n ) => Promise<void>;\n onPaymentCreationFailure?: (\n declaration: unknown,\n context: PaymentCreationFailureContext,\n ) => Promise<void | { recovered: true; payload: PaymentPayload }>;\n onPaymentResponse?: (\n declaration: unknown,\n context: PaymentResponseContext,\n ) => Promise<void | { recovered: true }>;\n}\n\nexport interface ClientTransportExtensionHooks {\n [transport: string]: unknown;\n}\n\n/**\n * Extension that can enrich payment payloads on the client side.\n *\n * Client extensions are invoked after the scheme creates the base payment payload\n * but before it is returned. This allows mechanism-specific logic (e.g., EVM EIP-2612\n * permit signing) to enrich the payload's extensions data.\n */\nexport interface ClientExtension {\n /**\n * Unique key identifying this extension (e.g., \"eip2612GasSponsoring\").\n * Must match the extension key used in PaymentRequired.extensions.\n */\n key: string;\n\n /**\n * Called after payload creation when the extension key is present in\n * paymentRequired.extensions. Allows the extension to enrich the payload\n * with extension-specific data (e.g., signing an EIP-2612 permit).\n *\n * @param paymentPayload - The payment payload to enrich\n * @param paymentRequired - The original PaymentRequired response\n * @returns The enriched payment payload\n */\n enrichPaymentPayload?: (\n paymentPayload: PaymentPayload,\n paymentRequired: PaymentRequired,\n ) => Promise<PaymentPayload>;\n\n hooks?: ClientExtensionHooks;\n transportHooks?: ClientTransportExtensionHooks;\n}\n\n/**\n * A policy function that filters or transforms payment requirements.\n * Policies are applied in order before the selector chooses the final option.\n *\n * @param x402Version - The x402 protocol version\n * @param paymentRequirements - Array of payment requirements to filter/transform\n * @returns Filtered array of payment requirements\n */\nexport type PaymentPolicy = (x402Version: number, paymentRequirements: PaymentRequirements[]) => PaymentRequirements[];\n\n\n/**\n * Configuration for registering a payment scheme with a specific network\n */\nexport interface SchemeRegistration {\n /**\n * The network identifier (e.g., 'eip155:8453', 'solana:mainnet')\n */\n network: Network;\n\n /**\n * The scheme client implementation for this network\n */\n client: SchemeNetworkClient;\n\n /**\n * The x402 protocol version to use for this scheme\n *\n * @default 2\n */\n x402Version?: number;\n}\n\n/**\n * Configuration options for the fetch wrapper\n */\nexport interface x402ClientConfig {\n /**\n * Array of scheme registrations defining which payment methods are supported\n */\n schemes: SchemeRegistration[];\n\n /**\n * Policies to apply to the client\n */\n policies?: PaymentPolicy[];\n\n /**\n * Custom payment requirements selector function\n * If not provided, uses the default selector (first available option)\n */\n paymentRequirementsSelector?: SelectPaymentRequirements;\n}\n\n/**\n * Core client for managing x402 payment schemes and creating payment payloads.\n *\n * Handles registration of payment schemes, policy-based filtering of payment requirements,\n * and creation of payment payloads based on server requirements.\n */\nexport class x402Client {\n private readonly paymentRequirementsSelector: SelectPaymentRequirements;\n private readonly registeredClientSchemes: Map<number, Map<string, Map<string, SchemeNetworkClient>>> = new Map();\n private readonly schemeClientHookAdapters: Map<number, Map<string, Map<string, ClientHookAdapterHandles>>> = new Map();\n private readonly policies: PaymentPolicy[] = [];\n private readonly registeredExtensions: Map<string, ClientExtension> = new Map();\n\n private beforePaymentCreationHooks: BeforePaymentCreationHook[] = [];\n private afterPaymentCreationHooks: AfterPaymentCreationHook[] = [];\n private onPaymentCreationFailureHooks: OnPaymentCreationFailureHook[] = [];\n private paymentResponseHooks: OnPaymentResponseHook[] = [];\n\n /**\n * Creates a new x402Client instance.\n *\n * @param paymentRequirementsSelector - Function to select payment requirements from available options\n */\n constructor(paymentRequirementsSelector?: SelectPaymentRequirements) {\n this.paymentRequirementsSelector = paymentRequirementsSelector || ((x402Version, accepts) => accepts[0]);\n }\n\n /**\n * Creates a new x402Client instance from a configuration object.\n *\n * @param config - The client configuration including schemes, policies, and payment requirements selector\n * @returns A configured x402Client instance\n */\n static fromConfig(config: x402ClientConfig): x402Client {\n const client = new x402Client(config.paymentRequirementsSelector);\n config.schemes.forEach(scheme => {\n if (scheme.x402Version === 1) {\n client.registerV1(scheme.network, scheme.client);\n } else {\n client.register(scheme.network, scheme.client);\n }\n });\n config.policies?.forEach(policy => {\n client.registerPolicy(policy);\n });\n return client;\n }\n\n /**\n * Registers a scheme client for the current x402 version.\n *\n * @param network - The network to register the client for\n * @param client - The scheme network client to register\n * @returns The x402Client instance for chaining\n */\n register(network: Network, client: SchemeNetworkClient): x402Client {\n return this._registerScheme(x402Version, network, client);\n }\n\n /**\n * Registers a scheme client for x402 version 1.\n *\n * @param network - The v1 network identifier (e.g., 'base-sepolia', 'solana-devnet')\n * @param client - The scheme network client to register\n * @returns The x402Client instance for chaining\n */\n registerV1(network: string, client: SchemeNetworkClient): x402Client {\n return this._registerScheme(1, network as Network, client);\n }\n\n /**\n * Registers a policy to filter or transform payment requirements.\n *\n * Policies are applied in order after filtering by registered schemes\n * and before the selector chooses the final payment requirement.\n *\n * @param policy - Function to filter/transform payment requirements\n * @returns The x402Client instance for chaining\n *\n * @example\n * ```typescript\n * // Prefer cheaper options\n * client.registerPolicy((version, reqs) =>\n * reqs.filter(r => BigInt(r.value) < BigInt('1000000'))\n * );\n *\n * // Prefer specific networks\n * client.registerPolicy((version, reqs) =>\n * reqs.filter(r => r.network.startsWith('eip155:'))\n * );\n * ```\n */\n registerPolicy(policy: PaymentPolicy): x402Client {\n this.policies.push(policy);\n return this;\n }\n\n /**\n * Registers a client extension that can enrich payment payloads.\n *\n * Extensions are invoked after the scheme creates the base payload and the\n * payload is wrapped with extensions/resource/accepted data. If the extension's\n * key is present in `paymentRequired.extensions`, the extension's\n * `enrichPaymentPayload` hook is called to modify the payload.\n *\n * @param extension - The client extension to register\n * @returns The x402Client instance for chaining\n */\n registerExtension(extension: ClientExtension): x402Client {\n this.registeredExtensions.set(extension.key, extension);\n return this;\n }\n\n /**\n * Get all registered client extensions.\n *\n * @returns Array of registered extensions\n */\n getExtensions(): ClientExtension[] {\n return Array.from(this.registeredExtensions.values());\n }\n\n /**\n * Register a hook to execute before payment payload creation.\n * Can abort creation by returning { abort: true, reason: string }\n *\n * @param hook - The hook function to register\n * @returns The x402Client instance for chaining\n */\n onBeforePaymentCreation(hook: BeforePaymentCreationHook): x402Client {\n this.beforePaymentCreationHooks.push(hook);\n return this;\n }\n\n /**\n * Register a hook to execute after successful payment payload creation.\n *\n * @param hook - The hook function to register\n * @returns The x402Client instance for chaining\n */\n onAfterPaymentCreation(hook: AfterPaymentCreationHook): x402Client {\n this.afterPaymentCreationHooks.push(hook);\n return this;\n }\n\n /**\n * Register a hook to execute when payment payload creation fails.\n * Can recover from failure by returning { recovered: true, payload: PaymentPayload }\n *\n * @param hook - The hook function to register\n * @returns The x402Client instance for chaining\n */\n onPaymentCreationFailure(hook: OnPaymentCreationFailureHook): x402Client {\n this.onPaymentCreationFailureHooks.push(hook);\n return this;\n }\n\n /**\n * Register a hook to execute after a paid request completes.\n * Can signal recovery by returning { recovered: true }, causing the transport to retry.\n *\n * @param hook - The hook function to register\n * @returns The x402Client instance for chaining\n */\n onPaymentResponse(hook: OnPaymentResponseHook): x402Client {\n this.paymentResponseHooks.push(hook);\n return this;\n }\n\n /**\n * Fires all registered payment response hooks in order.\n * Returns `{ recovered: true }` if any hook signals recovery (first wins).\n *\n * @param ctx - The payment response context\n * @returns Recovery signal or undefined\n */\n async handlePaymentResponse(\n ctx: PaymentResponseContext,\n ): Promise<{ recovered: true } | undefined> {\n for (const hook of this.getLabeledHooks(\n \"onPaymentResponse\",\n ctx.paymentPayload.x402Version,\n ctx.requirements,\n ctx.paymentRequired?.extensions ?? ctx.paymentPayload.extensions,\n )) {\n const result = await hook(ctx);\n if (result && \"recovered\" in result && result.recovered) {\n return { recovered: true };\n }\n }\n return undefined;\n }\n\n /**\n * Creates a payment payload based on a PaymentRequired response.\n *\n * Automatically extracts x402Version, resource, and extensions from the PaymentRequired\n * response and constructs a complete PaymentPayload with the accepted requirements.\n *\n * @param paymentRequired - The PaymentRequired response from the server\n * @returns Promise resolving to the complete payment payload\n */\n async createPaymentPayload(\n paymentRequired: PaymentRequired,\n ): Promise<PaymentPayload> {\n const clientSchemesByNetwork = this.registeredClientSchemes.get(paymentRequired.x402Version);\n if (!clientSchemesByNetwork) {\n throw new Error(`No client registered for x402 version: ${paymentRequired.x402Version}`);\n }\n\n const requirements = this.selectPaymentRequirements(paymentRequired.x402Version, paymentRequired.accepts);\n\n const context: PaymentCreationContext = {\n paymentRequired,\n selectedRequirements: requirements,\n };\n\n for (const hook of this.getLabeledHooks(\n \"beforePaymentCreation\",\n paymentRequired.x402Version,\n requirements,\n paymentRequired.extensions,\n )) {\n const result = await hook(context);\n if (result && \"abort\" in result && result.abort) {\n throw new Error(`Payment creation aborted: ${result.reason}`);\n }\n }\n\n try {\n const schemeNetworkClient = findByNetworkAndScheme(clientSchemesByNetwork, requirements.scheme, requirements.network);\n if (!schemeNetworkClient) {\n throw new Error(`No client registered for scheme: ${requirements.scheme} and network: ${requirements.network}`);\n }\n\n const partialPayload = await schemeNetworkClient.createPaymentPayload(\n paymentRequired.x402Version,\n requirements,\n { extensions: paymentRequired.extensions },\n );\n\n let paymentPayload: PaymentPayload;\n if (partialPayload.x402Version == 1) {\n paymentPayload = partialPayload as PaymentPayload;\n } else {\n // Merge server-declared extensions with any scheme-provided extensions.\n // Scheme extensions overlay on top (e.g., EIP-2612 info enriches server declaration).\n const mergedExtensions = this.mergeExtensions(\n paymentRequired.extensions,\n partialPayload.extensions,\n );\n\n paymentPayload = {\n x402Version: partialPayload.x402Version,\n payload: partialPayload.payload,\n extensions: mergedExtensions,\n resource: paymentRequired.resource,\n accepted: requirements,\n };\n }\n\n // Enrich payload via registered client extensions (for non-scheme extensions)\n paymentPayload = await this.enrichPaymentPayloadWithExtensions(paymentPayload, paymentRequired);\n\n const createdContext: PaymentCreatedContext = {\n ...context,\n paymentPayload,\n };\n\n for (const hook of this.getLabeledHooks(\n \"afterPaymentCreation\",\n paymentRequired.x402Version,\n requirements,\n paymentRequired.extensions,\n )) {\n await hook(createdContext);\n }\n\n return paymentPayload;\n } catch (error) {\n const failureContext: PaymentCreationFailureContext = {\n ...context,\n error: error as Error,\n };\n\n for (const hook of this.getLabeledHooks(\n \"onPaymentCreationFailure\",\n paymentRequired.x402Version,\n requirements,\n paymentRequired.extensions,\n )) {\n const result = await hook(failureContext);\n if (result && \"recovered\" in result && result.recovered) {\n return result.payload;\n }\n }\n\n throw error;\n }\n }\n\n\n\n /**\n * Merges server-declared extensions with client extension echoes.\n * Client extension data may add fields, but server-declared fields remain intact.\n *\n * @param serverExtensions - Extensions declared by the server in the 402 response\n * @param clientExtensions - Extensions provided by the client or scheme\n * @returns The merged extensions object, or undefined if both inputs are undefined\n */\n private mergeExtensions(\n serverExtensions?: Record<string, unknown>,\n clientExtensions?: Record<string, unknown>,\n ): Record<string, unknown> | undefined {\n if (!clientExtensions) return serverExtensions;\n if (!serverExtensions) return clientExtensions;\n\n const merged = { ...serverExtensions };\n for (const [key, clientValue] of Object.entries(clientExtensions)) {\n const serverValue = merged[key];\n if (\n serverValue === null ||\n typeof serverValue !== \"object\" ||\n Array.isArray(serverValue) ||\n clientValue === null ||\n typeof clientValue !== \"object\" ||\n Array.isArray(clientValue)\n ) {\n merged[key] = clientValue;\n continue;\n }\n\n const serverRecord = serverValue as Record<string, unknown>;\n const clientRecord = clientValue as Record<string, unknown>;\n const extensionValue = { ...serverRecord };\n const pending = [{ target: extensionValue, source: clientRecord }];\n for (const item of pending) {\n for (const [fieldKey, clientFieldValue] of Object.entries(item.source)) {\n const serverFieldValue = item.target[fieldKey];\n if (\n serverFieldValue !== null &&\n typeof serverFieldValue === \"object\" &&\n !Array.isArray(serverFieldValue) &&\n clientFieldValue !== null &&\n typeof clientFieldValue === \"object\" &&\n !Array.isArray(clientFieldValue)\n ) {\n const nestedValue = { ...(serverFieldValue as Record<string, unknown>) };\n item.target[fieldKey] = nestedValue;\n pending.push({\n target: nestedValue,\n source: clientFieldValue as Record<string, unknown>,\n });\n continue;\n }\n\n if (!Object.prototype.hasOwnProperty.call(item.target, fieldKey)) {\n item.target[fieldKey] = clientFieldValue;\n }\n }\n }\n\n merged[key] = extensionValue;\n }\n return merged;\n }\n\n /**\n * Enriches a payment payload by calling registered extension hooks.\n * For each extension key present in the PaymentRequired response,\n * invokes the corresponding extension's enrichPaymentPayload callback.\n *\n * @param paymentPayload - The payment payload to enrich with extension data\n * @param paymentRequired - The PaymentRequired response containing extension declarations\n * @returns The enriched payment payload with extension data applied\n */\n private async enrichPaymentPayloadWithExtensions(\n paymentPayload: PaymentPayload,\n paymentRequired: PaymentRequired,\n ): Promise<PaymentPayload> {\n if (!paymentRequired.extensions || this.registeredExtensions.size === 0) {\n return paymentPayload;\n }\n\n let enriched = paymentPayload;\n for (const [key, extension] of this.registeredExtensions) {\n if (key in paymentRequired.extensions && extension.enrichPaymentPayload) {\n enriched = await extension.enrichPaymentPayload(enriched, paymentRequired);\n }\n }\n\n return {\n ...enriched,\n extensions: this.mergeExtensions(paymentRequired.extensions, enriched.extensions),\n };\n }\n\n /**\n * Selects appropriate payment requirements based on registered clients and policies.\n *\n * Selection process:\n * 1. Filter by registered schemes (network + scheme support)\n * 2. Apply all registered policies in order\n * 3. Use selector to choose final requirement\n *\n * @param x402Version - The x402 protocol version\n * @param paymentRequirements - Array of available payment requirements\n * @returns The selected payment requirements\n */\n private selectPaymentRequirements(x402Version: number, paymentRequirements: PaymentRequirements[]): PaymentRequirements {\n const clientSchemesByNetwork = this.registeredClientSchemes.get(x402Version);\n if (!clientSchemesByNetwork) {\n throw new Error(`No client registered for x402 version: ${x402Version}`);\n }\n\n // Step 1: Filter by registered schemes\n const supportedPaymentRequirements = paymentRequirements.filter(requirement => {\n let clientSchemes = findSchemesByNetwork(clientSchemesByNetwork, requirement.network);\n if (!clientSchemes) {\n return false;\n }\n\n return clientSchemes.has(requirement.scheme);\n })\n\n if (supportedPaymentRequirements.length === 0) {\n throw new Error(`No network/scheme registered for x402 version: ${x402Version} which comply with the payment requirements. ${JSON.stringify({\n x402Version,\n paymentRequirements,\n x402Versions: Array.from(this.registeredClientSchemes.keys()),\n networks: Array.from(clientSchemesByNetwork.keys()),\n schemes: Array.from(clientSchemesByNetwork.values()).map(schemes => Array.from(schemes.keys())).flat(),\n })}`);\n }\n\n // Step 2: Apply all policies in order\n let filteredRequirements = supportedPaymentRequirements;\n for (const policy of this.policies) {\n filteredRequirements = policy(x402Version, filteredRequirements);\n\n if (filteredRequirements.length === 0) {\n throw new Error(`All payment requirements were filtered out by policies for x402 version: ${x402Version}`);\n }\n }\n\n // Step 3: Use selector to choose final requirement\n return this.paymentRequirementsSelector(x402Version, filteredRequirements);\n }\n\n /**\n * Internal method to register a scheme client.\n *\n * @param x402Version - The x402 protocol version\n * @param network - The network to register the client for\n * @param client - The scheme network client to register\n * @returns The x402Client instance for chaining\n */\n private _registerScheme(x402Version: number, network: Network, client: SchemeNetworkClient): x402Client {\n if (!this.registeredClientSchemes.has(x402Version)) {\n this.registeredClientSchemes.set(x402Version, new Map());\n }\n const clientSchemesByNetwork = this.registeredClientSchemes.get(x402Version)!;\n if (!clientSchemesByNetwork.has(network)) {\n clientSchemesByNetwork.set(network, new Map());\n }\n\n const clientByScheme = clientSchemesByNetwork.get(network)!;\n clientByScheme.set(client.scheme, client);\n\n if (!this.schemeClientHookAdapters.has(x402Version)) {\n this.schemeClientHookAdapters.set(x402Version, new Map());\n }\n const adaptersByNetwork = this.schemeClientHookAdapters.get(x402Version)!;\n if (!adaptersByNetwork.has(network)) {\n adaptersByNetwork.set(network, new Map());\n }\n\n const adaptersByScheme = adaptersByNetwork.get(network)!;\n const hooks = client.schemeHooks;\n if (!hooks) {\n adaptersByScheme.delete(client.scheme);\n return this;\n }\n\n const handles: ClientHookAdapterHandles = {};\n if (hooks.onBeforePaymentCreation) {\n handles.beforePaymentCreation = hooks.onBeforePaymentCreation;\n }\n if (hooks.onAfterPaymentCreation) {\n handles.afterPaymentCreation = hooks.onAfterPaymentCreation;\n }\n if (hooks.onPaymentCreationFailure) {\n handles.onPaymentCreationFailure = hooks.onPaymentCreationFailure;\n }\n if (hooks.onPaymentResponse) {\n handles.onPaymentResponse = hooks.onPaymentResponse;\n }\n\n if (Object.keys(handles).length > 0) {\n adaptersByScheme.set(client.scheme, handles);\n } else {\n adaptersByScheme.delete(client.scheme);\n }\n\n return this;\n }\n\n /**\n * Returns manual hooks followed by the selected scheme hook and declared extension hooks.\n *\n * @param phase - Hook slot to collect\n * @param x402Version - Protocol version for the selected requirement\n * @param requirements - Selected payment requirement\n * @param declaredExtensions - Extension declarations that scope extension hooks\n * @returns Hooks in invocation order\n */\n private getLabeledHooks<P extends ClientHookPhase>(\n phase: P,\n x402Version: number,\n requirements: PaymentRequirements,\n declaredExtensions?: Record<string, unknown>,\n ): Array<NonNullable<ClientHookAdapterHandles[P]>> {\n let manual: Array<NonNullable<ClientHookAdapterHandles[P]>>;\n switch (phase) {\n case \"beforePaymentCreation\":\n manual = this.beforePaymentCreationHooks as Array<\n NonNullable<ClientHookAdapterHandles[P]>\n >;\n break;\n case \"afterPaymentCreation\":\n manual = this.afterPaymentCreationHooks as Array<\n NonNullable<ClientHookAdapterHandles[P]>\n >;\n break;\n case \"onPaymentCreationFailure\":\n manual = this.onPaymentCreationFailureHooks as Array<\n NonNullable<ClientHookAdapterHandles[P]>\n >;\n break;\n case \"onPaymentResponse\":\n manual = this.paymentResponseHooks as Array<NonNullable<ClientHookAdapterHandles[P]>>;\n break;\n }\n\n const out: Array<NonNullable<ClientHookAdapterHandles[P]>> = [...manual];\n const adaptersByNetwork = this.schemeClientHookAdapters.get(x402Version);\n const schemeAdapter = adaptersByNetwork\n ? findByNetworkAndScheme(adaptersByNetwork, requirements.scheme, requirements.network)\n : undefined;\n const hook = schemeAdapter?.[phase];\n if (hook !== undefined) {\n out.push(hook);\n }\n if (!declaredExtensions) {\n return out;\n }\n\n const extensionHookKey = this.getClientExtensionHookKey(phase);\n for (const [extensionKey, extension] of this.registeredExtensions) {\n if (!(extensionKey in declaredExtensions)) continue;\n\n const extensionHook = extension.hooks?.[extensionHookKey];\n if (!extensionHook) continue;\n\n type HookFn = NonNullable<ClientHookAdapterHandles[P]>;\n type HookContext = Parameters<HookFn>[0];\n out.push((async (ctx: HookContext) => {\n return (\n extensionHook as (\n declaration: unknown,\n context: HookContext,\n ) => ReturnType<HookFn>\n )(declaredExtensions[extensionKey], ctx);\n }) as HookFn);\n }\n return out;\n }\n\n /**\n * Maps internal hook phases to extension hook names.\n *\n * @param phase - Internal hook phase\n * @returns Extension hook key for the phase\n */\n private getClientExtensionHookKey<P extends ClientHookPhase>(\n phase: P,\n ): keyof ClientExtensionHooks {\n switch (phase) {\n case \"beforePaymentCreation\":\n return \"onBeforePaymentCreation\";\n case \"afterPaymentCreation\":\n return \"onAfterPaymentCreation\";\n case \"onPaymentCreationFailure\":\n return \"onPaymentCreationFailure\";\n case \"onPaymentResponse\":\n return \"onPaymentResponse\";\n }\n }\n}\n","import { z } from \"zod\";\n\n// ============================================================================\n// Reusable Primitive Schemas\n// ============================================================================\n\n/**\n * Non-empty string schema - a string with at least one character.\n * Used for required string fields that cannot be empty.\n */\nexport const NonEmptyString = z.string().min(1);\nexport type NonEmptyString = z.infer<typeof NonEmptyString>;\n\n/**\n * Any record schema - an object with unknown keys and values.\n * Used for scheme-specific payloads and other extensible objects.\n */\nexport const Any = z.record(z.unknown());\nexport type Any = z.infer<typeof Any>;\n\n/**\n * Optional any record schema - an optional object with unknown keys and values.\n * Used for optional extension fields like `extra` and `extensions`.\n */\nexport const OptionalAny = z.record(z.unknown()).optional().nullable();\nexport type OptionalAny = z.infer<typeof OptionalAny>;\n\n// ============================================================================\n// Network Schemas\n// ============================================================================\n\n/**\n * Network identifier schema for V1 - loose validation.\n * V1 accepts any non-empty string for backwards compatibility.\n */\nexport const NetworkSchemaV1 = NonEmptyString;\nexport type NetworkV1 = z.infer<typeof NetworkSchemaV1>;\n\n/**\n * Network identifier schema for V2 - CAIP-2 format validation.\n * V2 requires minimum length of 3 and a colon separator (e.g., \"eip155:84532\", \"solana:devnet\").\n */\nexport const NetworkSchemaV2 = z\n .string()\n .min(3)\n .refine(val => val.includes(\":\"), {\n message: \"Network must be in CAIP-2 format (e.g., 'eip155:84532')\",\n });\nexport type NetworkV2 = z.infer<typeof NetworkSchemaV2>;\n\n/**\n * Union network schema - accepts either V1 or V2 format.\n */\nexport const NetworkSchema = z.union([NetworkSchemaV1, NetworkSchemaV2]);\nexport type Network = z.infer<typeof NetworkSchema>;\n\n// ============================================================================\n// Shared Schemas\n// ============================================================================\n\n/**\n * ResourceInfo schema for V2 - describes the protected resource.\n */\n// Printable ASCII (U+0020–U+007E) — matches the bazaar-facilitator\n// `isValidServiceName` / `sanitizeTags` regex. Constraining to ASCII keeps\n// the length cap consistent across TS / Python / Go (where String.length /\n// len() / len() otherwise diverge for multi-byte input).\nconst PRINTABLE_ASCII_REGEX = /^[\\x20-\\x7e]+$/;\n\nexport const ResourceInfoSchema = z.object({\n url: NonEmptyString,\n description: z.string().optional(),\n mimeType: z.string().optional(),\n serviceName: z.string().min(1).max(32).regex(PRINTABLE_ASCII_REGEX).optional(),\n tags: z.array(z.string().min(1).max(32).regex(PRINTABLE_ASCII_REGEX)).max(5).optional(),\n iconUrl: z.string().max(2048).optional(),\n});\nexport type ResourceInfo = z.infer<typeof ResourceInfoSchema>;\n\n// ============================================================================\n// V1 Schemas\n// ============================================================================\n\n/**\n * PaymentRequirements schema for V1.\n * V1 includes resource info directly in the requirements object.\n */\nexport const PaymentRequirementsV1Schema = z.object({\n scheme: NonEmptyString,\n network: NetworkSchemaV1,\n maxAmountRequired: NonEmptyString,\n resource: NonEmptyString, // URL string in V1\n description: z.string(),\n mimeType: z.string().optional(),\n outputSchema: Any.optional().nullable(),\n payTo: NonEmptyString,\n maxTimeoutSeconds: z.number().positive(),\n asset: NonEmptyString,\n extra: OptionalAny,\n});\nexport type PaymentRequirementsV1 = z.infer<typeof PaymentRequirementsV1Schema>;\n\n/**\n * PaymentRequired (402 response) schema for V1.\n * Contains payment requirements when a resource requires payment.\n */\nexport const PaymentRequiredV1Schema = z.object({\n x402Version: z.literal(1),\n error: z.string().optional(),\n accepts: z.array(PaymentRequirementsV1Schema).min(1),\n});\nexport type PaymentRequiredV1 = z.infer<typeof PaymentRequiredV1Schema>;\n\n/**\n * PaymentPayload schema for V1.\n * Contains the payment data sent by the client.\n */\nexport const PaymentPayloadV1Schema = z.object({\n x402Version: z.literal(1),\n scheme: NonEmptyString,\n network: NetworkSchemaV1,\n payload: Any,\n});\nexport type PaymentPayloadV1 = z.infer<typeof PaymentPayloadV1Schema>;\n\n// ============================================================================\n// V2 Schemas\n// ============================================================================\n\n/**\n * PaymentRequirements schema for V2.\n * V2 uses \"amount\" instead of \"maxAmountRequired\" and doesn't include resource info.\n */\nexport const PaymentRequirementsV2Schema = z.object({\n scheme: NonEmptyString,\n network: NetworkSchemaV2,\n amount: NonEmptyString,\n asset: NonEmptyString,\n payTo: NonEmptyString,\n maxTimeoutSeconds: z.number().positive(),\n extra: OptionalAny,\n});\nexport type PaymentRequirementsV2 = z.infer<typeof PaymentRequirementsV2Schema>;\n\n/**\n * PaymentRequired (402 response) schema for V2.\n * Contains payment requirements when a resource requires payment.\n */\nexport const PaymentRequiredV2Schema = z.object({\n x402Version: z.literal(2),\n error: z.string().optional(),\n resource: ResourceInfoSchema,\n accepts: z.array(PaymentRequirementsV2Schema).min(1),\n extensions: OptionalAny,\n});\nexport type PaymentRequiredV2 = z.infer<typeof PaymentRequiredV2Schema>;\n\n/**\n * PaymentPayload schema for V2.\n * Contains the payment data sent by the client.\n */\nexport const PaymentPayloadV2Schema = z.object({\n x402Version: z.literal(2),\n resource: ResourceInfoSchema.optional(),\n accepted: PaymentRequirementsV2Schema,\n payload: Any,\n extensions: OptionalAny,\n});\nexport type PaymentPayloadV2 = z.infer<typeof PaymentPayloadV2Schema>;\n\n// ============================================================================\n// Union Schemas (V1 | V2)\n// ============================================================================\n\n/**\n * PaymentRequirements union schema - accepts either V1 or V2 format.\n * Use this when you need to handle both versions.\n */\nexport const PaymentRequirementsSchema = z.union([\n PaymentRequirementsV1Schema,\n PaymentRequirementsV2Schema,\n]);\nexport type PaymentRequirements = z.infer<typeof PaymentRequirementsSchema>;\n\n/**\n * PaymentRequired union schema - accepts either V1 or V2 format.\n * Uses discriminated union on x402Version for efficient parsing.\n */\nexport const PaymentRequiredSchema = z.discriminatedUnion(\"x402Version\", [\n PaymentRequiredV1Schema,\n PaymentRequiredV2Schema,\n]);\nexport type PaymentRequired = z.infer<typeof PaymentRequiredSchema>;\n\n/**\n * PaymentPayload union schema - accepts either V1 or V2 format.\n * Uses discriminated union on x402Version for efficient parsing.\n */\nexport const PaymentPayloadSchema = z.discriminatedUnion(\"x402Version\", [\n PaymentPayloadV1Schema,\n PaymentPayloadV2Schema,\n]);\nexport type PaymentPayload = z.infer<typeof PaymentPayloadSchema>;\n\n// ============================================================================\n// Validation Functions\n// ============================================================================\n\n/**\n * Validates a PaymentRequired object (V1 or V2).\n *\n * @param value - The value to validate\n * @returns A result object with success status and data or error\n */\nexport function parsePaymentRequired(\n value: unknown,\n): z.SafeParseReturnType<unknown, PaymentRequired> {\n return PaymentRequiredSchema.safeParse(value);\n}\n\n/**\n * Validates a PaymentRequired object and throws on error.\n *\n * @param value - The value to validate\n * @returns The validated PaymentRequired\n * @throws ZodError if validation fails\n */\nexport function validatePaymentRequired(value: unknown): PaymentRequired {\n return PaymentRequiredSchema.parse(value);\n}\n\n/**\n * Type guard for PaymentRequired (V1 or V2).\n *\n * @param value - The value to check\n * @returns True if the value is a valid PaymentRequired\n */\nexport function isPaymentRequired(value: unknown): value is PaymentRequired {\n return PaymentRequiredSchema.safeParse(value).success;\n}\n\n/**\n * Validates a PaymentRequirements object (V1 or V2).\n *\n * @param value - The value to validate\n * @returns A result object with success status and data or error\n */\nexport function parsePaymentRequirements(\n value: unknown,\n): z.SafeParseReturnType<unknown, PaymentRequirements> {\n return PaymentRequirementsSchema.safeParse(value);\n}\n\n/**\n * Validates a PaymentRequirements object and throws on error.\n *\n * @param value - The value to validate\n * @returns The validated PaymentRequirements\n * @throws ZodError if validation fails\n */\nexport function validatePaymentRequirements(value: unknown): PaymentRequirements {\n return PaymentRequirementsSchema.parse(value);\n}\n\n/**\n * Type guard for PaymentRequirements (V1 or V2).\n *\n * @param value - The value to check\n * @returns True if the value is a valid PaymentRequirements\n */\nexport function isPaymentRequirements(value: unknown): value is PaymentRequirements {\n return PaymentRequirementsSchema.safeParse(value).success;\n}\n\n/**\n * Validates a PaymentPayload object (V1 or V2).\n *\n * @param value - The value to validate\n * @returns A result object with success status and data or error\n */\nexport function parsePaymentPayload(\n value: unknown,\n): z.SafeParseReturnType<unknown, PaymentPayload> {\n return PaymentPayloadSchema.safeParse(value);\n}\n\n/**\n * Validates a PaymentPayload object and throws on error.\n *\n * @param value - The value to validate\n * @returns The validated PaymentPayload\n * @throws ZodError if validation fails\n */\nexport function validatePaymentPayload(value: unknown): PaymentPayload {\n return PaymentPayloadSchema.parse(value);\n}\n\n/**\n * Type guard for PaymentPayload (V1 or V2).\n *\n * @param value - The value to check\n * @returns True if the value is a valid PaymentPayload\n */\nexport function isPaymentPayload(value: unknown): value is PaymentPayload {\n return PaymentPayloadSchema.safeParse(value).success;\n}\n\n// ============================================================================\n// Version-Specific Type Guards\n// ============================================================================\n\n/**\n * Type guard for PaymentRequiredV1.\n *\n * @param value - The value to check\n * @returns True if the value is a valid PaymentRequiredV1\n */\nexport function isPaymentRequiredV1(value: unknown): value is PaymentRequiredV1 {\n return PaymentRequiredV1Schema.safeParse(value).success;\n}\n\n/**\n * Type guard for PaymentRequiredV2.\n *\n * @param value - The value to check\n * @returns True if the value is a valid PaymentRequiredV2\n */\nexport function isPaymentRequiredV2(value: unknown): value is PaymentRequiredV2 {\n return PaymentRequiredV2Schema.safeParse(value).success;\n}\n\n/**\n * Type guard for PaymentRequirementsV1.\n *\n * @param value - The value to check\n * @returns True if the value is a valid PaymentRequirementsV1\n */\nexport function isPaymentRequirementsV1(value: unknown): value is PaymentRequirementsV1 {\n return PaymentRequirementsV1Schema.safeParse(value).success;\n}\n\n/**\n * Type guard for PaymentRequirementsV2.\n *\n * @param value - The value to check\n * @returns True if the value is a valid PaymentRequirementsV2\n */\nexport function isPaymentRequirementsV2(value: unknown): value is PaymentRequirementsV2 {\n return PaymentRequirementsV2Schema.safeParse(value).success;\n}\n\n/**\n * Type guard for PaymentPayloadV1.\n *\n * @param value - The value to check\n * @returns True if the value is a valid PaymentPayloadV1\n */\nexport function isPaymentPayloadV1(value: unknown): value is PaymentPayloadV1 {\n return PaymentPayloadV1Schema.safeParse(value).success;\n}\n\n/**\n * Type guard for PaymentPayloadV2.\n *\n * @param value - The value to check\n * @returns True if the value is a valid PaymentPayloadV2\n */\nexport function isPaymentPayloadV2(value: unknown): value is PaymentPayloadV2 {\n return PaymentPayloadV2Schema.safeParse(value).success;\n}\n\n// ============================================================================\n// Re-export zod for convenience\n// ============================================================================\n\nexport { z } from \"zod\";\n","import { PaymentPayload, PaymentRequirements } from \"../types/payments\";\nimport {\n VerifyResponse,\n SettleResponse,\n SupportedResponse,\n VerifyError,\n SettleError,\n FacilitatorResponseError,\n} from \"../types/facilitator\";\nimport { z } from \"../schemas\";\nimport { safeBase64Decode } from \"../utils\";\n\nconst DEFAULT_FACILITATOR_URL = \"https://x402.org/facilitator\";\n\nexport interface FacilitatorConfig {\n url?: string;\n createAuthHeaders?: () => Promise<{\n verify: Record<string, string>;\n settle: Record<string, string>;\n supported: Record<string, string>;\n bazaar?: Record<string, string>;\n }>;\n}\n\n/**\n * Interface for facilitator clients\n * Can be implemented for HTTP-based or local facilitators\n */\nexport interface FacilitatorClient {\n /**\n * Verify a payment with the facilitator\n *\n * @param paymentPayload - The payment to verify\n * @param paymentRequirements - The requirements to verify against\n * @returns Verification response\n */\n verify(\n paymentPayload: PaymentPayload,\n paymentRequirements: PaymentRequirements,\n ): Promise<VerifyResponse>;\n\n /**\n * Settle a payment with the facilitator\n *\n * @param paymentPayload - The payment to settle\n * @param paymentRequirements - The requirements for settlement\n * @returns Settlement response\n */\n settle(\n paymentPayload: PaymentPayload,\n paymentRequirements: PaymentRequirements,\n ): Promise<SettleResponse>;\n\n /**\n * Get supported payment kinds and extensions from the facilitator\n *\n * @returns Supported payment kinds and extensions\n */\n getSupported(): Promise<SupportedResponse>;\n}\n\n/** Number of retries for getSupported() on 429 rate limit errors */\nconst GET_SUPPORTED_RETRIES = 3;\n/** Base delay in ms for exponential backoff on retries */\nconst GET_SUPPORTED_RETRY_DELAY_MS = 1000;\n/** Upper bound on retry delay to prevent pathological waits from a misbehaving server */\nconst MAX_RETRY_DELAY_MS = 30_000;\n\n/**\n * Resolves the delay before the next 429 retry. Parses Retry-After per RFC 7231 §7.1.3\n * (delta-seconds or HTTP-date) and falls back to exponential backoff when the header\n * is absent, unparseable, or non-positive. The result is clamped to MAX_RETRY_DELAY_MS.\n *\n * @param retryAfter - Raw `Retry-After` header value, or null if not present\n * @param attempt - Zero-based retry attempt index used for exponential backoff\n * @returns Delay in milliseconds to wait before the next attempt\n */\nexport function computeRetryDelay(retryAfter: string | null, attempt: number): number {\n let delay: number | null = null;\n\n if (retryAfter !== null) {\n const seconds = Number(retryAfter);\n if (!isNaN(seconds)) {\n // delta-seconds form\n delay = seconds * 1000;\n } else {\n // HTTP-date form\n const retryDate = Date.parse(retryAfter);\n if (!isNaN(retryDate)) {\n delay = retryDate - Date.now();\n }\n }\n }\n\n // Fall back to exponential backoff for missing, invalid, or non-positive values\n if (delay === null || delay <= 0) {\n delay = GET_SUPPORTED_RETRY_DELAY_MS * Math.pow(2, attempt);\n }\n\n return Math.min(delay, MAX_RETRY_DELAY_MS);\n}\n\nconst verifyResponseSchema: z.ZodType<VerifyResponse, z.ZodTypeDef, unknown> = z.object({\n isValid: z.boolean(),\n invalidReason: z\n .string()\n .nullish()\n .transform(v => v ?? undefined),\n invalidMessage: z\n .string()\n .nullish()\n .transform(v => v ?? undefined),\n payer: z\n .string()\n .nullish()\n .transform(v => v ?? undefined),\n extensions: z\n .record(z.string(), z.unknown())\n .nullish()\n .transform(v => v ?? undefined),\n extra: z\n .record(z.string(), z.unknown())\n .nullish()\n .transform(v => v ?? undefined),\n});\n\nconst settleResponseSchema: z.ZodType<SettleResponse, z.ZodTypeDef, unknown> = z.object({\n success: z.boolean(),\n errorReason: z\n .string()\n .nullish()\n .transform(v => v ?? undefined),\n errorMessage: z\n .string()\n .nullish()\n .transform(v => v ?? undefined),\n payer: z\n .string()\n .nullish()\n .transform(v => v ?? undefined),\n transaction: z.string(),\n network: z.custom<SettleResponse[\"network\"]>(value => typeof value === \"string\"),\n amount: z\n .string()\n .nullish()\n .transform(v => v ?? undefined),\n extensions: z\n .record(z.string(), z.unknown())\n .nullish()\n .transform(v => v ?? undefined),\n extra: z\n .record(z.string(), z.unknown())\n .nullish()\n .transform(v => v ?? undefined),\n});\n\nconst supportedKindSchema: z.ZodType<SupportedResponse[\"kinds\"][number], z.ZodTypeDef, unknown> =\n z.object({\n x402Version: z.number(),\n scheme: z.string(),\n network: z.custom<SupportedResponse[\"kinds\"][number][\"network\"]>(\n value => typeof value === \"string\",\n ),\n extra: z\n .record(z.string(), z.unknown())\n .nullish()\n .transform(v => v ?? undefined),\n });\n\nconst supportedResponseSchema: z.ZodType<SupportedResponse, z.ZodTypeDef, unknown> = z.object({\n kinds: z.array(supportedKindSchema),\n extensions: z.array(z.string()).default([]),\n signers: z.record(z.string(), z.array(z.string())).default({}),\n});\n\n/**\n * Produces a compact excerpt of a facilitator response body for error messages.\n *\n * @param text - The raw response body text\n * @param limit - The maximum number of characters to include\n * @returns A normalized excerpt suitable for logs and thrown errors\n */\nfunction responseExcerpt(text: string, limit: number = 200): string {\n const compact = text.trim().replace(/\\s+/g, \" \");\n if (!compact) {\n return \"<empty response>\";\n }\n\n if (compact.length <= limit) {\n return compact;\n }\n\n return `${compact.slice(0, limit - 3)}...`;\n}\n\nconst EXTENSION_RESPONSE_LOG_FIELD_ALLOWLIST = [\"status\", \"rejectedReason\", \"reason\", \"code\"];\n\n/**\n * Reads the `EXTENSION-RESPONSES` header from a facilitator HTTP response and logs\n * allowlisted fields. Silently ignores malformed headers.\n *\n * @param response - The HTTP response from the facilitator\n */\nfunction logExtensionResponsesHeader(response: Response): void {\n const header = response.headers.get(\"EXTENSION-RESPONSES\");\n if (!header) return;\n try {\n const decoded = JSON.parse(safeBase64Decode(header));\n if (!decoded || typeof decoded !== \"object\" || Array.isArray(decoded)) return;\n const sanitized: Record<string, Record<string, unknown>> = {};\n for (const [extensionKey, payload] of Object.entries(decoded as Record<string, unknown>)) {\n const source =\n payload && typeof payload === \"object\" && !Array.isArray(payload)\n ? (payload as Record<string, unknown>)\n : {};\n const filtered: Record<string, unknown> = {};\n for (const key of EXTENSION_RESPONSE_LOG_FIELD_ALLOWLIST) {\n if (source[key] !== undefined) {\n filtered[key] = source[key];\n }\n }\n sanitized[extensionKey] = filtered;\n }\n console.log(`[x402] extension responses: ${JSON.stringify(sanitized)}`);\n } catch {\n // Ignore malformed header\n }\n}\n\n/**\n * Parses and validates a successful facilitator response body.\n *\n * @param response - The HTTP response returned by the facilitator\n * @param schema - The schema used to validate the response payload\n * @param operation - The facilitator operation name for error reporting\n * @returns The validated facilitator payload\n */\nasync function parseSuccessResponse<T>(\n response: Response,\n schema: z.ZodType<T, z.ZodTypeDef, unknown>,\n operation: string,\n): Promise<T> {\n const text = await response.text();\n\n let data: unknown;\n try {\n data = JSON.parse(text);\n } catch {\n throw new FacilitatorResponseError(\n `Facilitator ${operation} returned invalid JSON: ${responseExcerpt(text)}`,\n );\n }\n\n const parsed = schema.safeParse(data);\n if (!parsed.success) {\n throw new FacilitatorResponseError(\n `Facilitator ${operation} returned invalid data: ${responseExcerpt(text)}`,\n );\n }\n\n return parsed.data;\n}\n\n/**\n * HTTP-based client for interacting with x402 facilitator services\n * Handles HTTP communication with facilitator endpoints\n */\nexport class HTTPFacilitatorClient implements FacilitatorClient {\n readonly url: string;\n private readonly _createAuthHeaders?: FacilitatorConfig[\"createAuthHeaders\"];\n\n /**\n * Creates a new HTTPFacilitatorClient instance.\n *\n * @param config - Configuration options for the facilitator client\n */\n constructor(config?: FacilitatorConfig) {\n // Normalize URL: strip trailing slashes to prevent redirect loops (e.g. 308)\n // when constructing endpoint paths like `${url}/supported`\n this.url = (config?.url || DEFAULT_FACILITATOR_URL).replace(/\\/+$/, \"\");\n this._createAuthHeaders = config?.createAuthHeaders;\n }\n\n /**\n * Verify a payment with the facilitator\n *\n * @param paymentPayload - The payment to verify\n * @param paymentRequirements - The requirements to verify against\n * @returns Verification response\n */\n async verify(\n paymentPayload: PaymentPayload,\n paymentRequirements: PaymentRequirements,\n ): Promise<VerifyResponse> {\n let headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n\n if (this._createAuthHeaders) {\n const authHeaders = await this.createAuthHeaders(\"verify\");\n headers = { ...headers, ...authHeaders.headers };\n }\n\n const response = await fetch(`${this.url}/verify`, {\n method: \"POST\",\n headers,\n redirect: \"follow\",\n body: JSON.stringify({\n x402Version: paymentPayload.x402Version,\n paymentPayload: this.toJsonSafe(paymentPayload),\n paymentRequirements: this.toJsonSafe(paymentRequirements),\n }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n let data: unknown;\n try {\n data = JSON.parse(text);\n } catch {\n throw new Error(`Facilitator verify failed (${response.status}): ${responseExcerpt(text)}`);\n }\n\n if (typeof data === \"object\" && data !== null && \"isValid\" in data) {\n throw new VerifyError(response.status, data as VerifyResponse);\n }\n\n throw new Error(\n `Facilitator verify failed (${response.status}): ${responseExcerpt(JSON.stringify(data))}`,\n );\n }\n\n const verifyResult = await parseSuccessResponse(response, verifyResponseSchema, \"verify\");\n logExtensionResponsesHeader(response);\n return verifyResult;\n }\n\n /**\n * Settle a payment with the facilitator\n *\n * @param paymentPayload - The payment to settle\n * @param paymentRequirements - The requirements for settlement\n * @returns Settlement response\n */\n async settle(\n paymentPayload: PaymentPayload,\n paymentRequirements: PaymentRequirements,\n ): Promise<SettleResponse> {\n let headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n\n if (this._createAuthHeaders) {\n const authHeaders = await this.createAuthHeaders(\"settle\");\n headers = { ...headers, ...authHeaders.headers };\n }\n\n const response = await fetch(`${this.url}/settle`, {\n method: \"POST\",\n headers,\n redirect: \"follow\",\n body: JSON.stringify({\n x402Version: paymentPayload.x402Version,\n paymentPayload: this.toJsonSafe(paymentPayload),\n paymentRequirements: this.toJsonSafe(paymentRequirements),\n }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n let data: unknown;\n try {\n data = JSON.parse(text);\n } catch {\n throw new Error(`Facilitator settle failed (${response.status}): ${responseExcerpt(text)}`);\n }\n\n if (typeof data === \"object\" && data !== null && \"success\" in data) {\n throw new SettleError(response.status, data as SettleResponse);\n }\n\n throw new Error(\n `Facilitator settle failed (${response.status}): ${responseExcerpt(JSON.stringify(data))}`,\n );\n }\n\n const settleResult = await parseSuccessResponse(response, settleResponseSchema, \"settle\");\n logExtensionResponsesHeader(response);\n return settleResult;\n }\n\n /**\n * Get supported payment kinds and extensions from the facilitator.\n * Retries with exponential backoff on 429 rate limit errors.\n *\n * @returns Supported payment kinds and extensions\n */\n async getSupported(): Promise<SupportedResponse> {\n let headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n\n if (this._createAuthHeaders) {\n const authHeaders = await this.createAuthHeaders(\"supported\");\n headers = { ...headers, ...authHeaders.headers };\n }\n\n let lastError: Error | null = null;\n for (let attempt = 0; attempt < GET_SUPPORTED_RETRIES; attempt++) {\n const response = await fetch(`${this.url}/supported`, {\n method: \"GET\",\n headers,\n redirect: \"follow\",\n });\n\n if (response.ok) {\n return parseSuccessResponse(response, supportedResponseSchema, \"supported\");\n }\n\n const errorText = await response.text().catch(() => response.statusText);\n lastError = new Error(\n `Facilitator getSupported failed (${response.status}): ${responseExcerpt(errorText)}`,\n );\n\n // Retry on 429, honoring the server's Retry-After when available.\n if (response.status === 429 && attempt < GET_SUPPORTED_RETRIES - 1) {\n const delay = computeRetryDelay(response.headers.get(\"Retry-After\"), attempt);\n await new Promise(resolve => setTimeout(resolve, delay));\n continue;\n }\n\n throw lastError;\n }\n\n throw lastError ?? new Error(\"Facilitator getSupported failed after retries\");\n }\n\n /**\n * Creates authentication headers for a specific path.\n *\n * @param path - The path to create authentication headers for (e.g., \"verify\", \"settle\", \"supported\")\n * @returns An object containing the authentication headers for the specified path\n */\n async createAuthHeaders(path: string): Promise<{\n headers: Record<string, string>;\n }> {\n if (this._createAuthHeaders) {\n const authHeaders = (await this._createAuthHeaders()) as Record<\n string,\n Record<string, string>\n >;\n return {\n headers: authHeaders[path] ?? {},\n };\n }\n return {\n headers: {},\n };\n }\n\n /**\n * Helper to convert objects to JSON-safe format.\n * Handles BigInt and other non-JSON types.\n *\n * @param obj - The object to convert\n * @returns The JSON-safe representation of the object\n */\n private toJsonSafe(obj: unknown): unknown {\n return JSON.parse(\n JSON.stringify(obj, (_, value) => (typeof value === \"bigint\" ? value.toString() : value)),\n );\n }\n}\n","import { SettleResponse } from \"../types\";\nimport { PaymentPayload, PaymentRequired } from \"../types/payments\";\nimport { Base64EncodedRegex, safeBase64Decode, safeBase64Encode } from \"../utils\";\n\n// HTTP Methods that typically use query parameters\nexport type QueryParamMethods = \"GET\" | \"HEAD\" | \"DELETE\";\n\n// HTTP Methods that typically use request body\nexport type BodyMethods = \"POST\" | \"PUT\" | \"PATCH\";\n\n/**\n * Encodes a payment payload as a base64 header value.\n *\n * @param paymentPayload - The payment payload to encode\n * @returns Base64 encoded string representation of the payment payload\n */\nexport function encodePaymentSignatureHeader(paymentPayload: PaymentPayload): string {\n return safeBase64Encode(JSON.stringify(paymentPayload));\n}\n\n/**\n * Decodes a base64 payment signature header into a payment payload.\n *\n * @param paymentSignatureHeader - The base64 encoded payment signature header\n * @returns The decoded payment payload\n */\nexport function decodePaymentSignatureHeader(paymentSignatureHeader: string): PaymentPayload {\n if (!Base64EncodedRegex.test(paymentSignatureHeader)) {\n throw new Error(\"Invalid payment signature header\");\n }\n return JSON.parse(safeBase64Decode(paymentSignatureHeader)) as PaymentPayload;\n}\n\n/**\n * Encodes a payment required object as a base64 header value.\n *\n * @param paymentRequired - The payment required object to encode\n * @returns Base64 encoded string representation of the payment required object\n */\nexport function encodePaymentRequiredHeader(paymentRequired: PaymentRequired): string {\n return safeBase64Encode(JSON.stringify(paymentRequired));\n}\n\n/**\n * Decodes a base64 payment required header into a payment required object.\n *\n * @param paymentRequiredHeader - The base64 encoded payment required header\n * @returns The decoded payment required object\n */\nexport function decodePaymentRequiredHeader(paymentRequiredHeader: string): PaymentRequired {\n if (!Base64EncodedRegex.test(paymentRequiredHeader)) {\n throw new Error(\"Invalid payment required header\");\n }\n return JSON.parse(safeBase64Decode(paymentRequiredHeader)) as PaymentRequired;\n}\n\n/**\n * Encodes a payment response as a base64 header value.\n *\n * @param paymentResponse - The payment response to encode\n * @returns Base64 encoded string representation of the payment response\n */\nexport function encodePaymentResponseHeader(paymentResponse: SettleResponse): string {\n return safeBase64Encode(JSON.stringify(paymentResponse));\n}\n\n/**\n * Decodes a base64 payment response header into a settle response.\n *\n * @param paymentResponseHeader - The base64 encoded payment response header\n * @returns The decoded settle response\n */\nexport function decodePaymentResponseHeader(paymentResponseHeader: string): SettleResponse {\n if (!Base64EncodedRegex.test(paymentResponseHeader)) {\n throw new Error(\"Invalid payment response header\");\n }\n return JSON.parse(safeBase64Decode(paymentResponseHeader)) as SettleResponse;\n}\n\n// Export HTTP service and types\nexport {\n x402HTTPResourceServer,\n HTTPAdapter,\n HTTPRequestContext,\n HTTPTransportContext,\n HTTPResponseInstructions,\n HTTPProcessResult,\n PaywallConfig,\n PaywallProvider,\n PaymentOption,\n RouteConfig,\n RoutesConfig,\n CompiledRoute,\n DynamicPayTo,\n DynamicPrice,\n UnpaidResponseBody,\n HTTPResponseBody,\n SettlementFailedResponseBody,\n ProcessSettleResultResponse,\n ProcessSettleSuccessResponse,\n ProcessSettleFailureResponse,\n RouteValidationError,\n RouteConfigurationError,\n ProtectedRequestHook,\n HTTPResourceServerExtensionHooks,\n ResourceServerTransportExtensionHooks,\n} from \"./x402HTTPResourceServer\";\nexport {\n HTTPFacilitatorClient,\n FacilitatorClient,\n FacilitatorConfig,\n} from \"./httpFacilitatorClient\";\nexport { FacilitatorResponseError, getFacilitatorResponseError } from \"../types\";\nexport {\n x402HTTPClient,\n PaymentRequiredContext,\n PaymentRequiredHook,\n HTTPClientExtensionHooks,\n HTTPResourceResponse,\n HTTPPaymentStatus,\n} from \"./x402HTTPClient\";\n","import {\n decodePaymentRequiredHeader,\n decodePaymentResponseHeader,\n encodePaymentSignatureHeader,\n} from \".\";\nimport { SettleResponse } from \"../types\";\nimport { PaymentPayload, PaymentRequired } from \"../types/payments\";\nimport { x402Client, type PaymentResponseContext } from \"../client/x402Client\";\n\n/**\n * Context provided to onPaymentRequired hooks.\n */\nexport interface PaymentRequiredContext {\n paymentRequired: PaymentRequired;\n}\n\n/**\n * Hook called when a 402 response is received, before payment processing.\n * Return headers to try before payment, or void to proceed directly to payment.\n */\nexport type PaymentRequiredHook = (\n context: PaymentRequiredContext,\n) => Promise<{ headers: Record<string, string> } | void>;\n\nexport interface HTTPClientExtensionHooks {\n onPaymentRequired?: (\n declaration: unknown,\n context: PaymentRequiredContext,\n ) => Promise<{ headers: Record<string, string> } | void>;\n}\n\ntype HTTPClientTransportExtension = {\n transportHooks?: {\n http?: HTTPClientExtensionHooks;\n };\n};\n\n/**\n * HTTP-specific client for handling x402 payment protocol over HTTP.\n *\n * Wraps a x402Client to provide HTTP-specific encoding/decoding functionality\n * for payment headers and responses while maintaining the builder pattern.\n */\nexport class x402HTTPClient {\n private paymentRequiredHooks: PaymentRequiredHook[] = [];\n\n /**\n * Creates a new x402HTTPClient instance.\n *\n * @param client - The underlying x402Client for payment logic\n */\n constructor(private readonly client: x402Client) {}\n\n /**\n * Register a hook to handle 402 responses before payment.\n * Hooks run in order; first to return headers wins.\n *\n * @param hook - The hook function to register\n * @returns This instance for chaining\n */\n onPaymentRequired(hook: PaymentRequiredHook): this {\n this.paymentRequiredHooks.push(hook);\n return this;\n }\n\n /**\n * Run hooks and return headers if any hook provides them.\n *\n * @param paymentRequired - The payment required response from the server\n * @returns Headers to use for retry, or null to proceed to payment\n */\n async handlePaymentRequired(\n paymentRequired: PaymentRequired,\n ): Promise<Record<string, string> | null> {\n for (const hook of this.getPaymentRequiredHooks(paymentRequired)) {\n const result = await hook({ paymentRequired });\n if (result?.headers) {\n return result.headers;\n }\n }\n return null;\n }\n\n /**\n * Encodes a payment payload into appropriate HTTP headers based on version.\n *\n * @param paymentPayload - The payment payload to encode\n * @returns HTTP headers containing the encoded payment signature\n */\n encodePaymentSignatureHeader(paymentPayload: PaymentPayload): Record<string, string> {\n switch (paymentPayload.x402Version) {\n case 2:\n return {\n \"PAYMENT-SIGNATURE\": encodePaymentSignatureHeader(paymentPayload),\n };\n case 1:\n return {\n \"X-PAYMENT\": encodePaymentSignatureHeader(paymentPayload),\n };\n default:\n throw new Error(\n `Unsupported x402 version: ${(paymentPayload as PaymentPayload).x402Version}`,\n );\n }\n }\n\n /**\n * Extracts payment required information from HTTP response.\n *\n * @param getHeader - Function to retrieve header value by name (case-insensitive)\n * @param body - Optional response body for v1 compatibility\n * @returns The payment required object\n */\n getPaymentRequiredResponse(\n getHeader: (name: string) => string | null | undefined,\n body?: unknown,\n ): PaymentRequired {\n // v2\n const paymentRequired = getHeader(\"PAYMENT-REQUIRED\");\n if (paymentRequired) {\n return decodePaymentRequiredHeader(paymentRequired);\n }\n\n // v1\n if (\n body &&\n body instanceof Object &&\n \"x402Version\" in body &&\n (body as PaymentRequired).x402Version === 1\n ) {\n return body as PaymentRequired;\n }\n\n throw new Error(\"Invalid payment required response\");\n }\n\n /**\n * Extracts payment settlement response from HTTP headers.\n *\n * @param getHeader - Function to retrieve header value by name (case-insensitive)\n * @returns The settlement response object\n */\n getPaymentSettleResponse(getHeader: (name: string) => string | null | undefined): SettleResponse {\n // v2\n const paymentResponse = getHeader(\"PAYMENT-RESPONSE\");\n if (paymentResponse) {\n return decodePaymentResponseHeader(paymentResponse);\n }\n\n // v1\n const xPaymentResponse = getHeader(\"X-PAYMENT-RESPONSE\");\n if (xPaymentResponse) {\n return decodePaymentResponseHeader(xPaymentResponse);\n }\n\n throw new Error(\"Payment response header not found\");\n }\n\n /**\n * Creates a payment payload for the given payment requirements.\n * Delegates to the underlying x402Client.\n *\n * @param paymentRequired - The payment required response from the server\n * @returns Promise resolving to the payment payload\n */\n async createPaymentPayload(paymentRequired: PaymentRequired): Promise<PaymentPayload> {\n return this.client.createPaymentPayload(paymentRequired);\n }\n\n /**\n * Parses response headers into protocol types, fires payment response hooks (v2 only),\n * and returns whether a hook signaled recovery.\n *\n * Called by transport wrappers (fetch, axios) after the paid request completes.\n *\n * @param paymentPayload - The payload that was sent with the request\n * @param getHeader - Function to retrieve a response header by name\n * @param status - The HTTP status code of the response\n * @returns Whether a hook recovered and the parsed settle response (if any)\n */\n async processPaymentResult(\n paymentPayload: PaymentPayload,\n getHeader: (name: string) => string | null | undefined,\n status: number,\n ): Promise<{ recovered: boolean; settleResponse?: SettleResponse }> {\n let settleResponse: SettleResponse | undefined;\n try {\n settleResponse = this.getPaymentSettleResponse(getHeader);\n } catch {\n /* no header */\n }\n\n if (paymentPayload.x402Version === 1) {\n return { recovered: false, settleResponse };\n }\n\n let paymentRequired: PaymentRequired | undefined;\n if (!settleResponse && status === 402) {\n try {\n paymentRequired = this.getPaymentRequiredResponse(getHeader);\n } catch {\n /* no header */\n }\n }\n\n const requirements = paymentPayload.accepted;\n if (!requirements) {\n throw new Error(\"Invalid x402 v2 payment payload: missing `accepted`\");\n }\n\n const ctx: PaymentResponseContext = {\n paymentPayload,\n requirements,\n ...(settleResponse ? { settleResponse } : {}),\n ...(paymentRequired ? { paymentRequired } : {}),\n };\n\n const result = await this.client.handlePaymentResponse(ctx);\n return { recovered: result?.recovered === true, settleResponse };\n }\n\n /**\n * Parses HTTP status, headers, and body into an `HTTPResourceResponse`.\n *\n * Decodes the x402 payment header into `header`: the `PAYMENT-RESPONSE`\n * settlement if present, otherwise the `PAYMENT-REQUIRED` declaration on\n * 402 responses (whose `error` field carries the server's failure reason).\n *\n * @param args - Normalized response inputs from any HTTP transport\n * @param args.status - HTTP response status code\n * @param args.getHeader - Callback to read response headers by name\n * @param args.body - Response body payload\n * @returns The parsed status, body, and decoded payment header\n */\n parsePaymentResult(args: {\n status: number;\n getHeader: (name: string) => string | null | undefined;\n body: unknown;\n }): HTTPResourceResponse {\n const { status, getHeader, body } = args;\n\n let header: SettleResponse | PaymentRequired | undefined;\n try {\n header = this.getPaymentSettleResponse(getHeader);\n } catch {\n if (status === 402) {\n try {\n header = this.getPaymentRequiredResponse(getHeader, body);\n } catch {\n /* no payment header */\n }\n }\n }\n\n let paymentStatus: HTTPPaymentStatus = \"none\";\n if (header && !(\"success\" in header)) {\n paymentStatus = \"payment_required\";\n }\n if (header && \"success\" in header) {\n paymentStatus = header.success ? \"settled\" : \"settle_failed\";\n }\n\n return { status, paymentStatus, body, header };\n }\n\n /**\n * Parses a fetch Response into an `HTTPResourceResponse` for app-level convenience.\n *\n * @param response - The fetch Response to process\n * @returns The parsed status, body, and decoded payment header\n */\n async processResponse(response: Response): Promise<HTTPResourceResponse> {\n const getHeader = (name: string) => response.headers.get(name);\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n const body = contentType.includes(\"application/json\")\n ? await response.json()\n : await response.text();\n\n return this.parsePaymentResult({ status: response.status, getHeader, body });\n }\n\n /**\n * Manual HTTP hooks run before extension hooks scoped to the 402 response.\n *\n * @param paymentRequired - The payment required response from the server\n * @returns Hooks in invocation order\n */\n private getPaymentRequiredHooks(paymentRequired: PaymentRequired): PaymentRequiredHook[] {\n const hooks = [...this.paymentRequiredHooks];\n const declaredExtensions = paymentRequired.extensions;\n if (!declaredExtensions) return hooks;\n\n for (const extension of this.client.getExtensions()) {\n const httpExtension = extension as HTTPClientTransportExtension;\n const hook = httpExtension.transportHooks?.http?.onPaymentRequired;\n if (!hook || !(extension.key in declaredExtensions)) continue;\n\n hooks.push(context => hook(declaredExtensions[extension.key], context));\n }\n\n return hooks;\n }\n}\n\n/**\n * Parsed result of an HTTP request to an x402 resource.\n */\nexport type HTTPResourceResponse = {\n /** HTTP status code. */\n status: number;\n /** x402 payment outcome. */\n paymentStatus: HTTPPaymentStatus;\n /** Parsed response body. */\n body: unknown;\n /**\n * Decoded x402 payment header, if present:\n * - SettleResponse (from PAYMENT-RESPONSE / X-PAYMENT-RESPONSE)\n * - PaymentRequired (from PAYMENT-REQUIRED; its `error` carries the server reason)\n */\n header?: SettleResponse | PaymentRequired;\n};\n\nexport type HTTPPaymentStatus = \"settled\" | \"settle_failed\" | \"payment_required\" | \"none\";\n"],"mappings":"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","names":["x402Version","import_zod"]}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { P as PaymentPayload, a as PaymentRequirements, V as VerifyResponse, S as SettleResponse, N as Network, b as SchemeNetworkFacilitator, F as FacilitatorExtension } from '../x402Client-TQHctrG7.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Facilitator Hook Context Interfaces
|
|
5
|
+
*/
|
|
6
|
+
interface FacilitatorVerifyContext {
|
|
7
|
+
paymentPayload: PaymentPayload;
|
|
8
|
+
requirements: PaymentRequirements;
|
|
9
|
+
}
|
|
10
|
+
interface FacilitatorVerifyResultContext extends FacilitatorVerifyContext {
|
|
11
|
+
result: VerifyResponse;
|
|
12
|
+
}
|
|
13
|
+
interface FacilitatorVerifyFailureContext extends FacilitatorVerifyContext {
|
|
14
|
+
error: Error;
|
|
15
|
+
}
|
|
16
|
+
interface FacilitatorSettleContext {
|
|
17
|
+
paymentPayload: PaymentPayload;
|
|
18
|
+
requirements: PaymentRequirements;
|
|
19
|
+
}
|
|
20
|
+
interface FacilitatorSettleResultContext extends FacilitatorSettleContext {
|
|
21
|
+
result: SettleResponse;
|
|
22
|
+
}
|
|
23
|
+
interface FacilitatorSettleFailureContext extends FacilitatorSettleContext {
|
|
24
|
+
error: Error;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Facilitator Hook Type Definitions
|
|
28
|
+
*/
|
|
29
|
+
type FacilitatorBeforeVerifyHook = (context: FacilitatorVerifyContext) => Promise<void | {
|
|
30
|
+
abort: true;
|
|
31
|
+
reason: string;
|
|
32
|
+
}>;
|
|
33
|
+
type FacilitatorAfterVerifyHook = (context: FacilitatorVerifyResultContext) => Promise<void>;
|
|
34
|
+
type FacilitatorOnVerifyFailureHook = (context: FacilitatorVerifyFailureContext) => Promise<void | {
|
|
35
|
+
recovered: true;
|
|
36
|
+
result: VerifyResponse;
|
|
37
|
+
}>;
|
|
38
|
+
type FacilitatorBeforeSettleHook = (context: FacilitatorSettleContext) => Promise<void | {
|
|
39
|
+
abort: true;
|
|
40
|
+
reason: string;
|
|
41
|
+
}>;
|
|
42
|
+
type FacilitatorAfterSettleHook = (context: FacilitatorSettleResultContext) => Promise<void>;
|
|
43
|
+
type FacilitatorOnSettleFailureHook = (context: FacilitatorSettleFailureContext) => Promise<void | {
|
|
44
|
+
recovered: true;
|
|
45
|
+
result: SettleResponse;
|
|
46
|
+
}>;
|
|
47
|
+
/**
|
|
48
|
+
* Facilitator client for the x402 payment protocol.
|
|
49
|
+
* Manages payment scheme registration, verification, and settlement.
|
|
50
|
+
*/
|
|
51
|
+
declare class x402Facilitator {
|
|
52
|
+
private readonly registeredFacilitatorSchemes;
|
|
53
|
+
private readonly extensions;
|
|
54
|
+
private beforeVerifyHooks;
|
|
55
|
+
private afterVerifyHooks;
|
|
56
|
+
private onVerifyFailureHooks;
|
|
57
|
+
private beforeSettleHooks;
|
|
58
|
+
private afterSettleHooks;
|
|
59
|
+
private onSettleFailureHooks;
|
|
60
|
+
/**
|
|
61
|
+
* Registers a scheme facilitator for the current x402 version.
|
|
62
|
+
* Networks are stored and used for getSupported() - no need to specify them later.
|
|
63
|
+
*
|
|
64
|
+
* @param networks - Single network or array of networks this facilitator supports
|
|
65
|
+
* @param facilitator - The scheme network facilitator to register
|
|
66
|
+
* @returns The x402Facilitator instance for chaining
|
|
67
|
+
*/
|
|
68
|
+
register(networks: Network | Network[], facilitator: SchemeNetworkFacilitator): x402Facilitator;
|
|
69
|
+
/**
|
|
70
|
+
* Registers a scheme facilitator for x402 version 1.
|
|
71
|
+
* Networks are stored and used for getSupported() - no need to specify them later.
|
|
72
|
+
*
|
|
73
|
+
* @param networks - Single network or array of networks this facilitator supports
|
|
74
|
+
* @param facilitator - The scheme network facilitator to register
|
|
75
|
+
* @returns The x402Facilitator instance for chaining
|
|
76
|
+
*/
|
|
77
|
+
registerV1(networks: Network | Network[], facilitator: SchemeNetworkFacilitator): x402Facilitator;
|
|
78
|
+
/**
|
|
79
|
+
* Registers a protocol extension.
|
|
80
|
+
*
|
|
81
|
+
* @param extension - The extension object to register
|
|
82
|
+
* @returns The x402Facilitator instance for chaining
|
|
83
|
+
*/
|
|
84
|
+
registerExtension(extension: FacilitatorExtension): x402Facilitator;
|
|
85
|
+
/**
|
|
86
|
+
* Gets the list of registered extension keys.
|
|
87
|
+
*
|
|
88
|
+
* @returns Array of extension key strings
|
|
89
|
+
*/
|
|
90
|
+
getExtensions(): string[];
|
|
91
|
+
/**
|
|
92
|
+
* Gets a registered extension by key.
|
|
93
|
+
*
|
|
94
|
+
* @param key - The extension key to look up
|
|
95
|
+
* @returns The extension object, or undefined if not registered
|
|
96
|
+
*/
|
|
97
|
+
getExtension<T extends FacilitatorExtension = FacilitatorExtension>(key: string): T | undefined;
|
|
98
|
+
/**
|
|
99
|
+
* Register a hook to execute before facilitator payment verification.
|
|
100
|
+
* Can abort verification by returning { abort: true, reason: string }
|
|
101
|
+
*
|
|
102
|
+
* @param hook - The hook function to register
|
|
103
|
+
* @returns The x402Facilitator instance for chaining
|
|
104
|
+
*/
|
|
105
|
+
onBeforeVerify(hook: FacilitatorBeforeVerifyHook): x402Facilitator;
|
|
106
|
+
/**
|
|
107
|
+
* Register a hook to execute after successful facilitator payment verification (isValid: true).
|
|
108
|
+
* This hook is NOT called when verification fails (isValid: false) - use onVerifyFailure for that.
|
|
109
|
+
*
|
|
110
|
+
* @param hook - The hook function to register
|
|
111
|
+
* @returns The x402Facilitator instance for chaining
|
|
112
|
+
*/
|
|
113
|
+
onAfterVerify(hook: FacilitatorAfterVerifyHook): x402Facilitator;
|
|
114
|
+
/**
|
|
115
|
+
* Register a hook to execute when facilitator payment verification fails.
|
|
116
|
+
* Called when: verification returns isValid: false, or an exception is thrown during verification.
|
|
117
|
+
* Can recover from failure by returning { recovered: true, result: VerifyResponse }
|
|
118
|
+
*
|
|
119
|
+
* @param hook - The hook function to register
|
|
120
|
+
* @returns The x402Facilitator instance for chaining
|
|
121
|
+
*/
|
|
122
|
+
onVerifyFailure(hook: FacilitatorOnVerifyFailureHook): x402Facilitator;
|
|
123
|
+
/**
|
|
124
|
+
* Register a hook to execute before facilitator payment settlement.
|
|
125
|
+
* Can abort settlement by returning { abort: true, reason: string }
|
|
126
|
+
*
|
|
127
|
+
* @param hook - The hook function to register
|
|
128
|
+
* @returns The x402Facilitator instance for chaining
|
|
129
|
+
*/
|
|
130
|
+
onBeforeSettle(hook: FacilitatorBeforeSettleHook): x402Facilitator;
|
|
131
|
+
/**
|
|
132
|
+
* Register a hook to execute after successful facilitator payment settlement.
|
|
133
|
+
*
|
|
134
|
+
* @param hook - The hook function to register
|
|
135
|
+
* @returns The x402Facilitator instance for chaining
|
|
136
|
+
*/
|
|
137
|
+
onAfterSettle(hook: FacilitatorAfterSettleHook): x402Facilitator;
|
|
138
|
+
/**
|
|
139
|
+
* Register a hook to execute when facilitator payment settlement fails.
|
|
140
|
+
* Can recover from failure by returning { recovered: true, result: SettleResponse }
|
|
141
|
+
*
|
|
142
|
+
* @param hook - The hook function to register
|
|
143
|
+
* @returns The x402Facilitator instance for chaining
|
|
144
|
+
*/
|
|
145
|
+
onSettleFailure(hook: FacilitatorOnSettleFailureHook): x402Facilitator;
|
|
146
|
+
/**
|
|
147
|
+
* Gets supported payment kinds, extensions, and signers.
|
|
148
|
+
* Uses networks registered during register() calls - no parameters needed.
|
|
149
|
+
* Returns flat array format for backward compatibility with V1 clients.
|
|
150
|
+
*
|
|
151
|
+
* @returns Supported response with kinds as array (with version in each element), extensions, and signers
|
|
152
|
+
*/
|
|
153
|
+
getSupported(): {
|
|
154
|
+
kinds: Array<{
|
|
155
|
+
x402Version: number;
|
|
156
|
+
scheme: string;
|
|
157
|
+
network: string;
|
|
158
|
+
extra?: Record<string, unknown>;
|
|
159
|
+
}>;
|
|
160
|
+
extensions: string[];
|
|
161
|
+
signers: Record<string, string[]>;
|
|
162
|
+
};
|
|
163
|
+
/**
|
|
164
|
+
* Verifies a payment payload against requirements.
|
|
165
|
+
*
|
|
166
|
+
* @param paymentPayload - The payment payload to verify
|
|
167
|
+
* @param paymentRequirements - The payment requirements to verify against
|
|
168
|
+
* @returns Promise resolving to the verification response
|
|
169
|
+
*/
|
|
170
|
+
verify(paymentPayload: PaymentPayload, paymentRequirements: PaymentRequirements): Promise<VerifyResponse>;
|
|
171
|
+
/**
|
|
172
|
+
* Settles a payment based on the payload and requirements.
|
|
173
|
+
*
|
|
174
|
+
* @param paymentPayload - The payment payload to settle
|
|
175
|
+
* @param paymentRequirements - The payment requirements for settlement
|
|
176
|
+
* @returns Promise resolving to the settlement response
|
|
177
|
+
*/
|
|
178
|
+
settle(paymentPayload: PaymentPayload, paymentRequirements: PaymentRequirements): Promise<SettleResponse>;
|
|
179
|
+
/**
|
|
180
|
+
* Builds a FacilitatorContext from the registered extensions map.
|
|
181
|
+
* Passed to mechanism verify/settle so they can access extension capabilities.
|
|
182
|
+
*
|
|
183
|
+
* @returns A FacilitatorContext backed by this facilitator's registered extensions
|
|
184
|
+
*/
|
|
185
|
+
private buildFacilitatorContext;
|
|
186
|
+
/**
|
|
187
|
+
* Internal method to register a scheme facilitator.
|
|
188
|
+
*
|
|
189
|
+
* @param x402Version - The x402 protocol version
|
|
190
|
+
* @param networks - Array of concrete networks this facilitator supports
|
|
191
|
+
* @param facilitator - The scheme network facilitator to register
|
|
192
|
+
* @returns The x402Facilitator instance for chaining
|
|
193
|
+
*/
|
|
194
|
+
private _registerScheme;
|
|
195
|
+
/**
|
|
196
|
+
* Derives a wildcard pattern from an array of networks.
|
|
197
|
+
* If all networks share the same namespace, returns wildcard pattern.
|
|
198
|
+
* Otherwise returns the first network for exact matching.
|
|
199
|
+
*
|
|
200
|
+
* @param networks - Array of networks
|
|
201
|
+
* @returns Derived pattern for matching
|
|
202
|
+
*/
|
|
203
|
+
private derivePattern;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export { type FacilitatorAfterSettleHook, type FacilitatorAfterVerifyHook, type FacilitatorBeforeSettleHook, type FacilitatorBeforeVerifyHook, type FacilitatorOnSettleFailureHook, type FacilitatorOnVerifyFailureHook, type FacilitatorSettleContext, type FacilitatorSettleFailureContext, type FacilitatorSettleResultContext, type FacilitatorVerifyContext, type FacilitatorVerifyFailureContext, type FacilitatorVerifyResultContext, x402Facilitator };
|