@t402/core 2.4.0 → 2.5.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.
Files changed (40) hide show
  1. package/dist/cjs/client/index.d.ts +2 -2
  2. package/dist/cjs/client/index.js +2 -1
  3. package/dist/cjs/client/index.js.map +1 -1
  4. package/dist/cjs/facilitator/index.d.ts +1 -1
  5. package/dist/cjs/http/index.d.ts +3 -3
  6. package/dist/cjs/http/index.js +4 -3
  7. package/dist/cjs/http/index.js.map +1 -1
  8. package/dist/cjs/{mechanisms-C7yK91d4.d.ts → mechanisms-dYCiYgko.d.ts} +76 -7
  9. package/dist/cjs/server/index.d.ts +2 -2
  10. package/dist/cjs/server/index.js +4 -3
  11. package/dist/cjs/server/index.js.map +1 -1
  12. package/dist/cjs/{t402HTTPClient-DmkFydNG.d.ts → t402HTTPClient-CHaMMGBY.d.ts} +2 -2
  13. package/dist/cjs/{t402HTTPResourceServer-CybruqCk.d.ts → t402HTTPResourceServer-B-aOi0BZ.d.ts} +2 -2
  14. package/dist/cjs/types/index.d.ts +1 -1
  15. package/dist/cjs/types/index.js +2 -1
  16. package/dist/cjs/types/index.js.map +1 -1
  17. package/dist/cjs/types/v1/index.d.ts +1 -1
  18. package/dist/cjs/utils/index.d.ts +1 -1
  19. package/dist/esm/{chunk-REMGOG6C.mjs → chunk-7RHSIMQL.mjs} +4 -4
  20. package/dist/esm/chunk-7RHSIMQL.mjs.map +1 -0
  21. package/dist/esm/{chunk-KPNYZYDS.mjs → chunk-STKQDKUH.mjs} +3 -2
  22. package/dist/esm/chunk-STKQDKUH.mjs.map +1 -0
  23. package/dist/esm/client/index.d.mts +2 -2
  24. package/dist/esm/client/index.mjs +2 -2
  25. package/dist/esm/facilitator/index.d.mts +1 -1
  26. package/dist/esm/http/index.d.mts +3 -3
  27. package/dist/esm/http/index.mjs +2 -2
  28. package/dist/esm/{mechanisms-C7yK91d4.d.mts → mechanisms-dYCiYgko.d.mts} +76 -7
  29. package/dist/esm/server/index.d.mts +2 -2
  30. package/dist/esm/server/index.mjs +2 -2
  31. package/dist/esm/{t402HTTPClient-Bgjn3TRU.d.mts → t402HTTPClient-DbIXpGXL.d.mts} +2 -2
  32. package/dist/esm/{t402HTTPResourceServer-DuZIzhRI.d.mts → t402HTTPResourceServer-CstWZOsH.d.mts} +2 -2
  33. package/dist/esm/types/index.d.mts +1 -1
  34. package/dist/esm/types/index.mjs +1 -1
  35. package/dist/esm/types/index.mjs.map +1 -1
  36. package/dist/esm/types/v1/index.d.mts +1 -1
  37. package/dist/esm/utils/index.d.mts +1 -1
  38. package/package.json +11 -11
  39. package/dist/esm/chunk-KPNYZYDS.mjs.map +0 -1
  40. package/dist/esm/chunk-REMGOG6C.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/http/index.ts","../../../src/types/schemas.ts","../../../src/utils/index.ts","../../../src/index.ts","../../../src/http/t402HTTPResourceServer.ts","../../../src/http/httpFacilitatorClient.ts","../../../src/http/t402HTTPClient.ts"],"sourcesContent":["import { SettleResponse } from \"../types\";\nimport { PaymentPayload, PaymentRequired, PaymentRequirements } from \"../types/payments\";\nimport {\n PaymentPayloadSchema,\n PaymentRequiredSchema,\n SettleResponseSchema,\n} from \"../types/schemas\";\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 * Validates the payload structure using Zod schema.\n *\n * @param paymentSignatureHeader - The base64 encoded payment signature header\n * @returns The decoded and validated payment payload\n * @throws Error if the header is invalid or fails schema validation\n */\nexport function decodePaymentSignatureHeader(paymentSignatureHeader: string): PaymentPayload {\n if (!Base64EncodedRegex.test(paymentSignatureHeader)) {\n throw new Error(\"Invalid payment signature header\");\n }\n const parsed = JSON.parse(safeBase64Decode(paymentSignatureHeader));\n // Validate structure with Zod, then cast to TypeScript type\n // (Zod validates the structure; TypeScript types add template literal constraints)\n PaymentPayloadSchema.parse(parsed);\n return parsed 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 * Validates the structure using Zod schema.\n *\n * @param paymentRequiredHeader - The base64 encoded payment required header\n * @returns The decoded and validated payment required object\n * @throws Error if the header is invalid or fails schema validation\n */\nexport function decodePaymentRequiredHeader(paymentRequiredHeader: string): PaymentRequired {\n if (!Base64EncodedRegex.test(paymentRequiredHeader)) {\n throw new Error(\"Invalid payment required header\");\n }\n const parsed = JSON.parse(safeBase64Decode(paymentRequiredHeader));\n // Validate structure with Zod, then cast to TypeScript type\n PaymentRequiredSchema.parse(parsed);\n return parsed 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(\n paymentResponse: SettleResponse & { requirements: PaymentRequirements },\n): string {\n return safeBase64Encode(JSON.stringify(paymentResponse));\n}\n\n/**\n * Decodes a base64 payment response header into a settle response.\n * Validates the structure using Zod schema.\n *\n * @param paymentResponseHeader - The base64 encoded payment response header\n * @returns The decoded and validated settle response\n * @throws Error if the header is invalid or fails schema validation\n */\nexport function decodePaymentResponseHeader(paymentResponseHeader: string): SettleResponse {\n if (!Base64EncodedRegex.test(paymentResponseHeader)) {\n throw new Error(\"Invalid payment response header\");\n }\n const parsed = JSON.parse(safeBase64Decode(paymentResponseHeader));\n // Validate structure with Zod, then cast to TypeScript type\n SettleResponseSchema.parse(parsed);\n return parsed as SettleResponse;\n}\n\n// Export HTTP service classes (values)\nexport { t402HTTPResourceServer, RouteConfigurationError } from \"./t402HTTPResourceServer\";\nexport { HTTPFacilitatorClient } from \"./httpFacilitatorClient\";\nexport { t402HTTPClient } from \"./t402HTTPClient\";\n\n// Export HTTP types (type-only exports for isolatedModules compatibility)\nexport type {\n HTTPAdapter,\n HTTPRequestContext,\n HTTPResponseInstructions,\n HTTPProcessResult,\n PaywallConfig,\n PaywallProvider,\n PaymentOption,\n RouteConfig,\n RoutesConfig,\n CompiledRoute,\n DynamicPayTo,\n DynamicPrice,\n UnpaidResponseBody,\n UnpaidResponseResult,\n ProcessSettleResultResponse,\n ProcessSettleSuccessResponse,\n ProcessSettleFailureResponse,\n RouteValidationError,\n} from \"./t402HTTPResourceServer\";\nexport type { FacilitatorClient, FacilitatorConfig } from \"./httpFacilitatorClient\";\n","import { z } from \"zod\";\n\n/**\n * Zod schemas for T402 protocol types.\n * Used for runtime validation of incoming data.\n */\n\n// Network format: \"namespace:reference\" (CAIP-2)\nexport const NetworkSchema = z.string().regex(/^[a-z0-9-]+:[a-zA-Z0-9-]+$/, {\n message: \"Network must be in CAIP-2 format (e.g., 'eip155:1', 'solana:mainnet')\",\n});\n\n// Resource info for V2 protocol\nexport const ResourceInfoSchema = z.object({\n url: z.string().url({ message: \"Resource URL must be a valid URL\" }),\n description: z.string().optional(),\n mimeType: z.string().optional(),\n});\n\n// Payment requirements (what the server needs)\nexport const PaymentRequirementsSchema = z.object({\n scheme: z.string().min(1, { message: \"Scheme is required\" }),\n network: NetworkSchema,\n asset: z.string().min(1, { message: \"Asset address is required\" }),\n amount: z.string().regex(/^\\d+$/, { message: \"Amount must be a non-negative integer string\" }),\n payTo: z.string().min(1, { message: \"PayTo address is required\" }),\n maxTimeoutSeconds: z\n .number()\n .int()\n .positive({ message: \"maxTimeoutSeconds must be a positive integer\" }),\n extra: z.record(z.unknown()),\n});\n\n// Payment required response (402 response)\nexport const PaymentRequiredSchema = z.object({\n t402Version: z.literal(2, {\n errorMap: () => ({ message: \"t402Version must be 2 for V2 protocol\" }),\n }),\n error: z.string().optional(),\n resource: ResourceInfoSchema,\n accepts: z\n .array(PaymentRequirementsSchema)\n .min(1, { message: \"At least one payment option is required\" }),\n extensions: z.record(z.unknown()).optional(),\n});\n\n// Payment payload (client's signed payment)\nexport const PaymentPayloadSchema = z.object({\n t402Version: z.literal(2, {\n errorMap: () => ({ message: \"t402Version must be 2 for V2 protocol\" }),\n }),\n resource: ResourceInfoSchema.optional(),\n accepted: PaymentRequirementsSchema,\n payload: z.record(z.unknown()),\n extensions: z.record(z.unknown()).optional(),\n});\n\n// Verify response from facilitator\nexport const VerifyResponseSchema = z.object({\n isValid: z.boolean(),\n invalidReason: z.string().optional(),\n payer: z.string().optional(),\n});\n\n// Settle response from facilitator\nexport const SettleResponseSchema = z.object({\n success: z.boolean(),\n transaction: z.string(),\n network: NetworkSchema,\n errorReason: z.string().optional(),\n payer: z.string().optional(),\n});\n\n// V1 schemas for backward compatibility\nexport const PaymentRequirementsV1Schema = z.object({\n scheme: z.string().min(1),\n network: z.string().min(1),\n asset: z.string().min(1),\n amount: z.string().regex(/^\\d+$/),\n payTo: z.string().min(1),\n maxTimeoutSeconds: z.number().int().positive(),\n extra: z.record(z.unknown()).optional(),\n});\n\nexport const PaymentPayloadV1Schema = z.object({\n t402Version: z.literal(1).optional(),\n accepted: PaymentRequirementsV1Schema,\n payload: z.record(z.unknown()),\n});\n\n// Type inference helpers\nexport type ValidatedPaymentPayload = z.infer<typeof PaymentPayloadSchema>;\nexport type ValidatedPaymentRequired = z.infer<typeof PaymentRequiredSchema>;\nexport type ValidatedPaymentRequirements = z.infer<typeof PaymentRequirementsSchema>;\nexport type ValidatedVerifyResponse = z.infer<typeof VerifyResponseSchema>;\nexport type ValidatedSettleResponse = z.infer<typeof SettleResponseSchema>;\n\n/**\n * Parse and validate a PaymentPayload.\n *\n * @param data - The data to parse\n * @returns The validated payment payload\n * @throws ZodError if validation fails\n */\nexport function parsePaymentPayload(data: unknown): ValidatedPaymentPayload {\n return PaymentPayloadSchema.parse(data);\n}\n\n/**\n * Parse and validate a PaymentRequired response.\n *\n * @param data - The data to parse\n * @returns The validated payment required response\n * @throws ZodError if validation fails\n */\nexport function parsePaymentRequired(data: unknown): ValidatedPaymentRequired {\n return PaymentRequiredSchema.parse(data);\n}\n\n/**\n * Parse and validate PaymentRequirements.\n *\n * @param data - The data to parse\n * @returns The validated payment requirements\n * @throws ZodError if validation fails\n */\nexport function parsePaymentRequirements(data: unknown): ValidatedPaymentRequirements {\n return PaymentRequirementsSchema.parse(data);\n}\n\n/**\n * Safely parse a PaymentPayload, returning a result object.\n *\n * @param data - The data to parse\n * @returns The safe parse result\n */\nexport function safeParsePaymentPayload(\n data: unknown,\n): z.SafeParseReturnType<unknown, ValidatedPaymentPayload> {\n return PaymentPayloadSchema.safeParse(data);\n}\n\n/**\n * Safely parse a PaymentRequired response, returning a result object.\n *\n * @param data - The data to parse\n * @returns The safe parse result\n */\nexport function safeParsePaymentRequired(\n data: unknown,\n): z.SafeParseReturnType<unknown, ValidatedPaymentRequired> {\n return PaymentRequiredSchema.safeParse(data);\n}\n\n/**\n * Safely parse PaymentRequirements, returning a result object.\n *\n * @param data - The data to parse\n * @returns The safe parse result\n */\nexport function safeParsePaymentRequirements(\n data: unknown,\n): z.SafeParseReturnType<unknown, ValidatedPaymentRequirements> {\n return PaymentRequirementsSchema.safeParse(data);\n}\n","import { Network } from \"../types\";\n\n// ============================================================================\n// Cryptographically Secure Random Utilities\n// ============================================================================\n\n/**\n * Get the crypto object, works in both browser and Node.js (19+)\n *\n * @returns The crypto object\n * @throws Error if crypto API is not available\n */\nfunction getCrypto(): Crypto {\n const cryptoObj = globalThis.crypto;\n\n if (!cryptoObj || typeof cryptoObj.getRandomValues !== \"function\") {\n throw new Error(\n \"Crypto API not available. \" + \"Node.js 19+ or a browser with Web Crypto API is required.\",\n );\n }\n\n return cryptoObj;\n}\n\n/**\n * Generate a cryptographically secure random integer in range [0, max)\n *\n * Uses rejection sampling to ensure uniform distribution.\n *\n * @param max - Exclusive upper bound (must be > 0 and <= 2^32)\n * @returns Random integer in [0, max)\n * @throws Error if max is invalid or crypto unavailable\n */\nexport function cryptoRandomInt(max: number): number {\n if (max <= 0 || max > 0xffffffff || !Number.isInteger(max)) {\n throw new Error(`Invalid max value: ${max}. Must be positive integer <= 2^32`);\n }\n\n const crypto = getCrypto();\n const array = new Uint32Array(1);\n\n // Rejection sampling to avoid modulo bias\n const limit = Math.floor(0xffffffff / max) * max;\n let value: number;\n\n do {\n crypto.getRandomValues(array);\n value = array[0];\n } while (value >= limit);\n\n return value % max;\n}\n\n/**\n * Generate a cryptographically secure random BigInt\n *\n * @param bits - Number of bits (default 64, max 256)\n * @returns Random BigInt with specified number of bits\n * @throws Error if bits is invalid or crypto unavailable\n */\nexport function cryptoRandomBigInt(bits: number = 64): bigint {\n if (bits <= 0 || bits > 256) {\n throw new Error(`Invalid bits value: ${bits}. Must be 1-256`);\n }\n\n const crypto = getCrypto();\n const bytes = Math.ceil(bits / 8);\n const array = new Uint8Array(bytes);\n crypto.getRandomValues(array);\n\n // Convert bytes to BigInt\n let result = 0n;\n for (let i = 0; i < bytes; i++) {\n result = (result << 8n) | BigInt(array[i]);\n }\n\n // Mask to exact bit count\n const mask = (1n << BigInt(bits)) - 1n;\n return result & mask;\n}\n\n/**\n * Generate a cryptographically secure random hex string\n *\n * @param bytes - Number of random bytes (default 16)\n * @returns Hex-encoded random string\n * @throws Error if bytes is invalid or crypto unavailable\n */\nexport function cryptoRandomHex(bytes: number = 16): string {\n if (bytes <= 0 || bytes > 128) {\n throw new Error(`Invalid bytes value: ${bytes}. Must be 1-128`);\n }\n\n const crypto = getCrypto();\n const array = new Uint8Array(bytes);\n crypto.getRandomValues(array);\n\n return Array.from(array)\n .map(b => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n// ============================================================================\n// Network and Scheme Utilities\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\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 // Convert the registered network pattern to a regex\n // e.g., \"eip155:*\" becomes /^eip155:.*$/\n const pattern = registeredNetworkPattern\n .replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\") // Escape special regex chars except *\n .replace(/\\\\\\*/g, \".*\"); // Replace escaped * with .*\n\n const regex = new RegExp(`^${pattern}$`);\n\n if (regex.test(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 const patternRegex = new RegExp(\"^\" + schemeData.pattern.replace(\"*\", \".*\") + \"$\");\n if (patternRegex.test(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 return globalThis.btoa(data);\n }\n return Buffer.from(data).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 return globalThis.atob(data);\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","export const t402Version = 2;\n","import { t402ResourceServer } from \"../server\";\nimport {\n decodePaymentSignatureHeader,\n encodePaymentRequiredHeader,\n encodePaymentResponseHeader,\n} from \".\";\nimport {\n PaymentPayload,\n PaymentRequired,\n SettleResponse,\n Price,\n Network,\n PaymentRequirements,\n} from \"../types\";\nimport { t402Version } from \"..\";\n\n/**\n * Framework-agnostic HTTP adapter interface\n * Implementations provide framework-specific HTTP operations\n */\nexport interface HTTPAdapter {\n getHeader(name: string): string | undefined;\n getMethod(): string;\n getPath(): string;\n getUrl(): string;\n getAcceptHeader(): string;\n getUserAgent(): string;\n\n /**\n * Get query parameters from the request URL\n *\n * @returns Record of query parameter key-value pairs\n */\n getQueryParams?(): Record<string, string | string[]>;\n\n /**\n * Get a specific query parameter by name\n *\n * @param name - The query parameter name\n * @returns The query parameter value(s) or undefined\n */\n getQueryParam?(name: string): string | string[] | undefined;\n\n /**\n * Get the parsed request body\n * Framework adapters should parse JSON/form data appropriately\n *\n * @returns The parsed request body\n */\n getBody?(): unknown;\n}\n\n/**\n * Paywall configuration for HTML responses\n */\nexport interface PaywallConfig {\n appName?: string;\n appLogo?: string;\n sessionTokenEndpoint?: string;\n currentUrl?: string;\n testnet?: boolean;\n}\n\n/**\n * Paywall provider interface for generating HTML\n */\nexport interface PaywallProvider {\n generateHtml(paymentRequired: PaymentRequired, config?: PaywallConfig): string;\n}\n\n/**\n * Dynamic payTo function that receives HTTP request context\n */\nexport type DynamicPayTo = (context: HTTPRequestContext) => string | Promise<string>;\n\n/**\n * Dynamic price function that receives HTTP request context\n */\nexport type DynamicPrice = (context: HTTPRequestContext) => Price | Promise<Price>;\n\n/**\n * Result of the unpaid response callback containing content type and body.\n */\nexport interface UnpaidResponseResult {\n /**\n * The content type for the response (e.g., 'application/json', 'text/plain').\n */\n contentType: string;\n\n /**\n * The response body to include in the 402 response.\n */\n body: unknown;\n}\n\n/**\n * Dynamic function to generate a custom response for unpaid requests.\n * Receives the HTTP request context and returns the content type and body to include in the 402 response.\n */\nexport type UnpaidResponseBody = (\n context: HTTPRequestContext,\n) => UnpaidResponseResult | Promise<UnpaidResponseResult>;\n\n/**\n * A single payment option for a route\n * Represents one way a client can pay for access to the resource\n */\nexport interface PaymentOption {\n scheme: string;\n payTo: string | DynamicPayTo;\n price: Price | DynamicPrice;\n network: Network;\n maxTimeoutSeconds?: number;\n extra?: Record<string, unknown>;\n}\n\n/**\n * Route configuration for HTTP endpoints\n *\n * The 'accepts' field defines payment options for the route.\n * Can be a single PaymentOption or an array of PaymentOptions for multiple payment methods.\n */\nexport interface RouteConfig {\n // Payment option(s): single or array\n accepts: PaymentOption | PaymentOption[];\n\n // HTTP-specific metadata\n resource?: string;\n description?: string;\n mimeType?: string;\n customPaywallHtml?: string;\n\n /**\n * Optional callback to generate a custom response for unpaid API requests.\n * This allows servers to return preview data, error messages, or other content\n * when a request lacks payment.\n *\n * For browser requests (Accept: text/html), the paywall HTML takes precedence.\n * This callback is only used for API clients.\n *\n * If not provided, defaults to { contentType: 'application/json', body: {} }.\n *\n * @param context - The HTTP request context\n * @returns An object containing both contentType and body for the 402 response\n */\n unpaidResponseBody?: UnpaidResponseBody;\n\n // Extensions\n extensions?: Record<string, unknown>;\n}\n\n/**\n * Routes configuration - maps path patterns to route configs\n */\nexport type RoutesConfig = Record<string, RouteConfig> | RouteConfig;\n\n/**\n * Compiled route for efficient matching\n */\nexport interface CompiledRoute {\n verb: string;\n regex: RegExp;\n config: RouteConfig;\n}\n\n/**\n * HTTP request context that encapsulates all request data\n */\nexport interface HTTPRequestContext {\n adapter: HTTPAdapter;\n path: string;\n method: string;\n paymentHeader?: string;\n}\n\n/**\n * HTTP response instructions for the framework middleware\n */\nexport interface HTTPResponseInstructions {\n status: number;\n headers: Record<string, string>;\n body?: unknown; // e.g. Paywall for web browser requests, but could be any other type\n isHtml?: boolean; // e.g. if body is a paywall, then isHtml is true\n}\n\n/**\n * Result of processing an HTTP request for payment\n */\nexport type HTTPProcessResult =\n | { type: \"no-payment-required\" }\n | {\n type: \"payment-verified\";\n paymentPayload: PaymentPayload;\n paymentRequirements: PaymentRequirements;\n }\n | { type: \"payment-error\"; response: HTTPResponseInstructions };\n\n/**\n * Result of processSettlement\n */\nexport type ProcessSettleSuccessResponse = SettleResponse & {\n success: true;\n headers: Record<string, string>;\n requirements: PaymentRequirements;\n};\n\nexport type ProcessSettleFailureResponse = SettleResponse & {\n success: false;\n errorReason: string;\n};\n\nexport type ProcessSettleResultResponse =\n | ProcessSettleSuccessResponse\n | ProcessSettleFailureResponse;\n\n/**\n * Represents a validation error for a specific route's payment configuration.\n */\nexport interface RouteValidationError {\n /** The route pattern (e.g., \"GET /api/weather\") */\n routePattern: string;\n /** The payment scheme that failed validation */\n scheme: string;\n /** The network that failed validation */\n network: Network;\n /** The type of validation failure */\n reason: \"missing_scheme\" | \"missing_facilitator\";\n /** Human-readable error message */\n message: string;\n}\n\n/**\n * Error thrown when route configuration validation fails.\n */\nexport class RouteConfigurationError extends Error {\n /** The validation errors that caused this exception */\n public readonly errors: RouteValidationError[];\n\n /**\n * Creates a new RouteConfigurationError with the given validation errors.\n *\n * @param errors - The validation errors that caused this exception.\n */\n constructor(errors: RouteValidationError[]) {\n const message = `t402 Route Configuration Errors:\\n${errors.map(e => ` - ${e.message}`).join(\"\\n\")}`;\n super(message);\n this.name = \"RouteConfigurationError\";\n this.errors = errors;\n }\n}\n\n/**\n * HTTP-enhanced t402 resource server\n * Provides framework-agnostic HTTP protocol handling\n */\nexport class t402HTTPResourceServer {\n private ResourceServer: t402ResourceServer;\n private compiledRoutes: CompiledRoute[] = [];\n private routesConfig: RoutesConfig;\n private paywallProvider?: PaywallProvider;\n\n /**\n * Creates a new t402HTTPResourceServer instance.\n *\n * @param ResourceServer - The core t402ResourceServer instance to use\n * @param routes - Route configuration for payment-protected endpoints\n */\n constructor(ResourceServer: t402ResourceServer, routes: RoutesConfig) {\n this.ResourceServer = ResourceServer;\n this.routesConfig = routes;\n\n // Handle both single route and multiple routes\n const normalizedRoutes =\n typeof routes === \"object\" && !(\"accepts\" in routes)\n ? (routes as Record<string, RouteConfig>)\n : { \"*\": routes as RouteConfig };\n\n for (const [pattern, config] of Object.entries(normalizedRoutes)) {\n const parsed = this.parseRoutePattern(pattern);\n this.compiledRoutes.push({\n verb: parsed.verb,\n regex: parsed.regex,\n config,\n });\n }\n }\n\n /**\n * Initialize the HTTP resource server.\n *\n * This method initializes the underlying resource server (fetching facilitator support)\n * and then validates that all route payment configurations have corresponding\n * registered schemes and facilitator support.\n *\n * @throws RouteConfigurationError if any route's payment options don't have\n * corresponding registered schemes or facilitator support\n *\n * @example\n * ```typescript\n * const httpServer = new t402HTTPResourceServer(server, routes);\n * await httpServer.initialize();\n * ```\n */\n async initialize(): Promise<void> {\n // First, initialize the underlying resource server (fetches facilitator support)\n await this.ResourceServer.initialize();\n\n // Then validate route configuration\n const errors = this.validateRouteConfiguration();\n if (errors.length > 0) {\n throw new RouteConfigurationError(errors);\n }\n }\n\n /**\n * Register a custom paywall provider for generating HTML\n *\n * @param provider - PaywallProvider instance\n * @returns This service instance for chaining\n */\n registerPaywallProvider(provider: PaywallProvider): this {\n this.paywallProvider = provider;\n return this;\n }\n\n /**\n * Process HTTP request and return response instructions\n * This is the main entry point for framework middleware\n *\n * @param context - HTTP request context\n * @param paywallConfig - Optional paywall configuration\n * @returns Process result indicating next action for middleware\n */\n async processHTTPRequest(\n context: HTTPRequestContext,\n paywallConfig?: PaywallConfig,\n ): Promise<HTTPProcessResult> {\n const { adapter, path, method } = context;\n\n // Find matching route\n const routeConfig = this.getRouteConfig(path, method);\n if (!routeConfig) {\n return { type: \"no-payment-required\" }; // No payment required for this route\n }\n\n // Normalize accepts field to array of payment options\n const paymentOptions = this.normalizePaymentOptions(routeConfig);\n\n // Check for payment header (v1 or v2)\n const paymentPayload = this.extractPayment(adapter);\n\n // Create resource info, using config override if provided\n const resourceInfo = {\n url: routeConfig.resource || context.adapter.getUrl(),\n description: routeConfig.description || \"\",\n mimeType: routeConfig.mimeType || \"\",\n };\n\n // Build requirements from all payment options\n // (this method handles resolving dynamic functions internally)\n const requirements = await this.ResourceServer.buildPaymentRequirementsFromOptions(\n paymentOptions,\n context,\n );\n\n let extensions = routeConfig.extensions;\n if (extensions) {\n extensions = this.ResourceServer.enrichExtensions(extensions, context);\n }\n\n const paymentRequired = this.ResourceServer.createPaymentRequiredResponse(\n requirements,\n resourceInfo,\n !paymentPayload ? \"Payment required\" : undefined,\n extensions,\n );\n\n // If no payment provided\n if (!paymentPayload) {\n // Resolve custom unpaid response body if provided\n const unpaidBody = routeConfig.unpaidResponseBody\n ? await routeConfig.unpaidResponseBody(context)\n : undefined;\n\n return {\n type: \"payment-error\",\n response: this.createHTTPResponse(\n paymentRequired,\n this.isWebBrowser(adapter),\n paywallConfig,\n routeConfig.customPaywallHtml,\n unpaidBody,\n ),\n };\n }\n\n // Verify payment\n try {\n const matchingRequirements = this.ResourceServer.findMatchingRequirements(\n paymentRequired.accepts,\n paymentPayload,\n );\n\n if (!matchingRequirements) {\n const errorResponse = this.ResourceServer.createPaymentRequiredResponse(\n requirements,\n resourceInfo,\n \"No matching payment requirements\",\n routeConfig.extensions,\n );\n return {\n type: \"payment-error\",\n response: this.createHTTPResponse(errorResponse, false, paywallConfig),\n };\n }\n\n const verifyResult = await this.ResourceServer.verifyPayment(\n paymentPayload,\n matchingRequirements,\n );\n\n if (!verifyResult.isValid) {\n const errorResponse = this.ResourceServer.createPaymentRequiredResponse(\n requirements,\n resourceInfo,\n verifyResult.invalidReason,\n routeConfig.extensions,\n );\n return {\n type: \"payment-error\",\n response: this.createHTTPResponse(errorResponse, false, paywallConfig),\n };\n }\n\n // Payment is valid, return data needed for settlement\n return {\n type: \"payment-verified\",\n paymentPayload,\n paymentRequirements: matchingRequirements,\n };\n } catch (error) {\n const errorResponse = this.ResourceServer.createPaymentRequiredResponse(\n requirements,\n resourceInfo,\n error instanceof Error ? error.message : \"Payment verification failed\",\n routeConfig.extensions,\n );\n return {\n type: \"payment-error\",\n response: this.createHTTPResponse(errorResponse, false, paywallConfig),\n };\n }\n }\n\n /**\n * Process settlement after successful response\n *\n * @param paymentPayload - The verified payment payload\n * @param requirements - The matching payment requirements\n * @returns ProcessSettleResultResponse - SettleResponse with headers if success or errorReason if failure\n */\n async processSettlement(\n paymentPayload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<ProcessSettleResultResponse> {\n try {\n const settleResponse = await this.ResourceServer.settlePayment(paymentPayload, requirements);\n\n if (!settleResponse.success) {\n return {\n ...settleResponse,\n success: false,\n errorReason: settleResponse.errorReason || \"Settlement failed\",\n };\n }\n\n return {\n ...settleResponse,\n success: true,\n headers: this.createSettlementHeaders(settleResponse, requirements),\n requirements,\n };\n } catch (error) {\n throw new Error(error instanceof Error ? error.message : \"Settlement failed\");\n }\n }\n\n /**\n * Check if a request requires payment based on route configuration\n *\n * @param context - HTTP request context\n * @returns True if the route requires payment, false otherwise\n */\n requiresPayment(context: HTTPRequestContext): boolean {\n const routeConfig = this.getRouteConfig(context.path, context.method);\n return routeConfig !== undefined;\n }\n\n /**\n * Normalizes a RouteConfig's accepts field into an array of PaymentOptions\n * Handles both single PaymentOption and array formats\n *\n * @param routeConfig - Route configuration\n * @returns Array of payment options\n */\n private normalizePaymentOptions(routeConfig: RouteConfig): PaymentOption[] {\n return Array.isArray(routeConfig.accepts) ? routeConfig.accepts : [routeConfig.accepts];\n }\n\n /**\n * Validates that all payment options in routes have corresponding registered schemes\n * and facilitator support.\n *\n * @returns Array of validation errors (empty if all routes are valid)\n */\n private validateRouteConfiguration(): RouteValidationError[] {\n const errors: RouteValidationError[] = [];\n\n // Normalize routes to array of [pattern, config] pairs\n const normalizedRoutes =\n typeof this.routesConfig === \"object\" && !(\"accepts\" in this.routesConfig)\n ? Object.entries(this.routesConfig as Record<string, RouteConfig>)\n : [[\"*\", this.routesConfig as RouteConfig] as [string, RouteConfig]];\n\n for (const [pattern, config] of normalizedRoutes) {\n const paymentOptions = this.normalizePaymentOptions(config);\n\n for (const option of paymentOptions) {\n // Check 1: Is scheme registered?\n if (!this.ResourceServer.hasRegisteredScheme(option.network, option.scheme)) {\n errors.push({\n routePattern: pattern,\n scheme: option.scheme,\n network: option.network,\n reason: \"missing_scheme\",\n message: `Route \"${pattern}\": No scheme implementation registered for \"${option.scheme}\" on network \"${option.network}\"`,\n });\n // Skip facilitator check if scheme isn't registered\n continue;\n }\n\n // Check 2: Does facilitator support this scheme/network combination?\n const supportedKind = this.ResourceServer.getSupportedKind(\n t402Version,\n option.network,\n option.scheme,\n );\n\n if (!supportedKind) {\n errors.push({\n routePattern: pattern,\n scheme: option.scheme,\n network: option.network,\n reason: \"missing_facilitator\",\n message: `Route \"${pattern}\": Facilitator does not support scheme \"${option.scheme}\" on network \"${option.network}\"`,\n });\n }\n }\n }\n\n return errors;\n }\n\n /**\n * Get route configuration for a request\n *\n * @param path - Request path\n * @param method - HTTP method\n * @returns Route configuration or undefined if no match\n */\n private getRouteConfig(path: string, method: string): RouteConfig | undefined {\n const normalizedPath = this.normalizePath(path);\n const upperMethod = method.toUpperCase();\n\n const matchingRoute = this.compiledRoutes.find(\n route =>\n route.regex.test(normalizedPath) && (route.verb === \"*\" || route.verb === upperMethod),\n );\n\n return matchingRoute?.config;\n }\n\n /**\n * Extract payment from HTTP headers (handles v1 and v2)\n *\n * @param adapter - HTTP adapter\n * @returns Decoded payment payload or null\n */\n private extractPayment(adapter: HTTPAdapter): PaymentPayload | null {\n // Check v2 header first (PAYMENT-SIGNATURE)\n const header = adapter.getHeader(\"payment-signature\") || adapter.getHeader(\"PAYMENT-SIGNATURE\");\n\n if (header) {\n try {\n return decodePaymentSignatureHeader(header);\n } catch (error) {\n console.warn(\"Failed to decode PAYMENT-SIGNATURE header:\", error);\n }\n }\n\n return null;\n }\n\n /**\n * Check if request is from a web browser\n *\n * @param adapter - HTTP adapter\n * @returns True if request appears to be from a browser\n */\n private isWebBrowser(adapter: HTTPAdapter): boolean {\n const accept = adapter.getAcceptHeader();\n const userAgent = adapter.getUserAgent();\n return accept.includes(\"text/html\") && userAgent.includes(\"Mozilla\");\n }\n\n /**\n * Create HTTP response instructions from payment required\n *\n * @param paymentRequired - Payment requirements\n * @param isWebBrowser - Whether request is from browser\n * @param paywallConfig - Paywall configuration\n * @param customHtml - Custom HTML template\n * @param unpaidResponse - Optional custom response (content type and body) for unpaid API requests\n * @returns Response instructions\n */\n private createHTTPResponse(\n paymentRequired: PaymentRequired,\n isWebBrowser: boolean,\n paywallConfig?: PaywallConfig,\n customHtml?: string,\n unpaidResponse?: UnpaidResponseResult,\n ): HTTPResponseInstructions {\n if (isWebBrowser) {\n const html = this.generatePaywallHTML(paymentRequired, paywallConfig, customHtml);\n return {\n status: 402,\n headers: { \"Content-Type\": \"text/html\" },\n body: html,\n isHtml: true,\n };\n }\n\n const response = this.createHTTPPaymentRequiredResponse(paymentRequired);\n\n // Use callback result if provided, otherwise default to JSON with empty object\n const contentType = unpaidResponse ? unpaidResponse.contentType : \"application/json\";\n const body = unpaidResponse ? unpaidResponse.body : {};\n\n return {\n status: 402,\n headers: {\n \"Content-Type\": contentType,\n ...response.headers,\n },\n body,\n };\n }\n\n /**\n * Create HTTP payment required response (v1 puts in body, v2 puts in header)\n *\n * @param paymentRequired - Payment required object\n * @returns Headers and body for the HTTP response\n */\n private createHTTPPaymentRequiredResponse(paymentRequired: PaymentRequired): {\n headers: Record<string, string>;\n } {\n return {\n headers: {\n \"PAYMENT-REQUIRED\": encodePaymentRequiredHeader(paymentRequired),\n },\n };\n }\n\n /**\n * Create settlement response headers\n *\n * @param settleResponse - Settlement response\n * @param requirements - Payment requirements that were settled\n * @returns Headers to add to response\n */\n private createSettlementHeaders(\n settleResponse: SettleResponse,\n requirements: PaymentRequirements,\n ): Record<string, string> {\n const encoded = encodePaymentResponseHeader({\n ...settleResponse,\n requirements,\n });\n return { \"PAYMENT-RESPONSE\": encoded };\n }\n\n /**\n * Parse route pattern into verb and regex\n *\n * @param pattern - Route pattern like \"GET /api/*\" or \"/api/[id]\"\n * @returns Parsed pattern with verb and regex\n */\n private parseRoutePattern(pattern: string): { verb: string; regex: RegExp } {\n const [verb, path] = pattern.includes(\" \") ? pattern.split(/\\s+/) : [\"*\", pattern];\n\n const regex = new RegExp(\n `^${\n path\n .replace(/[$()+.?^{|}]/g, \"\\\\$&\") // Escape regex special chars\n .replace(/\\*/g, \".*?\") // Wildcards\n .replace(/\\[([^\\]]+)\\]/g, \"[^/]+\") // Parameters\n .replace(/\\//g, \"\\\\/\") // Escape slashes\n }$`,\n \"i\",\n );\n\n return { verb: verb.toUpperCase(), regex };\n }\n\n /**\n * Normalize path for matching\n *\n * @param path - Raw path from request\n * @returns Normalized path\n */\n private normalizePath(path: string): string {\n try {\n const pathWithoutQuery = path.split(/[?#]/)[0];\n const decodedPath = decodeURIComponent(pathWithoutQuery);\n return decodedPath\n .replace(/\\\\/g, \"/\")\n .replace(/\\/+/g, \"/\")\n .replace(/(.+?)\\/+$/, \"$1\");\n } catch {\n return path;\n }\n }\n\n /**\n * Generate paywall HTML for browser requests\n *\n * @param paymentRequired - Payment required response\n * @param paywallConfig - Optional paywall configuration\n * @param customHtml - Optional custom HTML template\n * @returns HTML string\n */\n private generatePaywallHTML(\n paymentRequired: PaymentRequired,\n paywallConfig?: PaywallConfig,\n customHtml?: string,\n ): string {\n if (customHtml) {\n return customHtml;\n }\n\n // Use custom paywall provider if set\n if (this.paywallProvider) {\n return this.paywallProvider.generateHtml(paymentRequired, paywallConfig);\n }\n\n // Try to use @t402/paywall if available (optional dependency)\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const paywall = require(\"@t402/paywall\");\n const displayAmount = this.getDisplayAmount(paymentRequired);\n const resource = paymentRequired.resource;\n\n return paywall.getPaywallHtml({\n amount: displayAmount,\n paymentRequired,\n currentUrl: resource?.url || paywallConfig?.currentUrl || \"\",\n testnet: paywallConfig?.testnet ?? true,\n appName: paywallConfig?.appName,\n appLogo: paywallConfig?.appLogo,\n sessionTokenEndpoint: paywallConfig?.sessionTokenEndpoint,\n });\n } catch {\n // @t402/paywall not installed, fall back to basic HTML\n }\n\n // Fallback: Basic HTML paywall\n const resource = paymentRequired.resource;\n const displayAmount = this.getDisplayAmount(paymentRequired);\n\n return `\n <!DOCTYPE html>\n <html>\n <head>\n <title>Payment Required</title>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n </head>\n <body>\n <div style=\"max-width: 600px; margin: 50px auto; padding: 20px; font-family: system-ui, -apple-system, sans-serif;\">\n ${paywallConfig?.appLogo ? `<img src=\"${paywallConfig.appLogo}\" alt=\"${paywallConfig.appName || \"App\"}\" style=\"max-width: 200px; margin-bottom: 20px;\">` : \"\"}\n <h1>Payment Required</h1>\n ${resource ? `<p><strong>Resource:</strong> ${resource.description || resource.url}</p>` : \"\"}\n <p><strong>Amount:</strong> $${displayAmount.toFixed(2)} USDC</p>\n <div id=\"payment-widget\" \n data-requirements='${JSON.stringify(paymentRequired)}'\n data-app-name=\"${paywallConfig?.appName || \"\"}\"\n data-testnet=\"${paywallConfig?.testnet || false}\">\n <!-- Install @t402/paywall for full wallet integration -->\n <p style=\"margin-top: 2rem; padding: 1rem; background: #fef3c7; border-radius: 0.5rem;\">\n <strong>Note:</strong> Install <code>@t402/paywall</code> for full wallet connection and payment UI.\n </p>\n </div>\n </div>\n </body>\n </html>\n `;\n }\n\n /**\n * Extract display amount from payment requirements.\n *\n * @param paymentRequired - The payment required object\n * @returns The display amount in decimal format\n */\n private getDisplayAmount(paymentRequired: PaymentRequired): number {\n const accepts = paymentRequired.accepts;\n if (accepts && accepts.length > 0) {\n const firstReq = accepts[0];\n if (\"amount\" in firstReq) {\n // V2 format\n return parseFloat(firstReq.amount) / 1000000; // Assuming USDC with 6 decimals\n }\n }\n return 0;\n }\n}\n","import { PaymentPayload, PaymentRequirements } from \"../types/payments\";\nimport { VerifyResponse, SettleResponse, SupportedResponse } from \"../types/facilitator\";\n\nconst DEFAULT_FACILITATOR_URL = \"https://facilitator.t402.io\";\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 }>;\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/**\n * HTTP-based client for interacting with t402 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 this.url = config?.url || DEFAULT_FACILITATOR_URL;\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 body: JSON.stringify({\n t402Version: paymentPayload.t402Version,\n paymentPayload: this.toJsonSafe(paymentPayload),\n paymentRequirements: this.toJsonSafe(paymentRequirements),\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n throw new Error(`Facilitator verify failed (${response.status}): ${errorText}`);\n }\n\n return (await response.json()) as VerifyResponse;\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 body: JSON.stringify({\n t402Version: paymentPayload.t402Version,\n paymentPayload: this.toJsonSafe(paymentPayload),\n paymentRequirements: this.toJsonSafe(paymentRequirements),\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n throw new Error(`Facilitator settle failed (${response.status}): ${errorText}`);\n }\n\n return (await response.json()) as SettleResponse;\n }\n\n /**\n * Get supported payment kinds and extensions from the facilitator\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 const response = await fetch(`${this.url}/supported`, {\n method: \"GET\",\n headers,\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n throw new Error(`Facilitator getSupported failed (${response.status}): ${errorText}`);\n }\n\n return (await response.json()) as SupportedResponse;\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 {\n decodePaymentRequiredHeader,\n decodePaymentResponseHeader,\n encodePaymentSignatureHeader,\n} from \".\";\nimport { SettleResponse } from \"../types\";\nimport { PaymentPayload, PaymentRequired } from \"../types/payments\";\nimport { t402Client } from \"../client/t402Client\";\n\n/**\n * HTTP-specific client for handling t402 payment protocol over HTTP.\n *\n * Wraps a t402Client to provide HTTP-specific encoding/decoding functionality\n * for payment headers and responses while maintaining the builder pattern.\n */\nexport class t402HTTPClient {\n /**\n * Creates a new t402HTTPClient instance.\n *\n * @param client - The underlying t402Client for payment logic\n */\n constructor(private readonly client: t402Client) {}\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.t402Version) {\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 t402 version: ${(paymentPayload as PaymentPayload).t402Version}`,\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 \"t402Version\" in body &&\n (body as PaymentRequired).t402Version === 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 t402Client.\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"],"mappings":"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","names":["displayAmount","resource"]}
1
+ {"version":3,"sources":["../../../src/http/index.ts","../../../src/types/schemas.ts","../../../src/utils/index.ts","../../../src/index.ts","../../../src/http/t402HTTPResourceServer.ts","../../../src/http/httpFacilitatorClient.ts","../../../src/http/t402HTTPClient.ts"],"sourcesContent":["import { SettleResponse } from \"../types\";\nimport { PaymentPayload, PaymentRequired, PaymentRequirements } from \"../types/payments\";\nimport {\n PaymentPayloadSchema,\n PaymentRequiredSchema,\n SettleResponseSchema,\n} from \"../types/schemas\";\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 * Validates the payload structure using Zod schema.\n *\n * @param paymentSignatureHeader - The base64 encoded payment signature header\n * @returns The decoded and validated payment payload\n * @throws Error if the header is invalid or fails schema validation\n */\nexport function decodePaymentSignatureHeader(paymentSignatureHeader: string): PaymentPayload {\n if (!Base64EncodedRegex.test(paymentSignatureHeader)) {\n throw new Error(\"Invalid payment signature header\");\n }\n const parsed = JSON.parse(safeBase64Decode(paymentSignatureHeader));\n // Validate structure with Zod, then cast to TypeScript type\n // (Zod validates the structure; TypeScript types add template literal constraints)\n PaymentPayloadSchema.parse(parsed);\n return parsed 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 * Validates the structure using Zod schema.\n *\n * @param paymentRequiredHeader - The base64 encoded payment required header\n * @returns The decoded and validated payment required object\n * @throws Error if the header is invalid or fails schema validation\n */\nexport function decodePaymentRequiredHeader(paymentRequiredHeader: string): PaymentRequired {\n if (!Base64EncodedRegex.test(paymentRequiredHeader)) {\n throw new Error(\"Invalid payment required header\");\n }\n const parsed = JSON.parse(safeBase64Decode(paymentRequiredHeader));\n // Validate structure with Zod, then cast to TypeScript type\n PaymentRequiredSchema.parse(parsed);\n return parsed 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(\n paymentResponse: SettleResponse & { requirements: PaymentRequirements },\n): string {\n return safeBase64Encode(JSON.stringify(paymentResponse));\n}\n\n/**\n * Decodes a base64 payment response header into a settle response.\n * Validates the structure using Zod schema.\n *\n * @param paymentResponseHeader - The base64 encoded payment response header\n * @returns The decoded and validated settle response\n * @throws Error if the header is invalid or fails schema validation\n */\nexport function decodePaymentResponseHeader(paymentResponseHeader: string): SettleResponse {\n if (!Base64EncodedRegex.test(paymentResponseHeader)) {\n throw new Error(\"Invalid payment response header\");\n }\n const parsed = JSON.parse(safeBase64Decode(paymentResponseHeader));\n // Validate structure with Zod, then cast to TypeScript type\n SettleResponseSchema.parse(parsed);\n return parsed as SettleResponse;\n}\n\n// Export HTTP service classes (values)\nexport { t402HTTPResourceServer, RouteConfigurationError } from \"./t402HTTPResourceServer\";\nexport { HTTPFacilitatorClient } from \"./httpFacilitatorClient\";\nexport { t402HTTPClient } from \"./t402HTTPClient\";\n\n// Export HTTP types (type-only exports for isolatedModules compatibility)\nexport type {\n HTTPAdapter,\n HTTPRequestContext,\n HTTPResponseInstructions,\n HTTPProcessResult,\n PaywallConfig,\n PaywallProvider,\n PaymentOption,\n RouteConfig,\n RoutesConfig,\n CompiledRoute,\n DynamicPayTo,\n DynamicPrice,\n UnpaidResponseBody,\n UnpaidResponseResult,\n ProcessSettleResultResponse,\n ProcessSettleSuccessResponse,\n ProcessSettleFailureResponse,\n RouteValidationError,\n} from \"./t402HTTPResourceServer\";\nexport type { FacilitatorClient, FacilitatorConfig } from \"./httpFacilitatorClient\";\n","import { z } from \"zod\";\n\n/**\n * Zod schemas for T402 protocol types.\n * Used for runtime validation of incoming data.\n */\n\n// Network format: \"namespace:reference\" (CAIP-2)\nexport const NetworkSchema = z.string().regex(/^[a-z0-9-]+:[a-zA-Z0-9-]+$/, {\n message: \"Network must be in CAIP-2 format (e.g., 'eip155:1', 'solana:mainnet')\",\n});\n\n// Resource info for V2 protocol\nexport const ResourceInfoSchema = z.object({\n url: z.string().url({ message: \"Resource URL must be a valid URL\" }),\n description: z.string().optional(),\n mimeType: z.string().optional(),\n});\n\n// Payment requirements (what the server needs)\nexport const PaymentRequirementsSchema = z.object({\n scheme: z.string().min(1, { message: \"Scheme is required\" }),\n network: NetworkSchema,\n asset: z.string().min(1, { message: \"Asset address is required\" }),\n amount: z.string().regex(/^\\d+$/, { message: \"Amount must be a non-negative integer string\" }),\n payTo: z.string().min(1, { message: \"PayTo address is required\" }),\n maxTimeoutSeconds: z\n .number()\n .int()\n .positive({ message: \"maxTimeoutSeconds must be a positive integer\" }),\n extra: z.record(z.unknown()),\n});\n\n// Payment required response (402 response)\nexport const PaymentRequiredSchema = z.object({\n t402Version: z.literal(2, {\n errorMap: () => ({ message: \"t402Version must be 2 for V2 protocol\" }),\n }),\n error: z.string().optional(),\n resource: ResourceInfoSchema,\n accepts: z\n .array(PaymentRequirementsSchema)\n .min(1, { message: \"At least one payment option is required\" }),\n extensions: z.record(z.unknown()).optional(),\n});\n\n// Payment payload (client's signed payment)\nexport const PaymentPayloadSchema = z.object({\n t402Version: z.literal(2, {\n errorMap: () => ({ message: \"t402Version must be 2 for V2 protocol\" }),\n }),\n resource: ResourceInfoSchema.optional(),\n accepted: PaymentRequirementsSchema,\n payload: z.record(z.unknown()),\n extensions: z.record(z.unknown()).optional(),\n});\n\n// Verify response from facilitator\nexport const VerifyResponseSchema = z.object({\n isValid: z.boolean(),\n invalidReason: z.string().optional(),\n payer: z.string().optional(),\n});\n\n// Settle response from facilitator\nexport const SettleResponseSchema = z.object({\n success: z.boolean(),\n transaction: z.string(),\n network: NetworkSchema,\n errorReason: z.string().optional(),\n payer: z.string().optional(),\n confirmations: z.string().optional(),\n});\n\n// V1 schemas for backward compatibility\nexport const PaymentRequirementsV1Schema = z.object({\n scheme: z.string().min(1),\n network: z.string().min(1),\n asset: z.string().min(1),\n amount: z.string().regex(/^\\d+$/),\n payTo: z.string().min(1),\n maxTimeoutSeconds: z.number().int().positive(),\n extra: z.record(z.unknown()).optional(),\n});\n\nexport const PaymentPayloadV1Schema = z.object({\n t402Version: z.literal(1).optional(),\n accepted: PaymentRequirementsV1Schema,\n payload: z.record(z.unknown()),\n});\n\n// Type inference helpers\nexport type ValidatedPaymentPayload = z.infer<typeof PaymentPayloadSchema>;\nexport type ValidatedPaymentRequired = z.infer<typeof PaymentRequiredSchema>;\nexport type ValidatedPaymentRequirements = z.infer<typeof PaymentRequirementsSchema>;\nexport type ValidatedVerifyResponse = z.infer<typeof VerifyResponseSchema>;\nexport type ValidatedSettleResponse = z.infer<typeof SettleResponseSchema>;\n\n/**\n * Parse and validate a PaymentPayload.\n *\n * @param data - The data to parse\n * @returns The validated payment payload\n * @throws ZodError if validation fails\n */\nexport function parsePaymentPayload(data: unknown): ValidatedPaymentPayload {\n return PaymentPayloadSchema.parse(data);\n}\n\n/**\n * Parse and validate a PaymentRequired response.\n *\n * @param data - The data to parse\n * @returns The validated payment required response\n * @throws ZodError if validation fails\n */\nexport function parsePaymentRequired(data: unknown): ValidatedPaymentRequired {\n return PaymentRequiredSchema.parse(data);\n}\n\n/**\n * Parse and validate PaymentRequirements.\n *\n * @param data - The data to parse\n * @returns The validated payment requirements\n * @throws ZodError if validation fails\n */\nexport function parsePaymentRequirements(data: unknown): ValidatedPaymentRequirements {\n return PaymentRequirementsSchema.parse(data);\n}\n\n/**\n * Safely parse a PaymentPayload, returning a result object.\n *\n * @param data - The data to parse\n * @returns The safe parse result\n */\nexport function safeParsePaymentPayload(\n data: unknown,\n): z.SafeParseReturnType<unknown, ValidatedPaymentPayload> {\n return PaymentPayloadSchema.safeParse(data);\n}\n\n/**\n * Safely parse a PaymentRequired response, returning a result object.\n *\n * @param data - The data to parse\n * @returns The safe parse result\n */\nexport function safeParsePaymentRequired(\n data: unknown,\n): z.SafeParseReturnType<unknown, ValidatedPaymentRequired> {\n return PaymentRequiredSchema.safeParse(data);\n}\n\n/**\n * Safely parse PaymentRequirements, returning a result object.\n *\n * @param data - The data to parse\n * @returns The safe parse result\n */\nexport function safeParsePaymentRequirements(\n data: unknown,\n): z.SafeParseReturnType<unknown, ValidatedPaymentRequirements> {\n return PaymentRequirementsSchema.safeParse(data);\n}\n","import { Network } from \"../types\";\n\n// ============================================================================\n// Cryptographically Secure Random Utilities\n// ============================================================================\n\n/**\n * Get the crypto object, works in both browser and Node.js (19+)\n *\n * @returns The crypto object\n * @throws Error if crypto API is not available\n */\nfunction getCrypto(): Crypto {\n const cryptoObj = globalThis.crypto;\n\n if (!cryptoObj || typeof cryptoObj.getRandomValues !== \"function\") {\n throw new Error(\n \"Crypto API not available. \" + \"Node.js 19+ or a browser with Web Crypto API is required.\",\n );\n }\n\n return cryptoObj;\n}\n\n/**\n * Generate a cryptographically secure random integer in range [0, max)\n *\n * Uses rejection sampling to ensure uniform distribution.\n *\n * @param max - Exclusive upper bound (must be > 0 and <= 2^32)\n * @returns Random integer in [0, max)\n * @throws Error if max is invalid or crypto unavailable\n */\nexport function cryptoRandomInt(max: number): number {\n if (max <= 0 || max > 0xffffffff || !Number.isInteger(max)) {\n throw new Error(`Invalid max value: ${max}. Must be positive integer <= 2^32`);\n }\n\n const crypto = getCrypto();\n const array = new Uint32Array(1);\n\n // Rejection sampling to avoid modulo bias\n const limit = Math.floor(0xffffffff / max) * max;\n let value: number;\n\n do {\n crypto.getRandomValues(array);\n value = array[0];\n } while (value >= limit);\n\n return value % max;\n}\n\n/**\n * Generate a cryptographically secure random BigInt\n *\n * @param bits - Number of bits (default 64, max 256)\n * @returns Random BigInt with specified number of bits\n * @throws Error if bits is invalid or crypto unavailable\n */\nexport function cryptoRandomBigInt(bits: number = 64): bigint {\n if (bits <= 0 || bits > 256) {\n throw new Error(`Invalid bits value: ${bits}. Must be 1-256`);\n }\n\n const crypto = getCrypto();\n const bytes = Math.ceil(bits / 8);\n const array = new Uint8Array(bytes);\n crypto.getRandomValues(array);\n\n // Convert bytes to BigInt\n let result = 0n;\n for (let i = 0; i < bytes; i++) {\n result = (result << 8n) | BigInt(array[i]);\n }\n\n // Mask to exact bit count\n const mask = (1n << BigInt(bits)) - 1n;\n return result & mask;\n}\n\n/**\n * Generate a cryptographically secure random hex string\n *\n * @param bytes - Number of random bytes (default 16)\n * @returns Hex-encoded random string\n * @throws Error if bytes is invalid or crypto unavailable\n */\nexport function cryptoRandomHex(bytes: number = 16): string {\n if (bytes <= 0 || bytes > 128) {\n throw new Error(`Invalid bytes value: ${bytes}. Must be 1-128`);\n }\n\n const crypto = getCrypto();\n const array = new Uint8Array(bytes);\n crypto.getRandomValues(array);\n\n return Array.from(array)\n .map(b => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n// ============================================================================\n// Network and Scheme Utilities\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\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 // Convert the registered network pattern to a regex\n // e.g., \"eip155:*\" becomes /^eip155:.*$/\n const pattern = registeredNetworkPattern\n .replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\") // Escape special regex chars except *\n .replace(/\\\\\\*/g, \".*\"); // Replace escaped * with .*\n\n const regex = new RegExp(`^${pattern}$`);\n\n if (regex.test(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 const patternRegex = new RegExp(\"^\" + schemeData.pattern.replace(\"*\", \".*\") + \"$\");\n if (patternRegex.test(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 return globalThis.btoa(data);\n }\n return Buffer.from(data).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 return globalThis.atob(data);\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","export const t402Version = 2;\n","import { t402ResourceServer } from \"../server\";\nimport {\n decodePaymentSignatureHeader,\n encodePaymentRequiredHeader,\n encodePaymentResponseHeader,\n} from \".\";\nimport {\n PaymentPayload,\n PaymentRequired,\n SettleResponse,\n Price,\n Network,\n PaymentRequirements,\n} from \"../types\";\nimport { t402Version } from \"..\";\n\n/**\n * Framework-agnostic HTTP adapter interface\n * Implementations provide framework-specific HTTP operations\n */\nexport interface HTTPAdapter {\n getHeader(name: string): string | undefined;\n getMethod(): string;\n getPath(): string;\n getUrl(): string;\n getAcceptHeader(): string;\n getUserAgent(): string;\n\n /**\n * Get query parameters from the request URL\n *\n * @returns Record of query parameter key-value pairs\n */\n getQueryParams?(): Record<string, string | string[]>;\n\n /**\n * Get a specific query parameter by name\n *\n * @param name - The query parameter name\n * @returns The query parameter value(s) or undefined\n */\n getQueryParam?(name: string): string | string[] | undefined;\n\n /**\n * Get the parsed request body\n * Framework adapters should parse JSON/form data appropriately\n *\n * @returns The parsed request body\n */\n getBody?(): unknown;\n}\n\n/**\n * Paywall configuration for HTML responses\n */\nexport interface PaywallConfig {\n appName?: string;\n appLogo?: string;\n sessionTokenEndpoint?: string;\n currentUrl?: string;\n testnet?: boolean;\n}\n\n/**\n * Paywall provider interface for generating HTML\n */\nexport interface PaywallProvider {\n generateHtml(paymentRequired: PaymentRequired, config?: PaywallConfig): string;\n}\n\n/**\n * Dynamic payTo function that receives HTTP request context\n */\nexport type DynamicPayTo = (context: HTTPRequestContext) => string | Promise<string>;\n\n/**\n * Dynamic price function that receives HTTP request context\n */\nexport type DynamicPrice = (context: HTTPRequestContext) => Price | Promise<Price>;\n\n/**\n * Result of the unpaid response callback containing content type and body.\n */\nexport interface UnpaidResponseResult {\n /**\n * The content type for the response (e.g., 'application/json', 'text/plain').\n */\n contentType: string;\n\n /**\n * The response body to include in the 402 response.\n */\n body: unknown;\n}\n\n/**\n * Dynamic function to generate a custom response for unpaid requests.\n * Receives the HTTP request context and returns the content type and body to include in the 402 response.\n */\nexport type UnpaidResponseBody = (\n context: HTTPRequestContext,\n) => UnpaidResponseResult | Promise<UnpaidResponseResult>;\n\n/**\n * A single payment option for a route\n * Represents one way a client can pay for access to the resource\n */\nexport interface PaymentOption {\n scheme: string;\n payTo: string | DynamicPayTo;\n price: Price | DynamicPrice;\n network: Network;\n maxTimeoutSeconds?: number;\n extra?: Record<string, unknown>;\n}\n\n/**\n * Route configuration for HTTP endpoints\n *\n * The 'accepts' field defines payment options for the route.\n * Can be a single PaymentOption or an array of PaymentOptions for multiple payment methods.\n */\nexport interface RouteConfig {\n // Payment option(s): single or array\n accepts: PaymentOption | PaymentOption[];\n\n // HTTP-specific metadata\n resource?: string;\n description?: string;\n mimeType?: string;\n customPaywallHtml?: string;\n\n /**\n * Optional callback to generate a custom response for unpaid API requests.\n * This allows servers to return preview data, error messages, or other content\n * when a request lacks payment.\n *\n * For browser requests (Accept: text/html), the paywall HTML takes precedence.\n * This callback is only used for API clients.\n *\n * If not provided, defaults to { contentType: 'application/json', body: {} }.\n *\n * @param context - The HTTP request context\n * @returns An object containing both contentType and body for the 402 response\n */\n unpaidResponseBody?: UnpaidResponseBody;\n\n // Extensions\n extensions?: Record<string, unknown>;\n}\n\n/**\n * Routes configuration - maps path patterns to route configs\n */\nexport type RoutesConfig = Record<string, RouteConfig> | RouteConfig;\n\n/**\n * Compiled route for efficient matching\n */\nexport interface CompiledRoute {\n verb: string;\n regex: RegExp;\n config: RouteConfig;\n}\n\n/**\n * HTTP request context that encapsulates all request data\n */\nexport interface HTTPRequestContext {\n adapter: HTTPAdapter;\n path: string;\n method: string;\n paymentHeader?: string;\n}\n\n/**\n * HTTP response instructions for the framework middleware\n */\nexport interface HTTPResponseInstructions {\n status: number;\n headers: Record<string, string>;\n body?: unknown; // e.g. Paywall for web browser requests, but could be any other type\n isHtml?: boolean; // e.g. if body is a paywall, then isHtml is true\n}\n\n/**\n * Result of processing an HTTP request for payment\n */\nexport type HTTPProcessResult =\n | { type: \"no-payment-required\" }\n | {\n type: \"payment-verified\";\n paymentPayload: PaymentPayload;\n paymentRequirements: PaymentRequirements;\n }\n | { type: \"payment-error\"; response: HTTPResponseInstructions };\n\n/**\n * Result of processSettlement\n */\nexport type ProcessSettleSuccessResponse = SettleResponse & {\n success: true;\n headers: Record<string, string>;\n requirements: PaymentRequirements;\n};\n\nexport type ProcessSettleFailureResponse = SettleResponse & {\n success: false;\n errorReason: string;\n};\n\nexport type ProcessSettleResultResponse =\n | ProcessSettleSuccessResponse\n | ProcessSettleFailureResponse;\n\n/**\n * Represents a validation error for a specific route's payment configuration.\n */\nexport interface RouteValidationError {\n /** The route pattern (e.g., \"GET /api/weather\") */\n routePattern: string;\n /** The payment scheme that failed validation */\n scheme: string;\n /** The network that failed validation */\n network: Network;\n /** The type of validation failure */\n reason: \"missing_scheme\" | \"missing_facilitator\";\n /** Human-readable error message */\n message: string;\n}\n\n/**\n * Error thrown when route configuration validation fails.\n */\nexport class RouteConfigurationError extends Error {\n /** The validation errors that caused this exception */\n public readonly errors: RouteValidationError[];\n\n /**\n * Creates a new RouteConfigurationError with the given validation errors.\n *\n * @param errors - The validation errors that caused this exception.\n */\n constructor(errors: RouteValidationError[]) {\n const message = `t402 Route Configuration Errors:\\n${errors.map(e => ` - ${e.message}`).join(\"\\n\")}`;\n super(message);\n this.name = \"RouteConfigurationError\";\n this.errors = errors;\n }\n}\n\n/**\n * HTTP-enhanced t402 resource server\n * Provides framework-agnostic HTTP protocol handling\n */\nexport class t402HTTPResourceServer {\n private ResourceServer: t402ResourceServer;\n private compiledRoutes: CompiledRoute[] = [];\n private routesConfig: RoutesConfig;\n private paywallProvider?: PaywallProvider;\n\n /**\n * Creates a new t402HTTPResourceServer instance.\n *\n * @param ResourceServer - The core t402ResourceServer instance to use\n * @param routes - Route configuration for payment-protected endpoints\n */\n constructor(ResourceServer: t402ResourceServer, routes: RoutesConfig) {\n this.ResourceServer = ResourceServer;\n this.routesConfig = routes;\n\n // Handle both single route and multiple routes\n const normalizedRoutes =\n typeof routes === \"object\" && !(\"accepts\" in routes)\n ? (routes as Record<string, RouteConfig>)\n : { \"*\": routes as RouteConfig };\n\n for (const [pattern, config] of Object.entries(normalizedRoutes)) {\n const parsed = this.parseRoutePattern(pattern);\n this.compiledRoutes.push({\n verb: parsed.verb,\n regex: parsed.regex,\n config,\n });\n }\n }\n\n /**\n * Initialize the HTTP resource server.\n *\n * This method initializes the underlying resource server (fetching facilitator support)\n * and then validates that all route payment configurations have corresponding\n * registered schemes and facilitator support.\n *\n * @throws RouteConfigurationError if any route's payment options don't have\n * corresponding registered schemes or facilitator support\n *\n * @example\n * ```typescript\n * const httpServer = new t402HTTPResourceServer(server, routes);\n * await httpServer.initialize();\n * ```\n */\n async initialize(): Promise<void> {\n // First, initialize the underlying resource server (fetches facilitator support)\n await this.ResourceServer.initialize();\n\n // Then validate route configuration\n const errors = this.validateRouteConfiguration();\n if (errors.length > 0) {\n throw new RouteConfigurationError(errors);\n }\n }\n\n /**\n * Register a custom paywall provider for generating HTML\n *\n * @param provider - PaywallProvider instance\n * @returns This service instance for chaining\n */\n registerPaywallProvider(provider: PaywallProvider): this {\n this.paywallProvider = provider;\n return this;\n }\n\n /**\n * Process HTTP request and return response instructions\n * This is the main entry point for framework middleware\n *\n * @param context - HTTP request context\n * @param paywallConfig - Optional paywall configuration\n * @returns Process result indicating next action for middleware\n */\n async processHTTPRequest(\n context: HTTPRequestContext,\n paywallConfig?: PaywallConfig,\n ): Promise<HTTPProcessResult> {\n const { adapter, path, method } = context;\n\n // Find matching route\n const routeConfig = this.getRouteConfig(path, method);\n if (!routeConfig) {\n return { type: \"no-payment-required\" }; // No payment required for this route\n }\n\n // Normalize accepts field to array of payment options\n const paymentOptions = this.normalizePaymentOptions(routeConfig);\n\n // Check for payment header (v1 or v2)\n const paymentPayload = this.extractPayment(adapter);\n\n // Create resource info, using config override if provided\n const resourceInfo = {\n url: routeConfig.resource || context.adapter.getUrl(),\n description: routeConfig.description || \"\",\n mimeType: routeConfig.mimeType || \"\",\n };\n\n // Build requirements from all payment options\n // (this method handles resolving dynamic functions internally)\n const requirements = await this.ResourceServer.buildPaymentRequirementsFromOptions(\n paymentOptions,\n context,\n );\n\n let extensions = routeConfig.extensions;\n if (extensions) {\n extensions = this.ResourceServer.enrichExtensions(extensions, context);\n }\n\n const paymentRequired = this.ResourceServer.createPaymentRequiredResponse(\n requirements,\n resourceInfo,\n !paymentPayload ? \"Payment required\" : undefined,\n extensions,\n );\n\n // If no payment provided\n if (!paymentPayload) {\n // Resolve custom unpaid response body if provided\n const unpaidBody = routeConfig.unpaidResponseBody\n ? await routeConfig.unpaidResponseBody(context)\n : undefined;\n\n return {\n type: \"payment-error\",\n response: this.createHTTPResponse(\n paymentRequired,\n this.isWebBrowser(adapter),\n paywallConfig,\n routeConfig.customPaywallHtml,\n unpaidBody,\n ),\n };\n }\n\n // Verify payment\n try {\n const matchingRequirements = this.ResourceServer.findMatchingRequirements(\n paymentRequired.accepts,\n paymentPayload,\n );\n\n if (!matchingRequirements) {\n const errorResponse = this.ResourceServer.createPaymentRequiredResponse(\n requirements,\n resourceInfo,\n \"No matching payment requirements\",\n routeConfig.extensions,\n );\n return {\n type: \"payment-error\",\n response: this.createHTTPResponse(errorResponse, false, paywallConfig),\n };\n }\n\n const verifyResult = await this.ResourceServer.verifyPayment(\n paymentPayload,\n matchingRequirements,\n );\n\n if (!verifyResult.isValid) {\n const errorResponse = this.ResourceServer.createPaymentRequiredResponse(\n requirements,\n resourceInfo,\n verifyResult.invalidReason,\n routeConfig.extensions,\n );\n return {\n type: \"payment-error\",\n response: this.createHTTPResponse(errorResponse, false, paywallConfig),\n };\n }\n\n // Payment is valid, return data needed for settlement\n return {\n type: \"payment-verified\",\n paymentPayload,\n paymentRequirements: matchingRequirements,\n };\n } catch (error) {\n const errorResponse = this.ResourceServer.createPaymentRequiredResponse(\n requirements,\n resourceInfo,\n error instanceof Error ? error.message : \"Payment verification failed\",\n routeConfig.extensions,\n );\n return {\n type: \"payment-error\",\n response: this.createHTTPResponse(errorResponse, false, paywallConfig),\n };\n }\n }\n\n /**\n * Process settlement after successful response\n *\n * @param paymentPayload - The verified payment payload\n * @param requirements - The matching payment requirements\n * @returns ProcessSettleResultResponse - SettleResponse with headers if success or errorReason if failure\n */\n async processSettlement(\n paymentPayload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<ProcessSettleResultResponse> {\n try {\n const settleResponse = await this.ResourceServer.settlePayment(paymentPayload, requirements);\n\n if (!settleResponse.success) {\n return {\n ...settleResponse,\n success: false,\n errorReason: settleResponse.errorReason || \"Settlement failed\",\n };\n }\n\n return {\n ...settleResponse,\n success: true,\n headers: this.createSettlementHeaders(settleResponse, requirements),\n requirements,\n };\n } catch (error) {\n throw new Error(error instanceof Error ? error.message : \"Settlement failed\");\n }\n }\n\n /**\n * Check if a request requires payment based on route configuration\n *\n * @param context - HTTP request context\n * @returns True if the route requires payment, false otherwise\n */\n requiresPayment(context: HTTPRequestContext): boolean {\n const routeConfig = this.getRouteConfig(context.path, context.method);\n return routeConfig !== undefined;\n }\n\n /**\n * Normalizes a RouteConfig's accepts field into an array of PaymentOptions\n * Handles both single PaymentOption and array formats\n *\n * @param routeConfig - Route configuration\n * @returns Array of payment options\n */\n private normalizePaymentOptions(routeConfig: RouteConfig): PaymentOption[] {\n return Array.isArray(routeConfig.accepts) ? routeConfig.accepts : [routeConfig.accepts];\n }\n\n /**\n * Validates that all payment options in routes have corresponding registered schemes\n * and facilitator support.\n *\n * @returns Array of validation errors (empty if all routes are valid)\n */\n private validateRouteConfiguration(): RouteValidationError[] {\n const errors: RouteValidationError[] = [];\n\n // Normalize routes to array of [pattern, config] pairs\n const normalizedRoutes =\n typeof this.routesConfig === \"object\" && !(\"accepts\" in this.routesConfig)\n ? Object.entries(this.routesConfig as Record<string, RouteConfig>)\n : [[\"*\", this.routesConfig as RouteConfig] as [string, RouteConfig]];\n\n for (const [pattern, config] of normalizedRoutes) {\n const paymentOptions = this.normalizePaymentOptions(config);\n\n for (const option of paymentOptions) {\n // Check 1: Is scheme registered?\n if (!this.ResourceServer.hasRegisteredScheme(option.network, option.scheme)) {\n errors.push({\n routePattern: pattern,\n scheme: option.scheme,\n network: option.network,\n reason: \"missing_scheme\",\n message: `Route \"${pattern}\": No scheme implementation registered for \"${option.scheme}\" on network \"${option.network}\"`,\n });\n // Skip facilitator check if scheme isn't registered\n continue;\n }\n\n // Check 2: Does facilitator support this scheme/network combination?\n const supportedKind = this.ResourceServer.getSupportedKind(\n t402Version,\n option.network,\n option.scheme,\n );\n\n if (!supportedKind) {\n errors.push({\n routePattern: pattern,\n scheme: option.scheme,\n network: option.network,\n reason: \"missing_facilitator\",\n message: `Route \"${pattern}\": Facilitator does not support scheme \"${option.scheme}\" on network \"${option.network}\"`,\n });\n }\n }\n }\n\n return errors;\n }\n\n /**\n * Get route configuration for a request\n *\n * @param path - Request path\n * @param method - HTTP method\n * @returns Route configuration or undefined if no match\n */\n private getRouteConfig(path: string, method: string): RouteConfig | undefined {\n const normalizedPath = this.normalizePath(path);\n const upperMethod = method.toUpperCase();\n\n const matchingRoute = this.compiledRoutes.find(\n route =>\n route.regex.test(normalizedPath) && (route.verb === \"*\" || route.verb === upperMethod),\n );\n\n return matchingRoute?.config;\n }\n\n /**\n * Extract payment from HTTP headers (handles v1 and v2)\n *\n * @param adapter - HTTP adapter\n * @returns Decoded payment payload or null\n */\n private extractPayment(adapter: HTTPAdapter): PaymentPayload | null {\n // Check v2 header first (PAYMENT-SIGNATURE), then v1 fallback (X-PAYMENT)\n const header =\n adapter.getHeader(\"payment-signature\") ||\n adapter.getHeader(\"PAYMENT-SIGNATURE\") ||\n adapter.getHeader(\"x-payment\") ||\n adapter.getHeader(\"X-PAYMENT\");\n\n if (header) {\n try {\n return decodePaymentSignatureHeader(header);\n } catch (error) {\n console.warn(\"Failed to decode payment header:\", error);\n }\n }\n\n return null;\n }\n\n /**\n * Check if request is from a web browser\n *\n * @param adapter - HTTP adapter\n * @returns True if request appears to be from a browser\n */\n private isWebBrowser(adapter: HTTPAdapter): boolean {\n const accept = adapter.getAcceptHeader();\n const userAgent = adapter.getUserAgent();\n return accept.includes(\"text/html\") && userAgent.includes(\"Mozilla\");\n }\n\n /**\n * Create HTTP response instructions from payment required\n *\n * @param paymentRequired - Payment requirements\n * @param isWebBrowser - Whether request is from browser\n * @param paywallConfig - Paywall configuration\n * @param customHtml - Custom HTML template\n * @param unpaidResponse - Optional custom response (content type and body) for unpaid API requests\n * @returns Response instructions\n */\n private createHTTPResponse(\n paymentRequired: PaymentRequired,\n isWebBrowser: boolean,\n paywallConfig?: PaywallConfig,\n customHtml?: string,\n unpaidResponse?: UnpaidResponseResult,\n ): HTTPResponseInstructions {\n if (isWebBrowser) {\n const html = this.generatePaywallHTML(paymentRequired, paywallConfig, customHtml);\n return {\n status: 402,\n headers: { \"Content-Type\": \"text/html\" },\n body: html,\n isHtml: true,\n };\n }\n\n const response = this.createHTTPPaymentRequiredResponse(paymentRequired);\n\n // Use callback result if provided, otherwise default to JSON with empty object\n const contentType = unpaidResponse ? unpaidResponse.contentType : \"application/json\";\n const body = unpaidResponse ? unpaidResponse.body : {};\n\n return {\n status: 402,\n headers: {\n \"Content-Type\": contentType,\n ...response.headers,\n },\n body,\n };\n }\n\n /**\n * Create HTTP payment required response (v1 puts in body, v2 puts in header)\n *\n * @param paymentRequired - Payment required object\n * @returns Headers and body for the HTTP response\n */\n private createHTTPPaymentRequiredResponse(paymentRequired: PaymentRequired): {\n headers: Record<string, string>;\n } {\n return {\n headers: {\n \"PAYMENT-REQUIRED\": encodePaymentRequiredHeader(paymentRequired),\n },\n };\n }\n\n /**\n * Create settlement response headers\n *\n * @param settleResponse - Settlement response\n * @param requirements - Payment requirements that were settled\n * @returns Headers to add to response\n */\n private createSettlementHeaders(\n settleResponse: SettleResponse,\n requirements: PaymentRequirements,\n ): Record<string, string> {\n const encoded = encodePaymentResponseHeader({\n ...settleResponse,\n requirements,\n });\n return { \"PAYMENT-RESPONSE\": encoded };\n }\n\n /**\n * Parse route pattern into verb and regex\n *\n * @param pattern - Route pattern like \"GET /api/*\" or \"/api/[id]\"\n * @returns Parsed pattern with verb and regex\n */\n private parseRoutePattern(pattern: string): { verb: string; regex: RegExp } {\n const [verb, path] = pattern.includes(\" \") ? pattern.split(/\\s+/) : [\"*\", pattern];\n\n const regex = new RegExp(\n `^${\n path\n .replace(/[$()+.?^{|}]/g, \"\\\\$&\") // Escape regex special chars\n .replace(/\\*/g, \".*?\") // Wildcards\n .replace(/\\[([^\\]]+)\\]/g, \"[^/]+\") // Parameters\n .replace(/\\//g, \"\\\\/\") // Escape slashes\n }$`,\n \"i\",\n );\n\n return { verb: verb.toUpperCase(), regex };\n }\n\n /**\n * Normalize path for matching\n *\n * @param path - Raw path from request\n * @returns Normalized path\n */\n private normalizePath(path: string): string {\n try {\n const pathWithoutQuery = path.split(/[?#]/)[0];\n const decodedPath = decodeURIComponent(pathWithoutQuery);\n return decodedPath\n .replace(/\\\\/g, \"/\")\n .replace(/\\/+/g, \"/\")\n .replace(/(.+?)\\/+$/, \"$1\");\n } catch {\n return path;\n }\n }\n\n /**\n * Generate paywall HTML for browser requests\n *\n * @param paymentRequired - Payment required response\n * @param paywallConfig - Optional paywall configuration\n * @param customHtml - Optional custom HTML template\n * @returns HTML string\n */\n private generatePaywallHTML(\n paymentRequired: PaymentRequired,\n paywallConfig?: PaywallConfig,\n customHtml?: string,\n ): string {\n if (customHtml) {\n return customHtml;\n }\n\n // Use custom paywall provider if set\n if (this.paywallProvider) {\n return this.paywallProvider.generateHtml(paymentRequired, paywallConfig);\n }\n\n // Try to use @t402/paywall if available (optional dependency)\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const paywall = require(\"@t402/paywall\");\n const displayAmount = this.getDisplayAmount(paymentRequired);\n const resource = paymentRequired.resource;\n\n return paywall.getPaywallHtml({\n amount: displayAmount,\n paymentRequired,\n currentUrl: resource?.url || paywallConfig?.currentUrl || \"\",\n testnet: paywallConfig?.testnet ?? true,\n appName: paywallConfig?.appName,\n appLogo: paywallConfig?.appLogo,\n sessionTokenEndpoint: paywallConfig?.sessionTokenEndpoint,\n });\n } catch {\n // @t402/paywall not installed, fall back to basic HTML\n }\n\n // Fallback: Basic HTML paywall\n const resource = paymentRequired.resource;\n const displayAmount = this.getDisplayAmount(paymentRequired);\n\n return `\n <!DOCTYPE html>\n <html>\n <head>\n <title>Payment Required</title>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n </head>\n <body>\n <div style=\"max-width: 600px; margin: 50px auto; padding: 20px; font-family: system-ui, -apple-system, sans-serif;\">\n ${paywallConfig?.appLogo ? `<img src=\"${paywallConfig.appLogo}\" alt=\"${paywallConfig.appName || \"App\"}\" style=\"max-width: 200px; margin-bottom: 20px;\">` : \"\"}\n <h1>Payment Required</h1>\n ${resource ? `<p><strong>Resource:</strong> ${resource.description || resource.url}</p>` : \"\"}\n <p><strong>Amount:</strong> $${displayAmount.toFixed(2)} USDC</p>\n <div id=\"payment-widget\" \n data-requirements='${JSON.stringify(paymentRequired)}'\n data-app-name=\"${paywallConfig?.appName || \"\"}\"\n data-testnet=\"${paywallConfig?.testnet || false}\">\n <!-- Install @t402/paywall for full wallet integration -->\n <p style=\"margin-top: 2rem; padding: 1rem; background: #fef3c7; border-radius: 0.5rem;\">\n <strong>Note:</strong> Install <code>@t402/paywall</code> for full wallet connection and payment UI.\n </p>\n </div>\n </div>\n </body>\n </html>\n `;\n }\n\n /**\n * Extract display amount from payment requirements.\n *\n * @param paymentRequired - The payment required object\n * @returns The display amount in decimal format\n */\n private getDisplayAmount(paymentRequired: PaymentRequired): number {\n const accepts = paymentRequired.accepts;\n if (accepts && accepts.length > 0) {\n const firstReq = accepts[0];\n if (\"amount\" in firstReq) {\n // V2 format\n return parseFloat(firstReq.amount) / 1000000; // Assuming USDC with 6 decimals\n }\n }\n return 0;\n }\n}\n","import { PaymentPayload, PaymentRequirements } from \"../types/payments\";\nimport { VerifyResponse, SettleResponse, SupportedResponse } from \"../types/facilitator\";\n\nconst DEFAULT_FACILITATOR_URL = \"https://facilitator.t402.io\";\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 }>;\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/**\n * HTTP-based client for interacting with t402 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 this.url = config?.url || DEFAULT_FACILITATOR_URL;\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 body: JSON.stringify({\n t402Version: paymentPayload.t402Version,\n paymentPayload: this.toJsonSafe(paymentPayload),\n paymentRequirements: this.toJsonSafe(paymentRequirements),\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n throw new Error(`Facilitator verify failed (${response.status}): ${errorText}`);\n }\n\n return (await response.json()) as VerifyResponse;\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 body: JSON.stringify({\n t402Version: paymentPayload.t402Version,\n paymentPayload: this.toJsonSafe(paymentPayload),\n paymentRequirements: this.toJsonSafe(paymentRequirements),\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n throw new Error(`Facilitator settle failed (${response.status}): ${errorText}`);\n }\n\n return (await response.json()) as SettleResponse;\n }\n\n /**\n * Get supported payment kinds and extensions from the facilitator\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 const response = await fetch(`${this.url}/supported`, {\n method: \"GET\",\n headers,\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n throw new Error(`Facilitator getSupported failed (${response.status}): ${errorText}`);\n }\n\n return (await response.json()) as SupportedResponse;\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 {\n decodePaymentRequiredHeader,\n decodePaymentResponseHeader,\n encodePaymentSignatureHeader,\n} from \".\";\nimport { SettleResponse } from \"../types\";\nimport { PaymentPayload, PaymentRequired } from \"../types/payments\";\nimport { t402Client } from \"../client/t402Client\";\n\n/**\n * HTTP-specific client for handling t402 payment protocol over HTTP.\n *\n * Wraps a t402Client to provide HTTP-specific encoding/decoding functionality\n * for payment headers and responses while maintaining the builder pattern.\n */\nexport class t402HTTPClient {\n /**\n * Creates a new t402HTTPClient instance.\n *\n * @param client - The underlying t402Client for payment logic\n */\n constructor(private readonly client: t402Client) {}\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.t402Version) {\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 t402 version: ${(paymentPayload as PaymentPayload).t402Version}`,\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 \"t402Version\" in body &&\n (body as PaymentRequired).t402Version === 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 t402Client.\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"],"mappings":"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","names":["displayAmount","resource"]}
@@ -240,42 +240,77 @@ declare const T402_A2A_EXTENSION_URI = "https://github.com/google-a2a/a2a-t402/v
240
240
  declare const A2A_EXTENSIONS_HEADER = "X-A2A-Extensions";
241
241
  /**
242
242
  * Check if a task is in a payment-required state
243
+ *
244
+ * @param task - The A2A task to check
245
+ * @returns Whether the task requires payment
243
246
  */
244
247
  declare function isPaymentRequired(task: A2ATask): boolean;
245
248
  /**
246
249
  * Check if a task has completed payment
250
+ *
251
+ * @param task - The A2A task to check
252
+ * @returns Whether the task has completed payment
247
253
  */
248
254
  declare function isPaymentCompleted(task: A2ATask): boolean;
249
255
  /**
250
256
  * Check if a task has failed payment
257
+ *
258
+ * @param task - The A2A task to check
259
+ * @returns Whether the task has failed payment
251
260
  */
252
261
  declare function isPaymentFailed(task: A2ATask): boolean;
253
262
  /**
254
263
  * Extract payment requirements from a task
264
+ *
265
+ * @param task - The A2A task to extract requirements from
266
+ * @returns The payment requirements if the task requires payment
255
267
  */
256
268
  declare function getPaymentRequired(task: A2ATask): PaymentRequired | undefined;
257
269
  /**
258
270
  * Extract payment receipts from a task
271
+ *
272
+ * @param task - The A2A task to extract receipts from
273
+ * @returns The settlement receipts if available
259
274
  */
260
275
  declare function getPaymentReceipts(task: A2ATask): SettleResponse[] | undefined;
261
276
  /**
262
277
  * Create a payment-required message
278
+ *
279
+ * @param paymentRequired - The payment requirements
280
+ * @param text - Optional message text
281
+ * @returns An A2A message with payment-required metadata
263
282
  */
264
283
  declare function createPaymentRequiredMessage(paymentRequired: PaymentRequired, text?: string): A2AMessage;
265
284
  /**
266
285
  * Create a payment submission message
286
+ *
287
+ * @param paymentPayload - The payment payload to submit
288
+ * @param text - Optional message text
289
+ * @returns An A2A message with payment-submitted metadata
267
290
  */
268
291
  declare function createPaymentSubmissionMessage(paymentPayload: PaymentPayload, text?: string): A2AMessage;
269
292
  /**
270
293
  * Create a payment completed message
294
+ *
295
+ * @param receipts - The settlement receipts
296
+ * @param text - Optional message text
297
+ * @returns An A2A message with payment-completed metadata
271
298
  */
272
299
  declare function createPaymentCompletedMessage(receipts: SettleResponse[], text?: string): A2AMessage;
273
300
  /**
274
301
  * Create a payment failed message
302
+ *
303
+ * @param receipts - The settlement receipts
304
+ * @param errorCode - The error code
305
+ * @param text - Optional message text
306
+ * @returns An A2A message with payment-failed metadata
275
307
  */
276
308
  declare function createPaymentFailedMessage(receipts: SettleResponse[], errorCode: string, text?: string): A2AMessage;
277
309
  /**
278
310
  * Create a T402 extension declaration for agent cards
311
+ *
312
+ * @param required - Whether the extension is required
313
+ * @returns An A2A extension declaration
279
314
  */
280
315
  declare function createT402Extension(required?: boolean): A2AExtension;
281
316
 
@@ -564,17 +599,47 @@ interface APIError {
564
599
  details?: string;
565
600
  retry?: boolean;
566
601
  }
567
- /** Returns the HTTP status code for a given error code */
602
+ /**
603
+ * Returns the HTTP status code for a given error code
604
+ *
605
+ * @param code - The T402 error code
606
+ * @returns The corresponding HTTP status code
607
+ */
568
608
  declare function httpStatusForCode(code: ErrorCode): number;
569
- /** Returns true if the error code is a client error (T402-1xxx) */
609
+ /**
610
+ * Returns true if the error code is a client error (T402-1xxx)
611
+ *
612
+ * @param code - The T402 error code
613
+ * @returns Whether the error is a client error
614
+ */
570
615
  declare function isClientError(code: ErrorCode): boolean;
571
- /** Returns true if the error code is a server error (T402-2xxx) */
616
+ /**
617
+ * Returns true if the error code is a server error (T402-2xxx)
618
+ *
619
+ * @param code - The T402 error code
620
+ * @returns Whether the error is a server error
621
+ */
572
622
  declare function isServerError(code: ErrorCode): boolean;
573
- /** Returns true if the error code is a facilitator error (T402-3xxx) */
623
+ /**
624
+ * Returns true if the error code is a facilitator error (T402-3xxx)
625
+ *
626
+ * @param code - The T402 error code
627
+ * @returns Whether the error is a facilitator error
628
+ */
574
629
  declare function isFacilitatorError(code: ErrorCode): boolean;
575
- /** Returns true if the error code is a chain error (T402-4xxx) */
630
+ /**
631
+ * Returns true if the error code is a chain error (T402-4xxx)
632
+ *
633
+ * @param code - The T402 error code
634
+ * @returns Whether the error is a chain error
635
+ */
576
636
  declare function isChainError(code: ErrorCode): boolean;
577
- /** Returns true if the error code is a bridge error (T402-5xxx) */
637
+ /**
638
+ * Returns true if the error code is a bridge error (T402-5xxx)
639
+ *
640
+ * @param code - The T402 error code
641
+ * @returns Whether the error is a bridge error
642
+ */
578
643
  declare function isBridgeError(code: ErrorCode): boolean;
579
644
 
580
645
  /**
@@ -797,18 +862,21 @@ declare const SettleResponseSchema: z.ZodObject<{
797
862
  network: z.ZodString;
798
863
  errorReason: z.ZodOptional<z.ZodString>;
799
864
  payer: z.ZodOptional<z.ZodString>;
865
+ confirmations: z.ZodOptional<z.ZodString>;
800
866
  }, "strip", z.ZodTypeAny, {
801
867
  network: string;
802
868
  success: boolean;
803
869
  transaction: string;
804
870
  payer?: string | undefined;
805
871
  errorReason?: string | undefined;
872
+ confirmations?: string | undefined;
806
873
  }, {
807
874
  network: string;
808
875
  success: boolean;
809
876
  transaction: string;
810
877
  payer?: string | undefined;
811
878
  errorReason?: string | undefined;
879
+ confirmations?: string | undefined;
812
880
  }>;
813
881
  declare const PaymentRequirementsV1Schema: z.ZodObject<{
814
882
  scheme: z.ZodString;
@@ -996,6 +1064,7 @@ type SettleResponse = {
996
1064
  payer?: string;
997
1065
  transaction: string;
998
1066
  network: Network;
1067
+ confirmations?: string;
999
1068
  };
1000
1069
  type SupportedKind = {
1001
1070
  t402Version: number;
@@ -1123,4 +1192,4 @@ interface SchemeNetworkServer {
1123
1192
  }, facilitatorExtensions: string[]): Promise<PaymentRequirements>;
1124
1193
  }
1125
1194
 
1126
- export { createPaymentFailedMessage as $, type AssetAmount as A, type A2AArtifact as B, type A2ATaskStatus as C, type A2ATask as D, type A2ARequest as E, type A2AResponse as F, type A2AError as G, type A2AExtension as H, type A2ACapabilities as I, type A2AAgentCard as J, type A2ASkill as K, A2A_EXTENSIONS_HEADER as L, type Money as M, type Network as N, isPaymentRequired as O, type PaymentRequirements as P, isPaymentCompleted as Q, type ResourceServerExtension as R, type SettleResponse as S, T402_A2A_EXTENSION_URI as T, isPaymentFailed as U, type VerifyResponse as V, getPaymentRequired as W, getPaymentReceipts as X, createPaymentRequiredMessage as Y, createPaymentSubmissionMessage as Z, createPaymentCompletedMessage as _, type PaymentPayload as a, ERR_STREAM_NOT_FOUND as a$, createT402Extension as a0, type UptoPaymentRequirements as a1, type UptoExtra as a2, type UptoPayloadBase as a3, type UptoEvmPayload as a4, type UptoEvmPayloadCompact as a5, type UptoSettlement as a6, type UptoUsageDetails as a7, type UptoSettlementResponse as a8, type UptoValidationResult as a9, ERR_RATE_LIMITED as aA, ERR_SERVICE_UNAVAILABLE as aB, ERR_VERIFICATION_FAILED as aC, ERR_SETTLEMENT_FAILED as aD, ERR_INSUFFICIENT_BALANCE as aE, ERR_ALLOWANCE_INSUFFICIENT as aF, ERR_PAYMENT_MISMATCH as aG, ERR_DUPLICATE_PAYMENT as aH, ERR_SETTLEMENT_PENDING as aI, ERR_SETTLEMENT_TIMEOUT as aJ, ERR_NONCE_REPLAY as aK, ERR_IDEMPOTENCY_CONFLICT as aL, ERR_IDEMPOTENCY_UNAVAILABLE as aM, ERR_PREVIOUS_REQUEST_FAILED as aN, ERR_REQUEST_IN_PROGRESS as aO, ERR_CHAIN_UNAVAILABLE as aP, ERR_TRANSACTION_FAILED as aQ, ERR_TRANSACTION_REVERTED as aR, ERR_GAS_ESTIMATION_FAILED as aS, ERR_NONCE_CONFLICT as aT, ERR_CHAIN_CONGESTED as aU, ERR_CONTRACT_ERROR as aV, ERR_BRIDGE_UNAVAILABLE as aW, ERR_BRIDGE_QUOTE_FAILED as aX, ERR_BRIDGE_TRANSFER_FAILED as aY, ERR_BRIDGE_TIMEOUT as aZ, ERR_UNSUPPORTED_ROUTE as a_, type UptoUnit as aa, isUptoPaymentRequirements as ab, isUptoEvmPayload as ac, UPTO_SCHEME as ad, UPTO_DEFAULTS as ae, type ErrorCode as af, type APIError as ag, ERR_INVALID_REQUEST as ah, ERR_MISSING_PAYLOAD as ai, ERR_MISSING_REQUIREMENTS as aj, ERR_INVALID_PAYLOAD as ak, ERR_INVALID_REQUIREMENTS as al, ERR_INVALID_SIGNATURE as am, ERR_INVALID_NETWORK as an, ERR_INVALID_SCHEME as ao, ERR_INVALID_AMOUNT as ap, ERR_INVALID_ADDRESS as aq, ERR_EXPIRED_PAYMENT as ar, ERR_INVALID_NONCE as as, ERR_INSUFFICIENT_AMOUNT as at, ERR_INVALID_IDEMPOTENCY_KEY as au, ERR_SIGNATURE_EXPIRED as av, ERR_INTERNAL as aw, ERR_DATABASE_UNAVAILABLE as ax, ERR_CACHE_UNAVAILABLE as ay, ERR_RPC_UNAVAILABLE as az, type SchemeNetworkFacilitator as b, ERR_STREAM_ALREADY_CLOSED as b0, ERR_STREAM_ALREADY_PAUSED as b1, ERR_STREAM_NOT_PAUSED as b2, ERR_STREAM_AMOUNT_EXCEEDED as b3, ERR_STREAM_EXPIRED as b4, ERR_STREAM_INVALID_STATE as b5, ERR_STREAM_RATE_LIMITED as b6, ERR_INTENT_NOT_FOUND as b7, ERR_INTENT_ALREADY_EXECUTED as b8, ERR_INTENT_CANCELLED as b9, parsePaymentRequirements as bA, safeParsePaymentPayload as bB, safeParsePaymentRequired as bC, safeParsePaymentRequirements as bD, type ValidatedPaymentPayload as bE, type ValidatedPaymentRequired as bF, type ValidatedPaymentRequirements as bG, type ValidatedVerifyResponse as bH, type ValidatedSettleResponse as bI, ERR_INTENT_EXPIRED as ba, ERR_NO_ROUTES_AVAILABLE as bb, ERR_ROUTE_EXPIRED as bc, ERR_ROUTE_NOT_SELECTED as bd, ERR_INTENT_INVALID_STATE as be, ERR_RESOURCE_NOT_FOUND as bf, ERR_RESOURCE_ALREADY_EXISTS as bg, ERR_INVALID_PARAMETERS as bh, ERR_NOT_AUTHORIZED as bi, httpStatusForCode as bj, isClientError as bk, isServerError as bl, isFacilitatorError as bm, isChainError as bn, isBridgeError as bo, NetworkSchema as bp, ResourceInfoSchema as bq, PaymentRequirementsSchema as br, PaymentRequiredSchema as bs, PaymentPayloadSchema as bt, VerifyResponseSchema as bu, SettleResponseSchema as bv, PaymentRequirementsV1Schema as bw, PaymentPayloadV1Schema as bx, parsePaymentPayload as by, parsePaymentRequired as bz, type PaymentRequired as c, type SchemeNetworkClient as d, type SupportedResponse as e, type SchemeNetworkServer as f, type SupportedKind as g, type Price as h, type PaymentRequirementsV1 as i, type PaymentRequiredV1 as j, type PaymentPayloadV1 as k, type VerifyRequestV1 as l, type SettleRequestV1 as m, type SettleResponseV1 as n, type SupportedResponseV1 as o, type VerifyRequest as p, type SettleRequest as q, type MoneyParser as r, type A2APaymentStatus as s, type A2ATaskState as t, type A2ATextPart as u, type A2AFilePart as v, type A2ADataPart as w, type A2AMessagePart as x, type A2APaymentMetadata as y, type A2AMessage as z };
1195
+ export { ERR_GAS_ESTIMATION_FAILED as $, type A2AAgentCard as A, type A2AResponse as B, type A2ASkill as C, type A2ATask as D, type A2ATaskState as E, type A2ATaskStatus as F, type A2ATextPart as G, A2A_EXTENSIONS_HEADER as H, type APIError as I, type AssetAmount as J, ERR_ALLOWANCE_INSUFFICIENT as K, ERR_BRIDGE_QUOTE_FAILED as L, ERR_BRIDGE_TIMEOUT as M, type Network as N, ERR_BRIDGE_TRANSFER_FAILED as O, type PaymentRequirements as P, ERR_BRIDGE_UNAVAILABLE as Q, type ResourceServerExtension as R, type SettleResponse as S, ERR_CACHE_UNAVAILABLE as T, ERR_CHAIN_CONGESTED as U, type VerifyResponse as V, ERR_CHAIN_UNAVAILABLE as W, ERR_CONTRACT_ERROR as X, ERR_DATABASE_UNAVAILABLE as Y, ERR_DUPLICATE_PAYMENT as Z, ERR_EXPIRED_PAYMENT as _, type PaymentPayload as a, type SettleRequest as a$, ERR_IDEMPOTENCY_CONFLICT as a0, ERR_IDEMPOTENCY_UNAVAILABLE as a1, ERR_INSUFFICIENT_AMOUNT as a2, ERR_INSUFFICIENT_BALANCE as a3, ERR_INTENT_ALREADY_EXECUTED as a4, ERR_INTENT_CANCELLED as a5, ERR_INTENT_EXPIRED as a6, ERR_INTENT_INVALID_STATE as a7, ERR_INTENT_NOT_FOUND as a8, ERR_INTERNAL as a9, ERR_SERVICE_UNAVAILABLE as aA, ERR_SETTLEMENT_FAILED as aB, ERR_SETTLEMENT_PENDING as aC, ERR_SETTLEMENT_TIMEOUT as aD, ERR_SIGNATURE_EXPIRED as aE, ERR_STREAM_ALREADY_CLOSED as aF, ERR_STREAM_ALREADY_PAUSED as aG, ERR_STREAM_AMOUNT_EXCEEDED as aH, ERR_STREAM_EXPIRED as aI, ERR_STREAM_INVALID_STATE as aJ, ERR_STREAM_NOT_FOUND as aK, ERR_STREAM_NOT_PAUSED as aL, ERR_STREAM_RATE_LIMITED as aM, ERR_TRANSACTION_FAILED as aN, ERR_TRANSACTION_REVERTED as aO, ERR_UNSUPPORTED_ROUTE as aP, ERR_VERIFICATION_FAILED as aQ, type ErrorCode as aR, type Money as aS, type MoneyParser as aT, NetworkSchema as aU, PaymentPayloadSchema as aV, PaymentPayloadV1Schema as aW, PaymentRequiredSchema as aX, PaymentRequirementsSchema as aY, PaymentRequirementsV1Schema as aZ, ResourceInfoSchema as a_, ERR_INVALID_ADDRESS as aa, ERR_INVALID_AMOUNT as ab, ERR_INVALID_IDEMPOTENCY_KEY as ac, ERR_INVALID_NETWORK as ad, ERR_INVALID_NONCE as ae, ERR_INVALID_PARAMETERS as af, ERR_INVALID_PAYLOAD as ag, ERR_INVALID_REQUEST as ah, ERR_INVALID_REQUIREMENTS as ai, ERR_INVALID_SCHEME as aj, ERR_INVALID_SIGNATURE as ak, ERR_MISSING_PAYLOAD as al, ERR_MISSING_REQUIREMENTS as am, ERR_NONCE_CONFLICT as an, ERR_NONCE_REPLAY as ao, ERR_NOT_AUTHORIZED as ap, ERR_NO_ROUTES_AVAILABLE as aq, ERR_PAYMENT_MISMATCH as ar, ERR_PREVIOUS_REQUEST_FAILED as as, ERR_RATE_LIMITED as at, ERR_REQUEST_IN_PROGRESS as au, ERR_RESOURCE_ALREADY_EXISTS as av, ERR_RESOURCE_NOT_FOUND as aw, ERR_ROUTE_EXPIRED as ax, ERR_ROUTE_NOT_SELECTED as ay, ERR_RPC_UNAVAILABLE as az, type SchemeNetworkFacilitator as b, SettleResponseSchema as b0, T402_A2A_EXTENSION_URI as b1, UPTO_DEFAULTS as b2, UPTO_SCHEME as b3, type UptoEvmPayload as b4, type UptoEvmPayloadCompact as b5, type UptoExtra as b6, type UptoPayloadBase as b7, type UptoPaymentRequirements as b8, type UptoSettlement as b9, isServerError as bA, isUptoEvmPayload as bB, isUptoPaymentRequirements as bC, parsePaymentPayload as bD, parsePaymentRequired as bE, parsePaymentRequirements as bF, safeParsePaymentPayload as bG, safeParsePaymentRequired as bH, safeParsePaymentRequirements as bI, type UptoSettlementResponse as ba, type UptoUnit as bb, type UptoUsageDetails as bc, type UptoValidationResult as bd, type ValidatedPaymentPayload as be, type ValidatedPaymentRequired as bf, type ValidatedPaymentRequirements as bg, type ValidatedSettleResponse as bh, type ValidatedVerifyResponse as bi, type VerifyRequest as bj, VerifyResponseSchema as bk, createPaymentCompletedMessage as bl, createPaymentFailedMessage as bm, createPaymentRequiredMessage as bn, createPaymentSubmissionMessage as bo, createT402Extension as bp, getPaymentReceipts as bq, getPaymentRequired as br, httpStatusForCode as bs, isBridgeError as bt, isChainError as bu, isClientError as bv, isFacilitatorError as bw, isPaymentCompleted as bx, isPaymentFailed as by, isPaymentRequired as bz, type PaymentRequired as c, type SchemeNetworkClient as d, type SupportedResponse as e, type SchemeNetworkServer as f, type SupportedKind as g, type Price as h, type PaymentPayloadV1 as i, type PaymentRequiredV1 as j, type PaymentRequirementsV1 as k, type SettleRequestV1 as l, type SettleResponseV1 as m, type SupportedResponseV1 as n, type VerifyRequestV1 as o, type A2AArtifact as p, type A2ACapabilities as q, type A2ADataPart as r, type A2AError as s, type A2AExtension as t, type A2AFilePart as u, type A2AMessage as v, type A2AMessagePart as w, type A2APaymentMetadata as x, type A2APaymentStatus as y, type A2ARequest as z };
@@ -1,3 +1,3 @@
1
- export { C as CompiledRoute, F as FacilitatorClient, o as FacilitatorConfig, a as HTTPAdapter, H as HTTPFacilitatorClient, d as HTTPProcessResult, b as HTTPRequestContext, c as HTTPResponseInstructions, P as PaywallConfig, e as PaywallProvider, m as ProcessSettleFailureResponse, k as ProcessSettleResultResponse, l as ProcessSettleSuccessResponse, q as ResourceConfig, r as ResourceInfo, g as RouteConfig, R as RouteConfigurationError, n as RouteValidationError, h as RoutesConfig, U as UnpaidResponseBody, j as UnpaidResponseResult, t as t402HTTPResourceServer, p as t402ResourceServer } from '../t402HTTPResourceServer-CybruqCk.js';
2
- import '../mechanisms-C7yK91d4.js';
1
+ export { C as CompiledRoute, F as FacilitatorClient, b as FacilitatorConfig, H as HTTPAdapter, c as HTTPFacilitatorClient, d as HTTPProcessResult, e as HTTPRequestContext, f as HTTPResponseInstructions, g as PaywallConfig, h as PaywallProvider, i as ProcessSettleFailureResponse, j as ProcessSettleResultResponse, k as ProcessSettleSuccessResponse, p as ResourceConfig, q as ResourceInfo, R as RouteConfig, l as RouteConfigurationError, m as RouteValidationError, n as RoutesConfig, U as UnpaidResponseBody, o as UnpaidResponseResult, t as t402HTTPResourceServer, r as t402ResourceServer } from '../t402HTTPResourceServer-B-aOi0BZ.js';
2
+ import '../mechanisms-dYCiYgko.js';
3
3
  import 'zod';
@@ -806,7 +806,8 @@ var SettleResponseSchema = import_zod.z.object({
806
806
  transaction: import_zod.z.string(),
807
807
  network: NetworkSchema,
808
808
  errorReason: import_zod.z.string().optional(),
809
- payer: import_zod.z.string().optional()
809
+ payer: import_zod.z.string().optional(),
810
+ confirmations: import_zod.z.string().optional()
810
811
  });
811
812
  var PaymentRequirementsV1Schema = import_zod.z.object({
812
813
  scheme: import_zod.z.string().min(1),
@@ -1121,12 +1122,12 @@ var t402HTTPResourceServer = class {
1121
1122
  * @returns Decoded payment payload or null
1122
1123
  */
1123
1124
  extractPayment(adapter) {
1124
- const header = adapter.getHeader("payment-signature") || adapter.getHeader("PAYMENT-SIGNATURE");
1125
+ const header = adapter.getHeader("payment-signature") || adapter.getHeader("PAYMENT-SIGNATURE") || adapter.getHeader("x-payment") || adapter.getHeader("X-PAYMENT");
1125
1126
  if (header) {
1126
1127
  try {
1127
1128
  return decodePaymentSignatureHeader(header);
1128
1129
  } catch (error) {
1129
- console.warn("Failed to decode PAYMENT-SIGNATURE header:", error);
1130
+ console.warn("Failed to decode payment header:", error);
1130
1131
  }
1131
1132
  }
1132
1133
  return null;