@t402/extensions 2.6.0 → 2.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/bazaar/index.js +1 -1
- package/dist/cjs/bazaar/index.js.map +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/bazaar/index.mjs +1 -1
- package/dist/esm/{chunk-HMNJHSWM.mjs → chunk-2DKNRJSJ.mjs} +2 -2
- package/dist/esm/{chunk-HMNJHSWM.mjs.map → chunk-2DKNRJSJ.mjs.map} +1 -1
- package/dist/esm/index.mjs +1 -1
- package/package.json +2 -2
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts","../../src/bazaar/types.ts","../../src/bazaar/resourceService.ts","../../src/bazaar/server.ts","../../src/bazaar/facilitator.ts","../../src/bazaar/v1/facilitator.ts","../../src/bazaar/facilitatorClient.ts","../../src/sign-in-with-x/server.ts","../../src/sign-in-with-x/client.ts","../../src/payment-id/types.ts","../../src/payment-id/server.ts","../../src/payment-id/client.ts","../../src/eip2612-gas-sponsoring/server.ts","../../src/eip2612-gas-sponsoring/client.ts","../../src/eip2612-gas-sponsoring/facilitator.ts","../../src/erc20-approval-gas-sponsoring/server.ts","../../src/erc20-approval-gas-sponsoring/client.ts","../../src/erc20-approval-gas-sponsoring/facilitator.ts"],"sourcesContent":["// Shared extension utilities\nexport type { WithExtensions } from \"./types\";\n\n// Bazaar extension\nexport * from \"./bazaar\";\nexport { bazaarResourceServerExtension } from \"./bazaar/server\";\n\n// Sign-in-with-x extension\nexport * from \"./sign-in-with-x\";\n\n// Payment ID extension\nexport * from \"./payment-id\";\n\n// EIP-2612 gas sponsoring extension\nexport * from \"./eip2612-gas-sponsoring\";\n\n// ERC-20 approval gas sponsoring extension\nexport * from \"./erc20-approval-gas-sponsoring\";\n","/**\n * Type definitions for the Bazaar Discovery Extension\n */\n\nimport type { BodyMethods, QueryParamMethods } from \"@t402/core/http\";\n\n/**\n * Extension identifier constant for the Bazaar discovery extension\n */\nexport const BAZAAR = \"bazaar\";\n\n/**\n * Discovery info for query parameter methods (GET, HEAD, DELETE)\n */\nexport interface QueryDiscoveryInfo {\n input: {\n type: \"http\";\n method: QueryParamMethods;\n queryParams?: Record<string, unknown>;\n headers?: Record<string, string>;\n };\n output?: {\n type?: string;\n format?: string;\n example?: unknown;\n };\n}\n\n/**\n * Discovery info for body methods (POST, PUT, PATCH)\n */\nexport interface BodyDiscoveryInfo {\n input: {\n type: \"http\";\n method: BodyMethods;\n bodyType: \"json\" | \"form-data\" | \"text\";\n body: Record<string, unknown>;\n queryParams?: Record<string, unknown>;\n headers?: Record<string, string>;\n };\n output?: {\n type?: string;\n format?: string;\n example?: unknown;\n };\n}\n\n/**\n * Combined discovery info type\n */\nexport type DiscoveryInfo = QueryDiscoveryInfo | BodyDiscoveryInfo;\n\n/**\n * Discovery extension for query parameter methods (GET, HEAD, DELETE)\n */\nexport interface QueryDiscoveryExtension {\n info: QueryDiscoveryInfo;\n\n schema: {\n $schema: \"https://json-schema.org/draft/2020-12/schema\";\n type: \"object\";\n properties: {\n input: {\n type: \"object\";\n properties: {\n type: {\n type: \"string\";\n const: \"http\";\n };\n method: {\n type: \"string\";\n enum: QueryParamMethods[];\n };\n queryParams?: {\n type: \"object\";\n properties?: Record<string, unknown>;\n required?: string[];\n additionalProperties?: boolean;\n };\n headers?: {\n type: \"object\";\n additionalProperties: {\n type: \"string\";\n };\n };\n };\n required: (\"type\" | \"method\")[];\n additionalProperties?: boolean;\n };\n output?: {\n type: \"object\";\n properties?: Record<string, unknown>;\n required?: readonly string[];\n additionalProperties?: boolean;\n };\n };\n required: [\"input\"];\n };\n}\n\n/**\n * Discovery extension for body methods (POST, PUT, PATCH)\n */\nexport interface BodyDiscoveryExtension {\n info: BodyDiscoveryInfo;\n\n schema: {\n $schema: \"https://json-schema.org/draft/2020-12/schema\";\n type: \"object\";\n properties: {\n input: {\n type: \"object\";\n properties: {\n type: {\n type: \"string\";\n const: \"http\";\n };\n method: {\n type: \"string\";\n enum: BodyMethods[];\n };\n bodyType: {\n type: \"string\";\n enum: [\"json\", \"form-data\", \"text\"];\n };\n body: Record<string, unknown>;\n queryParams?: {\n type: \"object\";\n properties?: Record<string, unknown>;\n required?: string[];\n additionalProperties?: boolean;\n };\n headers?: {\n type: \"object\";\n additionalProperties: {\n type: \"string\";\n };\n };\n };\n required: (\"type\" | \"method\" | \"bodyType\" | \"body\")[];\n additionalProperties?: boolean;\n };\n output?: {\n type: \"object\";\n properties?: Record<string, unknown>;\n required?: readonly string[];\n additionalProperties?: boolean;\n };\n };\n required: [\"input\"];\n };\n}\n\n/**\n * Combined discovery extension type\n */\nexport type DiscoveryExtension = QueryDiscoveryExtension | BodyDiscoveryExtension;\n\nexport interface DeclareQueryDiscoveryExtensionConfig {\n method?: QueryParamMethods;\n input?: Record<string, unknown>;\n inputSchema?: Record<string, unknown>;\n output?: {\n example?: unknown;\n schema?: Record<string, unknown>;\n };\n}\n\nexport interface DeclareBodyDiscoveryExtensionConfig {\n method?: BodyMethods;\n input?: Record<string, unknown>;\n inputSchema?: Record<string, unknown>;\n bodyType?: \"json\" | \"form-data\" | \"text\";\n output?: {\n example?: unknown;\n schema?: Record<string, unknown>;\n };\n}\n\nexport type DeclareDiscoveryExtensionConfig =\n | DeclareQueryDiscoveryExtensionConfig\n | DeclareBodyDiscoveryExtensionConfig;\n\nexport const isQueryExtensionConfig = (\n config: DeclareDiscoveryExtensionConfig,\n): config is DeclareQueryDiscoveryExtensionConfig => {\n return !(\"bodyType\" in config);\n};\n\nexport const isBodyExtensionConfig = (\n config: DeclareDiscoveryExtensionConfig,\n): config is DeclareBodyDiscoveryExtensionConfig => {\n return \"bodyType\" in config;\n};\n","/**\n * Resource Service functions for creating Bazaar discovery extensions\n *\n * These functions help servers declare the shape of their endpoints\n * for facilitator discovery and cataloging in the Bazaar.\n */\n\nimport {\n type DiscoveryExtension,\n type QueryDiscoveryExtension,\n type BodyDiscoveryExtension,\n type DeclareDiscoveryExtensionConfig,\n type DeclareQueryDiscoveryExtensionConfig,\n type DeclareBodyDiscoveryExtensionConfig,\n} from \"./types\";\n\n/**\n * Internal helper to create a query discovery extension\n *\n * @param root0 - Configuration object for query discovery extension\n * @param root0.method - HTTP method (GET, HEAD, DELETE)\n * @param root0.input - Query parameters\n * @param root0.inputSchema - JSON schema for query parameters\n * @param root0.output - Output specification with example\n * @returns QueryDiscoveryExtension with info and schema\n */\nfunction createQueryDiscoveryExtension({\n method,\n input = {},\n inputSchema = { properties: {} },\n output,\n}: DeclareQueryDiscoveryExtensionConfig): QueryDiscoveryExtension {\n return {\n info: {\n input: {\n type: \"http\",\n ...(method ? { method } : {}),\n ...(input ? { queryParams: input } : {}),\n } as QueryDiscoveryExtension[\"info\"][\"input\"],\n ...(output?.example\n ? {\n output: {\n type: \"json\",\n example: output.example,\n },\n }\n : {}),\n },\n schema: {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n properties: {\n input: {\n type: \"object\",\n properties: {\n type: {\n type: \"string\",\n const: \"http\",\n },\n method: {\n type: \"string\",\n enum: [\"GET\", \"HEAD\", \"DELETE\"],\n },\n ...(inputSchema\n ? {\n queryParams: {\n type: \"object\" as const,\n ...(typeof inputSchema === \"object\" ? inputSchema : {}),\n },\n }\n : {}),\n },\n required: [\"type\"] as (\"type\" | \"method\")[],\n additionalProperties: false,\n },\n ...(output?.example\n ? {\n output: {\n type: \"object\" as const,\n properties: {\n type: {\n type: \"string\" as const,\n },\n example: {\n type: \"object\" as const,\n ...(output.schema && typeof output.schema === \"object\" ? output.schema : {}),\n },\n },\n required: [\"type\"] as const,\n },\n }\n : {}),\n },\n required: [\"input\"],\n },\n };\n}\n\n/**\n * Internal helper to create a body discovery extension\n *\n * @param root0 - Configuration object for body discovery extension\n * @param root0.method - HTTP method (POST, PUT, PATCH)\n * @param root0.input - Request body specification\n * @param root0.inputSchema - JSON schema for request body\n * @param root0.bodyType - Content type of body (json, form, multipart)\n * @param root0.output - Output specification with example\n * @returns BodyDiscoveryExtension with info and schema\n */\nfunction createBodyDiscoveryExtension({\n method,\n input = {},\n inputSchema = { properties: {} },\n bodyType = \"json\",\n output,\n}: DeclareBodyDiscoveryExtensionConfig): BodyDiscoveryExtension {\n return {\n info: {\n input: {\n type: \"http\",\n ...(method ? { method } : {}),\n bodyType,\n body: input,\n } as BodyDiscoveryExtension[\"info\"][\"input\"],\n ...(output?.example\n ? {\n output: {\n type: \"json\",\n example: output.example,\n },\n }\n : {}),\n },\n schema: {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n properties: {\n input: {\n type: \"object\",\n properties: {\n type: {\n type: \"string\",\n const: \"http\",\n },\n method: {\n type: \"string\",\n enum: [\"POST\", \"PUT\", \"PATCH\"],\n },\n bodyType: {\n type: \"string\",\n enum: [\"json\", \"form-data\", \"text\"],\n },\n body: inputSchema,\n },\n required: [\"type\", \"bodyType\", \"body\"] as (\"type\" | \"method\" | \"bodyType\" | \"body\")[],\n additionalProperties: false,\n },\n ...(output?.example\n ? {\n output: {\n type: \"object\" as const,\n properties: {\n type: {\n type: \"string\" as const,\n },\n example: {\n type: \"object\" as const,\n ...(output.schema && typeof output.schema === \"object\" ? output.schema : {}),\n },\n },\n required: [\"type\"] as const,\n },\n }\n : {}),\n },\n required: [\"input\"],\n },\n };\n}\n\n/**\n * Create a discovery extension for any HTTP method\n *\n * This function helps servers declare how their endpoint should be called,\n * including the expected input parameters/body and output format.\n *\n * @param config - Configuration object for the discovery extension\n * @returns A discovery extension object with both info and schema\n *\n * @example\n * ```typescript\n * // For a GET endpoint with no input\n * const getExtension = declareDiscoveryExtension({\n * method: \"GET\",\n * output: {\n * example: { message: \"Success\", timestamp: \"2024-01-01T00:00:00Z\" }\n * }\n * });\n *\n * // For a GET endpoint with query params\n * const getWithParams = declareDiscoveryExtension({\n * method: \"GET\",\n * input: { query: \"example\" },\n * inputSchema: {\n * properties: {\n * query: { type: \"string\" }\n * },\n * required: [\"query\"]\n * }\n * });\n *\n * // For a POST endpoint with JSON body\n * const postExtension = declareDiscoveryExtension({\n * method: \"POST\",\n * input: { name: \"John\", age: 30 },\n * inputSchema: {\n * properties: {\n * name: { type: \"string\" },\n * age: { type: \"number\" }\n * },\n * required: [\"name\"]\n * },\n * bodyType: \"json\",\n * output: {\n * example: { success: true, id: \"123\" }\n * }\n * });\n * ```\n */\nexport function declareDiscoveryExtension(\n config: Omit<DeclareDiscoveryExtensionConfig, \"method\">,\n): Record<string, DiscoveryExtension> {\n const bodyType = (config as DeclareBodyDiscoveryExtensionConfig).bodyType;\n const isBodyMethod = bodyType !== undefined;\n\n const extension = isBodyMethod\n ? createBodyDiscoveryExtension(config as DeclareBodyDiscoveryExtensionConfig)\n : createQueryDiscoveryExtension(config as DeclareQueryDiscoveryExtensionConfig);\n\n return { bazaar: extension as DiscoveryExtension };\n}\n","import type { ResourceServerExtension } from \"@t402/core/types\";\nimport type { HTTPRequestContext } from \"@t402/core/http\";\nimport { BAZAAR } from \"./types\";\n\n/**\n * Type guard to check if context is an HTTP request context.\n *\n * @param ctx - The context to check\n * @returns True if context is an HTTPRequestContext\n */\nfunction isHTTPRequestContext(ctx: unknown): ctx is HTTPRequestContext {\n return ctx !== null && typeof ctx === \"object\" && \"method\" in ctx && \"adapter\" in ctx;\n}\n\ninterface ExtensionDeclaration {\n [key: string]: unknown;\n info?: {\n [key: string]: unknown;\n input?: Record<string, unknown>;\n };\n schema?: {\n [key: string]: unknown;\n properties?: {\n [key: string]: unknown;\n input?: {\n [key: string]: unknown;\n required?: string[];\n };\n };\n };\n}\n\nexport const bazaarResourceServerExtension: ResourceServerExtension = {\n key: BAZAAR,\n\n enrichDeclaration: (declaration, transportContext) => {\n if (!isHTTPRequestContext(transportContext)) {\n return declaration;\n }\n\n const extension = declaration as ExtensionDeclaration;\n const method = transportContext.method;\n\n return {\n ...extension,\n info: {\n ...(extension.info || {}),\n input: {\n ...(extension.info?.input || {}),\n method,\n },\n },\n schema: {\n ...(extension.schema || {}),\n properties: {\n ...(extension.schema?.properties || {}),\n input: {\n ...(extension.schema?.properties?.input || {}),\n required: [\n ...(extension.schema?.properties?.input?.required || []),\n ...(!(extension.schema?.properties?.input?.required || []).includes(\"method\")\n ? [\"method\"]\n : []),\n ],\n },\n },\n },\n };\n },\n};\n","/**\n * Facilitator functions for validating and extracting Bazaar discovery extensions\n *\n * These functions help facilitators validate extension data against schemas\n * and extract the discovery information for cataloging in the Bazaar.\n *\n * Supports both v2 (extensions in PaymentRequired) and v1 (outputSchema in PaymentRequirements).\n */\n\nimport Ajv from \"ajv/dist/2020\";\nimport type { PaymentPayload, PaymentRequirements, PaymentRequirementsV1 } from \"@t402/core/types\";\nimport type { DiscoveryExtension, DiscoveryInfo } from \"./types\";\nimport { BAZAAR } from \"./types\";\nimport { extractDiscoveryInfoV1 } from \"./v1/facilitator\";\n\n/**\n * Validation result for discovery extensions\n */\nexport interface ValidationResult {\n valid: boolean;\n errors?: string[];\n}\n\n/**\n * Validates a discovery extension's info against its schema\n *\n * @param extension - The discovery extension containing info and schema\n * @returns Validation result indicating if the info matches the schema\n *\n * @example\n * ```typescript\n * const extension = declareDiscoveryExtension(...);\n * const result = validateDiscoveryExtension(extension);\n *\n * if (result.valid) {\n * console.log(\"Extension is valid\");\n * } else {\n * console.error(\"Validation errors:\", result.errors);\n * }\n * ```\n */\nexport function validateDiscoveryExtension(extension: DiscoveryExtension): ValidationResult {\n try {\n const ajv = new Ajv({ strict: false, allErrors: true });\n const validate = ajv.compile(extension.schema);\n\n // The schema describes the structure of info directly\n // Schema has properties: { input: {...}, output: {...} }\n // So we validate extension.info which has { input: {...}, output: {...} }\n const valid = validate(extension.info);\n\n if (valid) {\n return { valid: true };\n }\n\n const errors = validate.errors?.map(err => {\n const path = err.instancePath || \"(root)\";\n return `${path}: ${err.message}`;\n }) || [\"Unknown validation error\"];\n\n return { valid: false, errors };\n } catch (error) {\n return {\n valid: false,\n errors: [\n `Schema validation failed: ${error instanceof Error ? error.message : String(error)}`,\n ],\n };\n }\n}\n\n/**\n * Extracts the discovery info from payment payload and requirements\n *\n * This function handles both v2 (extensions) and v1 (outputSchema) formats.\n *\n * For v2: Discovery info is in PaymentPayload.extensions (client copied it from PaymentRequired)\n * For v1: Discovery info is in PaymentRequirements.outputSchema\n *\n * V1 data is automatically transformed to v2 DiscoveryInfo format, making smart\n * assumptions about field names (queryParams/query/params for GET, bodyFields/body/data for POST, etc.)\n *\n * @param paymentPayload - The payment payload containing extensions (v2) and version info\n * @param paymentRequirements - The payment requirements (contains outputSchema for v1)\n * @param validate - Whether to validate v2 extensions before extracting (default: true)\n * @returns The discovery info in v2 format if present, or null if not discoverable\n *\n * @example\n * ```typescript\n * // V2 - extensions are in PaymentPayload\n * const info = extractDiscoveryInfo(paymentPayload, paymentRequirements);\n *\n * // V1 - discovery info is in PaymentRequirements.outputSchema\n * const info = extractDiscoveryInfo(paymentPayloadV1, paymentRequirementsV1);\n *\n * if (info) {\n * // Both v1 and v2 return the same DiscoveryInfo structure\n * console.log(\"Method:\", info.input.method);\n * }\n * ```\n */\nexport interface DiscoveredResource {\n resourceUrl: string;\n method: string;\n t402Version: number;\n discoveryInfo: DiscoveryInfo;\n}\n\n/**\n * Extracts discovery information from payment payload and requirements.\n * Combines resource URL, HTTP method, version, and discovery info into a single object.\n *\n * @param paymentPayload - The payment payload containing extensions and resource info\n * @param paymentRequirements - The payment requirements to validate against\n * @param validate - Whether to validate the discovery info against the schema (default: true)\n * @returns Discovered resource info with URL, method, version and discovery data, or null if not found\n */\nexport function extractDiscoveryInfo(\n paymentPayload: PaymentPayload,\n paymentRequirements: PaymentRequirements | PaymentRequirementsV1,\n validate: boolean = true,\n): DiscoveredResource | null {\n let discoveryInfo: DiscoveryInfo | null = null;\n let resourceUrl: string;\n\n if (paymentPayload.t402Version === 2) {\n resourceUrl = paymentPayload.resource?.url ?? \"\";\n\n if (paymentPayload.extensions) {\n const bazaarExtension = paymentPayload.extensions[BAZAAR];\n\n if (bazaarExtension && typeof bazaarExtension === \"object\") {\n try {\n const extension = bazaarExtension as DiscoveryExtension;\n\n if (validate) {\n const result = validateDiscoveryExtension(extension);\n if (!result.valid) {\n console.warn(\n `V2 discovery extension validation failed: ${result.errors?.join(\", \")}`,\n );\n } else {\n discoveryInfo = extension.info;\n }\n } else {\n discoveryInfo = extension.info;\n }\n } catch (error) {\n console.warn(`V2 discovery extension extraction failed: ${error}`);\n }\n }\n }\n } else if (paymentPayload.t402Version === 1) {\n const requirementsV1 = paymentRequirements as PaymentRequirementsV1;\n resourceUrl = requirementsV1.resource;\n discoveryInfo = extractDiscoveryInfoV1(requirementsV1);\n } else {\n return null;\n }\n\n if (!discoveryInfo) {\n return null;\n }\n\n return {\n resourceUrl,\n method: discoveryInfo.input.method,\n t402Version: paymentPayload.t402Version,\n discoveryInfo,\n };\n}\n\n/**\n * Extracts discovery info from a v2 extension directly\n *\n * This is a lower-level function for when you already have the extension object.\n * For general use, prefer the main extractDiscoveryInfo function.\n *\n * @param extension - The discovery extension to extract info from\n * @param validate - Whether to validate before extracting (default: true)\n * @returns The discovery info if valid\n * @throws Error if validation fails and validate is true\n */\nexport function extractDiscoveryInfoFromExtension(\n extension: DiscoveryExtension,\n validate: boolean = true,\n): DiscoveryInfo {\n if (validate) {\n const result = validateDiscoveryExtension(extension);\n if (!result.valid) {\n throw new Error(\n `Invalid discovery extension: ${result.errors?.join(\", \") || \"Unknown error\"}`,\n );\n }\n }\n\n return extension.info;\n}\n\n/**\n * Validates and extracts discovery info in one step\n *\n * This is a convenience function that combines validation and extraction,\n * returning both the validation result and the info if valid.\n *\n * @param extension - The discovery extension to validate and extract\n * @returns Object containing validation result and info (if valid)\n *\n * @example\n * ```typescript\n * const extension = declareDiscoveryExtension(...);\n * const { valid, info, errors } = validateAndExtract(extension);\n *\n * if (valid && info) {\n * // Store info in Bazaar catalog\n * } else {\n * console.error(\"Validation errors:\", errors);\n * }\n * ```\n */\nexport function validateAndExtract(extension: DiscoveryExtension): {\n valid: boolean;\n info?: DiscoveryInfo;\n errors?: string[];\n} {\n const result = validateDiscoveryExtension(extension);\n\n if (result.valid) {\n return {\n valid: true,\n info: extension.info,\n };\n }\n\n return {\n valid: false,\n errors: result.errors,\n };\n}\n","/**\n * V1 Facilitator functions for extracting Bazaar discovery information\n *\n * In v1, discovery information is stored in the `outputSchema` field\n * of PaymentRequirements, which has a different structure than v2.\n *\n * This module transforms v1 data into v2 DiscoveryInfo format.\n */\n\nimport type { PaymentRequirementsV1 } from \"@t402/core/types\";\nimport type { BodyMethods, QueryParamMethods } from \"@t402/core/http\";\nimport type { DiscoveryInfo, QueryDiscoveryInfo, BodyDiscoveryInfo } from \"../types\";\n\n/**\n * Type guard to check if an object has the v1 outputSchema structure\n *\n * @param obj - The object to check\n * @returns True if object has v1 outputSchema structure\n */\nfunction hasV1OutputSchema(\n obj: unknown,\n): obj is { input: Record<string, unknown>; output?: Record<string, unknown> } {\n return (\n obj !== null &&\n typeof obj === \"object\" &&\n \"input\" in obj &&\n obj.input !== null &&\n typeof obj.input === \"object\" &&\n \"type\" in obj.input &&\n obj.input.type === \"http\" &&\n \"method\" in obj.input\n );\n}\n\n/**\n * Checks if a method is a query parameter method\n *\n * @param method - HTTP method string to check\n * @returns True if method is GET, HEAD, or DELETE\n */\nfunction isQueryMethod(method: string): method is QueryParamMethods {\n const upperMethod = method.toUpperCase();\n return upperMethod === \"GET\" || upperMethod === \"HEAD\" || upperMethod === \"DELETE\";\n}\n\n/**\n * Checks if a method is a body method\n *\n * @param method - HTTP method string to check\n * @returns True if method is POST, PUT, or PATCH\n */\nfunction isBodyMethod(method: string): method is BodyMethods {\n const upperMethod = method.toUpperCase();\n return upperMethod === \"POST\" || upperMethod === \"PUT\" || upperMethod === \"PATCH\";\n}\n\n/**\n * Extracts query parameters from v1 input, making smart assumptions\n * about common field names used in v1\n *\n * @param v1Input - V1 input object from payment requirements\n * @returns Extracted query parameters or undefined\n */\nfunction extractQueryParams(v1Input: Record<string, unknown>): Record<string, unknown> | undefined {\n // Check various common field names used in v1 (both camelCase and snake_case)\n if (v1Input.queryParams && typeof v1Input.queryParams === \"object\") {\n return v1Input.queryParams as Record<string, unknown>;\n }\n if (v1Input.query_params && typeof v1Input.query_params === \"object\") {\n return v1Input.query_params as Record<string, unknown>;\n }\n if (v1Input.query && typeof v1Input.query === \"object\") {\n return v1Input.query as Record<string, unknown>;\n }\n if (v1Input.params && typeof v1Input.params === \"object\") {\n return v1Input.params as Record<string, unknown>;\n }\n return undefined;\n}\n\n/**\n * Extracts body information from v1 input, making smart assumptions\n *\n * @param v1Input - V1 input object from payment requirements\n * @returns Object containing body content and bodyType\n */\nfunction extractBodyInfo(v1Input: Record<string, unknown>): {\n body: Record<string, unknown>;\n bodyType: \"json\" | \"form-data\" | \"text\";\n} {\n // Determine body type (check both camelCase and snake_case)\n let bodyType: \"json\" | \"form-data\" | \"text\" = \"json\";\n const bodyTypeField = v1Input.bodyType || v1Input.body_type;\n\n if (bodyTypeField && typeof bodyTypeField === \"string\") {\n const type = bodyTypeField.toLowerCase();\n if (type.includes(\"form\") || type.includes(\"multipart\")) {\n bodyType = \"form-data\";\n } else if (type.includes(\"text\") || type.includes(\"plain\")) {\n bodyType = \"text\";\n } else {\n bodyType = \"json\";\n }\n }\n\n // Extract body content from various possible fields\n // Priority order based on observed patterns in real data\n let body: Record<string, unknown> = {};\n\n if (v1Input.bodyFields && typeof v1Input.bodyFields === \"object\") {\n body = v1Input.bodyFields as Record<string, unknown>;\n } else if (\n v1Input.body_fields &&\n v1Input.body_fields !== null &&\n typeof v1Input.body_fields === \"object\"\n ) {\n body = v1Input.body_fields as Record<string, unknown>;\n } else if (v1Input.bodyParams && typeof v1Input.bodyParams === \"object\") {\n body = v1Input.bodyParams as Record<string, unknown>;\n } else if (v1Input.body && typeof v1Input.body === \"object\") {\n body = v1Input.body as Record<string, unknown>;\n } else if (v1Input.data && typeof v1Input.data === \"object\") {\n body = v1Input.data as Record<string, unknown>;\n } else if (v1Input.properties && typeof v1Input.properties === \"object\") {\n // Some endpoints have properties directly at the input level\n body = v1Input.properties as Record<string, unknown>;\n }\n\n return { body, bodyType };\n}\n\n/**\n * Extracts discovery info from v1 PaymentRequirements and transforms to v2 format\n *\n * In v1, the discovery information is stored in the `outputSchema` field,\n * which contains both input (endpoint shape) and output (response schema) information.\n *\n * This function makes smart assumptions to normalize v1 data into v2 DiscoveryInfo format:\n * - For GET/HEAD/DELETE: Looks for queryParams, query, or params fields\n * - For POST/PUT/PATCH: Looks for bodyFields, body, or data fields and normalizes bodyType\n * - Extracts optional headers if present\n *\n * @param paymentRequirements - V1 payment requirements\n * @returns Discovery info in v2 format if present and valid, or null if not discoverable\n *\n * @example\n * ```typescript\n * const requirements: PaymentRequirementsV1 = {\n * scheme: \"exact\",\n * network: \"eip155:8453\",\n * maxAmountRequired: \"100000\",\n * resource: \"https://api.example.com/data\",\n * description: \"Get data\",\n * mimeType: \"application/json\",\n * outputSchema: {\n * input: {\n * type: \"http\",\n * method: \"GET\",\n * discoverable: true,\n * queryParams: { query: \"string\" }\n * },\n * output: { type: \"object\" }\n * },\n * payTo: \"0x...\",\n * maxTimeoutSeconds: 300,\n * asset: \"0x...\",\n * extra: {}\n * };\n *\n * const info = extractDiscoveryInfoV1(requirements);\n * if (info) {\n * console.log(\"Endpoint method:\", info.input.method);\n * }\n * ```\n */\nexport function extractDiscoveryInfoV1(\n paymentRequirements: PaymentRequirementsV1,\n): DiscoveryInfo | null {\n const { outputSchema } = paymentRequirements;\n\n // Check if outputSchema exists and has the expected structure\n if (!outputSchema || !hasV1OutputSchema(outputSchema)) {\n return null;\n }\n\n const v1Input = outputSchema.input;\n\n // Check if the endpoint is marked as discoverable\n // Default to true if not specified (for backwards compatibility)\n const isDiscoverable = v1Input.discoverable ?? true;\n\n if (!isDiscoverable) {\n return null;\n }\n\n const method = typeof v1Input.method === \"string\" ? v1Input.method.toUpperCase() : \"\";\n\n // Extract headers if present (check both camelCase and snake_case)\n const headersRaw = v1Input.headerFields || v1Input.header_fields || v1Input.headers;\n const headers =\n headersRaw && typeof headersRaw === \"object\"\n ? (headersRaw as Record<string, string>)\n : undefined;\n\n // Extract output example/schema if present\n const output = outputSchema.output\n ? {\n type: \"json\" as const,\n example: outputSchema.output,\n }\n : undefined;\n\n // Transform based on method type\n if (isQueryMethod(method)) {\n // Query parameter method (GET, HEAD, DELETE)\n const queryParams = extractQueryParams(v1Input);\n\n const discoveryInfo: QueryDiscoveryInfo = {\n input: {\n type: \"http\",\n method: method as QueryParamMethods,\n ...(queryParams ? { queryParams } : {}),\n ...(headers ? { headers } : {}),\n },\n ...(output ? { output } : {}),\n };\n\n return discoveryInfo;\n } else if (isBodyMethod(method)) {\n // Body method (POST, PUT, PATCH)\n const { body, bodyType } = extractBodyInfo(v1Input);\n const queryParams = extractQueryParams(v1Input); // Some POST requests also have query params\n\n const discoveryInfo: BodyDiscoveryInfo = {\n input: {\n type: \"http\",\n method: method as BodyMethods,\n bodyType,\n body,\n ...(queryParams ? { queryParams } : {}),\n ...(headers ? { headers } : {}),\n },\n ...(output ? { output } : {}),\n };\n\n return discoveryInfo;\n }\n\n // Unsupported method, return null\n return null;\n}\n\n/**\n * Checks if v1 PaymentRequirements contains discoverable information\n *\n * @param paymentRequirements - V1 payment requirements\n * @returns True if the requirements contain valid discovery info\n *\n * @example\n * ```typescript\n * if (isDiscoverableV1(requirements)) {\n * const info = extractDiscoveryInfoV1(requirements);\n * // Catalog info in Bazaar\n * }\n * ```\n */\nexport function isDiscoverableV1(paymentRequirements: PaymentRequirementsV1): boolean {\n return extractDiscoveryInfoV1(paymentRequirements) !== null;\n}\n\n/**\n * Extracts resource metadata from v1 PaymentRequirements\n *\n * In v1, resource information is embedded directly in the payment requirements\n * rather than in a separate resource object.\n *\n * @param paymentRequirements - V1 payment requirements\n * @returns Resource metadata\n *\n * @example\n * ```typescript\n * const metadata = extractResourceMetadataV1(requirements);\n * console.log(\"Resource URL:\", metadata.url);\n * console.log(\"Description:\", metadata.description);\n * ```\n */\nexport function extractResourceMetadataV1(paymentRequirements: PaymentRequirementsV1): {\n url: string;\n description: string;\n mimeType: string;\n} {\n return {\n url: paymentRequirements.resource,\n description: paymentRequirements.description,\n mimeType: paymentRequirements.mimeType,\n };\n}\n","/**\n * Client extensions for querying Bazaar discovery resources\n */\n\nimport { HTTPFacilitatorClient } from \"@t402/core/http\";\nimport { WithExtensions } from \"../types\";\n\n/**\n * Parameters for listing discovery resources.\n * All parameters are optional and used for filtering/pagination.\n */\nexport interface ListDiscoveryResourcesParams {\n /**\n * Filter by protocol type (e.g., \"http\", \"mcp\").\n * Currently, the only supported protocol type is \"http\".\n */\n type?: string;\n\n /**\n * The number of discovered t402 resources to return per page.\n */\n limit?: number;\n\n /**\n * The offset of the first discovered t402 resource to return.\n */\n offset?: number;\n}\n\n/**\n * A discovered t402 resource from the bazaar.\n */\nexport interface DiscoveryResource {\n /** The URL of the discovered resource */\n url: string;\n /** The protocol type of the resource */\n type: string;\n /** Additional metadata about the resource */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Response from listing discovery resources.\n */\nexport interface DiscoveryResourcesResponse {\n /** The list of discovered resources */\n resources: DiscoveryResource[];\n /** Total count of resources matching the query */\n total?: number;\n /** The limit used for this query */\n limit?: number;\n /** The offset used for this query */\n offset?: number;\n}\n\n/**\n * Bazaar client extension interface providing discovery query functionality.\n */\nexport interface BazaarClientExtension {\n discovery: {\n /**\n * List t402 discovery resources from the bazaar.\n *\n * @param params - Optional filtering and pagination parameters\n * @returns A promise resolving to the discovery resources response\n */\n listResources(params?: ListDiscoveryResourcesParams): Promise<DiscoveryResourcesResponse>;\n };\n}\n\n/**\n * Extends a facilitator client with Bazaar discovery query functionality.\n * Preserves and merges with any existing extensions from prior chaining.\n *\n * @param client - The facilitator client to extend\n * @returns The client extended with bazaar discovery capabilities\n *\n * @example\n * ```ts\n * // Basic usage\n * const client = withBazaar(new HTTPFacilitatorClient());\n * const resources = await client.extensions.discovery.listResources({ type: \"http\" });\n *\n * // Chaining with other extensions\n * const client = withBazaar(withOtherExtension(new HTTPFacilitatorClient()));\n * await client.extensions.other.someMethod();\n * await client.extensions.discovery.listResources();\n * ```\n */\nexport function withBazaar<T extends HTTPFacilitatorClient>(\n client: T,\n): WithExtensions<T, BazaarClientExtension> {\n // Preserve any existing extensions from prior chaining\n const existingExtensions =\n (client as T & { extensions?: Record<string, unknown> }).extensions ?? {};\n\n const extended = client as WithExtensions<T, BazaarClientExtension>;\n\n extended.extensions = {\n ...existingExtensions,\n discovery: {\n async listResources(\n params?: ListDiscoveryResourcesParams,\n ): Promise<DiscoveryResourcesResponse> {\n let headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n\n const authHeaders = await client.createAuthHeaders(\"discovery\");\n headers = { ...headers, ...authHeaders.headers };\n\n const queryParams = new URLSearchParams();\n if (params?.type !== undefined) {\n queryParams.set(\"type\", params.type);\n }\n if (params?.limit !== undefined) {\n queryParams.set(\"limit\", params.limit.toString());\n }\n if (params?.offset !== undefined) {\n queryParams.set(\"offset\", params.offset.toString());\n }\n\n const queryString = queryParams.toString();\n const endpoint = `${client.url}/discovery/resources${queryString ? `?${queryString}` : \"\"}`;\n\n const response = await fetch(endpoint, {\n method: \"GET\",\n headers,\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n throw new Error(\n `Facilitator listDiscoveryResources failed (${response.status}): ${errorText}`,\n );\n }\n\n return (await response.json()) as DiscoveryResourcesResponse;\n },\n },\n } as WithExtensions<T, BazaarClientExtension>[\"extensions\"];\n\n return extended;\n}\n","/**\n * Sign-In-With-X (SIWx) Server-Side Implementation\n *\n * Provides functions for servers to declare SIWx requirements,\n * parse client headers, and verify signatures.\n */\n\nimport { randomBytes } from \"crypto\";\nimport { keccak_256 } from \"@noble/hashes/sha3\";\nimport { sha256 as nobleSha256 } from \"@noble/hashes/sha2\";\nimport { secp256k1 } from \"@noble/curves/secp256k1\";\nimport { ed25519 } from \"@noble/curves/ed25519\";\nimport { bytesToHex, hexToBytes } from \"@noble/hashes/utils\";\nimport {\n SIWxExtension,\n SIWxExtensionInfo,\n SIWxPayload,\n DeclareSIWxOptions,\n ValidateSIWxOptions,\n VerifySIWxOptions,\n SIWxValidationResult,\n SIWxVerificationResult,\n} from \"./types.js\";\n\n/**\n * JSON Schema for SIWx payload validation.\n */\nconst SIWX_SCHEMA = {\n type: \"object\",\n required: [\"domain\", \"address\", \"uri\", \"version\", \"chainId\", \"nonce\", \"issuedAt\", \"signature\"],\n properties: {\n domain: { type: \"string\" },\n address: { type: \"string\" },\n statement: { type: \"string\" },\n uri: { type: \"string\" },\n version: { type: \"string\" },\n chainId: { type: \"string\" },\n nonce: { type: \"string\" },\n issuedAt: { type: \"string\", format: \"date-time\" },\n expirationTime: { type: \"string\", format: \"date-time\" },\n notBefore: { type: \"string\", format: \"date-time\" },\n requestId: { type: \"string\" },\n resources: { type: \"array\", items: { type: \"string\" } },\n signature: { type: \"string\" },\n },\n};\n\n/**\n * EIP-1271 magic value for valid signatures.\n */\nconst EIP1271_MAGIC_VALUE = \"0x1626ba7e\";\n\n/**\n * Extracts domain from a resource URI.\n *\n * @param resourceUri - Full resource URI (e.g., \"https://api.example.com/resource\")\n * @returns Domain without protocol (e.g., \"api.example.com\")\n */\nfunction extractDomain(resourceUri: string): string {\n try {\n const url = new URL(resourceUri);\n return url.host;\n } catch {\n // Fallback for non-URL formats\n return resourceUri.replace(/^https?:\\/\\//, \"\").split(\"/\")[0];\n }\n}\n\n/**\n * Generates a cryptographically secure nonce.\n *\n * @returns 32-byte hex-encoded nonce\n */\nfunction generateNonce(): string {\n return randomBytes(16).toString(\"hex\");\n}\n\n/**\n * Declares a SIWx extension for server responses.\n *\n * @param options - Extension declaration options\n * @returns SIWx extension object ready for response\n *\n * @example\n * ```typescript\n * const extension = declareSIWxExtension({\n * resourceUri: \"https://api.example.com/premium\",\n * network: \"eip155:8453\",\n * statement: \"Sign in to access premium content\",\n * });\n * ```\n */\nexport function declareSIWxExtension(options: DeclareSIWxOptions): SIWxExtension {\n const domain = extractDomain(options.resourceUri);\n const now = new Date();\n const expirationTime =\n options.expirationTime || new Date(now.getTime() + 5 * 60 * 1000).toISOString();\n\n const info: SIWxExtensionInfo = {\n domain,\n uri: options.resourceUri,\n statement: options.statement,\n version: options.version || \"1\",\n chainId: options.network,\n nonce: generateNonce(),\n issuedAt: now.toISOString(),\n expirationTime,\n resources: [options.resourceUri],\n signatureScheme: options.signatureScheme,\n };\n\n return {\n info,\n schema: SIWX_SCHEMA,\n };\n}\n\n/**\n * Parses a SIWx header from client request.\n *\n * The header format is base64-encoded JSON.\n *\n * @param header - Base64-encoded SIWx header value\n * @returns Parsed SIWx payload\n * @throws Error if header is invalid\n *\n * @example\n * ```typescript\n * const payload = parseSIWxHeader(request.headers['x-t402-siwx']);\n * ```\n */\nexport function parseSIWxHeader(header: string): SIWxPayload {\n if (!header) {\n throw new Error(\"Missing SIWx header\");\n }\n\n try {\n const decoded = Buffer.from(header, \"base64\").toString(\"utf-8\");\n const payload = JSON.parse(decoded) as SIWxPayload;\n\n // Validate required fields\n const required = [\n \"domain\",\n \"address\",\n \"uri\",\n \"version\",\n \"chainId\",\n \"nonce\",\n \"issuedAt\",\n \"signature\",\n ];\n for (const field of required) {\n if (!(field in payload)) {\n throw new Error(`Missing required field: ${field}`);\n }\n }\n\n return payload;\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new Error(\"Invalid SIWx header: malformed JSON\");\n }\n throw error;\n }\n}\n\n/**\n * Validates a SIWx message against expected values.\n *\n * @param message - The SIWx payload to validate\n * @param expectedResourceUri - Expected resource URI (domain validated from this)\n * @param options - Validation options\n * @returns Validation result\n *\n * @example\n * ```typescript\n * const result = validateSIWxMessage(payload, \"https://api.example.com/premium\", {\n * maxAge: 5 * 60 * 1000, // 5 minutes\n * checkNonce: (nonce) => usedNonces.has(nonce) === false,\n * });\n * ```\n */\nexport function validateSIWxMessage(\n message: SIWxPayload,\n expectedResourceUri: string,\n options: ValidateSIWxOptions = {},\n): SIWxValidationResult {\n const { maxAge = 5 * 60 * 1000, checkNonce } = options;\n\n // Validate domain matches\n const expectedDomain = extractDomain(expectedResourceUri);\n if (message.domain !== expectedDomain) {\n return {\n valid: false,\n error: `Domain mismatch: expected ${expectedDomain}, got ${message.domain}`,\n };\n }\n\n // Validate URI matches\n if (message.uri !== expectedResourceUri) {\n return {\n valid: false,\n error: `URI mismatch: expected ${expectedResourceUri}, got ${message.uri}`,\n };\n }\n\n // Validate version\n if (message.version !== \"1\") {\n return { valid: false, error: `Unsupported version: ${message.version}` };\n }\n\n // Validate issuedAt is not too old\n const issuedAt = new Date(message.issuedAt);\n const now = new Date();\n if (now.getTime() - issuedAt.getTime() > maxAge) {\n return { valid: false, error: \"Message has expired (issuedAt too old)\" };\n }\n\n // Validate expirationTime if present\n if (message.expirationTime) {\n const expiration = new Date(message.expirationTime);\n if (expiration < now) {\n return { valid: false, error: \"Message has expired\" };\n }\n }\n\n // Validate notBefore if present\n if (message.notBefore) {\n const notBefore = new Date(message.notBefore);\n if (notBefore > now) {\n return { valid: false, error: \"Message not yet valid (notBefore in future)\" };\n }\n }\n\n // Custom nonce validation\n if (checkNonce && !checkNonce(message.nonce)) {\n return { valid: false, error: \"Invalid nonce (replay attack detected)\" };\n }\n\n return { valid: true };\n}\n\n/**\n * Detects the signature scheme from chain ID.\n *\n * @param chainId - CAIP-2 chain ID (e.g., \"eip155:1\", \"solana:mainnet\", \"stellar:pubnet\")\n * @returns The signature scheme to use for verification\n */\nfunction detectSignatureScheme(chainId: string): \"evm\" | \"ed25519\" | \"tron\" {\n const namespace = chainId.split(\":\")[0];\n\n switch (namespace) {\n case \"solana\":\n case \"stellar\":\n case \"ton\":\n return \"ed25519\";\n case \"tron\":\n return \"tron\";\n case \"eip155\":\n default:\n return \"evm\";\n }\n}\n\n/**\n * Verifies an Ed25519 signature (used by Solana and Stellar).\n *\n * @param message - The message that was signed\n * @param signature - Hex-encoded Ed25519 signature (64 bytes)\n * @param publicKey - The public key to verify against (hex or base58)\n * @returns True if signature is valid\n */\nfunction verifyEd25519Signature(message: string, signature: string, publicKey: string): boolean {\n try {\n // Remove 0x prefix if present\n const sigHex = signature.startsWith(\"0x\") ? signature.slice(2) : signature;\n const sigBytes = hexToBytes(sigHex);\n\n if (sigBytes.length !== 64) {\n throw new Error(\n `Invalid Ed25519 signature length: expected 64 bytes, got ${sigBytes.length}`,\n );\n }\n\n // Get public key bytes\n let pubKeyBytes: Uint8Array;\n const pubKeyHex = publicKey.startsWith(\"0x\") ? publicKey.slice(2) : publicKey;\n\n // Check if it's a hex string (64 chars = 32 bytes)\n if (/^[0-9a-fA-F]{64}$/.test(pubKeyHex)) {\n pubKeyBytes = hexToBytes(pubKeyHex);\n } else {\n // Try to decode as base58 (Solana format)\n pubKeyBytes = decodeBase58(publicKey);\n }\n\n if (pubKeyBytes.length !== 32) {\n throw new Error(\n `Invalid Ed25519 public key length: expected 32 bytes, got ${pubKeyBytes.length}`,\n );\n }\n\n // Hash the message (Ed25519 signs the raw message or its hash depending on implementation)\n const messageBytes = new TextEncoder().encode(message);\n\n // Verify the signature\n return ed25519.verify(sigBytes, messageBytes, pubKeyBytes);\n } catch {\n return false;\n }\n}\n\n/**\n * Decodes a base58 string to bytes (for Solana addresses).\n *\n * @param str - Base58 encoded string\n * @returns Decoded bytes\n */\nfunction decodeBase58(str: string): Uint8Array {\n const ALPHABET = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\n const ALPHABET_MAP = new Map<string, number>();\n for (let i = 0; i < ALPHABET.length; i++) {\n ALPHABET_MAP.set(ALPHABET[i], i);\n }\n\n if (str.length === 0) return new Uint8Array(0);\n\n const bytes: number[] = [0];\n for (const char of str) {\n const value = ALPHABET_MAP.get(char);\n if (value === undefined) {\n throw new Error(`Invalid base58 character: ${char}`);\n }\n\n let carry = value;\n for (let j = 0; j < bytes.length; j++) {\n carry += bytes[j] * 58;\n bytes[j] = carry & 0xff;\n carry >>= 8;\n }\n\n while (carry > 0) {\n bytes.push(carry & 0xff);\n carry >>= 8;\n }\n }\n\n // Add leading zeros\n for (const char of str) {\n if (char !== \"1\") break;\n bytes.push(0);\n }\n\n return new Uint8Array(bytes.reverse());\n}\n\n/**\n * Encodes bytes to base58 string.\n *\n * @param bytes - Bytes to encode\n * @returns Base58 encoded string\n */\nfunction encodeBase58(bytes: Uint8Array): string {\n const ALPHABET = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\n\n if (bytes.length === 0) return \"\";\n\n // Count leading zeros\n let leadingZeros = 0;\n for (const b of bytes) {\n if (b !== 0) break;\n leadingZeros++;\n }\n\n // Convert to base58\n const digits: number[] = [0];\n for (const b of bytes) {\n let carry = b;\n for (let j = 0; j < digits.length; j++) {\n carry += digits[j] * 256;\n digits[j] = carry % 58;\n carry = Math.floor(carry / 58);\n }\n while (carry > 0) {\n digits.push(carry % 58);\n carry = Math.floor(carry / 58);\n }\n }\n\n let result = ALPHABET[0].repeat(leadingZeros);\n for (let i = digits.length - 1; i >= 0; i--) {\n result += ALPHABET[digits[i]];\n }\n\n return result;\n}\n\n/**\n * Converts an EVM hex address to a TRON base58check address.\n *\n * TRON addresses are the same as EVM addresses but with a 0x41 prefix\n * instead of 0x, encoded in base58check format.\n *\n * @param evmAddress - EVM address with 0x prefix\n * @returns TRON base58check address starting with 'T'\n */\nfunction evmAddressToTron(evmAddress: string): string {\n const addr = evmAddress.toLowerCase().replace(\"0x\", \"\");\n // TRON address = 0x41 + 20-byte address\n const addressBytes = hexToBytes(\"41\" + addr);\n\n // Double SHA-256 for base58check checksum\n const hash1 = nobleSha256(addressBytes);\n const hash2 = nobleSha256(hash1);\n const checksum = hash2.slice(0, 4);\n\n // Concatenate address + checksum\n const fullAddress = new Uint8Array(addressBytes.length + 4);\n fullAddress.set(addressBytes, 0);\n fullAddress.set(checksum, addressBytes.length);\n\n return encodeBase58(fullAddress);\n}\n\n/**\n * Verifies a SIWx signature.\n *\n * Supports EIP-191 personal signatures for EVM chains, Ed25519 for Solana/Stellar/TON,\n * TRON secp256k1 with base58check addresses,\n * and can optionally verify smart wallet signatures via EIP-1271/6492.\n *\n * @param message - The SIWx payload to verify\n * @param signature - The signature to verify (hex-encoded)\n * @param options - Verification options\n * @returns Verification result with recovered address\n *\n * @example\n * ```typescript\n * const result = await verifySIWxSignature(payload, payload.signature, {\n * checkSmartWallet: true,\n * provider: web3Provider,\n * });\n * ```\n */\nexport async function verifySIWxSignature(\n message: SIWxPayload,\n signature: string,\n options: VerifySIWxOptions = {},\n): Promise<SIWxVerificationResult> {\n const { checkSmartWallet = false } = options;\n\n try {\n // Reconstruct the CAIP-122 message that was signed\n const messageText = constructMessage(message);\n\n // Detect signature scheme based on chain ID\n const scheme = detectSignatureScheme(message.chainId);\n\n if (scheme === \"ed25519\") {\n // Ed25519 verification for Solana, Stellar, and TON\n // For Ed25519, the address IS the public key, so we verify directly\n const isValid = verifyEd25519Signature(messageText, signature, message.address);\n\n if (isValid) {\n return { valid: true, address: message.address };\n }\n\n return {\n valid: false,\n error: \"Ed25519 signature verification failed\",\n };\n }\n\n if (scheme === \"tron\") {\n // TRON uses secp256k1 (same as EVM) but with base58check address format\n const messageHash = hashMessage(messageText);\n const recoveredEvmAddress = recoverAddress(messageHash, signature);\n\n // Convert recovered EVM address to TRON base58check address\n const recoveredTronAddress = evmAddressToTron(recoveredEvmAddress);\n\n if (recoveredTronAddress === message.address) {\n return { valid: true, address: message.address };\n }\n\n return {\n valid: false,\n address: recoveredTronAddress,\n error: `Signature mismatch: expected ${message.address}, recovered ${recoveredTronAddress}`,\n };\n }\n\n // EVM verification (secp256k1)\n // Hash the message with Ethereum prefix\n const messageHash = hashMessage(messageText);\n\n // Try to recover the signer address\n const recoveredAddress = recoverAddress(messageHash, signature);\n\n // Check if recovered address matches claimed address\n if (recoveredAddress.toLowerCase() !== message.address.toLowerCase()) {\n // If smart wallet checking is enabled, try EIP-1271 verification\n if (checkSmartWallet && options.provider) {\n const isValidSmartWallet = await verifySmartWalletSignature(\n message.address,\n messageHash,\n signature,\n options.provider,\n );\n\n if (isValidSmartWallet) {\n return { valid: true, address: message.address };\n }\n }\n\n return {\n valid: false,\n address: recoveredAddress,\n error: `Signature mismatch: expected ${message.address}, recovered ${recoveredAddress}`,\n };\n }\n\n return { valid: true, address: recoveredAddress };\n } catch (error) {\n return {\n valid: false,\n error: `Signature verification failed: ${error instanceof Error ? error.message : \"unknown error\"}`,\n };\n }\n}\n\n/**\n * Constructs the CAIP-122 message string from payload.\n *\n * @param payload - SIWx payload\n * @returns CAIP-122 formatted message string\n */\nexport function constructMessage(payload: SIWxPayload): string {\n const lines: string[] = [];\n\n // Header\n lines.push(`${payload.domain} wants you to sign in with your ${payload.chainId} account:`);\n lines.push(payload.address);\n lines.push(\"\");\n\n // Statement (optional)\n if (payload.statement) {\n lines.push(payload.statement);\n lines.push(\"\");\n }\n\n // Required fields\n lines.push(`URI: ${payload.uri}`);\n lines.push(`Version: ${payload.version}`);\n lines.push(`Chain ID: ${payload.chainId}`);\n lines.push(`Nonce: ${payload.nonce}`);\n lines.push(`Issued At: ${payload.issuedAt}`);\n\n // Optional fields\n if (payload.expirationTime) {\n lines.push(`Expiration Time: ${payload.expirationTime}`);\n }\n if (payload.notBefore) {\n lines.push(`Not Before: ${payload.notBefore}`);\n }\n if (payload.requestId) {\n lines.push(`Request ID: ${payload.requestId}`);\n }\n\n // Resources\n if (payload.resources && payload.resources.length > 0) {\n lines.push(\"Resources:\");\n for (const resource of payload.resources) {\n lines.push(`- ${resource}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Hashes a message with the Ethereum signed message prefix (EIP-191).\n *\n * @param message - Message to hash\n * @returns Hex-encoded keccak256 hash with 0x prefix\n */\nexport function hashMessage(message: string): string {\n const messageBytes = new TextEncoder().encode(message);\n const prefix = `\\x19Ethereum Signed Message:\\n${messageBytes.length}`;\n const prefixBytes = new TextEncoder().encode(prefix);\n\n // Concatenate prefix and message\n const combined = new Uint8Array(prefixBytes.length + messageBytes.length);\n combined.set(prefixBytes, 0);\n combined.set(messageBytes, prefixBytes.length);\n\n // Hash with keccak256\n const hash = keccak_256(combined);\n return \"0x\" + bytesToHex(hash);\n}\n\n/**\n * Recovers the signer address from an EIP-191 signature.\n *\n * @param messageHash - Keccak256 hash of the prefixed message (with 0x prefix)\n * @param signature - Hex-encoded signature (65 bytes: r + s + v)\n * @returns Checksummed Ethereum address\n */\nfunction recoverAddress(messageHash: string, signature: string): string {\n // Remove 0x prefix if present\n const sigHex = signature.startsWith(\"0x\") ? signature.slice(2) : signature;\n const hashHex = messageHash.startsWith(\"0x\") ? messageHash.slice(2) : messageHash;\n\n if (sigHex.length !== 130) {\n throw new Error(`Invalid signature length: expected 130 hex chars, got ${sigHex.length}`);\n }\n\n // Parse signature components\n const r = BigInt(\"0x\" + sigHex.slice(0, 64));\n const s = BigInt(\"0x\" + sigHex.slice(64, 128));\n let v = parseInt(sigHex.slice(128, 130), 16);\n\n // Normalize v to 0 or 1 (EIP-155 compatibility)\n if (v >= 27) {\n v -= 27;\n }\n\n if (v !== 0 && v !== 1) {\n throw new Error(`Invalid recovery id: ${v}`);\n }\n\n // Create signature object\n const sig = new secp256k1.Signature(r, s).addRecoveryBit(v);\n\n // Recover public key\n const hashBytes = hexToBytes(hashHex);\n const publicKey = sig.recoverPublicKey(hashBytes);\n\n // Get uncompressed public key (65 bytes) and remove the 04 prefix\n const pubKeyBytes = publicKey.toRawBytes(false).slice(1);\n\n // Hash public key to get address\n const addressHash = keccak_256(pubKeyBytes);\n\n // Take last 20 bytes\n const addressBytes = addressHash.slice(-20);\n const address = \"0x\" + bytesToHex(addressBytes);\n\n // Return checksummed address\n return toChecksumAddress(address);\n}\n\n/**\n * Converts an Ethereum address to checksummed format (EIP-55).\n *\n * @param address - Ethereum address (with or without 0x prefix)\n * @returns Checksummed address with 0x prefix\n */\nfunction toChecksumAddress(address: string): string {\n const addr = address.toLowerCase().replace(\"0x\", \"\");\n const hash = bytesToHex(keccak_256(new TextEncoder().encode(addr)));\n\n let checksummed = \"0x\";\n for (let i = 0; i < 40; i++) {\n if (parseInt(hash[i], 16) >= 8) {\n checksummed += addr[i].toUpperCase();\n } else {\n checksummed += addr[i];\n }\n }\n\n return checksummed;\n}\n\n/**\n * Verifies a smart wallet signature using EIP-1271.\n *\n * @param walletAddress - Smart wallet contract address\n * @param messageHash - Hash of the message that was signed\n * @param signature - The signature to verify\n * @param provider - Ethereum provider with call capability\n * @returns True if signature is valid according to the smart wallet\n */\nasync function verifySmartWalletSignature(\n walletAddress: string,\n messageHash: string,\n signature: string,\n provider: unknown,\n): Promise<boolean> {\n // Type guard for provider\n interface EthProvider {\n request(args: { method: string; params: unknown[] }): Promise<unknown>;\n }\n\n /**\n * Type guard for Ethereum provider interface\n *\n * @param p - Value to check\n * @returns True if value is an EthProvider\n */\n function isEthProvider(p: unknown): p is EthProvider {\n return typeof p === \"object\" && p !== null && \"request\" in p;\n }\n\n if (!isEthProvider(provider)) {\n return false;\n }\n\n try {\n // EIP-1271 isValidSignature(bytes32 hash, bytes signature) returns bytes4\n const hashHex = messageHash.startsWith(\"0x\") ? messageHash : \"0x\" + messageHash;\n const sigHex = signature.startsWith(\"0x\") ? signature : \"0x\" + signature;\n\n // Encode function call\n // isValidSignature(bytes32,bytes) selector: 0x1626ba7e\n const data =\n \"0x1626ba7e\" +\n hashHex.slice(2).padStart(64, \"0\") + // bytes32 hash\n \"0000000000000000000000000000000000000000000000000000000000000040\" + // offset to bytes\n (sigHex.length / 2 - 1).toString(16).padStart(64, \"0\") + // bytes length\n sigHex.slice(2).padEnd(Math.ceil((sigHex.length - 2) / 64) * 64, \"0\"); // bytes data\n\n const result = (await provider.request({\n method: \"eth_call\",\n params: [{ to: walletAddress, data }, \"latest\"],\n })) as string;\n\n // Check if result matches magic value\n return result.toLowerCase().startsWith(EIP1271_MAGIC_VALUE);\n } catch {\n return false;\n }\n}\n\n/**\n * Verifies a signature using EIP-6492 (universal signature verification).\n *\n * This supports both deployed and undeployed smart wallets.\n *\n * @param walletAddress - Wallet address (may be counterfactual)\n * @param messageHash - Hash of the message that was signed\n * @param signature - The signature (may include deployment data)\n * @param provider - Ethereum provider\n * @returns True if signature is valid\n */\nexport async function verifyEIP6492Signature(\n walletAddress: string,\n messageHash: string,\n signature: string,\n provider: unknown,\n): Promise<boolean> {\n // EIP-6492 signatures end with the magic suffix\n const EIP6492_SUFFIX = \"6492649264926492649264926492649264926492649264926492649264926492\";\n const sigHex = signature.startsWith(\"0x\") ? signature.slice(2) : signature;\n\n if (sigHex.endsWith(EIP6492_SUFFIX)) {\n // This is an EIP-6492 signature with deployment data\n // For full implementation, we would need to:\n // 1. Deploy the wallet contract to a local fork\n // 2. Then call isValidSignature\n // This requires more complex provider interaction\n console.warn(\"EIP-6492 deployment signatures not yet fully implemented\");\n return false;\n }\n\n // Fall back to standard EIP-1271 verification\n return verifySmartWalletSignature(walletAddress, messageHash, signature, provider);\n}\n","/**\n * Sign-In-With-X (SIWx) Client-Side Implementation\n *\n * Provides functions for clients to create and sign SIWx messages.\n */\n\nimport {\n SIWxPayload,\n SIWxExtension,\n SIWxExtensionInfo,\n SIWxSigner,\n SignatureScheme,\n} from \"./types.js\";\nimport { constructMessage } from \"./server.js\";\n\n/**\n * Encodes a SIWx payload for transmission in HTTP header.\n *\n * @param payload - The SIWx payload to encode\n * @returns Base64-encoded JSON string\n *\n * @example\n * ```typescript\n * const header = encodeSIWxHeader(payload);\n * fetch(url, {\n * headers: { 'X-T402-SIWx': header }\n * });\n * ```\n */\nexport function encodeSIWxHeader(payload: SIWxPayload): string {\n const json = JSON.stringify(payload);\n // Use Buffer in Node.js or btoa in browser\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(json, \"utf-8\").toString(\"base64\");\n }\n return btoa(json);\n}\n\n/**\n * Creates a CAIP-122 formatted message string from server info.\n *\n * @param serverInfo - Extension info from server\n * @param address - Wallet address signing the message\n * @returns CAIP-122 formatted message string ready for signing\n *\n * @example\n * ```typescript\n * const message = createSIWxMessage(extension.info, wallet.address);\n * const signature = await wallet.signMessage(message);\n * ```\n */\nexport function createSIWxMessage(serverInfo: SIWxExtensionInfo, address: string): string {\n // Create a temporary payload for message construction\n const payload: SIWxPayload = {\n domain: serverInfo.domain,\n address,\n statement: serverInfo.statement,\n uri: serverInfo.uri,\n version: serverInfo.version,\n chainId: serverInfo.chainId,\n nonce: serverInfo.nonce,\n issuedAt: serverInfo.issuedAt,\n expirationTime: serverInfo.expirationTime,\n notBefore: serverInfo.notBefore,\n requestId: serverInfo.requestId,\n resources: serverInfo.resources,\n signature: \"\", // Will be added after signing\n };\n\n return constructMessage(payload);\n}\n\n/**\n * Creates EIP-712 typed data for SIWx signing.\n *\n * @param serverInfo - Extension info from server\n * @param address - Wallet address signing the message\n * @returns EIP-712 typed data object\n */\nexport function createSIWxTypedData(\n serverInfo: SIWxExtensionInfo,\n address: string,\n): {\n domain: {\n name: string;\n version: string;\n chainId: number;\n };\n types: {\n SIWx: Array<{ name: string; type: string }>;\n };\n primaryType: \"SIWx\";\n message: Record<string, unknown>;\n} {\n // Extract chain ID number from CAIP-2 format (e.g., \"eip155:8453\" -> 8453)\n const chainIdParts = serverInfo.chainId.split(\":\");\n const chainIdNum =\n chainIdParts.length > 1 ? parseInt(chainIdParts[1], 10) : parseInt(chainIdParts[0], 10);\n\n return {\n domain: {\n name: serverInfo.domain,\n version: serverInfo.version,\n chainId: chainIdNum,\n },\n types: {\n SIWx: [\n { name: \"domain\", type: \"string\" },\n { name: \"address\", type: \"address\" },\n { name: \"statement\", type: \"string\" },\n { name: \"uri\", type: \"string\" },\n { name: \"version\", type: \"string\" },\n { name: \"chainId\", type: \"string\" },\n { name: \"nonce\", type: \"string\" },\n { name: \"issuedAt\", type: \"string\" },\n { name: \"expirationTime\", type: \"string\" },\n { name: \"resources\", type: \"string[]\" },\n ],\n },\n primaryType: \"SIWx\",\n message: {\n domain: serverInfo.domain,\n address,\n statement: serverInfo.statement || \"\",\n uri: serverInfo.uri,\n version: serverInfo.version,\n chainId: serverInfo.chainId,\n nonce: serverInfo.nonce,\n issuedAt: serverInfo.issuedAt,\n expirationTime: serverInfo.expirationTime || \"\",\n resources: serverInfo.resources || [],\n },\n };\n}\n\n/**\n * Signs a SIWx message using the provided signer.\n *\n * @param message - CAIP-122 formatted message to sign\n * @param signer - Wallet/signer interface with signMessage\n * @param options - Signing options\n * @param options.signatureScheme - Signature scheme to use\n * @param options.serverInfo - Server info for verification\n * @returns Hex-encoded signature\n *\n * @example\n * ```typescript\n * const signature = await signSIWxMessage(message, wallet, {\n * signatureScheme: 'eip191'\n * });\n * ```\n */\nexport async function signSIWxMessage(\n message: string,\n signer: SIWxSigner,\n options?: { signatureScheme?: SignatureScheme; serverInfo?: SIWxExtensionInfo },\n): Promise<string> {\n const scheme = options?.signatureScheme || \"eip191\";\n\n switch (scheme) {\n case \"eip191\":\n if (!signer.signMessage) {\n throw new Error(\"Signer does not support personal_sign (EIP-191)\");\n }\n return signer.signMessage(message);\n\n case \"eip712\":\n if (!signer.signTypedData) {\n throw new Error(\"Signer does not support signTypedData (EIP-712)\");\n }\n if (!options?.serverInfo) {\n throw new Error(\"EIP-712 signing requires serverInfo in options\");\n }\n const typedData = createSIWxTypedData(options.serverInfo, signer.address);\n return signer.signTypedData(typedData);\n\n case \"eip1271\":\n case \"eip6492\":\n // Smart wallet signatures go through the same signMessage path\n // but verification happens on-chain\n if (!signer.signMessage) {\n throw new Error(\"Signer does not support signing\");\n }\n return signer.signMessage(message);\n\n case \"siws\":\n // Sign-In With Solana uses Ed25519 signatures\n if (!signer.signMessage) {\n throw new Error(\"Signer does not support signing\");\n }\n // Solana wallets typically implement signMessage that handles the encoding\n return signer.signMessage(message);\n\n case \"sep10\":\n // Stellar SEP-10 uses Ed25519 signatures (same as Solana)\n if (!signer.signMessage) {\n throw new Error(\"Signer does not support signing\");\n }\n // Stellar wallets implement signMessage for Ed25519 signing\n // The wallet handles proper message encoding and returns hex signature\n return signer.signMessage(message);\n\n default:\n throw new Error(`Unknown signature scheme: ${scheme}`);\n }\n}\n\n/**\n * Creates a complete SIWx payload from server extension and signer.\n *\n * This is the main entry point for clients - it handles message construction,\n * signing, and payload assembly.\n *\n * @param serverExtension - Extension from server's 402 response\n * @param signer - Wallet/signer interface\n * @returns Complete signed SIWx payload ready for header encoding\n *\n * @example\n * ```typescript\n * // Get extension from server 402 response\n * const extension = paymentRequirements.extensions?.siwx;\n *\n * // Create signed payload\n * const payload = await createSIWxPayload(extension, wallet);\n *\n * // Encode and send with retry\n * const header = encodeSIWxHeader(payload);\n * fetch(url, {\n * headers: { 'X-T402-SIWx': header }\n * });\n * ```\n */\nexport async function createSIWxPayload(\n serverExtension: SIWxExtension,\n signer: SIWxSigner,\n): Promise<SIWxPayload> {\n const { info } = serverExtension;\n\n // Create the message to sign\n const message = createSIWxMessage(info, signer.address);\n\n // Sign the message\n const signature = await signSIWxMessage(message, signer, {\n signatureScheme: info.signatureScheme,\n serverInfo: info,\n });\n\n // Assemble the complete payload\n return {\n domain: info.domain,\n address: signer.address,\n statement: info.statement,\n uri: info.uri,\n version: info.version,\n chainId: info.chainId,\n nonce: info.nonce,\n issuedAt: info.issuedAt,\n expirationTime: info.expirationTime,\n notBefore: info.notBefore,\n requestId: info.requestId,\n resources: info.resources,\n signature,\n };\n}\n\n/**\n * Extension key for SIWx in payment requirements.\n */\nexport const SIWX_EXTENSION_KEY = \"siwx\";\n\n/**\n * HTTP header name for SIWx payload.\n */\nexport const SIWX_HEADER_NAME = \"X-T402-SIWx\";\n","/**\n * Payment ID Extension Type Definitions\n *\n * Allows servers to attach unique identifiers to payments for\n * correlation, idempotency, and audit trails.\n */\n\n/**\n * Extension key for payment ID in requirements/payload extensions.\n */\nexport const PAYMENT_ID_EXTENSION_KEY = \"paymentId\";\n\n/**\n * Information provided by server about the payment identifier.\n */\nexport interface PaymentIdExtensionInfo {\n /** Unique payment identifier (UUID v4) */\n id: string;\n\n /** Optional idempotency key for replay protection */\n idempotencyKey?: string;\n\n /** Optional payment group for batching */\n groupId?: string;\n\n /** Optional metadata */\n metadata?: Record<string, string>;\n}\n\n/**\n * Payment ID extension declaration for server responses.\n */\nexport interface PaymentIdExtension {\n /** Extension information */\n info: PaymentIdExtensionInfo;\n\n /** JSON Schema for validation */\n schema: object;\n}\n\n/**\n * Payment ID payload echoed back by the client.\n */\nexport interface PaymentIdPayload {\n /** Payment ID echoed back from requirements */\n id: string;\n\n /** Optional client-generated correlation ID */\n clientId?: string;\n}\n\n/**\n * Options for declaring a payment ID extension.\n */\nexport interface DeclarePaymentIdOptions {\n /** Custom payment ID (defaults to crypto.randomUUID()) */\n id?: string;\n\n /** Optional idempotency key for replay protection */\n idempotencyKey?: string;\n\n /** Optional payment group for batching */\n groupId?: string;\n\n /** Optional metadata */\n metadata?: Record<string, string>;\n}\n","/**\n * Payment ID Extension Server-Side Implementation\n *\n * Provides functions for servers to declare payment ID requirements,\n * parse client payloads, and validate payment IDs.\n */\n\nimport { randomUUID } from \"crypto\";\nimport {\n PaymentIdExtension,\n PaymentIdExtensionInfo,\n PaymentIdPayload,\n DeclarePaymentIdOptions,\n PAYMENT_ID_EXTENSION_KEY,\n} from \"./types.js\";\n\n/**\n * JSON Schema for payment ID payload validation.\n */\nconst PAYMENT_ID_SCHEMA = {\n type: \"object\",\n required: [\"id\"],\n properties: {\n id: { type: \"string\", format: \"uuid\" },\n clientId: { type: \"string\" },\n },\n};\n\n/**\n * Declares a payment ID extension for server responses.\n *\n * @param options - Optional configuration for the payment ID\n * @returns Payment ID extension object ready for response\n *\n * @example\n * ```typescript\n * const extension = declarePaymentIdExtension();\n * // Include in PaymentRequired response extensions:\n * // extensions: { [PAYMENT_ID_EXTENSION_KEY]: extension }\n * ```\n */\nexport function declarePaymentIdExtension(\n options: DeclarePaymentIdOptions = {},\n): PaymentIdExtension {\n const info: PaymentIdExtensionInfo = {\n id: options.id || randomUUID(),\n idempotencyKey: options.idempotencyKey,\n groupId: options.groupId,\n metadata: options.metadata,\n };\n\n return {\n info,\n schema: PAYMENT_ID_SCHEMA,\n };\n}\n\n/**\n * Parses a payment ID payload from client request extensions.\n *\n * @param extensions - Extensions object from the payment payload\n * @returns Parsed payment ID payload, or null if not present\n * @throws Error if payload is present but invalid\n *\n * @example\n * ```typescript\n * const payload = parsePaymentIdPayload(paymentPayload.extensions);\n * if (payload) {\n * console.log(\"Payment ID:\", payload.id);\n * }\n * ```\n */\nexport function parsePaymentIdPayload(\n extensions?: Record<string, unknown>,\n): PaymentIdPayload | null {\n if (!extensions || !(PAYMENT_ID_EXTENSION_KEY in extensions)) {\n return null;\n }\n\n const raw = extensions[PAYMENT_ID_EXTENSION_KEY];\n if (typeof raw !== \"object\" || raw === null) {\n throw new Error(\"Invalid paymentId extension: expected object\");\n }\n\n const obj = raw as Record<string, unknown>;\n\n if (typeof obj.id !== \"string\" || obj.id.length === 0) {\n throw new Error(\"Invalid paymentId extension: missing or empty id\");\n }\n\n return {\n id: obj.id,\n clientId: typeof obj.clientId === \"string\" ? obj.clientId : undefined,\n };\n}\n\n/**\n * Validates that a client's payment ID payload matches the expected extension.\n *\n * @param payload - The client's payment ID payload\n * @param expected - The expected payment ID from the server extension\n * @returns True if the payment ID matches\n *\n * @example\n * ```typescript\n * const isValid = validatePaymentId(clientPayload, serverExtension.info);\n * if (!isValid) {\n * throw new Error(\"Payment ID mismatch\");\n * }\n * ```\n */\nexport function validatePaymentId(\n payload: PaymentIdPayload,\n expected: PaymentIdExtensionInfo,\n): boolean {\n return payload.id === expected.id;\n}\n","/**\n * Payment ID Extension Client-Side Implementation\n *\n * Provides functions for clients to echo payment IDs back to servers.\n */\n\nimport { PaymentIdExtension, PaymentIdPayload } from \"./types.js\";\n\n/**\n * Creates a payment ID payload from a server extension.\n *\n * Reads the payment ID from requirements and echoes it back.\n *\n * @param extension - Payment ID extension from server's 402 response\n * @param clientId - Optional client-generated correlation ID\n * @returns Payment ID payload for inclusion in payment extensions\n *\n * @example\n * ```typescript\n * const extension = paymentRequirements.extensions?.paymentId;\n * const payload = createPaymentIdPayload(extension, \"my-correlation-id\");\n * // Include in payment payload extensions:\n * // extensions: { [PAYMENT_ID_EXTENSION_KEY]: payload }\n * ```\n */\nexport function createPaymentIdPayload(\n extension: PaymentIdExtension,\n clientId?: string,\n): PaymentIdPayload {\n return {\n id: extension.info.id,\n clientId,\n };\n}\n\n/**\n * Encodes a payment ID payload for header-based transport.\n *\n * @param payload - The payment ID payload to encode\n * @returns Base64-encoded JSON string\n */\nexport function encodePaymentIdHeader(payload: PaymentIdPayload): string {\n const json = JSON.stringify(payload);\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(json, \"utf-8\").toString(\"base64\");\n }\n return btoa(json);\n}\n","/**\n * EIP-2612 Gas Sponsoring Extension Server-Side Implementation\n *\n * Provides functions for servers to declare gas sponsoring requirements,\n * parse client headers, and validate permit payloads.\n */\n\nimport type {\n Eip2612GasSponsorExtension,\n Eip2612GasSponsorExtensionInfo,\n Eip2612GasSponsorPayload,\n DeclareEip2612GasSponsorOptions,\n ValidateEip2612GasSponsorOptions,\n Eip2612GasSponsorValidationResult,\n} from \"./types.js\";\n\n/**\n * JSON Schema for EIP-2612 gas sponsor payload validation.\n */\nconst EIP2612_GAS_SPONSOR_SCHEMA = {\n type: \"object\",\n required: [\"network\", \"permitSignature\", \"owner\", \"spender\", \"value\", \"deadline\", \"v\", \"r\", \"s\"],\n properties: {\n network: { type: \"string\" },\n permitSignature: { type: \"string\" },\n owner: { type: \"string\" },\n spender: { type: \"string\" },\n value: { type: \"string\" },\n deadline: { type: \"number\" },\n v: { type: \"number\" },\n r: { type: \"string\" },\n s: { type: \"string\" },\n },\n};\n\n/**\n * Declares an EIP-2612 gas sponsor extension for server responses.\n *\n * @param options - Extension declaration options\n * @returns Gas sponsor extension object ready for response\n *\n * @example\n * ```typescript\n * const extension = declareEip2612GasSponsorExtension({\n * sponsoredNetworks: [\"eip155:8453\", \"eip155:42161\"],\n * maxAmount: \"1000000000\",\n * sponsorAddress: \"0xFacilitator...\",\n * });\n * ```\n */\nexport function declareEip2612GasSponsorExtension(\n options: DeclareEip2612GasSponsorOptions,\n): Eip2612GasSponsorExtension {\n const info: Eip2612GasSponsorExtensionInfo = {\n sponsoredNetworks: options.sponsoredNetworks,\n maxAmount: options.maxAmount,\n permitDeadline: options.permitDeadline ?? 300,\n sponsorAddress: options.sponsorAddress,\n };\n\n return {\n info,\n schema: EIP2612_GAS_SPONSOR_SCHEMA,\n };\n}\n\n/**\n * Parses an EIP-2612 gas sponsor header from client request.\n *\n * The header format is base64-encoded JSON.\n *\n * @param header - Base64-encoded gas sponsor header value\n * @returns Parsed gas sponsor payload\n * @throws Error if header is invalid\n *\n * @example\n * ```typescript\n * const payload = parseEip2612GasSponsorHeader(\n * request.headers['x-t402-eip2612-gas-sponsoring']\n * );\n * ```\n */\nexport function parseEip2612GasSponsorHeader(header: string): Eip2612GasSponsorPayload {\n if (!header) {\n throw new Error(\"Missing EIP-2612 gas sponsor header\");\n }\n\n try {\n const decoded = Buffer.from(header, \"base64\").toString(\"utf-8\");\n const payload = JSON.parse(decoded) as Eip2612GasSponsorPayload;\n\n const required = [\n \"network\",\n \"permitSignature\",\n \"owner\",\n \"spender\",\n \"value\",\n \"deadline\",\n \"v\",\n \"r\",\n \"s\",\n ];\n for (const field of required) {\n if (!(field in payload)) {\n throw new Error(`Missing required field: ${field}`);\n }\n }\n\n return payload;\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new Error(\"Invalid EIP-2612 gas sponsor header: malformed JSON\");\n }\n throw error;\n }\n}\n\n/**\n * Validates an EIP-2612 gas sponsor payload against server extension info.\n *\n * @param payload - The gas sponsor payload from the client\n * @param extensionInfo - The server's gas sponsor extension info\n * @param options - Validation options\n * @returns Validation result\n *\n * @example\n * ```typescript\n * const result = validateEip2612GasSponsorPayload(payload, extension.info);\n * if (!result.valid) {\n * throw new Error(result.error);\n * }\n * ```\n */\nexport function validateEip2612GasSponsorPayload(\n payload: Eip2612GasSponsorPayload,\n extensionInfo: Eip2612GasSponsorExtensionInfo,\n options: ValidateEip2612GasSponsorOptions = {},\n): Eip2612GasSponsorValidationResult {\n const now = options.now ? options.now() : Date.now();\n const nowSeconds = Math.floor(now / 1000);\n\n // Validate network is in sponsoredNetworks\n if (!extensionInfo.sponsoredNetworks.includes(payload.network)) {\n return {\n valid: false,\n error: `Network ${payload.network} is not in sponsored networks: ${extensionInfo.sponsoredNetworks.join(\", \")}`,\n };\n }\n\n // Validate amount does not exceed maxAmount\n const payloadValue = BigInt(payload.value);\n const maxAmount = BigInt(extensionInfo.maxAmount);\n if (payloadValue > maxAmount) {\n return {\n valid: false,\n error: `Value ${payload.value} exceeds maximum amount ${extensionInfo.maxAmount}`,\n };\n }\n\n // Validate deadline is in the future\n if (payload.deadline <= nowSeconds) {\n return {\n valid: false,\n error: \"Permit deadline has expired\",\n };\n }\n\n // Validate deadline does not exceed permitDeadline seconds from now\n const maxDeadline = nowSeconds + extensionInfo.permitDeadline;\n if (payload.deadline > maxDeadline) {\n return {\n valid: false,\n error: `Permit deadline ${payload.deadline} exceeds maximum allowed deadline ${maxDeadline}`,\n };\n }\n\n // Validate spender matches sponsorAddress\n if (payload.spender.toLowerCase() !== extensionInfo.sponsorAddress.toLowerCase()) {\n return {\n valid: false,\n error: `Spender ${payload.spender} does not match sponsor address ${extensionInfo.sponsorAddress}`,\n };\n }\n\n // Validate permitSignature format (65 bytes = 130 hex chars)\n const sigHex = payload.permitSignature.startsWith(\"0x\")\n ? payload.permitSignature.slice(2)\n : payload.permitSignature;\n if (sigHex.length !== 130) {\n return {\n valid: false,\n error: `Invalid permit signature length: expected 130 hex chars, got ${sigHex.length}`,\n };\n }\n\n // Validate v is 27 or 28\n if (payload.v !== 27 && payload.v !== 28) {\n return {\n valid: false,\n error: `Invalid v value: expected 27 or 28, got ${payload.v}`,\n };\n }\n\n // Validate r format (32 bytes = 64 hex chars)\n const rHex = payload.r.startsWith(\"0x\") ? payload.r.slice(2) : payload.r;\n if (rHex.length !== 64) {\n return {\n valid: false,\n error: `Invalid r length: expected 64 hex chars, got ${rHex.length}`,\n };\n }\n\n // Validate s format (32 bytes = 64 hex chars)\n const sHex = payload.s.startsWith(\"0x\") ? payload.s.slice(2) : payload.s;\n if (sHex.length !== 64) {\n return {\n valid: false,\n error: `Invalid s length: expected 64 hex chars, got ${sHex.length}`,\n };\n }\n\n return { valid: true };\n}\n","/**\n * EIP-2612 Gas Sponsoring Extension Client-Side Implementation\n *\n * Provides functions for clients to create EIP-2612 permit signatures\n * and encode gas sponsor payloads for transmission.\n */\n\nimport type { Eip2612GasSponsorPayload, CreatePermitParams } from \"./types.js\";\n\n/**\n * Extension key for EIP-2612 gas sponsoring in payment requirements.\n */\nexport const EIP2612_GAS_SPONSOR_EXTENSION_KEY = \"eip2612GasSponsoring\";\n\n/**\n * HTTP header name for EIP-2612 gas sponsor payload.\n */\nexport const EIP2612_GAS_SPONSOR_HEADER_NAME = \"X-T402-EIP2612-Gas-Sponsoring\";\n\n/**\n * Creates an EIP-2612 permit signature using EIP-712 typed data signing.\n *\n * @param params - Permit signing parameters\n * @returns Permit data including the signature components\n *\n * @example\n * ```typescript\n * const permit = await createPermitSignature({\n * signer: wallet,\n * tokenAddress: \"0xUSDT...\",\n * tokenName: \"Tether USD\",\n * chainId: 8453,\n * spender: facilitatorAddress,\n * value: \"1000000\",\n * deadline: Math.floor(Date.now() / 1000) + 300,\n * });\n * ```\n */\nexport async function createPermitSignature(params: CreatePermitParams): Promise<{\n owner: string;\n spender: string;\n value: string;\n deadline: number;\n v: number;\n r: string;\n s: string;\n permitSignature: string;\n}> {\n const { signer, tokenAddress, tokenName, chainId, spender, value, deadline, nonce = 0 } = params;\n\n const domain = {\n name: tokenName,\n version: \"1\",\n chainId,\n verifyingContract: tokenAddress,\n };\n\n const types = {\n Permit: [\n { name: \"owner\", type: \"address\" },\n { name: \"spender\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"deadline\", type: \"uint256\" },\n ],\n };\n\n const message = {\n owner: signer.address,\n spender,\n value,\n nonce,\n deadline,\n };\n\n const signature = await signer.signTypedData({\n domain,\n types,\n primaryType: \"Permit\",\n message,\n });\n\n // Parse signature into components\n const sigHex = signature.startsWith(\"0x\") ? signature.slice(2) : signature;\n\n if (sigHex.length !== 130) {\n throw new Error(`Invalid signature length: expected 130 hex chars, got ${sigHex.length}`);\n }\n\n const r = \"0x\" + sigHex.slice(0, 64);\n const s = \"0x\" + sigHex.slice(64, 128);\n let v = parseInt(sigHex.slice(128, 130), 16);\n\n // Normalize v to 27 or 28\n if (v < 27) {\n v += 27;\n }\n\n return {\n owner: signer.address,\n spender,\n value,\n deadline,\n v,\n r,\n s,\n permitSignature: signature.startsWith(\"0x\") ? signature : \"0x\" + signature,\n };\n}\n\n/**\n * Creates a gas sponsor payload from permit data and network.\n *\n * @param permit - Permit signature data from createPermitSignature\n * @param network - CAIP-2 network identifier (e.g., \"eip155:8453\")\n * @returns Gas sponsor payload ready for header encoding\n *\n * @example\n * ```typescript\n * const payload = createEip2612GasSponsorPayload(permit, \"eip155:8453\");\n * ```\n */\nexport function createEip2612GasSponsorPayload(\n permit: {\n owner: string;\n spender: string;\n value: string;\n deadline: number;\n v: number;\n r: string;\n s: string;\n permitSignature: string;\n },\n network: string,\n): Eip2612GasSponsorPayload {\n return {\n network,\n permitSignature: permit.permitSignature,\n owner: permit.owner,\n spender: permit.spender,\n value: permit.value,\n deadline: permit.deadline,\n v: permit.v,\n r: permit.r,\n s: permit.s,\n };\n}\n\n/**\n * Encodes a gas sponsor payload for transmission in HTTP header.\n *\n * @param payload - The gas sponsor payload to encode\n * @returns Base64-encoded JSON string\n *\n * @example\n * ```typescript\n * const header = encodeEip2612GasSponsorHeader(payload);\n * fetch(url, {\n * headers: { [EIP2612_GAS_SPONSOR_HEADER_NAME]: header }\n * });\n * ```\n */\nexport function encodeEip2612GasSponsorHeader(payload: Eip2612GasSponsorPayload): string {\n const json = JSON.stringify(payload);\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(json, \"utf-8\").toString(\"base64\");\n }\n return btoa(json);\n}\n","/**\n * EIP-2612 Gas Sponsoring Extension Facilitator-Side Implementation\n *\n * Provides functions for facilitators to extract permit data from payment\n * extensions, validate permits, and prepare on-chain submission.\n */\n\nimport type {\n Eip2612GasSponsorPayload,\n Eip2612GasSponsorExtensionInfo,\n Eip2612GasSponsorValidationResult,\n} from \"./types.js\";\nimport { EIP2612_GAS_SPONSOR_EXTENSION_KEY } from \"./client.js\";\nimport { validateEip2612GasSponsorPayload } from \"./server.js\";\n\n/**\n * Extracts the EIP-2612 gas sponsor payload from payment extensions.\n *\n * @param extensions - The extensions map from a PaymentPayload\n * @returns The gas sponsor payload if present, or null\n *\n * @example\n * ```typescript\n * const permit = extractEip2612GasSponsorPayload(paymentPayload.extensions);\n * if (permit) {\n * // Submit permit tx then settle via Permit2\n * }\n * ```\n */\nexport function extractEip2612GasSponsorPayload(\n extensions: Record<string, unknown> | undefined,\n): Eip2612GasSponsorPayload | null {\n if (!extensions) {\n return null;\n }\n\n const raw = extensions[EIP2612_GAS_SPONSOR_EXTENSION_KEY];\n if (!raw || typeof raw !== \"object\") {\n return null;\n }\n\n const payload = raw as Record<string, unknown>;\n\n // Validate required fields are present\n const required = [\n \"network\",\n \"permitSignature\",\n \"owner\",\n \"spender\",\n \"value\",\n \"deadline\",\n \"v\",\n \"r\",\n \"s\",\n ];\n for (const field of required) {\n if (!(field in payload)) {\n return null;\n }\n }\n\n return {\n network: payload.network as string,\n permitSignature: payload.permitSignature as string,\n owner: payload.owner as string,\n spender: payload.spender as string,\n value: payload.value as string,\n deadline: payload.deadline as number,\n v: payload.v as number,\n r: payload.r as string,\n s: payload.s as string,\n };\n}\n\n/**\n * Validates and extracts the EIP-2612 gas sponsor payload in one step.\n *\n * This is a convenience function for facilitators that combines extraction\n * and validation against the server's extension info.\n *\n * @param extensions - The extensions map from a PaymentPayload\n * @param extensionInfo - The server's gas sponsor extension info\n * @returns Validation result with the extracted payload if valid\n *\n * @example\n * ```typescript\n * const result = validateAndExtractPermit(\n * paymentPayload.extensions,\n * extensionInfo\n * );\n * if (result.valid && result.payload) {\n * // Submit permit() on token contract, then settle via Permit2\n * }\n * ```\n */\nexport function validateAndExtractPermit(\n extensions: Record<string, unknown> | undefined,\n extensionInfo: Eip2612GasSponsorExtensionInfo,\n): Eip2612GasSponsorValidationResult & { payload?: Eip2612GasSponsorPayload } {\n const payload = extractEip2612GasSponsorPayload(extensions);\n\n if (!payload) {\n return {\n valid: false,\n error: `Missing or invalid ${EIP2612_GAS_SPONSOR_EXTENSION_KEY} extension in payment`,\n };\n }\n\n const result = validateEip2612GasSponsorPayload(payload, extensionInfo);\n\n if (!result.valid) {\n return result;\n }\n\n return { valid: true, payload };\n}\n\n/**\n * Builds the EIP-2612 permit function call data for on-chain submission.\n *\n * Returns the ABI-encoded parameters needed to call `permit(owner, spender, value, deadline, v, r, s)`\n * on the token contract.\n *\n * @param payload - The validated gas sponsor payload\n * @returns Object with the permit call parameters\n *\n * @example\n * ```typescript\n * const permitCall = buildPermitCallData(payload);\n * // Use permitCall with your preferred web3 library to submit the tx\n * ```\n */\nexport function buildPermitCallData(payload: Eip2612GasSponsorPayload): {\n owner: string;\n spender: string;\n value: string;\n deadline: number;\n v: number;\n r: string;\n s: string;\n} {\n return {\n owner: payload.owner,\n spender: payload.spender,\n value: payload.value,\n deadline: payload.deadline,\n v: payload.v,\n r: payload.r,\n s: payload.s,\n };\n}\n","/**\n * ERC-20 Approval Gas Sponsoring Extension Server-Side Implementation\n *\n * Provides functions for servers to declare gas sponsoring requirements,\n * parse client headers, and validate approval payloads.\n */\n\nimport type {\n ERC20ApprovalGasSponsorExtension,\n ERC20ApprovalGasSponsorExtensionInfo,\n ERC20ApprovalGasSponsorPayload,\n DeclareERC20ApprovalGasSponsorOptions,\n ValidateERC20ApprovalGasSponsorOptions,\n ERC20ApprovalGasSponsorValidationResult,\n} from \"./types.js\";\n\n/**\n * JSON Schema for ERC-20 approval gas sponsor payload validation.\n */\nconst ERC20_APPROVAL_GAS_SPONSOR_SCHEMA = {\n type: \"object\",\n required: [\"network\", \"from\", \"asset\", \"amount\", \"signedApprovalTx\", \"chainId\"],\n properties: {\n network: { type: \"string\" },\n from: { type: \"string\" },\n asset: { type: \"string\" },\n amount: { type: \"string\" },\n signedApprovalTx: { type: \"string\" },\n chainId: { type: \"number\" },\n nonce: { type: \"number\" },\n },\n};\n\n/**\n * Declares an ERC-20 approval gas sponsor extension for server responses.\n *\n * @param options - Extension declaration options\n * @returns Gas sponsor extension object ready for response\n *\n * @example\n * ```typescript\n * const extension = declareERC20ApprovalGasSponsorExtension({\n * sponsoredNetworks: [\"eip155:8453\", \"eip155:42161\"],\n * maxAmount: \"1000000000\",\n * sponsorAddress: \"0xFacilitator...\",\n * requiresAtomicBatch: true,\n * });\n * ```\n */\nexport function declareERC20ApprovalGasSponsorExtension(\n options: DeclareERC20ApprovalGasSponsorOptions,\n): ERC20ApprovalGasSponsorExtension {\n const info: ERC20ApprovalGasSponsorExtensionInfo = {\n sponsoredNetworks: options.sponsoredNetworks,\n maxAmount: options.maxAmount,\n sponsorAddress: options.sponsorAddress,\n requiresAtomicBatch: options.requiresAtomicBatch ?? false,\n };\n\n if (options.permit2Address) {\n info.permit2Address = options.permit2Address;\n }\n\n return {\n info,\n schema: ERC20_APPROVAL_GAS_SPONSOR_SCHEMA,\n };\n}\n\n/**\n * Parses an ERC-20 approval gas sponsor header from client request.\n *\n * The header format is base64-encoded JSON.\n *\n * @param header - Base64-encoded gas sponsor header value\n * @returns Parsed gas sponsor payload\n * @throws Error if header is invalid\n *\n * @example\n * ```typescript\n * const payload = parseERC20ApprovalGasSponsorHeader(\n * request.headers['x-t402-erc20-approval-gas-sponsoring']\n * );\n * ```\n */\nexport function parseERC20ApprovalGasSponsorHeader(header: string): ERC20ApprovalGasSponsorPayload {\n if (!header) {\n throw new Error(\"Missing ERC-20 approval gas sponsor header\");\n }\n\n try {\n const decoded = Buffer.from(header, \"base64\").toString(\"utf-8\");\n const payload = JSON.parse(decoded) as ERC20ApprovalGasSponsorPayload;\n\n const required = [\"network\", \"from\", \"asset\", \"amount\", \"signedApprovalTx\", \"chainId\"];\n for (const field of required) {\n if (!(field in payload)) {\n throw new Error(`Missing required field: ${field}`);\n }\n }\n\n return payload;\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new Error(\"Invalid ERC-20 approval gas sponsor header: malformed JSON\");\n }\n throw error;\n }\n}\n\n/**\n * Validates an ERC-20 approval gas sponsor payload against server extension info.\n *\n * @param payload - The gas sponsor payload from the client\n * @param extensionInfo - The server's gas sponsor extension info\n * @param options - Validation options\n * @returns Validation result\n *\n * @example\n * ```typescript\n * const result = validateERC20ApprovalGasSponsorPayload(payload, extension.info);\n * if (!result.valid) {\n * throw new Error(result.error);\n * }\n * ```\n */\nexport function validateERC20ApprovalGasSponsorPayload(\n payload: ERC20ApprovalGasSponsorPayload,\n extensionInfo: ERC20ApprovalGasSponsorExtensionInfo,\n options: ValidateERC20ApprovalGasSponsorOptions = {},\n): ERC20ApprovalGasSponsorValidationResult {\n // Validate network is in sponsoredNetworks\n if (!extensionInfo.sponsoredNetworks.includes(payload.network)) {\n return {\n valid: false,\n error: `Network ${payload.network} is not in sponsored networks: ${extensionInfo.sponsoredNetworks.join(\", \")}`,\n };\n }\n\n // Validate amount does not exceed maxAmount\n const payloadAmount = BigInt(payload.amount);\n const maxAmount = BigInt(extensionInfo.maxAmount);\n if (payloadAmount > maxAmount) {\n return {\n valid: false,\n error: `Amount ${payload.amount} exceeds maximum amount ${extensionInfo.maxAmount}`,\n };\n }\n\n // Validate chainId matches expected value for network (if provided)\n if (options.expectedChainIds) {\n const expectedChainId = options.expectedChainIds[payload.network];\n if (expectedChainId !== undefined && payload.chainId !== expectedChainId) {\n return {\n valid: false,\n error: `Chain ID ${payload.chainId} does not match expected chain ID ${expectedChainId} for network ${payload.network}`,\n };\n }\n }\n\n // Validate signedApprovalTx is hex-encoded\n const txHex = payload.signedApprovalTx.startsWith(\"0x\")\n ? payload.signedApprovalTx.slice(2)\n : payload.signedApprovalTx;\n if (txHex.length === 0) {\n return {\n valid: false,\n error: \"Signed approval transaction is empty\",\n };\n }\n if (!/^[0-9a-fA-F]+$/.test(txHex)) {\n return {\n valid: false,\n error: \"Signed approval transaction is not valid hex\",\n };\n }\n\n // Validate from address format\n const fromHex = payload.from.startsWith(\"0x\") ? payload.from.slice(2) : payload.from;\n if (fromHex.length !== 40 || !/^[0-9a-fA-F]+$/.test(fromHex)) {\n return {\n valid: false,\n error: `Invalid from address: ${payload.from}`,\n };\n }\n\n // Validate asset address format\n const assetHex = payload.asset.startsWith(\"0x\") ? payload.asset.slice(2) : payload.asset;\n if (assetHex.length !== 40 || !/^[0-9a-fA-F]+$/.test(assetHex)) {\n return {\n valid: false,\n error: `Invalid asset address: ${payload.asset}`,\n };\n }\n\n return { valid: true };\n}\n","/**\n * ERC-20 Approval Gas Sponsoring Extension Client-Side Implementation\n *\n * Provides functions for clients to construct ERC-20 approve() calldata\n * and encode gas sponsor payloads for transmission.\n */\n\nimport type {\n ERC20ApprovalGasSponsorPayload,\n ERC20ApprovalGasSponsorExtensionInfo,\n CreateERC20ApprovalParams,\n} from \"./types.js\";\n\n/**\n * Extension key for ERC-20 approval gas sponsoring in payment requirements.\n */\nexport const ERC20_APPROVAL_GAS_SPONSOR_EXTENSION_KEY = \"erc20ApprovalGasSponsoring\";\n\n/**\n * HTTP header name for ERC-20 approval gas sponsor payload.\n */\nexport const ERC20_APPROVAL_GAS_SPONSOR_HEADER_NAME = \"X-T402-ERC20-Approval-Gas-Sponsoring\";\n\n/**\n * ERC-20 approve(address,uint256) function selector.\n */\nexport const APPROVE_FUNCTION_SELECTOR = \"0x095ea7b3\";\n\n/**\n * Encodes ERC-20 approve(address spender, uint256 amount) calldata.\n *\n * @param spender - The spender address to approve\n * @param amount - The approval amount in base units\n * @returns Hex-encoded calldata with 0x prefix\n *\n * @example\n * ```typescript\n * const calldata = encodeApproveCalldata(\"0xFacilitator...\", \"1000000\");\n * // Returns \"0x095ea7b3\" + abi-encoded args\n * ```\n */\nexport function encodeApproveCalldata(spender: string, amount: string): string {\n // Remove 0x prefix from spender address\n const spenderHex = spender.startsWith(\"0x\") ? spender.slice(2) : spender;\n\n // Pad spender address to 32 bytes (left-padded with zeros)\n const paddedSpender = spenderHex.toLowerCase().padStart(64, \"0\");\n\n // Convert amount to hex and pad to 32 bytes (left-padded with zeros)\n const amountBigInt = BigInt(amount);\n const amountHex = amountBigInt.toString(16).padStart(64, \"0\");\n\n return APPROVE_FUNCTION_SELECTOR + paddedSpender + amountHex;\n}\n\n/**\n * Creates an ERC-20 approval gas sponsor payload from params and extension info.\n *\n * @param info - The server's extension info\n * @param params - The approval parameters\n * @returns Gas sponsor payload ready for header encoding\n *\n * @example\n * ```typescript\n * const payload = createERC20ApprovalGasSponsorPayload(extensionInfo, {\n * network: \"eip155:8453\",\n * from: wallet.address,\n * asset: \"0xUSDT...\",\n * amount: \"1000000\",\n * signedApprovalTx: signedTx,\n * chainId: 8453,\n * });\n * ```\n */\nexport function createERC20ApprovalGasSponsorPayload(\n _info: ERC20ApprovalGasSponsorExtensionInfo,\n params: CreateERC20ApprovalParams,\n): ERC20ApprovalGasSponsorPayload {\n const payload: ERC20ApprovalGasSponsorPayload = {\n network: params.network,\n from: params.from,\n asset: params.asset,\n amount: params.amount,\n signedApprovalTx: params.signedApprovalTx.startsWith(\"0x\")\n ? params.signedApprovalTx\n : \"0x\" + params.signedApprovalTx,\n chainId: params.chainId,\n };\n\n if (params.nonce !== undefined) {\n payload.nonce = params.nonce;\n }\n\n return payload;\n}\n\n/**\n * Encodes an ERC-20 approval gas sponsor payload for transmission in HTTP header.\n *\n * @param payload - The gas sponsor payload to encode\n * @returns Base64-encoded JSON string\n *\n * @example\n * ```typescript\n * const header = encodeERC20ApprovalGasSponsorHeader(payload);\n * fetch(url, {\n * headers: { [ERC20_APPROVAL_GAS_SPONSOR_HEADER_NAME]: header }\n * });\n * ```\n */\nexport function encodeERC20ApprovalGasSponsorHeader(\n payload: ERC20ApprovalGasSponsorPayload,\n): string {\n const json = JSON.stringify(payload);\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(json, \"utf-8\").toString(\"base64\");\n }\n return btoa(json);\n}\n","/**\n * ERC-20 Approval Gas Sponsoring Extension Facilitator-Side Implementation\n *\n * Provides functions for facilitators to extract approval data from payment\n * extensions, validate the signed approve() transaction, and prepare for\n * on-chain submission.\n */\n\nimport type {\n ERC20ApprovalGasSponsorPayload,\n ERC20ApprovalGasSponsorExtensionInfo,\n ERC20ApprovalGasSponsorValidationResult,\n} from \"./types.js\";\nimport { ERC20_APPROVAL_GAS_SPONSOR_EXTENSION_KEY, APPROVE_FUNCTION_SELECTOR } from \"./client.js\";\nimport { validateERC20ApprovalGasSponsorPayload } from \"./server.js\";\n\n/**\n * Extracts the ERC-20 approval gas sponsor payload from payment extensions.\n *\n * @param extensions - The extensions map from a PaymentPayload\n * @returns The gas sponsor payload if present, or null\n *\n * @example\n * ```typescript\n * const approval = extractERC20ApprovalGasSponsorPayload(paymentPayload.extensions);\n * if (approval) {\n * // Validate and broadcast the approval tx, then settle\n * }\n * ```\n */\nexport function extractERC20ApprovalGasSponsorPayload(\n extensions: Record<string, unknown> | undefined,\n): ERC20ApprovalGasSponsorPayload | null {\n if (!extensions) {\n return null;\n }\n\n const raw = extensions[ERC20_APPROVAL_GAS_SPONSOR_EXTENSION_KEY];\n if (!raw || typeof raw !== \"object\") {\n return null;\n }\n\n const payload = raw as Record<string, unknown>;\n\n // Validate required fields are present\n const required = [\"network\", \"from\", \"asset\", \"amount\", \"signedApprovalTx\", \"chainId\"];\n for (const field of required) {\n if (!(field in payload)) {\n return null;\n }\n }\n\n const result: ERC20ApprovalGasSponsorPayload = {\n network: payload.network as string,\n from: payload.from as string,\n asset: payload.asset as string,\n amount: payload.amount as string,\n signedApprovalTx: payload.signedApprovalTx as string,\n chainId: payload.chainId as number,\n };\n\n if (\"nonce\" in payload && payload.nonce !== undefined) {\n result.nonce = payload.nonce as number;\n }\n\n return result;\n}\n\n/**\n * Processes and validates an ERC-20 approval payload for the facilitator.\n *\n * Combines extraction validation with approve() function selector verification.\n * Checks that the signed transaction data contains the correct approve() selector\n * and that the approval amount matches the declared amount.\n *\n * @param payload - The ERC-20 approval gas sponsor payload\n * @param extensionInfo - The server's gas sponsor extension info\n * @returns Validation result\n *\n * @example\n * ```typescript\n * const result = processERC20ApprovalPayload(payload, extensionInfo);\n * if (result.valid) {\n * // Safe to broadcast the approval tx and settle\n * }\n * ```\n */\nexport function processERC20ApprovalPayload(\n payload: ERC20ApprovalGasSponsorPayload,\n extensionInfo: ERC20ApprovalGasSponsorExtensionInfo,\n): ERC20ApprovalGasSponsorValidationResult {\n // Run standard validation\n const validationResult = validateERC20ApprovalGasSponsorPayload(payload, extensionInfo);\n if (!validationResult.valid) {\n return validationResult;\n }\n\n // Verify the signed tx is not empty\n const txHex = payload.signedApprovalTx.startsWith(\"0x\")\n ? payload.signedApprovalTx.slice(2)\n : payload.signedApprovalTx;\n\n if (txHex.length < 8) {\n return {\n valid: false,\n error: \"Signed approval transaction is too short to contain function selector\",\n };\n }\n\n return { valid: true };\n}\n\n/**\n * Validates and extracts the ERC-20 approval gas sponsor payload in one step.\n *\n * This is a convenience function for facilitators that combines extraction\n * and validation against the server's extension info.\n *\n * @param extensions - The extensions map from a PaymentPayload\n * @param extensionInfo - The server's gas sponsor extension info\n * @returns Validation result with the extracted payload if valid\n *\n * @example\n * ```typescript\n * const result = validateAndExtractApproval(\n * paymentPayload.extensions,\n * extensionInfo\n * );\n * if (result.valid && result.payload) {\n * // Broadcast approval tx, then settle\n * }\n * ```\n */\nexport function validateAndExtractApproval(\n extensions: Record<string, unknown> | undefined,\n extensionInfo: ERC20ApprovalGasSponsorExtensionInfo,\n): ERC20ApprovalGasSponsorValidationResult & { payload?: ERC20ApprovalGasSponsorPayload } {\n const payload = extractERC20ApprovalGasSponsorPayload(extensions);\n\n if (!payload) {\n return {\n valid: false,\n error: `Missing or invalid ${ERC20_APPROVAL_GAS_SPONSOR_EXTENSION_KEY} extension in payment`,\n };\n }\n\n const result = processERC20ApprovalPayload(payload, extensionInfo);\n\n if (!result.valid) {\n return result;\n }\n\n return { valid: true, payload };\n}\n\n/**\n * Decodes the approve() calldata from a hex string to extract spender and amount.\n *\n * @param calldata - Hex-encoded approve() calldata (with or without 0x prefix)\n * @returns Decoded spender and amount, or null if not valid approve() calldata\n *\n * @example\n * ```typescript\n * const decoded = decodeApproveCalldata(\"0x095ea7b3...\");\n * if (decoded) {\n * console.log(decoded.spender, decoded.amount);\n * }\n * ```\n */\nexport function decodeApproveCalldata(\n calldata: string,\n): { spender: string; amount: string } | null {\n const hex = calldata.startsWith(\"0x\") ? calldata.slice(2) : calldata;\n\n // approve(address,uint256) = 4 byte selector + 32 byte address + 32 byte amount = 136 hex chars\n if (hex.length < 136) {\n return null;\n }\n\n const selector = \"0x\" + hex.slice(0, 8);\n if (selector !== APPROVE_FUNCTION_SELECTOR) {\n return null;\n }\n\n // Extract spender address (bytes 4-36, last 20 bytes of the 32-byte word)\n const spenderWord = hex.slice(8, 72);\n const spender = \"0x\" + spenderWord.slice(24);\n\n // Extract amount (bytes 36-68)\n const amountHex = hex.slice(72, 136);\n const amount = BigInt(\"0x\" + amountHex).toString(10);\n\n return { spender, amount };\n}\n"],"mappings":"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","names":["isBodyMethod","Ajv","nobleSha256","messageHash","import_crypto"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts","../../src/bazaar/types.ts","../../src/bazaar/resourceService.ts","../../src/bazaar/server.ts","../../src/bazaar/facilitator.ts","../../src/bazaar/v1/facilitator.ts","../../src/bazaar/facilitatorClient.ts","../../src/sign-in-with-x/server.ts","../../src/sign-in-with-x/client.ts","../../src/payment-id/types.ts","../../src/payment-id/server.ts","../../src/payment-id/client.ts","../../src/eip2612-gas-sponsoring/server.ts","../../src/eip2612-gas-sponsoring/client.ts","../../src/eip2612-gas-sponsoring/facilitator.ts","../../src/erc20-approval-gas-sponsoring/server.ts","../../src/erc20-approval-gas-sponsoring/client.ts","../../src/erc20-approval-gas-sponsoring/facilitator.ts"],"sourcesContent":["// Shared extension utilities\nexport type { WithExtensions } from \"./types\";\n\n// Bazaar extension\nexport * from \"./bazaar\";\nexport { bazaarResourceServerExtension } from \"./bazaar/server\";\n\n// Sign-in-with-x extension\nexport * from \"./sign-in-with-x\";\n\n// Payment ID extension\nexport * from \"./payment-id\";\n\n// EIP-2612 gas sponsoring extension\nexport * from \"./eip2612-gas-sponsoring\";\n\n// ERC-20 approval gas sponsoring extension\nexport * from \"./erc20-approval-gas-sponsoring\";\n","/**\n * Type definitions for the Bazaar Discovery Extension\n */\n\nimport type { BodyMethods, QueryParamMethods } from \"@t402/core/http\";\n\n/**\n * Extension identifier constant for the Bazaar discovery extension\n */\nexport const BAZAAR = \"bazaar\";\n\n/**\n * Discovery info for query parameter methods (GET, HEAD, DELETE)\n */\nexport interface QueryDiscoveryInfo {\n input: {\n type: \"http\";\n method: QueryParamMethods;\n queryParams?: Record<string, unknown>;\n headers?: Record<string, string>;\n };\n output?: {\n type?: string;\n format?: string;\n example?: unknown;\n };\n}\n\n/**\n * Discovery info for body methods (POST, PUT, PATCH)\n */\nexport interface BodyDiscoveryInfo {\n input: {\n type: \"http\";\n method: BodyMethods;\n bodyType: \"json\" | \"form-data\" | \"text\";\n body: Record<string, unknown>;\n queryParams?: Record<string, unknown>;\n headers?: Record<string, string>;\n };\n output?: {\n type?: string;\n format?: string;\n example?: unknown;\n };\n}\n\n/**\n * Combined discovery info type\n */\nexport type DiscoveryInfo = QueryDiscoveryInfo | BodyDiscoveryInfo;\n\n/**\n * Discovery extension for query parameter methods (GET, HEAD, DELETE)\n */\nexport interface QueryDiscoveryExtension {\n info: QueryDiscoveryInfo;\n\n schema: {\n $schema: \"https://json-schema.org/draft/2020-12/schema\";\n type: \"object\";\n properties: {\n input: {\n type: \"object\";\n properties: {\n type: {\n type: \"string\";\n const: \"http\";\n };\n method: {\n type: \"string\";\n enum: QueryParamMethods[];\n };\n queryParams?: {\n type: \"object\";\n properties?: Record<string, unknown>;\n required?: string[];\n additionalProperties?: boolean;\n };\n headers?: {\n type: \"object\";\n additionalProperties: {\n type: \"string\";\n };\n };\n };\n required: (\"type\" | \"method\")[];\n additionalProperties?: boolean;\n };\n output?: {\n type: \"object\";\n properties?: Record<string, unknown>;\n required?: readonly string[];\n additionalProperties?: boolean;\n };\n };\n required: [\"input\"];\n };\n}\n\n/**\n * Discovery extension for body methods (POST, PUT, PATCH)\n */\nexport interface BodyDiscoveryExtension {\n info: BodyDiscoveryInfo;\n\n schema: {\n $schema: \"https://json-schema.org/draft/2020-12/schema\";\n type: \"object\";\n properties: {\n input: {\n type: \"object\";\n properties: {\n type: {\n type: \"string\";\n const: \"http\";\n };\n method: {\n type: \"string\";\n enum: BodyMethods[];\n };\n bodyType: {\n type: \"string\";\n enum: [\"json\", \"form-data\", \"text\"];\n };\n body: Record<string, unknown>;\n queryParams?: {\n type: \"object\";\n properties?: Record<string, unknown>;\n required?: string[];\n additionalProperties?: boolean;\n };\n headers?: {\n type: \"object\";\n additionalProperties: {\n type: \"string\";\n };\n };\n };\n required: (\"type\" | \"method\" | \"bodyType\" | \"body\")[];\n additionalProperties?: boolean;\n };\n output?: {\n type: \"object\";\n properties?: Record<string, unknown>;\n required?: readonly string[];\n additionalProperties?: boolean;\n };\n };\n required: [\"input\"];\n };\n}\n\n/**\n * Combined discovery extension type\n */\nexport type DiscoveryExtension = QueryDiscoveryExtension | BodyDiscoveryExtension;\n\nexport interface DeclareQueryDiscoveryExtensionConfig {\n method?: QueryParamMethods;\n input?: Record<string, unknown>;\n inputSchema?: Record<string, unknown>;\n output?: {\n example?: unknown;\n schema?: Record<string, unknown>;\n };\n}\n\nexport interface DeclareBodyDiscoveryExtensionConfig {\n method?: BodyMethods;\n input?: Record<string, unknown>;\n inputSchema?: Record<string, unknown>;\n bodyType?: \"json\" | \"form-data\" | \"text\";\n output?: {\n example?: unknown;\n schema?: Record<string, unknown>;\n };\n}\n\nexport type DeclareDiscoveryExtensionConfig =\n | DeclareQueryDiscoveryExtensionConfig\n | DeclareBodyDiscoveryExtensionConfig;\n\nexport const isQueryExtensionConfig = (\n config: DeclareDiscoveryExtensionConfig,\n): config is DeclareQueryDiscoveryExtensionConfig => {\n return !(\"bodyType\" in config);\n};\n\nexport const isBodyExtensionConfig = (\n config: DeclareDiscoveryExtensionConfig,\n): config is DeclareBodyDiscoveryExtensionConfig => {\n return \"bodyType\" in config;\n};\n","/**\n * Resource Service functions for creating Bazaar discovery extensions\n *\n * These functions help servers declare the shape of their endpoints\n * for facilitator discovery and cataloging in the Bazaar.\n */\n\nimport {\n type DiscoveryExtension,\n type QueryDiscoveryExtension,\n type BodyDiscoveryExtension,\n type DeclareDiscoveryExtensionConfig,\n type DeclareQueryDiscoveryExtensionConfig,\n type DeclareBodyDiscoveryExtensionConfig,\n} from \"./types\";\n\n/**\n * Internal helper to create a query discovery extension\n *\n * @param root0 - Configuration object for query discovery extension\n * @param root0.method - HTTP method (GET, HEAD, DELETE)\n * @param root0.input - Query parameters\n * @param root0.inputSchema - JSON schema for query parameters\n * @param root0.output - Output specification with example\n * @returns QueryDiscoveryExtension with info and schema\n */\nfunction createQueryDiscoveryExtension({\n method,\n input = {},\n inputSchema = { properties: {} },\n output,\n}: DeclareQueryDiscoveryExtensionConfig): QueryDiscoveryExtension {\n return {\n info: {\n input: {\n type: \"http\",\n ...(method ? { method } : {}),\n ...(input ? { queryParams: input } : {}),\n } as QueryDiscoveryExtension[\"info\"][\"input\"],\n ...(output?.example\n ? {\n output: {\n type: \"json\",\n example: output.example,\n },\n }\n : {}),\n },\n schema: {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n properties: {\n input: {\n type: \"object\",\n properties: {\n type: {\n type: \"string\",\n const: \"http\",\n },\n method: {\n type: \"string\",\n enum: [\"GET\", \"HEAD\", \"DELETE\"],\n },\n ...(inputSchema\n ? {\n queryParams: {\n type: \"object\" as const,\n ...(typeof inputSchema === \"object\" ? inputSchema : {}),\n },\n }\n : {}),\n },\n required: [\"type\"] as (\"type\" | \"method\")[],\n additionalProperties: false,\n },\n ...(output?.example\n ? {\n output: {\n type: \"object\" as const,\n properties: {\n type: {\n type: \"string\" as const,\n },\n example: {\n type: \"object\" as const,\n ...(output.schema && typeof output.schema === \"object\" ? output.schema : {}),\n },\n },\n required: [\"type\"] as const,\n },\n }\n : {}),\n },\n required: [\"input\"],\n },\n };\n}\n\n/**\n * Internal helper to create a body discovery extension\n *\n * @param root0 - Configuration object for body discovery extension\n * @param root0.method - HTTP method (POST, PUT, PATCH)\n * @param root0.input - Request body specification\n * @param root0.inputSchema - JSON schema for request body\n * @param root0.bodyType - Content type of body (json, form, multipart)\n * @param root0.output - Output specification with example\n * @returns BodyDiscoveryExtension with info and schema\n */\nfunction createBodyDiscoveryExtension({\n method,\n input = {},\n inputSchema = { properties: {} },\n bodyType = \"json\",\n output,\n}: DeclareBodyDiscoveryExtensionConfig): BodyDiscoveryExtension {\n return {\n info: {\n input: {\n type: \"http\",\n ...(method ? { method } : {}),\n bodyType,\n body: input,\n } as BodyDiscoveryExtension[\"info\"][\"input\"],\n ...(output?.example\n ? {\n output: {\n type: \"json\",\n example: output.example,\n },\n }\n : {}),\n },\n schema: {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n properties: {\n input: {\n type: \"object\",\n properties: {\n type: {\n type: \"string\",\n const: \"http\",\n },\n method: {\n type: \"string\",\n enum: [\"POST\", \"PUT\", \"PATCH\"],\n },\n bodyType: {\n type: \"string\",\n enum: [\"json\", \"form-data\", \"text\"],\n },\n body: inputSchema,\n },\n required: [\"type\", \"bodyType\", \"body\"] as (\"type\" | \"method\" | \"bodyType\" | \"body\")[],\n additionalProperties: false,\n },\n ...(output?.example\n ? {\n output: {\n type: \"object\" as const,\n properties: {\n type: {\n type: \"string\" as const,\n },\n example: {\n type: \"object\" as const,\n ...(output.schema && typeof output.schema === \"object\" ? output.schema : {}),\n },\n },\n required: [\"type\"] as const,\n },\n }\n : {}),\n },\n required: [\"input\"],\n },\n };\n}\n\n/**\n * Create a discovery extension for any HTTP method\n *\n * This function helps servers declare how their endpoint should be called,\n * including the expected input parameters/body and output format.\n *\n * @param config - Configuration object for the discovery extension\n * @returns A discovery extension object with both info and schema\n *\n * @example\n * ```typescript\n * // For a GET endpoint with no input\n * const getExtension = declareDiscoveryExtension({\n * method: \"GET\",\n * output: {\n * example: { message: \"Success\", timestamp: \"2024-01-01T00:00:00Z\" }\n * }\n * });\n *\n * // For a GET endpoint with query params\n * const getWithParams = declareDiscoveryExtension({\n * method: \"GET\",\n * input: { query: \"example\" },\n * inputSchema: {\n * properties: {\n * query: { type: \"string\" }\n * },\n * required: [\"query\"]\n * }\n * });\n *\n * // For a POST endpoint with JSON body\n * const postExtension = declareDiscoveryExtension({\n * method: \"POST\",\n * input: { name: \"John\", age: 30 },\n * inputSchema: {\n * properties: {\n * name: { type: \"string\" },\n * age: { type: \"number\" }\n * },\n * required: [\"name\"]\n * },\n * bodyType: \"json\",\n * output: {\n * example: { success: true, id: \"123\" }\n * }\n * });\n * ```\n */\nexport function declareDiscoveryExtension(\n config: Omit<DeclareDiscoveryExtensionConfig, \"method\">,\n): Record<string, DiscoveryExtension> {\n const bodyType = (config as DeclareBodyDiscoveryExtensionConfig).bodyType;\n const isBodyMethod = bodyType !== undefined;\n\n const extension = isBodyMethod\n ? createBodyDiscoveryExtension(config as DeclareBodyDiscoveryExtensionConfig)\n : createQueryDiscoveryExtension(config as DeclareQueryDiscoveryExtensionConfig);\n\n return { bazaar: extension as DiscoveryExtension };\n}\n","import type { ResourceServerExtension } from \"@t402/core/types\";\nimport type { HTTPRequestContext } from \"@t402/core/http\";\nimport { BAZAAR } from \"./types\";\n\n/**\n * Type guard to check if context is an HTTP request context.\n *\n * @param ctx - The context to check\n * @returns True if context is an HTTPRequestContext\n */\nfunction isHTTPRequestContext(ctx: unknown): ctx is HTTPRequestContext {\n return ctx !== null && typeof ctx === \"object\" && \"method\" in ctx && \"adapter\" in ctx;\n}\n\ninterface ExtensionDeclaration {\n [key: string]: unknown;\n info?: {\n [key: string]: unknown;\n input?: Record<string, unknown>;\n };\n schema?: {\n [key: string]: unknown;\n properties?: {\n [key: string]: unknown;\n input?: {\n [key: string]: unknown;\n required?: string[];\n };\n };\n };\n}\n\nexport const bazaarResourceServerExtension: ResourceServerExtension = {\n key: BAZAAR,\n\n enrichDeclaration: (declaration, transportContext) => {\n if (!isHTTPRequestContext(transportContext)) {\n return declaration;\n }\n\n const extension = declaration as ExtensionDeclaration;\n const method = transportContext.method;\n\n return {\n ...extension,\n info: {\n ...(extension.info || {}),\n input: {\n ...(extension.info?.input || {}),\n method,\n },\n },\n schema: {\n ...(extension.schema || {}),\n properties: {\n ...(extension.schema?.properties || {}),\n input: {\n ...(extension.schema?.properties?.input || {}),\n required: [\n ...(extension.schema?.properties?.input?.required || []),\n ...(!(extension.schema?.properties?.input?.required || []).includes(\"method\")\n ? [\"method\"]\n : []),\n ],\n },\n },\n },\n };\n },\n};\n","/**\n * Facilitator functions for validating and extracting Bazaar discovery extensions\n *\n * These functions help facilitators validate extension data against schemas\n * and extract the discovery information for cataloging in the Bazaar.\n *\n * Supports both v2 (extensions in PaymentRequired) and v1 (outputSchema in PaymentRequirements).\n */\n\nimport Ajv from \"ajv/dist/2020\";\nimport type { PaymentPayload, PaymentRequirements, PaymentRequirementsV1 } from \"@t402/core/types\";\nimport type { DiscoveryExtension, DiscoveryInfo } from \"./types\";\nimport { BAZAAR } from \"./types\";\nimport { extractDiscoveryInfoV1 } from \"./v1/facilitator\";\n\n/**\n * Validation result for discovery extensions\n */\nexport interface ValidationResult {\n valid: boolean;\n errors?: string[];\n}\n\n/**\n * Validates a discovery extension's info against its schema\n *\n * @param extension - The discovery extension containing info and schema\n * @returns Validation result indicating if the info matches the schema\n *\n * @example\n * ```typescript\n * const extension = declareDiscoveryExtension(...);\n * const result = validateDiscoveryExtension(extension);\n *\n * if (result.valid) {\n * console.log(\"Extension is valid\");\n * } else {\n * console.error(\"Validation errors:\", result.errors);\n * }\n * ```\n */\nexport function validateDiscoveryExtension(extension: DiscoveryExtension): ValidationResult {\n try {\n const ajv = new Ajv({ strict: false, allErrors: true });\n const validate = ajv.compile(extension.schema);\n\n // The schema describes the structure of info directly\n // Schema has properties: { input: {...}, output: {...} }\n // So we validate extension.info which has { input: {...}, output: {...} }\n const valid = validate(extension.info);\n\n if (valid) {\n return { valid: true };\n }\n\n const errors = validate.errors?.map(err => {\n const path = err.instancePath || \"(root)\";\n return `${path}: ${err.message}`;\n }) || [\"Unknown validation error\"];\n\n return { valid: false, errors };\n } catch (error) {\n return {\n valid: false,\n errors: [\n `Schema validation failed: ${error instanceof Error ? error.message : String(error)}`,\n ],\n };\n }\n}\n\n/**\n * Extracts the discovery info from payment payload and requirements\n *\n * This function handles both v2 (extensions) and v1 (outputSchema) formats.\n *\n * For v2: Discovery info is in PaymentPayload.extensions (client copied it from PaymentRequired)\n * For v1: Discovery info is in PaymentRequirements.outputSchema\n *\n * V1 data is automatically transformed to v2 DiscoveryInfo format, making smart\n * assumptions about field names (queryParams/query/params for GET, bodyFields/body/data for POST, etc.)\n *\n * @param paymentPayload - The payment payload containing extensions (v2) and version info\n * @param paymentRequirements - The payment requirements (contains outputSchema for v1)\n * @param validate - Whether to validate v2 extensions before extracting (default: true)\n * @returns The discovery info in v2 format if present, or null if not discoverable\n *\n * @example\n * ```typescript\n * // V2 - extensions are in PaymentPayload\n * const info = extractDiscoveryInfo(paymentPayload, paymentRequirements);\n *\n * // V1 - discovery info is in PaymentRequirements.outputSchema\n * const info = extractDiscoveryInfo(paymentPayloadV1, paymentRequirementsV1);\n *\n * if (info) {\n * // Both v1 and v2 return the same DiscoveryInfo structure\n * console.log(\"Method:\", info.input.method);\n * }\n * ```\n */\nexport interface DiscoveredResource {\n resourceUrl: string;\n method: string;\n t402Version: number;\n discoveryInfo: DiscoveryInfo;\n}\n\n/**\n * Extracts discovery information from payment payload and requirements.\n * Combines resource URL, HTTP method, version, and discovery info into a single object.\n *\n * @param paymentPayload - The payment payload containing extensions and resource info\n * @param paymentRequirements - The payment requirements to validate against\n * @param validate - Whether to validate the discovery info against the schema (default: true)\n * @returns Discovered resource info with URL, method, version and discovery data, or null if not found\n */\nexport function extractDiscoveryInfo(\n paymentPayload: PaymentPayload,\n paymentRequirements: PaymentRequirements | PaymentRequirementsV1,\n validate: boolean = true,\n): DiscoveredResource | null {\n let discoveryInfo: DiscoveryInfo | null = null;\n let resourceUrl: string;\n\n if (paymentPayload.t402Version === 2) {\n resourceUrl = paymentPayload.resource?.url ?? \"\";\n\n if (paymentPayload.extensions) {\n const bazaarExtension = paymentPayload.extensions[BAZAAR];\n\n if (bazaarExtension && typeof bazaarExtension === \"object\") {\n try {\n const extension = bazaarExtension as DiscoveryExtension;\n\n if (validate) {\n const result = validateDiscoveryExtension(extension);\n if (!result.valid) {\n console.warn(\n `V2 discovery extension validation failed: ${result.errors?.join(\", \")}`,\n );\n } else {\n discoveryInfo = extension.info;\n }\n } else {\n discoveryInfo = extension.info;\n }\n } catch (error) {\n console.warn(`V2 discovery extension extraction failed: ${error}`);\n }\n }\n }\n } else if (paymentPayload.t402Version === 1) {\n const requirementsV1 = paymentRequirements as PaymentRequirementsV1;\n resourceUrl = requirementsV1.resource;\n discoveryInfo = extractDiscoveryInfoV1(requirementsV1);\n } else {\n return null;\n }\n\n if (!discoveryInfo) {\n return null;\n }\n\n return {\n resourceUrl,\n method: discoveryInfo.input.method,\n t402Version: paymentPayload.t402Version,\n discoveryInfo,\n };\n}\n\n/**\n * Extracts discovery info from a v2 extension directly\n *\n * This is a lower-level function for when you already have the extension object.\n * For general use, prefer the main extractDiscoveryInfo function.\n *\n * @param extension - The discovery extension to extract info from\n * @param validate - Whether to validate before extracting (default: true)\n * @returns The discovery info if valid\n * @throws Error if validation fails and validate is true\n */\nexport function extractDiscoveryInfoFromExtension(\n extension: DiscoveryExtension,\n validate: boolean = true,\n): DiscoveryInfo {\n if (validate) {\n const result = validateDiscoveryExtension(extension);\n if (!result.valid) {\n throw new Error(\n `Invalid discovery extension: ${result.errors?.join(\", \") || \"Unknown error\"}`,\n );\n }\n }\n\n return extension.info;\n}\n\n/**\n * Validates and extracts discovery info in one step\n *\n * This is a convenience function that combines validation and extraction,\n * returning both the validation result and the info if valid.\n *\n * @param extension - The discovery extension to validate and extract\n * @returns Object containing validation result and info (if valid)\n *\n * @example\n * ```typescript\n * const extension = declareDiscoveryExtension(...);\n * const { valid, info, errors } = validateAndExtract(extension);\n *\n * if (valid && info) {\n * // Store info in Bazaar catalog\n * } else {\n * console.error(\"Validation errors:\", errors);\n * }\n * ```\n */\nexport function validateAndExtract(extension: DiscoveryExtension): {\n valid: boolean;\n info?: DiscoveryInfo;\n errors?: string[];\n} {\n const result = validateDiscoveryExtension(extension);\n\n if (result.valid) {\n return {\n valid: true,\n info: extension.info,\n };\n }\n\n return {\n valid: false,\n errors: result.errors,\n };\n}\n","/**\n * V1 Facilitator functions for extracting Bazaar discovery information\n *\n * In v1, discovery information is stored in the `outputSchema` field\n * of PaymentRequirements, which has a different structure than v2.\n *\n * This module transforms v1 data into v2 DiscoveryInfo format.\n */\n\nimport type { PaymentRequirementsV1 } from \"@t402/core/types\";\nimport type { BodyMethods, QueryParamMethods } from \"@t402/core/http\";\nimport type { DiscoveryInfo, QueryDiscoveryInfo, BodyDiscoveryInfo } from \"../types\";\n\n/**\n * Type guard to check if an object has the v1 outputSchema structure\n *\n * @param obj - The object to check\n * @returns True if object has v1 outputSchema structure\n */\nfunction hasV1OutputSchema(\n obj: unknown,\n): obj is { input: Record<string, unknown>; output?: Record<string, unknown> } {\n return (\n obj !== null &&\n typeof obj === \"object\" &&\n \"input\" in obj &&\n obj.input !== null &&\n typeof obj.input === \"object\" &&\n \"type\" in obj.input &&\n obj.input.type === \"http\" &&\n \"method\" in obj.input\n );\n}\n\n/**\n * Checks if a method is a query parameter method\n *\n * @param method - HTTP method string to check\n * @returns True if method is GET, HEAD, or DELETE\n */\nfunction isQueryMethod(method: string): method is QueryParamMethods {\n const upperMethod = method.toUpperCase();\n return upperMethod === \"GET\" || upperMethod === \"HEAD\" || upperMethod === \"DELETE\";\n}\n\n/**\n * Checks if a method is a body method\n *\n * @param method - HTTP method string to check\n * @returns True if method is POST, PUT, or PATCH\n */\nfunction isBodyMethod(method: string): method is BodyMethods {\n const upperMethod = method.toUpperCase();\n return upperMethod === \"POST\" || upperMethod === \"PUT\" || upperMethod === \"PATCH\";\n}\n\n/**\n * Extracts query parameters from v1 input, making smart assumptions\n * about common field names used in v1\n *\n * @param v1Input - V1 input object from payment requirements\n * @returns Extracted query parameters or undefined\n */\nfunction extractQueryParams(v1Input: Record<string, unknown>): Record<string, unknown> | undefined {\n // Check various common field names used in v1 (both camelCase and snake_case)\n if (v1Input.queryParams && typeof v1Input.queryParams === \"object\") {\n return v1Input.queryParams as Record<string, unknown>;\n }\n if (v1Input.query_params && typeof v1Input.query_params === \"object\") {\n return v1Input.query_params as Record<string, unknown>;\n }\n if (v1Input.query && typeof v1Input.query === \"object\") {\n return v1Input.query as Record<string, unknown>;\n }\n if (v1Input.params && typeof v1Input.params === \"object\") {\n return v1Input.params as Record<string, unknown>;\n }\n return undefined;\n}\n\n/**\n * Extracts body information from v1 input, making smart assumptions\n *\n * @param v1Input - V1 input object from payment requirements\n * @returns Object containing body content and bodyType\n */\nfunction extractBodyInfo(v1Input: Record<string, unknown>): {\n body: Record<string, unknown>;\n bodyType: \"json\" | \"form-data\" | \"text\";\n} {\n // Determine body type (check both camelCase and snake_case)\n let bodyType: \"json\" | \"form-data\" | \"text\" = \"json\";\n const bodyTypeField = v1Input.bodyType || v1Input.body_type;\n\n if (bodyTypeField && typeof bodyTypeField === \"string\") {\n const type = bodyTypeField.toLowerCase();\n if (type.includes(\"form\") || type.includes(\"multipart\")) {\n bodyType = \"form-data\";\n } else if (type.includes(\"text\") || type.includes(\"plain\")) {\n bodyType = \"text\";\n } else {\n bodyType = \"json\";\n }\n }\n\n // Extract body content from various possible fields\n // Priority order based on observed patterns in real data\n let body: Record<string, unknown> = {};\n\n if (v1Input.bodyFields && typeof v1Input.bodyFields === \"object\") {\n body = v1Input.bodyFields as Record<string, unknown>;\n } else if (\n v1Input.body_fields &&\n v1Input.body_fields !== null &&\n typeof v1Input.body_fields === \"object\"\n ) {\n body = v1Input.body_fields as Record<string, unknown>;\n } else if (v1Input.bodyParams && typeof v1Input.bodyParams === \"object\") {\n body = v1Input.bodyParams as Record<string, unknown>;\n } else if (v1Input.body && typeof v1Input.body === \"object\") {\n body = v1Input.body as Record<string, unknown>;\n } else if (v1Input.data && typeof v1Input.data === \"object\") {\n body = v1Input.data as Record<string, unknown>;\n } else if (v1Input.properties && typeof v1Input.properties === \"object\") {\n // Some endpoints have properties directly at the input level\n body = v1Input.properties as Record<string, unknown>;\n }\n\n return { body, bodyType };\n}\n\n/**\n * Extracts discovery info from v1 PaymentRequirements and transforms to v2 format\n *\n * In v1, the discovery information is stored in the `outputSchema` field,\n * which contains both input (endpoint shape) and output (response schema) information.\n *\n * This function makes smart assumptions to normalize v1 data into v2 DiscoveryInfo format:\n * - For GET/HEAD/DELETE: Looks for queryParams, query, or params fields\n * - For POST/PUT/PATCH: Looks for bodyFields, body, or data fields and normalizes bodyType\n * - Extracts optional headers if present\n *\n * @param paymentRequirements - V1 payment requirements\n * @returns Discovery info in v2 format if present and valid, or null if not discoverable\n *\n * @example\n * ```typescript\n * const requirements: PaymentRequirementsV1 = {\n * scheme: \"exact\",\n * network: \"eip155:8453\",\n * maxAmountRequired: \"100000\",\n * resource: \"https://api.example.com/data\",\n * description: \"Get data\",\n * mimeType: \"application/json\",\n * outputSchema: {\n * input: {\n * type: \"http\",\n * method: \"GET\",\n * discoverable: true,\n * queryParams: { query: \"string\" }\n * },\n * output: { type: \"object\" }\n * },\n * payTo: \"0x...\",\n * maxTimeoutSeconds: 300,\n * asset: \"0x...\",\n * extra: {}\n * };\n *\n * const info = extractDiscoveryInfoV1(requirements);\n * if (info) {\n * console.log(\"Endpoint method:\", info.input.method);\n * }\n * ```\n */\nexport function extractDiscoveryInfoV1(\n paymentRequirements: PaymentRequirementsV1,\n): DiscoveryInfo | null {\n const { outputSchema } = paymentRequirements;\n\n // Check if outputSchema exists and has the expected structure\n if (!outputSchema || !hasV1OutputSchema(outputSchema)) {\n return null;\n }\n\n const v1Input = outputSchema.input;\n\n // Check if the endpoint is marked as discoverable\n // Default to true if not specified (for backwards compatibility)\n const isDiscoverable = v1Input.discoverable ?? true;\n\n if (!isDiscoverable) {\n return null;\n }\n\n const method = typeof v1Input.method === \"string\" ? v1Input.method.toUpperCase() : \"\";\n\n // Extract headers if present (check both camelCase and snake_case)\n const headersRaw = v1Input.headerFields || v1Input.header_fields || v1Input.headers;\n const headers =\n headersRaw && typeof headersRaw === \"object\"\n ? (headersRaw as Record<string, string>)\n : undefined;\n\n // Extract output example/schema if present\n const output = outputSchema.output\n ? {\n type: \"json\" as const,\n example: outputSchema.output,\n }\n : undefined;\n\n // Transform based on method type\n if (isQueryMethod(method)) {\n // Query parameter method (GET, HEAD, DELETE)\n const queryParams = extractQueryParams(v1Input);\n\n const discoveryInfo: QueryDiscoveryInfo = {\n input: {\n type: \"http\",\n method: method as QueryParamMethods,\n ...(queryParams ? { queryParams } : {}),\n ...(headers ? { headers } : {}),\n },\n ...(output ? { output } : {}),\n };\n\n return discoveryInfo;\n } else if (isBodyMethod(method)) {\n // Body method (POST, PUT, PATCH)\n const { body, bodyType } = extractBodyInfo(v1Input);\n const queryParams = extractQueryParams(v1Input); // Some POST requests also have query params\n\n const discoveryInfo: BodyDiscoveryInfo = {\n input: {\n type: \"http\",\n method: method as BodyMethods,\n bodyType,\n body,\n ...(queryParams ? { queryParams } : {}),\n ...(headers ? { headers } : {}),\n },\n ...(output ? { output } : {}),\n };\n\n return discoveryInfo;\n }\n\n // Unsupported method, return null\n return null;\n}\n\n/**\n * Checks if v1 PaymentRequirements contains discoverable information\n *\n * @param paymentRequirements - V1 payment requirements\n * @returns True if the requirements contain valid discovery info\n *\n * @example\n * ```typescript\n * if (isDiscoverableV1(requirements)) {\n * const info = extractDiscoveryInfoV1(requirements);\n * // Catalog info in Bazaar\n * }\n * ```\n */\nexport function isDiscoverableV1(paymentRequirements: PaymentRequirementsV1): boolean {\n return extractDiscoveryInfoV1(paymentRequirements) !== null;\n}\n\n/**\n * Extracts resource metadata from v1 PaymentRequirements\n *\n * In v1, resource information is embedded directly in the payment requirements\n * rather than in a separate resource object.\n *\n * @param paymentRequirements - V1 payment requirements\n * @returns Resource metadata\n *\n * @example\n * ```typescript\n * const metadata = extractResourceMetadataV1(requirements);\n * console.log(\"Resource URL:\", metadata.url);\n * console.log(\"Description:\", metadata.description);\n * ```\n */\nexport function extractResourceMetadataV1(paymentRequirements: PaymentRequirementsV1): {\n url: string;\n description: string;\n mimeType: string;\n} {\n return {\n url: paymentRequirements.resource,\n description: paymentRequirements.description,\n mimeType: paymentRequirements.mimeType,\n };\n}\n","/**\n * Client extensions for querying Bazaar discovery resources\n */\n\nimport { HTTPFacilitatorClient } from \"@t402/core/http\";\nimport { WithExtensions } from \"../types\";\n\n/**\n * Parameters for listing discovery resources.\n * All parameters are optional and used for filtering/pagination.\n */\nexport interface ListDiscoveryResourcesParams {\n /**\n * Filter by protocol type (e.g., \"http\", \"mcp\").\n * Currently, the only supported protocol type is \"http\".\n */\n type?: string;\n\n /**\n * The number of discovered t402 resources to return per page.\n */\n limit?: number;\n\n /**\n * The offset of the first discovered t402 resource to return.\n */\n offset?: number;\n}\n\n/**\n * A discovered t402 resource from the bazaar.\n */\nexport interface DiscoveryResource {\n /** The URL of the discovered resource */\n url: string;\n /** The protocol type of the resource */\n type: string;\n /** Additional metadata about the resource */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Response from listing discovery resources.\n */\nexport interface DiscoveryResourcesResponse {\n /** The list of discovered resources */\n resources: DiscoveryResource[];\n /** Total count of resources matching the query */\n total?: number;\n /** The limit used for this query */\n limit?: number;\n /** The offset used for this query */\n offset?: number;\n}\n\n/**\n * Bazaar client extension interface providing discovery query functionality.\n */\nexport interface BazaarClientExtension {\n discovery: {\n /**\n * List t402 discovery resources from the bazaar.\n *\n * @param params - Optional filtering and pagination parameters\n * @returns A promise resolving to the discovery resources response\n */\n listResources(params?: ListDiscoveryResourcesParams): Promise<DiscoveryResourcesResponse>;\n };\n}\n\n/**\n * Extends a facilitator client with Bazaar discovery query functionality.\n * Preserves and merges with any existing extensions from prior chaining.\n *\n * @param client - The facilitator client to extend\n * @returns The client extended with bazaar discovery capabilities\n *\n * @example\n * ```ts\n * // Basic usage\n * const client = withBazaar(new HTTPFacilitatorClient());\n * const resources = await client.extensions.discovery.listResources({ type: \"http\" });\n *\n * // Chaining with other extensions\n * const client = withBazaar(withOtherExtension(new HTTPFacilitatorClient()));\n * await client.extensions.other.someMethod();\n * await client.extensions.discovery.listResources();\n * ```\n */\nexport function withBazaar<T extends HTTPFacilitatorClient>(\n client: T,\n): WithExtensions<T, BazaarClientExtension> {\n // Preserve any existing extensions from prior chaining\n const existingExtensions =\n (client as T & { extensions?: Record<string, unknown> }).extensions ?? {};\n\n const extended = client as WithExtensions<T, BazaarClientExtension>;\n\n extended.extensions = {\n ...existingExtensions,\n discovery: {\n async listResources(\n params?: ListDiscoveryResourcesParams,\n ): Promise<DiscoveryResourcesResponse> {\n let headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n\n const authHeaders = await client.createAuthHeaders(\"discovery\");\n headers = { ...headers, ...authHeaders.headers };\n\n const queryParams = new URLSearchParams();\n if (params?.type !== undefined) {\n queryParams.set(\"type\", params.type);\n }\n if (params?.limit !== undefined) {\n queryParams.set(\"limit\", params.limit.toString());\n }\n if (params?.offset !== undefined) {\n queryParams.set(\"offset\", params.offset.toString());\n }\n\n const queryString = queryParams.toString();\n const endpoint = `${client.url}/v1/discovery/resources${queryString ? `?${queryString}` : \"\"}`;\n\n const response = await fetch(endpoint, {\n method: \"GET\",\n headers,\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n throw new Error(\n `Facilitator listDiscoveryResources failed (${response.status}): ${errorText}`,\n );\n }\n\n return (await response.json()) as DiscoveryResourcesResponse;\n },\n },\n } as WithExtensions<T, BazaarClientExtension>[\"extensions\"];\n\n return extended;\n}\n","/**\n * Sign-In-With-X (SIWx) Server-Side Implementation\n *\n * Provides functions for servers to declare SIWx requirements,\n * parse client headers, and verify signatures.\n */\n\nimport { randomBytes } from \"crypto\";\nimport { keccak_256 } from \"@noble/hashes/sha3\";\nimport { sha256 as nobleSha256 } from \"@noble/hashes/sha2\";\nimport { secp256k1 } from \"@noble/curves/secp256k1\";\nimport { ed25519 } from \"@noble/curves/ed25519\";\nimport { bytesToHex, hexToBytes } from \"@noble/hashes/utils\";\nimport {\n SIWxExtension,\n SIWxExtensionInfo,\n SIWxPayload,\n DeclareSIWxOptions,\n ValidateSIWxOptions,\n VerifySIWxOptions,\n SIWxValidationResult,\n SIWxVerificationResult,\n} from \"./types.js\";\n\n/**\n * JSON Schema for SIWx payload validation.\n */\nconst SIWX_SCHEMA = {\n type: \"object\",\n required: [\"domain\", \"address\", \"uri\", \"version\", \"chainId\", \"nonce\", \"issuedAt\", \"signature\"],\n properties: {\n domain: { type: \"string\" },\n address: { type: \"string\" },\n statement: { type: \"string\" },\n uri: { type: \"string\" },\n version: { type: \"string\" },\n chainId: { type: \"string\" },\n nonce: { type: \"string\" },\n issuedAt: { type: \"string\", format: \"date-time\" },\n expirationTime: { type: \"string\", format: \"date-time\" },\n notBefore: { type: \"string\", format: \"date-time\" },\n requestId: { type: \"string\" },\n resources: { type: \"array\", items: { type: \"string\" } },\n signature: { type: \"string\" },\n },\n};\n\n/**\n * EIP-1271 magic value for valid signatures.\n */\nconst EIP1271_MAGIC_VALUE = \"0x1626ba7e\";\n\n/**\n * Extracts domain from a resource URI.\n *\n * @param resourceUri - Full resource URI (e.g., \"https://api.example.com/resource\")\n * @returns Domain without protocol (e.g., \"api.example.com\")\n */\nfunction extractDomain(resourceUri: string): string {\n try {\n const url = new URL(resourceUri);\n return url.host;\n } catch {\n // Fallback for non-URL formats\n return resourceUri.replace(/^https?:\\/\\//, \"\").split(\"/\")[0];\n }\n}\n\n/**\n * Generates a cryptographically secure nonce.\n *\n * @returns 32-byte hex-encoded nonce\n */\nfunction generateNonce(): string {\n return randomBytes(16).toString(\"hex\");\n}\n\n/**\n * Declares a SIWx extension for server responses.\n *\n * @param options - Extension declaration options\n * @returns SIWx extension object ready for response\n *\n * @example\n * ```typescript\n * const extension = declareSIWxExtension({\n * resourceUri: \"https://api.example.com/premium\",\n * network: \"eip155:8453\",\n * statement: \"Sign in to access premium content\",\n * });\n * ```\n */\nexport function declareSIWxExtension(options: DeclareSIWxOptions): SIWxExtension {\n const domain = extractDomain(options.resourceUri);\n const now = new Date();\n const expirationTime =\n options.expirationTime || new Date(now.getTime() + 5 * 60 * 1000).toISOString();\n\n const info: SIWxExtensionInfo = {\n domain,\n uri: options.resourceUri,\n statement: options.statement,\n version: options.version || \"1\",\n chainId: options.network,\n nonce: generateNonce(),\n issuedAt: now.toISOString(),\n expirationTime,\n resources: [options.resourceUri],\n signatureScheme: options.signatureScheme,\n };\n\n return {\n info,\n schema: SIWX_SCHEMA,\n };\n}\n\n/**\n * Parses a SIWx header from client request.\n *\n * The header format is base64-encoded JSON.\n *\n * @param header - Base64-encoded SIWx header value\n * @returns Parsed SIWx payload\n * @throws Error if header is invalid\n *\n * @example\n * ```typescript\n * const payload = parseSIWxHeader(request.headers['x-t402-siwx']);\n * ```\n */\nexport function parseSIWxHeader(header: string): SIWxPayload {\n if (!header) {\n throw new Error(\"Missing SIWx header\");\n }\n\n try {\n const decoded = Buffer.from(header, \"base64\").toString(\"utf-8\");\n const payload = JSON.parse(decoded) as SIWxPayload;\n\n // Validate required fields\n const required = [\n \"domain\",\n \"address\",\n \"uri\",\n \"version\",\n \"chainId\",\n \"nonce\",\n \"issuedAt\",\n \"signature\",\n ];\n for (const field of required) {\n if (!(field in payload)) {\n throw new Error(`Missing required field: ${field}`);\n }\n }\n\n return payload;\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new Error(\"Invalid SIWx header: malformed JSON\");\n }\n throw error;\n }\n}\n\n/**\n * Validates a SIWx message against expected values.\n *\n * @param message - The SIWx payload to validate\n * @param expectedResourceUri - Expected resource URI (domain validated from this)\n * @param options - Validation options\n * @returns Validation result\n *\n * @example\n * ```typescript\n * const result = validateSIWxMessage(payload, \"https://api.example.com/premium\", {\n * maxAge: 5 * 60 * 1000, // 5 minutes\n * checkNonce: (nonce) => usedNonces.has(nonce) === false,\n * });\n * ```\n */\nexport function validateSIWxMessage(\n message: SIWxPayload,\n expectedResourceUri: string,\n options: ValidateSIWxOptions = {},\n): SIWxValidationResult {\n const { maxAge = 5 * 60 * 1000, checkNonce } = options;\n\n // Validate domain matches\n const expectedDomain = extractDomain(expectedResourceUri);\n if (message.domain !== expectedDomain) {\n return {\n valid: false,\n error: `Domain mismatch: expected ${expectedDomain}, got ${message.domain}`,\n };\n }\n\n // Validate URI matches\n if (message.uri !== expectedResourceUri) {\n return {\n valid: false,\n error: `URI mismatch: expected ${expectedResourceUri}, got ${message.uri}`,\n };\n }\n\n // Validate version\n if (message.version !== \"1\") {\n return { valid: false, error: `Unsupported version: ${message.version}` };\n }\n\n // Validate issuedAt is not too old\n const issuedAt = new Date(message.issuedAt);\n const now = new Date();\n if (now.getTime() - issuedAt.getTime() > maxAge) {\n return { valid: false, error: \"Message has expired (issuedAt too old)\" };\n }\n\n // Validate expirationTime if present\n if (message.expirationTime) {\n const expiration = new Date(message.expirationTime);\n if (expiration < now) {\n return { valid: false, error: \"Message has expired\" };\n }\n }\n\n // Validate notBefore if present\n if (message.notBefore) {\n const notBefore = new Date(message.notBefore);\n if (notBefore > now) {\n return { valid: false, error: \"Message not yet valid (notBefore in future)\" };\n }\n }\n\n // Custom nonce validation\n if (checkNonce && !checkNonce(message.nonce)) {\n return { valid: false, error: \"Invalid nonce (replay attack detected)\" };\n }\n\n return { valid: true };\n}\n\n/**\n * Detects the signature scheme from chain ID.\n *\n * @param chainId - CAIP-2 chain ID (e.g., \"eip155:1\", \"solana:mainnet\", \"stellar:pubnet\")\n * @returns The signature scheme to use for verification\n */\nfunction detectSignatureScheme(chainId: string): \"evm\" | \"ed25519\" | \"tron\" {\n const namespace = chainId.split(\":\")[0];\n\n switch (namespace) {\n case \"solana\":\n case \"stellar\":\n case \"ton\":\n return \"ed25519\";\n case \"tron\":\n return \"tron\";\n case \"eip155\":\n default:\n return \"evm\";\n }\n}\n\n/**\n * Verifies an Ed25519 signature (used by Solana and Stellar).\n *\n * @param message - The message that was signed\n * @param signature - Hex-encoded Ed25519 signature (64 bytes)\n * @param publicKey - The public key to verify against (hex or base58)\n * @returns True if signature is valid\n */\nfunction verifyEd25519Signature(message: string, signature: string, publicKey: string): boolean {\n try {\n // Remove 0x prefix if present\n const sigHex = signature.startsWith(\"0x\") ? signature.slice(2) : signature;\n const sigBytes = hexToBytes(sigHex);\n\n if (sigBytes.length !== 64) {\n throw new Error(\n `Invalid Ed25519 signature length: expected 64 bytes, got ${sigBytes.length}`,\n );\n }\n\n // Get public key bytes\n let pubKeyBytes: Uint8Array;\n const pubKeyHex = publicKey.startsWith(\"0x\") ? publicKey.slice(2) : publicKey;\n\n // Check if it's a hex string (64 chars = 32 bytes)\n if (/^[0-9a-fA-F]{64}$/.test(pubKeyHex)) {\n pubKeyBytes = hexToBytes(pubKeyHex);\n } else {\n // Try to decode as base58 (Solana format)\n pubKeyBytes = decodeBase58(publicKey);\n }\n\n if (pubKeyBytes.length !== 32) {\n throw new Error(\n `Invalid Ed25519 public key length: expected 32 bytes, got ${pubKeyBytes.length}`,\n );\n }\n\n // Hash the message (Ed25519 signs the raw message or its hash depending on implementation)\n const messageBytes = new TextEncoder().encode(message);\n\n // Verify the signature\n return ed25519.verify(sigBytes, messageBytes, pubKeyBytes);\n } catch {\n return false;\n }\n}\n\n/**\n * Decodes a base58 string to bytes (for Solana addresses).\n *\n * @param str - Base58 encoded string\n * @returns Decoded bytes\n */\nfunction decodeBase58(str: string): Uint8Array {\n const ALPHABET = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\n const ALPHABET_MAP = new Map<string, number>();\n for (let i = 0; i < ALPHABET.length; i++) {\n ALPHABET_MAP.set(ALPHABET[i], i);\n }\n\n if (str.length === 0) return new Uint8Array(0);\n\n const bytes: number[] = [0];\n for (const char of str) {\n const value = ALPHABET_MAP.get(char);\n if (value === undefined) {\n throw new Error(`Invalid base58 character: ${char}`);\n }\n\n let carry = value;\n for (let j = 0; j < bytes.length; j++) {\n carry += bytes[j] * 58;\n bytes[j] = carry & 0xff;\n carry >>= 8;\n }\n\n while (carry > 0) {\n bytes.push(carry & 0xff);\n carry >>= 8;\n }\n }\n\n // Add leading zeros\n for (const char of str) {\n if (char !== \"1\") break;\n bytes.push(0);\n }\n\n return new Uint8Array(bytes.reverse());\n}\n\n/**\n * Encodes bytes to base58 string.\n *\n * @param bytes - Bytes to encode\n * @returns Base58 encoded string\n */\nfunction encodeBase58(bytes: Uint8Array): string {\n const ALPHABET = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\n\n if (bytes.length === 0) return \"\";\n\n // Count leading zeros\n let leadingZeros = 0;\n for (const b of bytes) {\n if (b !== 0) break;\n leadingZeros++;\n }\n\n // Convert to base58\n const digits: number[] = [0];\n for (const b of bytes) {\n let carry = b;\n for (let j = 0; j < digits.length; j++) {\n carry += digits[j] * 256;\n digits[j] = carry % 58;\n carry = Math.floor(carry / 58);\n }\n while (carry > 0) {\n digits.push(carry % 58);\n carry = Math.floor(carry / 58);\n }\n }\n\n let result = ALPHABET[0].repeat(leadingZeros);\n for (let i = digits.length - 1; i >= 0; i--) {\n result += ALPHABET[digits[i]];\n }\n\n return result;\n}\n\n/**\n * Converts an EVM hex address to a TRON base58check address.\n *\n * TRON addresses are the same as EVM addresses but with a 0x41 prefix\n * instead of 0x, encoded in base58check format.\n *\n * @param evmAddress - EVM address with 0x prefix\n * @returns TRON base58check address starting with 'T'\n */\nfunction evmAddressToTron(evmAddress: string): string {\n const addr = evmAddress.toLowerCase().replace(\"0x\", \"\");\n // TRON address = 0x41 + 20-byte address\n const addressBytes = hexToBytes(\"41\" + addr);\n\n // Double SHA-256 for base58check checksum\n const hash1 = nobleSha256(addressBytes);\n const hash2 = nobleSha256(hash1);\n const checksum = hash2.slice(0, 4);\n\n // Concatenate address + checksum\n const fullAddress = new Uint8Array(addressBytes.length + 4);\n fullAddress.set(addressBytes, 0);\n fullAddress.set(checksum, addressBytes.length);\n\n return encodeBase58(fullAddress);\n}\n\n/**\n * Verifies a SIWx signature.\n *\n * Supports EIP-191 personal signatures for EVM chains, Ed25519 for Solana/Stellar/TON,\n * TRON secp256k1 with base58check addresses,\n * and can optionally verify smart wallet signatures via EIP-1271/6492.\n *\n * @param message - The SIWx payload to verify\n * @param signature - The signature to verify (hex-encoded)\n * @param options - Verification options\n * @returns Verification result with recovered address\n *\n * @example\n * ```typescript\n * const result = await verifySIWxSignature(payload, payload.signature, {\n * checkSmartWallet: true,\n * provider: web3Provider,\n * });\n * ```\n */\nexport async function verifySIWxSignature(\n message: SIWxPayload,\n signature: string,\n options: VerifySIWxOptions = {},\n): Promise<SIWxVerificationResult> {\n const { checkSmartWallet = false } = options;\n\n try {\n // Reconstruct the CAIP-122 message that was signed\n const messageText = constructMessage(message);\n\n // Detect signature scheme based on chain ID\n const scheme = detectSignatureScheme(message.chainId);\n\n if (scheme === \"ed25519\") {\n // Ed25519 verification for Solana, Stellar, and TON\n // For Ed25519, the address IS the public key, so we verify directly\n const isValid = verifyEd25519Signature(messageText, signature, message.address);\n\n if (isValid) {\n return { valid: true, address: message.address };\n }\n\n return {\n valid: false,\n error: \"Ed25519 signature verification failed\",\n };\n }\n\n if (scheme === \"tron\") {\n // TRON uses secp256k1 (same as EVM) but with base58check address format\n const messageHash = hashMessage(messageText);\n const recoveredEvmAddress = recoverAddress(messageHash, signature);\n\n // Convert recovered EVM address to TRON base58check address\n const recoveredTronAddress = evmAddressToTron(recoveredEvmAddress);\n\n if (recoveredTronAddress === message.address) {\n return { valid: true, address: message.address };\n }\n\n return {\n valid: false,\n address: recoveredTronAddress,\n error: `Signature mismatch: expected ${message.address}, recovered ${recoveredTronAddress}`,\n };\n }\n\n // EVM verification (secp256k1)\n // Hash the message with Ethereum prefix\n const messageHash = hashMessage(messageText);\n\n // Try to recover the signer address\n const recoveredAddress = recoverAddress(messageHash, signature);\n\n // Check if recovered address matches claimed address\n if (recoveredAddress.toLowerCase() !== message.address.toLowerCase()) {\n // If smart wallet checking is enabled, try EIP-1271 verification\n if (checkSmartWallet && options.provider) {\n const isValidSmartWallet = await verifySmartWalletSignature(\n message.address,\n messageHash,\n signature,\n options.provider,\n );\n\n if (isValidSmartWallet) {\n return { valid: true, address: message.address };\n }\n }\n\n return {\n valid: false,\n address: recoveredAddress,\n error: `Signature mismatch: expected ${message.address}, recovered ${recoveredAddress}`,\n };\n }\n\n return { valid: true, address: recoveredAddress };\n } catch (error) {\n return {\n valid: false,\n error: `Signature verification failed: ${error instanceof Error ? error.message : \"unknown error\"}`,\n };\n }\n}\n\n/**\n * Constructs the CAIP-122 message string from payload.\n *\n * @param payload - SIWx payload\n * @returns CAIP-122 formatted message string\n */\nexport function constructMessage(payload: SIWxPayload): string {\n const lines: string[] = [];\n\n // Header\n lines.push(`${payload.domain} wants you to sign in with your ${payload.chainId} account:`);\n lines.push(payload.address);\n lines.push(\"\");\n\n // Statement (optional)\n if (payload.statement) {\n lines.push(payload.statement);\n lines.push(\"\");\n }\n\n // Required fields\n lines.push(`URI: ${payload.uri}`);\n lines.push(`Version: ${payload.version}`);\n lines.push(`Chain ID: ${payload.chainId}`);\n lines.push(`Nonce: ${payload.nonce}`);\n lines.push(`Issued At: ${payload.issuedAt}`);\n\n // Optional fields\n if (payload.expirationTime) {\n lines.push(`Expiration Time: ${payload.expirationTime}`);\n }\n if (payload.notBefore) {\n lines.push(`Not Before: ${payload.notBefore}`);\n }\n if (payload.requestId) {\n lines.push(`Request ID: ${payload.requestId}`);\n }\n\n // Resources\n if (payload.resources && payload.resources.length > 0) {\n lines.push(\"Resources:\");\n for (const resource of payload.resources) {\n lines.push(`- ${resource}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Hashes a message with the Ethereum signed message prefix (EIP-191).\n *\n * @param message - Message to hash\n * @returns Hex-encoded keccak256 hash with 0x prefix\n */\nexport function hashMessage(message: string): string {\n const messageBytes = new TextEncoder().encode(message);\n const prefix = `\\x19Ethereum Signed Message:\\n${messageBytes.length}`;\n const prefixBytes = new TextEncoder().encode(prefix);\n\n // Concatenate prefix and message\n const combined = new Uint8Array(prefixBytes.length + messageBytes.length);\n combined.set(prefixBytes, 0);\n combined.set(messageBytes, prefixBytes.length);\n\n // Hash with keccak256\n const hash = keccak_256(combined);\n return \"0x\" + bytesToHex(hash);\n}\n\n/**\n * Recovers the signer address from an EIP-191 signature.\n *\n * @param messageHash - Keccak256 hash of the prefixed message (with 0x prefix)\n * @param signature - Hex-encoded signature (65 bytes: r + s + v)\n * @returns Checksummed Ethereum address\n */\nfunction recoverAddress(messageHash: string, signature: string): string {\n // Remove 0x prefix if present\n const sigHex = signature.startsWith(\"0x\") ? signature.slice(2) : signature;\n const hashHex = messageHash.startsWith(\"0x\") ? messageHash.slice(2) : messageHash;\n\n if (sigHex.length !== 130) {\n throw new Error(`Invalid signature length: expected 130 hex chars, got ${sigHex.length}`);\n }\n\n // Parse signature components\n const r = BigInt(\"0x\" + sigHex.slice(0, 64));\n const s = BigInt(\"0x\" + sigHex.slice(64, 128));\n let v = parseInt(sigHex.slice(128, 130), 16);\n\n // Normalize v to 0 or 1 (EIP-155 compatibility)\n if (v >= 27) {\n v -= 27;\n }\n\n if (v !== 0 && v !== 1) {\n throw new Error(`Invalid recovery id: ${v}`);\n }\n\n // Create signature object\n const sig = new secp256k1.Signature(r, s).addRecoveryBit(v);\n\n // Recover public key\n const hashBytes = hexToBytes(hashHex);\n const publicKey = sig.recoverPublicKey(hashBytes);\n\n // Get uncompressed public key (65 bytes) and remove the 04 prefix\n const pubKeyBytes = publicKey.toRawBytes(false).slice(1);\n\n // Hash public key to get address\n const addressHash = keccak_256(pubKeyBytes);\n\n // Take last 20 bytes\n const addressBytes = addressHash.slice(-20);\n const address = \"0x\" + bytesToHex(addressBytes);\n\n // Return checksummed address\n return toChecksumAddress(address);\n}\n\n/**\n * Converts an Ethereum address to checksummed format (EIP-55).\n *\n * @param address - Ethereum address (with or without 0x prefix)\n * @returns Checksummed address with 0x prefix\n */\nfunction toChecksumAddress(address: string): string {\n const addr = address.toLowerCase().replace(\"0x\", \"\");\n const hash = bytesToHex(keccak_256(new TextEncoder().encode(addr)));\n\n let checksummed = \"0x\";\n for (let i = 0; i < 40; i++) {\n if (parseInt(hash[i], 16) >= 8) {\n checksummed += addr[i].toUpperCase();\n } else {\n checksummed += addr[i];\n }\n }\n\n return checksummed;\n}\n\n/**\n * Verifies a smart wallet signature using EIP-1271.\n *\n * @param walletAddress - Smart wallet contract address\n * @param messageHash - Hash of the message that was signed\n * @param signature - The signature to verify\n * @param provider - Ethereum provider with call capability\n * @returns True if signature is valid according to the smart wallet\n */\nasync function verifySmartWalletSignature(\n walletAddress: string,\n messageHash: string,\n signature: string,\n provider: unknown,\n): Promise<boolean> {\n // Type guard for provider\n interface EthProvider {\n request(args: { method: string; params: unknown[] }): Promise<unknown>;\n }\n\n /**\n * Type guard for Ethereum provider interface\n *\n * @param p - Value to check\n * @returns True if value is an EthProvider\n */\n function isEthProvider(p: unknown): p is EthProvider {\n return typeof p === \"object\" && p !== null && \"request\" in p;\n }\n\n if (!isEthProvider(provider)) {\n return false;\n }\n\n try {\n // EIP-1271 isValidSignature(bytes32 hash, bytes signature) returns bytes4\n const hashHex = messageHash.startsWith(\"0x\") ? messageHash : \"0x\" + messageHash;\n const sigHex = signature.startsWith(\"0x\") ? signature : \"0x\" + signature;\n\n // Encode function call\n // isValidSignature(bytes32,bytes) selector: 0x1626ba7e\n const data =\n \"0x1626ba7e\" +\n hashHex.slice(2).padStart(64, \"0\") + // bytes32 hash\n \"0000000000000000000000000000000000000000000000000000000000000040\" + // offset to bytes\n (sigHex.length / 2 - 1).toString(16).padStart(64, \"0\") + // bytes length\n sigHex.slice(2).padEnd(Math.ceil((sigHex.length - 2) / 64) * 64, \"0\"); // bytes data\n\n const result = (await provider.request({\n method: \"eth_call\",\n params: [{ to: walletAddress, data }, \"latest\"],\n })) as string;\n\n // Check if result matches magic value\n return result.toLowerCase().startsWith(EIP1271_MAGIC_VALUE);\n } catch {\n return false;\n }\n}\n\n/**\n * Verifies a signature using EIP-6492 (universal signature verification).\n *\n * This supports both deployed and undeployed smart wallets.\n *\n * @param walletAddress - Wallet address (may be counterfactual)\n * @param messageHash - Hash of the message that was signed\n * @param signature - The signature (may include deployment data)\n * @param provider - Ethereum provider\n * @returns True if signature is valid\n */\nexport async function verifyEIP6492Signature(\n walletAddress: string,\n messageHash: string,\n signature: string,\n provider: unknown,\n): Promise<boolean> {\n // EIP-6492 signatures end with the magic suffix\n const EIP6492_SUFFIX = \"6492649264926492649264926492649264926492649264926492649264926492\";\n const sigHex = signature.startsWith(\"0x\") ? signature.slice(2) : signature;\n\n if (sigHex.endsWith(EIP6492_SUFFIX)) {\n // This is an EIP-6492 signature with deployment data\n // For full implementation, we would need to:\n // 1. Deploy the wallet contract to a local fork\n // 2. Then call isValidSignature\n // This requires more complex provider interaction\n console.warn(\"EIP-6492 deployment signatures not yet fully implemented\");\n return false;\n }\n\n // Fall back to standard EIP-1271 verification\n return verifySmartWalletSignature(walletAddress, messageHash, signature, provider);\n}\n","/**\n * Sign-In-With-X (SIWx) Client-Side Implementation\n *\n * Provides functions for clients to create and sign SIWx messages.\n */\n\nimport {\n SIWxPayload,\n SIWxExtension,\n SIWxExtensionInfo,\n SIWxSigner,\n SignatureScheme,\n} from \"./types.js\";\nimport { constructMessage } from \"./server.js\";\n\n/**\n * Encodes a SIWx payload for transmission in HTTP header.\n *\n * @param payload - The SIWx payload to encode\n * @returns Base64-encoded JSON string\n *\n * @example\n * ```typescript\n * const header = encodeSIWxHeader(payload);\n * fetch(url, {\n * headers: { 'X-T402-SIWx': header }\n * });\n * ```\n */\nexport function encodeSIWxHeader(payload: SIWxPayload): string {\n const json = JSON.stringify(payload);\n // Use Buffer in Node.js or btoa in browser\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(json, \"utf-8\").toString(\"base64\");\n }\n return btoa(json);\n}\n\n/**\n * Creates a CAIP-122 formatted message string from server info.\n *\n * @param serverInfo - Extension info from server\n * @param address - Wallet address signing the message\n * @returns CAIP-122 formatted message string ready for signing\n *\n * @example\n * ```typescript\n * const message = createSIWxMessage(extension.info, wallet.address);\n * const signature = await wallet.signMessage(message);\n * ```\n */\nexport function createSIWxMessage(serverInfo: SIWxExtensionInfo, address: string): string {\n // Create a temporary payload for message construction\n const payload: SIWxPayload = {\n domain: serverInfo.domain,\n address,\n statement: serverInfo.statement,\n uri: serverInfo.uri,\n version: serverInfo.version,\n chainId: serverInfo.chainId,\n nonce: serverInfo.nonce,\n issuedAt: serverInfo.issuedAt,\n expirationTime: serverInfo.expirationTime,\n notBefore: serverInfo.notBefore,\n requestId: serverInfo.requestId,\n resources: serverInfo.resources,\n signature: \"\", // Will be added after signing\n };\n\n return constructMessage(payload);\n}\n\n/**\n * Creates EIP-712 typed data for SIWx signing.\n *\n * @param serverInfo - Extension info from server\n * @param address - Wallet address signing the message\n * @returns EIP-712 typed data object\n */\nexport function createSIWxTypedData(\n serverInfo: SIWxExtensionInfo,\n address: string,\n): {\n domain: {\n name: string;\n version: string;\n chainId: number;\n };\n types: {\n SIWx: Array<{ name: string; type: string }>;\n };\n primaryType: \"SIWx\";\n message: Record<string, unknown>;\n} {\n // Extract chain ID number from CAIP-2 format (e.g., \"eip155:8453\" -> 8453)\n const chainIdParts = serverInfo.chainId.split(\":\");\n const chainIdNum =\n chainIdParts.length > 1 ? parseInt(chainIdParts[1], 10) : parseInt(chainIdParts[0], 10);\n\n return {\n domain: {\n name: serverInfo.domain,\n version: serverInfo.version,\n chainId: chainIdNum,\n },\n types: {\n SIWx: [\n { name: \"domain\", type: \"string\" },\n { name: \"address\", type: \"address\" },\n { name: \"statement\", type: \"string\" },\n { name: \"uri\", type: \"string\" },\n { name: \"version\", type: \"string\" },\n { name: \"chainId\", type: \"string\" },\n { name: \"nonce\", type: \"string\" },\n { name: \"issuedAt\", type: \"string\" },\n { name: \"expirationTime\", type: \"string\" },\n { name: \"resources\", type: \"string[]\" },\n ],\n },\n primaryType: \"SIWx\",\n message: {\n domain: serverInfo.domain,\n address,\n statement: serverInfo.statement || \"\",\n uri: serverInfo.uri,\n version: serverInfo.version,\n chainId: serverInfo.chainId,\n nonce: serverInfo.nonce,\n issuedAt: serverInfo.issuedAt,\n expirationTime: serverInfo.expirationTime || \"\",\n resources: serverInfo.resources || [],\n },\n };\n}\n\n/**\n * Signs a SIWx message using the provided signer.\n *\n * @param message - CAIP-122 formatted message to sign\n * @param signer - Wallet/signer interface with signMessage\n * @param options - Signing options\n * @param options.signatureScheme - Signature scheme to use\n * @param options.serverInfo - Server info for verification\n * @returns Hex-encoded signature\n *\n * @example\n * ```typescript\n * const signature = await signSIWxMessage(message, wallet, {\n * signatureScheme: 'eip191'\n * });\n * ```\n */\nexport async function signSIWxMessage(\n message: string,\n signer: SIWxSigner,\n options?: { signatureScheme?: SignatureScheme; serverInfo?: SIWxExtensionInfo },\n): Promise<string> {\n const scheme = options?.signatureScheme || \"eip191\";\n\n switch (scheme) {\n case \"eip191\":\n if (!signer.signMessage) {\n throw new Error(\"Signer does not support personal_sign (EIP-191)\");\n }\n return signer.signMessage(message);\n\n case \"eip712\":\n if (!signer.signTypedData) {\n throw new Error(\"Signer does not support signTypedData (EIP-712)\");\n }\n if (!options?.serverInfo) {\n throw new Error(\"EIP-712 signing requires serverInfo in options\");\n }\n const typedData = createSIWxTypedData(options.serverInfo, signer.address);\n return signer.signTypedData(typedData);\n\n case \"eip1271\":\n case \"eip6492\":\n // Smart wallet signatures go through the same signMessage path\n // but verification happens on-chain\n if (!signer.signMessage) {\n throw new Error(\"Signer does not support signing\");\n }\n return signer.signMessage(message);\n\n case \"siws\":\n // Sign-In With Solana uses Ed25519 signatures\n if (!signer.signMessage) {\n throw new Error(\"Signer does not support signing\");\n }\n // Solana wallets typically implement signMessage that handles the encoding\n return signer.signMessage(message);\n\n case \"sep10\":\n // Stellar SEP-10 uses Ed25519 signatures (same as Solana)\n if (!signer.signMessage) {\n throw new Error(\"Signer does not support signing\");\n }\n // Stellar wallets implement signMessage for Ed25519 signing\n // The wallet handles proper message encoding and returns hex signature\n return signer.signMessage(message);\n\n default:\n throw new Error(`Unknown signature scheme: ${scheme}`);\n }\n}\n\n/**\n * Creates a complete SIWx payload from server extension and signer.\n *\n * This is the main entry point for clients - it handles message construction,\n * signing, and payload assembly.\n *\n * @param serverExtension - Extension from server's 402 response\n * @param signer - Wallet/signer interface\n * @returns Complete signed SIWx payload ready for header encoding\n *\n * @example\n * ```typescript\n * // Get extension from server 402 response\n * const extension = paymentRequirements.extensions?.siwx;\n *\n * // Create signed payload\n * const payload = await createSIWxPayload(extension, wallet);\n *\n * // Encode and send with retry\n * const header = encodeSIWxHeader(payload);\n * fetch(url, {\n * headers: { 'X-T402-SIWx': header }\n * });\n * ```\n */\nexport async function createSIWxPayload(\n serverExtension: SIWxExtension,\n signer: SIWxSigner,\n): Promise<SIWxPayload> {\n const { info } = serverExtension;\n\n // Create the message to sign\n const message = createSIWxMessage(info, signer.address);\n\n // Sign the message\n const signature = await signSIWxMessage(message, signer, {\n signatureScheme: info.signatureScheme,\n serverInfo: info,\n });\n\n // Assemble the complete payload\n return {\n domain: info.domain,\n address: signer.address,\n statement: info.statement,\n uri: info.uri,\n version: info.version,\n chainId: info.chainId,\n nonce: info.nonce,\n issuedAt: info.issuedAt,\n expirationTime: info.expirationTime,\n notBefore: info.notBefore,\n requestId: info.requestId,\n resources: info.resources,\n signature,\n };\n}\n\n/**\n * Extension key for SIWx in payment requirements.\n */\nexport const SIWX_EXTENSION_KEY = \"siwx\";\n\n/**\n * HTTP header name for SIWx payload.\n */\nexport const SIWX_HEADER_NAME = \"X-T402-SIWx\";\n","/**\n * Payment ID Extension Type Definitions\n *\n * Allows servers to attach unique identifiers to payments for\n * correlation, idempotency, and audit trails.\n */\n\n/**\n * Extension key for payment ID in requirements/payload extensions.\n */\nexport const PAYMENT_ID_EXTENSION_KEY = \"paymentId\";\n\n/**\n * Information provided by server about the payment identifier.\n */\nexport interface PaymentIdExtensionInfo {\n /** Unique payment identifier (UUID v4) */\n id: string;\n\n /** Optional idempotency key for replay protection */\n idempotencyKey?: string;\n\n /** Optional payment group for batching */\n groupId?: string;\n\n /** Optional metadata */\n metadata?: Record<string, string>;\n}\n\n/**\n * Payment ID extension declaration for server responses.\n */\nexport interface PaymentIdExtension {\n /** Extension information */\n info: PaymentIdExtensionInfo;\n\n /** JSON Schema for validation */\n schema: object;\n}\n\n/**\n * Payment ID payload echoed back by the client.\n */\nexport interface PaymentIdPayload {\n /** Payment ID echoed back from requirements */\n id: string;\n\n /** Optional client-generated correlation ID */\n clientId?: string;\n}\n\n/**\n * Options for declaring a payment ID extension.\n */\nexport interface DeclarePaymentIdOptions {\n /** Custom payment ID (defaults to crypto.randomUUID()) */\n id?: string;\n\n /** Optional idempotency key for replay protection */\n idempotencyKey?: string;\n\n /** Optional payment group for batching */\n groupId?: string;\n\n /** Optional metadata */\n metadata?: Record<string, string>;\n}\n","/**\n * Payment ID Extension Server-Side Implementation\n *\n * Provides functions for servers to declare payment ID requirements,\n * parse client payloads, and validate payment IDs.\n */\n\nimport { randomUUID } from \"crypto\";\nimport {\n PaymentIdExtension,\n PaymentIdExtensionInfo,\n PaymentIdPayload,\n DeclarePaymentIdOptions,\n PAYMENT_ID_EXTENSION_KEY,\n} from \"./types.js\";\n\n/**\n * JSON Schema for payment ID payload validation.\n */\nconst PAYMENT_ID_SCHEMA = {\n type: \"object\",\n required: [\"id\"],\n properties: {\n id: { type: \"string\", format: \"uuid\" },\n clientId: { type: \"string\" },\n },\n};\n\n/**\n * Declares a payment ID extension for server responses.\n *\n * @param options - Optional configuration for the payment ID\n * @returns Payment ID extension object ready for response\n *\n * @example\n * ```typescript\n * const extension = declarePaymentIdExtension();\n * // Include in PaymentRequired response extensions:\n * // extensions: { [PAYMENT_ID_EXTENSION_KEY]: extension }\n * ```\n */\nexport function declarePaymentIdExtension(\n options: DeclarePaymentIdOptions = {},\n): PaymentIdExtension {\n const info: PaymentIdExtensionInfo = {\n id: options.id || randomUUID(),\n idempotencyKey: options.idempotencyKey,\n groupId: options.groupId,\n metadata: options.metadata,\n };\n\n return {\n info,\n schema: PAYMENT_ID_SCHEMA,\n };\n}\n\n/**\n * Parses a payment ID payload from client request extensions.\n *\n * @param extensions - Extensions object from the payment payload\n * @returns Parsed payment ID payload, or null if not present\n * @throws Error if payload is present but invalid\n *\n * @example\n * ```typescript\n * const payload = parsePaymentIdPayload(paymentPayload.extensions);\n * if (payload) {\n * console.log(\"Payment ID:\", payload.id);\n * }\n * ```\n */\nexport function parsePaymentIdPayload(\n extensions?: Record<string, unknown>,\n): PaymentIdPayload | null {\n if (!extensions || !(PAYMENT_ID_EXTENSION_KEY in extensions)) {\n return null;\n }\n\n const raw = extensions[PAYMENT_ID_EXTENSION_KEY];\n if (typeof raw !== \"object\" || raw === null) {\n throw new Error(\"Invalid paymentId extension: expected object\");\n }\n\n const obj = raw as Record<string, unknown>;\n\n if (typeof obj.id !== \"string\" || obj.id.length === 0) {\n throw new Error(\"Invalid paymentId extension: missing or empty id\");\n }\n\n return {\n id: obj.id,\n clientId: typeof obj.clientId === \"string\" ? obj.clientId : undefined,\n };\n}\n\n/**\n * Validates that a client's payment ID payload matches the expected extension.\n *\n * @param payload - The client's payment ID payload\n * @param expected - The expected payment ID from the server extension\n * @returns True if the payment ID matches\n *\n * @example\n * ```typescript\n * const isValid = validatePaymentId(clientPayload, serverExtension.info);\n * if (!isValid) {\n * throw new Error(\"Payment ID mismatch\");\n * }\n * ```\n */\nexport function validatePaymentId(\n payload: PaymentIdPayload,\n expected: PaymentIdExtensionInfo,\n): boolean {\n return payload.id === expected.id;\n}\n","/**\n * Payment ID Extension Client-Side Implementation\n *\n * Provides functions for clients to echo payment IDs back to servers.\n */\n\nimport { PaymentIdExtension, PaymentIdPayload } from \"./types.js\";\n\n/**\n * Creates a payment ID payload from a server extension.\n *\n * Reads the payment ID from requirements and echoes it back.\n *\n * @param extension - Payment ID extension from server's 402 response\n * @param clientId - Optional client-generated correlation ID\n * @returns Payment ID payload for inclusion in payment extensions\n *\n * @example\n * ```typescript\n * const extension = paymentRequirements.extensions?.paymentId;\n * const payload = createPaymentIdPayload(extension, \"my-correlation-id\");\n * // Include in payment payload extensions:\n * // extensions: { [PAYMENT_ID_EXTENSION_KEY]: payload }\n * ```\n */\nexport function createPaymentIdPayload(\n extension: PaymentIdExtension,\n clientId?: string,\n): PaymentIdPayload {\n return {\n id: extension.info.id,\n clientId,\n };\n}\n\n/**\n * Encodes a payment ID payload for header-based transport.\n *\n * @param payload - The payment ID payload to encode\n * @returns Base64-encoded JSON string\n */\nexport function encodePaymentIdHeader(payload: PaymentIdPayload): string {\n const json = JSON.stringify(payload);\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(json, \"utf-8\").toString(\"base64\");\n }\n return btoa(json);\n}\n","/**\n * EIP-2612 Gas Sponsoring Extension Server-Side Implementation\n *\n * Provides functions for servers to declare gas sponsoring requirements,\n * parse client headers, and validate permit payloads.\n */\n\nimport type {\n Eip2612GasSponsorExtension,\n Eip2612GasSponsorExtensionInfo,\n Eip2612GasSponsorPayload,\n DeclareEip2612GasSponsorOptions,\n ValidateEip2612GasSponsorOptions,\n Eip2612GasSponsorValidationResult,\n} from \"./types.js\";\n\n/**\n * JSON Schema for EIP-2612 gas sponsor payload validation.\n */\nconst EIP2612_GAS_SPONSOR_SCHEMA = {\n type: \"object\",\n required: [\"network\", \"permitSignature\", \"owner\", \"spender\", \"value\", \"deadline\", \"v\", \"r\", \"s\"],\n properties: {\n network: { type: \"string\" },\n permitSignature: { type: \"string\" },\n owner: { type: \"string\" },\n spender: { type: \"string\" },\n value: { type: \"string\" },\n deadline: { type: \"number\" },\n v: { type: \"number\" },\n r: { type: \"string\" },\n s: { type: \"string\" },\n },\n};\n\n/**\n * Declares an EIP-2612 gas sponsor extension for server responses.\n *\n * @param options - Extension declaration options\n * @returns Gas sponsor extension object ready for response\n *\n * @example\n * ```typescript\n * const extension = declareEip2612GasSponsorExtension({\n * sponsoredNetworks: [\"eip155:8453\", \"eip155:42161\"],\n * maxAmount: \"1000000000\",\n * sponsorAddress: \"0xFacilitator...\",\n * });\n * ```\n */\nexport function declareEip2612GasSponsorExtension(\n options: DeclareEip2612GasSponsorOptions,\n): Eip2612GasSponsorExtension {\n const info: Eip2612GasSponsorExtensionInfo = {\n sponsoredNetworks: options.sponsoredNetworks,\n maxAmount: options.maxAmount,\n permitDeadline: options.permitDeadline ?? 300,\n sponsorAddress: options.sponsorAddress,\n };\n\n return {\n info,\n schema: EIP2612_GAS_SPONSOR_SCHEMA,\n };\n}\n\n/**\n * Parses an EIP-2612 gas sponsor header from client request.\n *\n * The header format is base64-encoded JSON.\n *\n * @param header - Base64-encoded gas sponsor header value\n * @returns Parsed gas sponsor payload\n * @throws Error if header is invalid\n *\n * @example\n * ```typescript\n * const payload = parseEip2612GasSponsorHeader(\n * request.headers['x-t402-eip2612-gas-sponsoring']\n * );\n * ```\n */\nexport function parseEip2612GasSponsorHeader(header: string): Eip2612GasSponsorPayload {\n if (!header) {\n throw new Error(\"Missing EIP-2612 gas sponsor header\");\n }\n\n try {\n const decoded = Buffer.from(header, \"base64\").toString(\"utf-8\");\n const payload = JSON.parse(decoded) as Eip2612GasSponsorPayload;\n\n const required = [\n \"network\",\n \"permitSignature\",\n \"owner\",\n \"spender\",\n \"value\",\n \"deadline\",\n \"v\",\n \"r\",\n \"s\",\n ];\n for (const field of required) {\n if (!(field in payload)) {\n throw new Error(`Missing required field: ${field}`);\n }\n }\n\n return payload;\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new Error(\"Invalid EIP-2612 gas sponsor header: malformed JSON\");\n }\n throw error;\n }\n}\n\n/**\n * Validates an EIP-2612 gas sponsor payload against server extension info.\n *\n * @param payload - The gas sponsor payload from the client\n * @param extensionInfo - The server's gas sponsor extension info\n * @param options - Validation options\n * @returns Validation result\n *\n * @example\n * ```typescript\n * const result = validateEip2612GasSponsorPayload(payload, extension.info);\n * if (!result.valid) {\n * throw new Error(result.error);\n * }\n * ```\n */\nexport function validateEip2612GasSponsorPayload(\n payload: Eip2612GasSponsorPayload,\n extensionInfo: Eip2612GasSponsorExtensionInfo,\n options: ValidateEip2612GasSponsorOptions = {},\n): Eip2612GasSponsorValidationResult {\n const now = options.now ? options.now() : Date.now();\n const nowSeconds = Math.floor(now / 1000);\n\n // Validate network is in sponsoredNetworks\n if (!extensionInfo.sponsoredNetworks.includes(payload.network)) {\n return {\n valid: false,\n error: `Network ${payload.network} is not in sponsored networks: ${extensionInfo.sponsoredNetworks.join(\", \")}`,\n };\n }\n\n // Validate amount does not exceed maxAmount\n const payloadValue = BigInt(payload.value);\n const maxAmount = BigInt(extensionInfo.maxAmount);\n if (payloadValue > maxAmount) {\n return {\n valid: false,\n error: `Value ${payload.value} exceeds maximum amount ${extensionInfo.maxAmount}`,\n };\n }\n\n // Validate deadline is in the future\n if (payload.deadline <= nowSeconds) {\n return {\n valid: false,\n error: \"Permit deadline has expired\",\n };\n }\n\n // Validate deadline does not exceed permitDeadline seconds from now\n const maxDeadline = nowSeconds + extensionInfo.permitDeadline;\n if (payload.deadline > maxDeadline) {\n return {\n valid: false,\n error: `Permit deadline ${payload.deadline} exceeds maximum allowed deadline ${maxDeadline}`,\n };\n }\n\n // Validate spender matches sponsorAddress\n if (payload.spender.toLowerCase() !== extensionInfo.sponsorAddress.toLowerCase()) {\n return {\n valid: false,\n error: `Spender ${payload.spender} does not match sponsor address ${extensionInfo.sponsorAddress}`,\n };\n }\n\n // Validate permitSignature format (65 bytes = 130 hex chars)\n const sigHex = payload.permitSignature.startsWith(\"0x\")\n ? payload.permitSignature.slice(2)\n : payload.permitSignature;\n if (sigHex.length !== 130) {\n return {\n valid: false,\n error: `Invalid permit signature length: expected 130 hex chars, got ${sigHex.length}`,\n };\n }\n\n // Validate v is 27 or 28\n if (payload.v !== 27 && payload.v !== 28) {\n return {\n valid: false,\n error: `Invalid v value: expected 27 or 28, got ${payload.v}`,\n };\n }\n\n // Validate r format (32 bytes = 64 hex chars)\n const rHex = payload.r.startsWith(\"0x\") ? payload.r.slice(2) : payload.r;\n if (rHex.length !== 64) {\n return {\n valid: false,\n error: `Invalid r length: expected 64 hex chars, got ${rHex.length}`,\n };\n }\n\n // Validate s format (32 bytes = 64 hex chars)\n const sHex = payload.s.startsWith(\"0x\") ? payload.s.slice(2) : payload.s;\n if (sHex.length !== 64) {\n return {\n valid: false,\n error: `Invalid s length: expected 64 hex chars, got ${sHex.length}`,\n };\n }\n\n return { valid: true };\n}\n","/**\n * EIP-2612 Gas Sponsoring Extension Client-Side Implementation\n *\n * Provides functions for clients to create EIP-2612 permit signatures\n * and encode gas sponsor payloads for transmission.\n */\n\nimport type { Eip2612GasSponsorPayload, CreatePermitParams } from \"./types.js\";\n\n/**\n * Extension key for EIP-2612 gas sponsoring in payment requirements.\n */\nexport const EIP2612_GAS_SPONSOR_EXTENSION_KEY = \"eip2612GasSponsoring\";\n\n/**\n * HTTP header name for EIP-2612 gas sponsor payload.\n */\nexport const EIP2612_GAS_SPONSOR_HEADER_NAME = \"X-T402-EIP2612-Gas-Sponsoring\";\n\n/**\n * Creates an EIP-2612 permit signature using EIP-712 typed data signing.\n *\n * @param params - Permit signing parameters\n * @returns Permit data including the signature components\n *\n * @example\n * ```typescript\n * const permit = await createPermitSignature({\n * signer: wallet,\n * tokenAddress: \"0xUSDT...\",\n * tokenName: \"Tether USD\",\n * chainId: 8453,\n * spender: facilitatorAddress,\n * value: \"1000000\",\n * deadline: Math.floor(Date.now() / 1000) + 300,\n * });\n * ```\n */\nexport async function createPermitSignature(params: CreatePermitParams): Promise<{\n owner: string;\n spender: string;\n value: string;\n deadline: number;\n v: number;\n r: string;\n s: string;\n permitSignature: string;\n}> {\n const { signer, tokenAddress, tokenName, chainId, spender, value, deadline, nonce = 0 } = params;\n\n const domain = {\n name: tokenName,\n version: \"1\",\n chainId,\n verifyingContract: tokenAddress,\n };\n\n const types = {\n Permit: [\n { name: \"owner\", type: \"address\" },\n { name: \"spender\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"deadline\", type: \"uint256\" },\n ],\n };\n\n const message = {\n owner: signer.address,\n spender,\n value,\n nonce,\n deadline,\n };\n\n const signature = await signer.signTypedData({\n domain,\n types,\n primaryType: \"Permit\",\n message,\n });\n\n // Parse signature into components\n const sigHex = signature.startsWith(\"0x\") ? signature.slice(2) : signature;\n\n if (sigHex.length !== 130) {\n throw new Error(`Invalid signature length: expected 130 hex chars, got ${sigHex.length}`);\n }\n\n const r = \"0x\" + sigHex.slice(0, 64);\n const s = \"0x\" + sigHex.slice(64, 128);\n let v = parseInt(sigHex.slice(128, 130), 16);\n\n // Normalize v to 27 or 28\n if (v < 27) {\n v += 27;\n }\n\n return {\n owner: signer.address,\n spender,\n value,\n deadline,\n v,\n r,\n s,\n permitSignature: signature.startsWith(\"0x\") ? signature : \"0x\" + signature,\n };\n}\n\n/**\n * Creates a gas sponsor payload from permit data and network.\n *\n * @param permit - Permit signature data from createPermitSignature\n * @param network - CAIP-2 network identifier (e.g., \"eip155:8453\")\n * @returns Gas sponsor payload ready for header encoding\n *\n * @example\n * ```typescript\n * const payload = createEip2612GasSponsorPayload(permit, \"eip155:8453\");\n * ```\n */\nexport function createEip2612GasSponsorPayload(\n permit: {\n owner: string;\n spender: string;\n value: string;\n deadline: number;\n v: number;\n r: string;\n s: string;\n permitSignature: string;\n },\n network: string,\n): Eip2612GasSponsorPayload {\n return {\n network,\n permitSignature: permit.permitSignature,\n owner: permit.owner,\n spender: permit.spender,\n value: permit.value,\n deadline: permit.deadline,\n v: permit.v,\n r: permit.r,\n s: permit.s,\n };\n}\n\n/**\n * Encodes a gas sponsor payload for transmission in HTTP header.\n *\n * @param payload - The gas sponsor payload to encode\n * @returns Base64-encoded JSON string\n *\n * @example\n * ```typescript\n * const header = encodeEip2612GasSponsorHeader(payload);\n * fetch(url, {\n * headers: { [EIP2612_GAS_SPONSOR_HEADER_NAME]: header }\n * });\n * ```\n */\nexport function encodeEip2612GasSponsorHeader(payload: Eip2612GasSponsorPayload): string {\n const json = JSON.stringify(payload);\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(json, \"utf-8\").toString(\"base64\");\n }\n return btoa(json);\n}\n","/**\n * EIP-2612 Gas Sponsoring Extension Facilitator-Side Implementation\n *\n * Provides functions for facilitators to extract permit data from payment\n * extensions, validate permits, and prepare on-chain submission.\n */\n\nimport type {\n Eip2612GasSponsorPayload,\n Eip2612GasSponsorExtensionInfo,\n Eip2612GasSponsorValidationResult,\n} from \"./types.js\";\nimport { EIP2612_GAS_SPONSOR_EXTENSION_KEY } from \"./client.js\";\nimport { validateEip2612GasSponsorPayload } from \"./server.js\";\n\n/**\n * Extracts the EIP-2612 gas sponsor payload from payment extensions.\n *\n * @param extensions - The extensions map from a PaymentPayload\n * @returns The gas sponsor payload if present, or null\n *\n * @example\n * ```typescript\n * const permit = extractEip2612GasSponsorPayload(paymentPayload.extensions);\n * if (permit) {\n * // Submit permit tx then settle via Permit2\n * }\n * ```\n */\nexport function extractEip2612GasSponsorPayload(\n extensions: Record<string, unknown> | undefined,\n): Eip2612GasSponsorPayload | null {\n if (!extensions) {\n return null;\n }\n\n const raw = extensions[EIP2612_GAS_SPONSOR_EXTENSION_KEY];\n if (!raw || typeof raw !== \"object\") {\n return null;\n }\n\n const payload = raw as Record<string, unknown>;\n\n // Validate required fields are present\n const required = [\n \"network\",\n \"permitSignature\",\n \"owner\",\n \"spender\",\n \"value\",\n \"deadline\",\n \"v\",\n \"r\",\n \"s\",\n ];\n for (const field of required) {\n if (!(field in payload)) {\n return null;\n }\n }\n\n return {\n network: payload.network as string,\n permitSignature: payload.permitSignature as string,\n owner: payload.owner as string,\n spender: payload.spender as string,\n value: payload.value as string,\n deadline: payload.deadline as number,\n v: payload.v as number,\n r: payload.r as string,\n s: payload.s as string,\n };\n}\n\n/**\n * Validates and extracts the EIP-2612 gas sponsor payload in one step.\n *\n * This is a convenience function for facilitators that combines extraction\n * and validation against the server's extension info.\n *\n * @param extensions - The extensions map from a PaymentPayload\n * @param extensionInfo - The server's gas sponsor extension info\n * @returns Validation result with the extracted payload if valid\n *\n * @example\n * ```typescript\n * const result = validateAndExtractPermit(\n * paymentPayload.extensions,\n * extensionInfo\n * );\n * if (result.valid && result.payload) {\n * // Submit permit() on token contract, then settle via Permit2\n * }\n * ```\n */\nexport function validateAndExtractPermit(\n extensions: Record<string, unknown> | undefined,\n extensionInfo: Eip2612GasSponsorExtensionInfo,\n): Eip2612GasSponsorValidationResult & { payload?: Eip2612GasSponsorPayload } {\n const payload = extractEip2612GasSponsorPayload(extensions);\n\n if (!payload) {\n return {\n valid: false,\n error: `Missing or invalid ${EIP2612_GAS_SPONSOR_EXTENSION_KEY} extension in payment`,\n };\n }\n\n const result = validateEip2612GasSponsorPayload(payload, extensionInfo);\n\n if (!result.valid) {\n return result;\n }\n\n return { valid: true, payload };\n}\n\n/**\n * Builds the EIP-2612 permit function call data for on-chain submission.\n *\n * Returns the ABI-encoded parameters needed to call `permit(owner, spender, value, deadline, v, r, s)`\n * on the token contract.\n *\n * @param payload - The validated gas sponsor payload\n * @returns Object with the permit call parameters\n *\n * @example\n * ```typescript\n * const permitCall = buildPermitCallData(payload);\n * // Use permitCall with your preferred web3 library to submit the tx\n * ```\n */\nexport function buildPermitCallData(payload: Eip2612GasSponsorPayload): {\n owner: string;\n spender: string;\n value: string;\n deadline: number;\n v: number;\n r: string;\n s: string;\n} {\n return {\n owner: payload.owner,\n spender: payload.spender,\n value: payload.value,\n deadline: payload.deadline,\n v: payload.v,\n r: payload.r,\n s: payload.s,\n };\n}\n","/**\n * ERC-20 Approval Gas Sponsoring Extension Server-Side Implementation\n *\n * Provides functions for servers to declare gas sponsoring requirements,\n * parse client headers, and validate approval payloads.\n */\n\nimport type {\n ERC20ApprovalGasSponsorExtension,\n ERC20ApprovalGasSponsorExtensionInfo,\n ERC20ApprovalGasSponsorPayload,\n DeclareERC20ApprovalGasSponsorOptions,\n ValidateERC20ApprovalGasSponsorOptions,\n ERC20ApprovalGasSponsorValidationResult,\n} from \"./types.js\";\n\n/**\n * JSON Schema for ERC-20 approval gas sponsor payload validation.\n */\nconst ERC20_APPROVAL_GAS_SPONSOR_SCHEMA = {\n type: \"object\",\n required: [\"network\", \"from\", \"asset\", \"amount\", \"signedApprovalTx\", \"chainId\"],\n properties: {\n network: { type: \"string\" },\n from: { type: \"string\" },\n asset: { type: \"string\" },\n amount: { type: \"string\" },\n signedApprovalTx: { type: \"string\" },\n chainId: { type: \"number\" },\n nonce: { type: \"number\" },\n },\n};\n\n/**\n * Declares an ERC-20 approval gas sponsor extension for server responses.\n *\n * @param options - Extension declaration options\n * @returns Gas sponsor extension object ready for response\n *\n * @example\n * ```typescript\n * const extension = declareERC20ApprovalGasSponsorExtension({\n * sponsoredNetworks: [\"eip155:8453\", \"eip155:42161\"],\n * maxAmount: \"1000000000\",\n * sponsorAddress: \"0xFacilitator...\",\n * requiresAtomicBatch: true,\n * });\n * ```\n */\nexport function declareERC20ApprovalGasSponsorExtension(\n options: DeclareERC20ApprovalGasSponsorOptions,\n): ERC20ApprovalGasSponsorExtension {\n const info: ERC20ApprovalGasSponsorExtensionInfo = {\n sponsoredNetworks: options.sponsoredNetworks,\n maxAmount: options.maxAmount,\n sponsorAddress: options.sponsorAddress,\n requiresAtomicBatch: options.requiresAtomicBatch ?? false,\n };\n\n if (options.permit2Address) {\n info.permit2Address = options.permit2Address;\n }\n\n return {\n info,\n schema: ERC20_APPROVAL_GAS_SPONSOR_SCHEMA,\n };\n}\n\n/**\n * Parses an ERC-20 approval gas sponsor header from client request.\n *\n * The header format is base64-encoded JSON.\n *\n * @param header - Base64-encoded gas sponsor header value\n * @returns Parsed gas sponsor payload\n * @throws Error if header is invalid\n *\n * @example\n * ```typescript\n * const payload = parseERC20ApprovalGasSponsorHeader(\n * request.headers['x-t402-erc20-approval-gas-sponsoring']\n * );\n * ```\n */\nexport function parseERC20ApprovalGasSponsorHeader(header: string): ERC20ApprovalGasSponsorPayload {\n if (!header) {\n throw new Error(\"Missing ERC-20 approval gas sponsor header\");\n }\n\n try {\n const decoded = Buffer.from(header, \"base64\").toString(\"utf-8\");\n const payload = JSON.parse(decoded) as ERC20ApprovalGasSponsorPayload;\n\n const required = [\"network\", \"from\", \"asset\", \"amount\", \"signedApprovalTx\", \"chainId\"];\n for (const field of required) {\n if (!(field in payload)) {\n throw new Error(`Missing required field: ${field}`);\n }\n }\n\n return payload;\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new Error(\"Invalid ERC-20 approval gas sponsor header: malformed JSON\");\n }\n throw error;\n }\n}\n\n/**\n * Validates an ERC-20 approval gas sponsor payload against server extension info.\n *\n * @param payload - The gas sponsor payload from the client\n * @param extensionInfo - The server's gas sponsor extension info\n * @param options - Validation options\n * @returns Validation result\n *\n * @example\n * ```typescript\n * const result = validateERC20ApprovalGasSponsorPayload(payload, extension.info);\n * if (!result.valid) {\n * throw new Error(result.error);\n * }\n * ```\n */\nexport function validateERC20ApprovalGasSponsorPayload(\n payload: ERC20ApprovalGasSponsorPayload,\n extensionInfo: ERC20ApprovalGasSponsorExtensionInfo,\n options: ValidateERC20ApprovalGasSponsorOptions = {},\n): ERC20ApprovalGasSponsorValidationResult {\n // Validate network is in sponsoredNetworks\n if (!extensionInfo.sponsoredNetworks.includes(payload.network)) {\n return {\n valid: false,\n error: `Network ${payload.network} is not in sponsored networks: ${extensionInfo.sponsoredNetworks.join(\", \")}`,\n };\n }\n\n // Validate amount does not exceed maxAmount\n const payloadAmount = BigInt(payload.amount);\n const maxAmount = BigInt(extensionInfo.maxAmount);\n if (payloadAmount > maxAmount) {\n return {\n valid: false,\n error: `Amount ${payload.amount} exceeds maximum amount ${extensionInfo.maxAmount}`,\n };\n }\n\n // Validate chainId matches expected value for network (if provided)\n if (options.expectedChainIds) {\n const expectedChainId = options.expectedChainIds[payload.network];\n if (expectedChainId !== undefined && payload.chainId !== expectedChainId) {\n return {\n valid: false,\n error: `Chain ID ${payload.chainId} does not match expected chain ID ${expectedChainId} for network ${payload.network}`,\n };\n }\n }\n\n // Validate signedApprovalTx is hex-encoded\n const txHex = payload.signedApprovalTx.startsWith(\"0x\")\n ? payload.signedApprovalTx.slice(2)\n : payload.signedApprovalTx;\n if (txHex.length === 0) {\n return {\n valid: false,\n error: \"Signed approval transaction is empty\",\n };\n }\n if (!/^[0-9a-fA-F]+$/.test(txHex)) {\n return {\n valid: false,\n error: \"Signed approval transaction is not valid hex\",\n };\n }\n\n // Validate from address format\n const fromHex = payload.from.startsWith(\"0x\") ? payload.from.slice(2) : payload.from;\n if (fromHex.length !== 40 || !/^[0-9a-fA-F]+$/.test(fromHex)) {\n return {\n valid: false,\n error: `Invalid from address: ${payload.from}`,\n };\n }\n\n // Validate asset address format\n const assetHex = payload.asset.startsWith(\"0x\") ? payload.asset.slice(2) : payload.asset;\n if (assetHex.length !== 40 || !/^[0-9a-fA-F]+$/.test(assetHex)) {\n return {\n valid: false,\n error: `Invalid asset address: ${payload.asset}`,\n };\n }\n\n return { valid: true };\n}\n","/**\n * ERC-20 Approval Gas Sponsoring Extension Client-Side Implementation\n *\n * Provides functions for clients to construct ERC-20 approve() calldata\n * and encode gas sponsor payloads for transmission.\n */\n\nimport type {\n ERC20ApprovalGasSponsorPayload,\n ERC20ApprovalGasSponsorExtensionInfo,\n CreateERC20ApprovalParams,\n} from \"./types.js\";\n\n/**\n * Extension key for ERC-20 approval gas sponsoring in payment requirements.\n */\nexport const ERC20_APPROVAL_GAS_SPONSOR_EXTENSION_KEY = \"erc20ApprovalGasSponsoring\";\n\n/**\n * HTTP header name for ERC-20 approval gas sponsor payload.\n */\nexport const ERC20_APPROVAL_GAS_SPONSOR_HEADER_NAME = \"X-T402-ERC20-Approval-Gas-Sponsoring\";\n\n/**\n * ERC-20 approve(address,uint256) function selector.\n */\nexport const APPROVE_FUNCTION_SELECTOR = \"0x095ea7b3\";\n\n/**\n * Encodes ERC-20 approve(address spender, uint256 amount) calldata.\n *\n * @param spender - The spender address to approve\n * @param amount - The approval amount in base units\n * @returns Hex-encoded calldata with 0x prefix\n *\n * @example\n * ```typescript\n * const calldata = encodeApproveCalldata(\"0xFacilitator...\", \"1000000\");\n * // Returns \"0x095ea7b3\" + abi-encoded args\n * ```\n */\nexport function encodeApproveCalldata(spender: string, amount: string): string {\n // Remove 0x prefix from spender address\n const spenderHex = spender.startsWith(\"0x\") ? spender.slice(2) : spender;\n\n // Pad spender address to 32 bytes (left-padded with zeros)\n const paddedSpender = spenderHex.toLowerCase().padStart(64, \"0\");\n\n // Convert amount to hex and pad to 32 bytes (left-padded with zeros)\n const amountBigInt = BigInt(amount);\n const amountHex = amountBigInt.toString(16).padStart(64, \"0\");\n\n return APPROVE_FUNCTION_SELECTOR + paddedSpender + amountHex;\n}\n\n/**\n * Creates an ERC-20 approval gas sponsor payload from params and extension info.\n *\n * @param info - The server's extension info\n * @param params - The approval parameters\n * @returns Gas sponsor payload ready for header encoding\n *\n * @example\n * ```typescript\n * const payload = createERC20ApprovalGasSponsorPayload(extensionInfo, {\n * network: \"eip155:8453\",\n * from: wallet.address,\n * asset: \"0xUSDT...\",\n * amount: \"1000000\",\n * signedApprovalTx: signedTx,\n * chainId: 8453,\n * });\n * ```\n */\nexport function createERC20ApprovalGasSponsorPayload(\n _info: ERC20ApprovalGasSponsorExtensionInfo,\n params: CreateERC20ApprovalParams,\n): ERC20ApprovalGasSponsorPayload {\n const payload: ERC20ApprovalGasSponsorPayload = {\n network: params.network,\n from: params.from,\n asset: params.asset,\n amount: params.amount,\n signedApprovalTx: params.signedApprovalTx.startsWith(\"0x\")\n ? params.signedApprovalTx\n : \"0x\" + params.signedApprovalTx,\n chainId: params.chainId,\n };\n\n if (params.nonce !== undefined) {\n payload.nonce = params.nonce;\n }\n\n return payload;\n}\n\n/**\n * Encodes an ERC-20 approval gas sponsor payload for transmission in HTTP header.\n *\n * @param payload - The gas sponsor payload to encode\n * @returns Base64-encoded JSON string\n *\n * @example\n * ```typescript\n * const header = encodeERC20ApprovalGasSponsorHeader(payload);\n * fetch(url, {\n * headers: { [ERC20_APPROVAL_GAS_SPONSOR_HEADER_NAME]: header }\n * });\n * ```\n */\nexport function encodeERC20ApprovalGasSponsorHeader(\n payload: ERC20ApprovalGasSponsorPayload,\n): string {\n const json = JSON.stringify(payload);\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(json, \"utf-8\").toString(\"base64\");\n }\n return btoa(json);\n}\n","/**\n * ERC-20 Approval Gas Sponsoring Extension Facilitator-Side Implementation\n *\n * Provides functions for facilitators to extract approval data from payment\n * extensions, validate the signed approve() transaction, and prepare for\n * on-chain submission.\n */\n\nimport type {\n ERC20ApprovalGasSponsorPayload,\n ERC20ApprovalGasSponsorExtensionInfo,\n ERC20ApprovalGasSponsorValidationResult,\n} from \"./types.js\";\nimport { ERC20_APPROVAL_GAS_SPONSOR_EXTENSION_KEY, APPROVE_FUNCTION_SELECTOR } from \"./client.js\";\nimport { validateERC20ApprovalGasSponsorPayload } from \"./server.js\";\n\n/**\n * Extracts the ERC-20 approval gas sponsor payload from payment extensions.\n *\n * @param extensions - The extensions map from a PaymentPayload\n * @returns The gas sponsor payload if present, or null\n *\n * @example\n * ```typescript\n * const approval = extractERC20ApprovalGasSponsorPayload(paymentPayload.extensions);\n * if (approval) {\n * // Validate and broadcast the approval tx, then settle\n * }\n * ```\n */\nexport function extractERC20ApprovalGasSponsorPayload(\n extensions: Record<string, unknown> | undefined,\n): ERC20ApprovalGasSponsorPayload | null {\n if (!extensions) {\n return null;\n }\n\n const raw = extensions[ERC20_APPROVAL_GAS_SPONSOR_EXTENSION_KEY];\n if (!raw || typeof raw !== \"object\") {\n return null;\n }\n\n const payload = raw as Record<string, unknown>;\n\n // Validate required fields are present\n const required = [\"network\", \"from\", \"asset\", \"amount\", \"signedApprovalTx\", \"chainId\"];\n for (const field of required) {\n if (!(field in payload)) {\n return null;\n }\n }\n\n const result: ERC20ApprovalGasSponsorPayload = {\n network: payload.network as string,\n from: payload.from as string,\n asset: payload.asset as string,\n amount: payload.amount as string,\n signedApprovalTx: payload.signedApprovalTx as string,\n chainId: payload.chainId as number,\n };\n\n if (\"nonce\" in payload && payload.nonce !== undefined) {\n result.nonce = payload.nonce as number;\n }\n\n return result;\n}\n\n/**\n * Processes and validates an ERC-20 approval payload for the facilitator.\n *\n * Combines extraction validation with approve() function selector verification.\n * Checks that the signed transaction data contains the correct approve() selector\n * and that the approval amount matches the declared amount.\n *\n * @param payload - The ERC-20 approval gas sponsor payload\n * @param extensionInfo - The server's gas sponsor extension info\n * @returns Validation result\n *\n * @example\n * ```typescript\n * const result = processERC20ApprovalPayload(payload, extensionInfo);\n * if (result.valid) {\n * // Safe to broadcast the approval tx and settle\n * }\n * ```\n */\nexport function processERC20ApprovalPayload(\n payload: ERC20ApprovalGasSponsorPayload,\n extensionInfo: ERC20ApprovalGasSponsorExtensionInfo,\n): ERC20ApprovalGasSponsorValidationResult {\n // Run standard validation\n const validationResult = validateERC20ApprovalGasSponsorPayload(payload, extensionInfo);\n if (!validationResult.valid) {\n return validationResult;\n }\n\n // Verify the signed tx is not empty\n const txHex = payload.signedApprovalTx.startsWith(\"0x\")\n ? payload.signedApprovalTx.slice(2)\n : payload.signedApprovalTx;\n\n if (txHex.length < 8) {\n return {\n valid: false,\n error: \"Signed approval transaction is too short to contain function selector\",\n };\n }\n\n return { valid: true };\n}\n\n/**\n * Validates and extracts the ERC-20 approval gas sponsor payload in one step.\n *\n * This is a convenience function for facilitators that combines extraction\n * and validation against the server's extension info.\n *\n * @param extensions - The extensions map from a PaymentPayload\n * @param extensionInfo - The server's gas sponsor extension info\n * @returns Validation result with the extracted payload if valid\n *\n * @example\n * ```typescript\n * const result = validateAndExtractApproval(\n * paymentPayload.extensions,\n * extensionInfo\n * );\n * if (result.valid && result.payload) {\n * // Broadcast approval tx, then settle\n * }\n * ```\n */\nexport function validateAndExtractApproval(\n extensions: Record<string, unknown> | undefined,\n extensionInfo: ERC20ApprovalGasSponsorExtensionInfo,\n): ERC20ApprovalGasSponsorValidationResult & { payload?: ERC20ApprovalGasSponsorPayload } {\n const payload = extractERC20ApprovalGasSponsorPayload(extensions);\n\n if (!payload) {\n return {\n valid: false,\n error: `Missing or invalid ${ERC20_APPROVAL_GAS_SPONSOR_EXTENSION_KEY} extension in payment`,\n };\n }\n\n const result = processERC20ApprovalPayload(payload, extensionInfo);\n\n if (!result.valid) {\n return result;\n }\n\n return { valid: true, payload };\n}\n\n/**\n * Decodes the approve() calldata from a hex string to extract spender and amount.\n *\n * @param calldata - Hex-encoded approve() calldata (with or without 0x prefix)\n * @returns Decoded spender and amount, or null if not valid approve() calldata\n *\n * @example\n * ```typescript\n * const decoded = decodeApproveCalldata(\"0x095ea7b3...\");\n * if (decoded) {\n * console.log(decoded.spender, decoded.amount);\n * }\n * ```\n */\nexport function decodeApproveCalldata(\n calldata: string,\n): { spender: string; amount: string } | null {\n const hex = calldata.startsWith(\"0x\") ? calldata.slice(2) : calldata;\n\n // approve(address,uint256) = 4 byte selector + 32 byte address + 32 byte amount = 136 hex chars\n if (hex.length < 136) {\n return null;\n }\n\n const selector = \"0x\" + hex.slice(0, 8);\n if (selector !== APPROVE_FUNCTION_SELECTOR) {\n return null;\n }\n\n // Extract spender address (bytes 4-36, last 20 bytes of the 32-byte word)\n const spenderWord = hex.slice(8, 72);\n const spender = \"0x\" + spenderWord.slice(24);\n\n // Extract amount (bytes 36-68)\n const amountHex = hex.slice(72, 136);\n const amount = BigInt(\"0x\" + amountHex).toString(10);\n\n return { spender, amount };\n}\n"],"mappings":"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","names":["isBodyMethod","Ajv","nobleSha256","messageHash","import_crypto"]}
|