@x402/extensions 2.5.0 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts","../../src/bazaar/http/types.ts","../../src/bazaar/mcp/types.ts","../../src/bazaar/types.ts","../../src/bazaar/http/resourceService.ts","../../src/bazaar/mcp/resourceService.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/types.ts","../../src/sign-in-with-x/solana.ts","../../src/sign-in-with-x/schema.ts","../../src/sign-in-with-x/declare.ts","../../src/sign-in-with-x/server.ts","../../src/sign-in-with-x/parse.ts","../../src/sign-in-with-x/validate.ts","../../src/sign-in-with-x/evm.ts","../../src/sign-in-with-x/verify.ts","../../src/sign-in-with-x/message.ts","../../src/sign-in-with-x/sign.ts","../../src/sign-in-with-x/client.ts","../../src/sign-in-with-x/encode.ts","../../src/sign-in-with-x/fetch.ts","../../src/sign-in-with-x/storage.ts","../../src/sign-in-with-x/hooks.ts","../../src/payment-identifier/types.ts","../../src/payment-identifier/schema.ts","../../src/payment-identifier/utils.ts","../../src/payment-identifier/validation.ts","../../src/payment-identifier/client.ts","../../src/payment-identifier/resourceServer.ts","../../src/eip2612-gas-sponsoring/types.ts","../../src/eip2612-gas-sponsoring/resourceService.ts","../../src/eip2612-gas-sponsoring/facilitator.ts","../../src/erc20-approval-gas-sponsoring/types.ts","../../src/erc20-approval-gas-sponsoring/resourceService.ts","../../src/erc20-approval-gas-sponsoring/facilitator.ts"],"sourcesContent":["// Shared extension utilities\nexport { 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-identifier extension\nexport * from \"./payment-identifier\";\nexport { paymentIdentifierResourceServerExtension } from \"./payment-identifier/resourceServer\";\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 * HTTP-specific type definitions for the Bazaar Discovery Extension\n */\n\nimport type { BodyMethods, QueryParamMethods } from \"@x402/core/http\";\nimport type { DiscoveryInfo } from \"../types\";\n\n/**\n * Discovery info for query parameter methods (GET, HEAD, DELETE)\n */\nexport interface QueryDiscoveryInfo {\n input: {\n type: \"http\";\n /** Absent at declaration time; set by bazaarResourceServerExtension.enrichDeclaration */\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 /** Absent at declaration time; set by bazaarResourceServerExtension.enrichDeclaration */\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 * 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\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 interface DiscoveredHTTPResource {\n resourceUrl: string;\n description?: string;\n mimeType?: string;\n /** Present after server extension enrichment; may be absent for pre-enrichment data */\n method?: string;\n x402Version: number;\n discoveryInfo: DiscoveryInfo;\n}\n\nexport const isQueryExtensionConfig = (\n config: DeclareQueryDiscoveryExtensionConfig | DeclareBodyDiscoveryExtensionConfig,\n): config is DeclareQueryDiscoveryExtensionConfig => {\n return !(\"bodyType\" in config) && !(\"toolName\" in config);\n};\n\nexport const isBodyExtensionConfig = (\n config: DeclareQueryDiscoveryExtensionConfig | DeclareBodyDiscoveryExtensionConfig,\n): config is DeclareBodyDiscoveryExtensionConfig => {\n return \"bodyType\" in config;\n};\n","/**\n * MCP-specific type definitions for the Bazaar Discovery Extension\n */\n\nimport type { DiscoveryInfo } from \"../types\";\n\n/**\n * Discovery info for MCP tools\n */\nexport interface McpDiscoveryInfo {\n input: {\n type: \"mcp\";\n toolName: string;\n description?: string;\n transport?: \"streamable-http\" | \"sse\";\n inputSchema: Record<string, unknown>;\n example?: Record<string, unknown>;\n };\n output?: {\n type?: string;\n format?: string;\n example?: unknown;\n };\n}\n\n/**\n * Discovery extension for MCP tools\n */\nexport interface McpDiscoveryExtension {\n info: McpDiscoveryInfo;\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: \"mcp\";\n };\n toolName: {\n type: \"string\";\n };\n description?: {\n type: \"string\";\n };\n transport?: {\n type: \"string\";\n enum: [\"streamable-http\", \"sse\"];\n };\n inputSchema: Record<string, unknown>;\n example?: Record<string, unknown>;\n };\n required: (\"type\" | \"toolName\" | \"inputSchema\")[];\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\nexport interface DeclareMcpDiscoveryExtensionConfig {\n toolName: string;\n description?: string;\n transport?: \"streamable-http\" | \"sse\";\n inputSchema: Record<string, unknown>;\n example?: Record<string, unknown>;\n output?: {\n example?: unknown;\n schema?: Record<string, unknown>;\n };\n}\n\nexport interface DiscoveredMCPResource {\n resourceUrl: string;\n description?: string;\n mimeType?: string;\n toolName: string;\n x402Version: number;\n discoveryInfo: DiscoveryInfo;\n}\n\nexport const isMcpExtensionConfig = (\n config: DeclareMcpDiscoveryExtensionConfig | Record<string, unknown>,\n): config is DeclareMcpDiscoveryExtensionConfig => {\n return \"toolName\" in config;\n};\n","/**\n * Shared type definitions for the Bazaar Discovery Extension\n *\n * Protocol-specific types live in their own directories (http/, mcp/).\n * This file defines the shared unions, constants, and utility types,\n * and re-exports all protocol-specific types for backwards compatibility.\n */\n\nimport type { FacilitatorExtension } from \"@x402/core/types\";\n\n// --- Shared union types ---\n\nimport type { QueryDiscoveryInfo, BodyDiscoveryInfo } from \"./http/types\";\nimport type { McpDiscoveryInfo } from \"./mcp/types\";\nimport type { QueryDiscoveryExtension, BodyDiscoveryExtension } from \"./http/types\";\nimport type { McpDiscoveryExtension } from \"./mcp/types\";\nimport type {\n DeclareQueryDiscoveryExtensionConfig,\n DeclareBodyDiscoveryExtensionConfig,\n} from \"./http/types\";\nimport type { DeclareMcpDiscoveryExtensionConfig } from \"./mcp/types\";\n\n// Re-export protocol-specific types\nexport type {\n QueryDiscoveryInfo,\n BodyDiscoveryInfo,\n QueryDiscoveryExtension,\n BodyDiscoveryExtension,\n DeclareQueryDiscoveryExtensionConfig,\n DeclareBodyDiscoveryExtensionConfig,\n DiscoveredHTTPResource,\n} from \"./http/types\";\n\nexport { isQueryExtensionConfig, isBodyExtensionConfig } from \"./http/types\";\n\nexport type {\n McpDiscoveryInfo,\n McpDiscoveryExtension,\n DeclareMcpDiscoveryExtensionConfig,\n DiscoveredMCPResource,\n} from \"./mcp/types\";\n\nexport { isMcpExtensionConfig } from \"./mcp/types\";\n\n// --- Shared constants ---\n\n/**\n * Extension identifier for the Bazaar discovery extension.\n */\nexport const BAZAAR: FacilitatorExtension = { key: \"bazaar\" };\n\n/**\n * Combined discovery info type\n */\nexport type DiscoveryInfo = QueryDiscoveryInfo | BodyDiscoveryInfo | McpDiscoveryInfo;\n\n/**\n * Combined discovery extension type\n */\nexport type DiscoveryExtension =\n | QueryDiscoveryExtension\n | BodyDiscoveryExtension\n | McpDiscoveryExtension;\n\nexport type DeclareDiscoveryExtensionConfig =\n | DeclareQueryDiscoveryExtensionConfig\n | DeclareBodyDiscoveryExtensionConfig\n | DeclareMcpDiscoveryExtensionConfig;\n\n/**\n * Distributive Omit - properly distributes Omit over union types.\n *\n * Standard `Omit<A | B, K>` collapses to common properties only,\n * losing discriminant properties like `bodyType`.\n *\n * This type uses conditional type distribution to preserve the union:\n * `DistributiveOmit<A | B, K>` = `Omit<A, K> | Omit<B, K>`\n */\nexport type DistributiveOmit<T, K extends keyof T> = T extends T ? Omit<T, K> : never;\n\n/**\n * Config type for declareDiscoveryExtension function.\n * Uses DistributiveOmit to preserve bodyType discriminant in the union for HTTP configs.\n * MCP config has no `method` field so it's included directly.\n */\nexport type DeclareDiscoveryExtensionInput =\n | DistributiveOmit<DeclareQueryDiscoveryExtensionConfig, \"method\">\n | DistributiveOmit<DeclareBodyDiscoveryExtensionConfig, \"method\">\n | DeclareMcpDiscoveryExtensionConfig;\n","/**\n * HTTP resource service functions for creating Bazaar discovery extensions\n */\n\nimport type {\n QueryDiscoveryExtension,\n BodyDiscoveryExtension,\n DeclareQueryDiscoveryExtensionConfig,\n DeclareBodyDiscoveryExtensionConfig,\n} from \"./types\";\n\n/**\n * Create a query discovery extension (GET, HEAD, DELETE)\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 */\nexport function createQueryDiscoveryExtension({\n method,\n input = {},\n inputSchema = { properties: {} },\n output,\n}: DeclareQueryDiscoveryExtensionConfig): QueryDiscoveryExtension {\n return {\n info: {\n input: {\n type: \"http\" as const,\n ...(method ? { method } : {}),\n ...(input ? { queryParams: input } : {}),\n },\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 * Create a body discovery extension (POST, PUT, PATCH)\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-data, text)\n * @param root0.output - Output specification with example\n * @returns BodyDiscoveryExtension with info and schema\n */\nexport function createBodyDiscoveryExtension({\n method,\n input = {},\n inputSchema = { properties: {} },\n bodyType,\n output,\n}: DeclareBodyDiscoveryExtensionConfig): BodyDiscoveryExtension {\n return {\n info: {\n input: {\n type: \"http\" as const,\n ...(method ? { method } : {}),\n bodyType,\n body: input,\n },\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 * MCP resource service functions for creating Bazaar discovery extensions\n */\n\nimport type { McpDiscoveryExtension, DeclareMcpDiscoveryExtensionConfig } from \"./types\";\n\n/**\n * Create an MCP tool discovery extension\n *\n * @param root0 - Configuration object for MCP discovery extension\n * @param root0.toolName - MCP tool name\n * @param root0.description - Tool description\n * @param root0.inputSchema - JSON Schema for tool arguments\n * @param root0.example - Example tool arguments\n * @param root0.output - Output specification with example\n * @param root0.transport - MCP transport type (streamable-http or sse)\n * @returns McpDiscoveryExtension with info and schema\n */\nexport function createMcpDiscoveryExtension({\n toolName,\n description,\n transport,\n inputSchema,\n example,\n output,\n}: DeclareMcpDiscoveryExtensionConfig): McpDiscoveryExtension {\n return {\n info: {\n input: {\n type: \"mcp\",\n toolName,\n ...(description !== undefined ? { description } : {}),\n ...(transport !== undefined ? { transport } : {}),\n inputSchema,\n ...(example !== undefined ? { example } : {}),\n },\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: \"mcp\",\n },\n toolName: {\n type: \"string\",\n },\n ...(description !== undefined\n ? {\n description: {\n type: \"string\" as const,\n },\n }\n : {}),\n ...(transport !== undefined\n ? {\n transport: {\n type: \"string\" as const,\n enum: [\"streamable-http\", \"sse\"],\n },\n }\n : {}),\n inputSchema: {\n type: \"object\" as const,\n },\n ...(example !== undefined\n ? {\n example: {\n type: \"object\" as const,\n },\n }\n : {}),\n },\n required: [\"type\", \"toolName\", \"inputSchema\"] as (\"type\" | \"toolName\" | \"inputSchema\")[],\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 * Resource Service entry point for creating Bazaar discovery extensions\n *\n * This module provides the unified `declareDiscoveryExtension` function that\n * routes to protocol-specific builders in http/ and mcp/.\n */\n\nimport type { DiscoveryExtension, DeclareDiscoveryExtensionInput } from \"./types\";\nimport type {\n DeclareQueryDiscoveryExtensionConfig,\n DeclareBodyDiscoveryExtensionConfig,\n} from \"./http/types\";\nimport type { DeclareMcpDiscoveryExtensionConfig } from \"./mcp/types\";\nimport {\n createQueryDiscoveryExtension,\n createBodyDiscoveryExtension,\n} from \"./http/resourceService\";\nimport { createMcpDiscoveryExtension } from \"./mcp/resourceService\";\n\n/**\n * Create a discovery extension for any HTTP method or MCP tool\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 * // For an MCP tool\n * const mcpExtension = declareDiscoveryExtension({\n * toolName: \"financial_analysis\",\n * description: \"Analyze financial data for a given ticker\",\n * inputSchema: {\n * type: \"object\",\n * properties: {\n * ticker: { type: \"string\" },\n * },\n * required: [\"ticker\"],\n * },\n * output: {\n * example: { pe_ratio: 28.5, recommendation: \"hold\" }\n * }\n * });\n * ```\n */\nexport function declareDiscoveryExtension(\n config: DeclareDiscoveryExtensionInput,\n): Record<string, DiscoveryExtension> {\n if (\"toolName\" in config) {\n const extension = createMcpDiscoveryExtension(config as DeclareMcpDiscoveryExtensionConfig);\n return { bazaar: extension as DiscoveryExtension };\n }\n\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 \"@x402/core/types\";\nimport type { HTTPRequestContext } from \"@x402/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 properties?: {\n [key: string]: unknown;\n method?: Record<string, unknown>;\n };\n required?: string[];\n };\n };\n };\n}\n\nexport const bazaarResourceServerExtension: ResourceServerExtension = {\n key: BAZAAR.key,\n\n enrichDeclaration: (declaration, transportContext) => {\n if (!isHTTPRequestContext(transportContext)) {\n return declaration;\n }\n\n const extension = declaration as ExtensionDeclaration;\n\n // MCP extensions don't need HTTP method enrichment\n if (extension.info?.input?.type === \"mcp\") {\n return declaration;\n }\n\n const method = transportContext.method;\n\n // At declaration time, the schema uses a broad enum ([\"GET\", \"HEAD\", \"DELETE\"] or [\"POST\", \"PUT\", \"PATCH\"])\n // because the method isn't known until the HTTP context is available.\n // Here we narrow it to the actual method for precise schema validation.\n const existingInputProps = extension.schema?.properties?.input?.properties || {};\n const updatedInputProps = {\n ...existingInputProps,\n method: {\n type: \"string\",\n enum: [method],\n },\n };\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 properties: updatedInputProps,\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.js\";\nimport type { PaymentPayload, PaymentRequirements, PaymentRequirementsV1 } from \"@x402/core/types\";\nimport type { DiscoveryExtension, DiscoveryInfo } from \"./types\";\nimport type { McpDiscoveryInfo } from \"./mcp/types\";\nimport type { DiscoveredHTTPResource } from \"./http/types\";\nimport type { DiscoveredMCPResource } from \"./mcp/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 type { DiscoveredHTTPResource } from \"./http/types\";\nexport type { DiscoveredMCPResource } from \"./mcp/types\";\n\nexport type DiscoveredResource = DiscoveredHTTPResource | DiscoveredMCPResource;\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.x402Version === 2) {\n resourceUrl = paymentPayload.resource?.url ?? \"\";\n\n if (paymentPayload.extensions) {\n const bazaarExtension = paymentPayload.extensions[BAZAAR.key];\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.x402Version === 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 // Strip query params (?) and hash sections (#) for discovery cataloging\n const url = new URL(resourceUrl);\n const normalizedResourceUrl = `${url.origin}${url.pathname}`;\n\n // Extract description and mimeType from resource info (v2) or requirements (v1)\n let description: string | undefined;\n let mimeType: string | undefined;\n\n if (paymentPayload.x402Version === 2) {\n description = paymentPayload.resource?.description;\n mimeType = paymentPayload.resource?.mimeType;\n } else if (paymentPayload.x402Version === 1) {\n const requirementsV1 = paymentRequirements as PaymentRequirementsV1;\n description = requirementsV1.description;\n mimeType = requirementsV1.mimeType;\n }\n\n const base = {\n resourceUrl: normalizedResourceUrl,\n description,\n mimeType,\n x402Version: paymentPayload.x402Version,\n discoveryInfo,\n };\n\n if (discoveryInfo.input.type === \"mcp\") {\n return { ...base, toolName: (discoveryInfo as McpDiscoveryInfo).input.toolName };\n }\n\n return { ...base, method: discoveryInfo.input.method };\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 \"@x402/core/types\";\nimport type { BodyMethods, QueryParamMethods } from \"@x402/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 \"@x402/core/http\";\nimport type { PaymentRequirements } from \"@x402/core/types\";\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 */\n type?: string;\n\n /**\n * The number of discovered x402 resources to return per page.\n */\n limit?: number;\n\n /**\n * The offset of the first discovered x402 resource to return.\n */\n offset?: number;\n}\n\n/**\n * A discovered x402 resource from the bazaar.\n */\nexport interface DiscoveryResource {\n /** The URL or identifier of the discovered resource */\n resource: string;\n /** The protocol type of the resource (e.g., \"http\") */\n type: string;\n /** The x402 protocol version supported by this resource */\n x402Version: number;\n /** Array of accepted payment methods for this resource */\n accepts: PaymentRequirements[];\n /** ISO 8601 timestamp of when the resource was last updated */\n lastUpdated: 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 x402 protocol version of this response */\n x402Version: number;\n /** The list of discovered resources */\n items: DiscoveryResource[];\n /** Pagination information for the response */\n pagination: {\n /** Maximum number of results returned */\n limit: number;\n /** Number of results skipped */\n offset: number;\n /** Total count of resources matching the query */\n total: number;\n };\n}\n\n/**\n * Bazaar client extension interface providing discovery query functionality.\n */\nexport interface BazaarClientExtension {\n discovery: {\n /**\n * List x402 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 * Type definitions for the Sign-In-With-X (SIWX) extension\n *\n * Implements CAIP-122 standard for chain-agnostic wallet-based identity assertions.\n * Per x402 v2 spec: typescript/site/CHANGELOG-v2.md lines 237-341\n */\n\nimport { z } from \"zod\";\n\n/**\n * Extension identifier constant\n */\nexport const SIGN_IN_WITH_X = \"sign-in-with-x\";\n\n/**\n * Supported signature schemes per CHANGELOG-v2.md line 271.\n *\n * NOTE: This is primarily informational. Actual signature verification\n * is determined by the chainId prefix, not this field:\n * - `eip155:*` chains use EVM verification (handles eip191, eip712, eip1271, eip6492 automatically)\n * - `solana:*` chains use Ed25519 verification (siws)\n *\n * The signatureScheme field serves as a hint for clients to select\n * the appropriate signing UX.\n */\nexport type SignatureScheme =\n | \"eip191\" // personal_sign (default for EVM EOAs)\n | \"eip1271\" // smart contract wallet verification\n | \"eip6492\" // counterfactual smart wallet verification\n | \"siws\"; // Sign-In-With-Solana\n\n/** Signature algorithm type per CAIP-122 */\nexport type SignatureType = \"eip191\" | \"ed25519\";\n\n/**\n * Supported chain configuration in supportedChains array.\n * Specifies which chains the server accepts for authentication.\n */\nexport interface SupportedChain {\n /** CAIP-2 chain identifier (e.g., \"eip155:8453\", \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\") */\n chainId: string;\n /** Signature algorithm type per CAIP-122 */\n type: SignatureType;\n /** Optional signature scheme hint (informational) */\n signatureScheme?: SignatureScheme;\n}\n\n/**\n * Server-declared extension info included in PaymentRequired.extensions.\n * Contains message metadata shared across all supported chains.\n * Per CHANGELOG-v2.md lines 263-272\n */\nexport interface SIWxExtensionInfo {\n /** Server's domain */\n domain: string;\n /** Full resource URI */\n uri: string;\n /** Human-readable purpose for signing */\n statement?: string;\n /** CAIP-122 version, always \"1\" */\n version: string;\n /** Cryptographic nonce (SDK auto-generates) */\n nonce: string;\n /** ISO 8601 timestamp (SDK auto-generates) */\n issuedAt: string;\n /** Optional expiry (default: +5 min) */\n expirationTime?: string;\n /** Optional validity start */\n notBefore?: string;\n /** Optional correlation ID */\n requestId?: string;\n /** Associated resources */\n resources?: string[];\n}\n\n/**\n * JSON Schema for SIWX extension validation\n * Per CHANGELOG-v2.md lines 276-292\n */\nexport interface SIWxExtensionSchema {\n $schema: string;\n type: \"object\";\n properties: {\n domain: { type: \"string\" };\n address: { type: \"string\" };\n statement?: { type: \"string\" };\n uri: { type: \"string\"; format: \"uri\" };\n version: { type: \"string\" };\n chainId: { type: \"string\" };\n type: { 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\"; format: \"uri\" } };\n signature: { type: \"string\" };\n };\n required: string[];\n}\n\n/**\n * Complete SIWX extension structure (info + supportedChains + schema).\n * Follows standard x402 v2 extension pattern with multi-chain support.\n */\nexport interface SIWxExtension {\n info: SIWxExtensionInfo;\n supportedChains: SupportedChain[];\n schema: SIWxExtensionSchema;\n}\n\n/**\n * Zod schema for SIWX payload validation\n * Client proof payload sent in SIGN-IN-WITH-X header\n * Per CHANGELOG-v2.md lines 301-315\n */\nexport const SIWxPayloadSchema = z.object({\n domain: z.string(),\n address: z.string(),\n statement: z.string().optional(),\n uri: z.string(),\n version: z.string(),\n chainId: z.string(),\n type: z.enum([\"eip191\", \"ed25519\"]),\n nonce: z.string(),\n issuedAt: z.string(),\n expirationTime: z.string().optional(),\n notBefore: z.string().optional(),\n requestId: z.string().optional(),\n resources: z.array(z.string()).optional(),\n signatureScheme: z.enum([\"eip191\", \"eip1271\", \"eip6492\", \"siws\"]).optional(),\n signature: z.string(),\n});\n\n/**\n * Client proof payload type (inferred from zod schema)\n */\nexport type SIWxPayload = z.infer<typeof SIWxPayloadSchema>;\n\n/**\n * Options for declaring SIWX extension on server.\n *\n * Most fields are optional and derived automatically from request context:\n * - `domain`: Parsed from resourceUri or request URL\n * - `resourceUri`: From request URL\n * - `network`: From payment requirements (accepts[].network)\n *\n * Explicit values override automatic derivation.\n */\nexport interface DeclareSIWxOptions {\n /** Server's domain. If omitted, derived from resourceUri or request URL. */\n domain?: string;\n /** Full resource URI. If omitted, derived from request URL. */\n resourceUri?: string;\n /** Human-readable purpose */\n statement?: string;\n /** CAIP-122 version (default: \"1\") */\n version?: string;\n /**\n * Network(s) to support. If omitted, derived from payment requirements.\n * - Single chain: \"eip155:8453\" or \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\"\n * - Multi-chain: [\"eip155:8453\", \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\"]\n */\n network?: string | string[];\n /**\n * Optional expiration duration in seconds.\n * - Number (e.g., 300): Signature expires after this many seconds\n * - undefined: Infinite expiration (no expirationTime field in wire format)\n */\n expirationSeconds?: number;\n}\n\n/**\n * Validation result from validateSIWxMessage\n */\nexport interface SIWxValidationResult {\n valid: boolean;\n error?: string;\n}\n\n/**\n * Options for message validation\n */\nexport interface SIWxValidationOptions {\n /** Maximum age for issuedAt in milliseconds (default: 5 minutes) */\n maxAge?: number;\n /** Custom nonce validation function */\n checkNonce?: (nonce: string) => boolean | Promise<boolean>;\n}\n\n/**\n * Result from signature verification\n */\nexport interface SIWxVerifyResult {\n valid: boolean;\n /** Recovered/verified address (checksummed) */\n address?: string;\n error?: string;\n}\n\n/**\n * EVM message verifier function type.\n * Compatible with viem's publicClient.verifyMessage().\n *\n * When provided to verifySIWxSignature, enables:\n * - EIP-1271 (deployed smart contract wallets)\n * - EIP-6492 (counterfactual/pre-deploy smart wallets)\n *\n * Without a verifier, only EOA signatures (EIP-191) can be verified.\n *\n * @example\n * ```typescript\n * import { createPublicClient, http } from 'viem';\n * import { base } from 'viem/chains';\n *\n * const publicClient = createPublicClient({ chain: base, transport: http() });\n * // publicClient.verifyMessage satisfies EVMMessageVerifier\n * ```\n */\nexport type EVMMessageVerifier = (args: {\n address: `0x${string}`;\n message: string;\n signature: `0x${string}`;\n}) => Promise<boolean>;\n\n/**\n * Options for SIWX signature verification\n */\nexport interface SIWxVerifyOptions {\n /**\n * EVM message verifier for smart wallet support.\n *\n * Pass `publicClient.verifyMessage` from viem to enable verification of:\n * - Smart contract wallets (EIP-1271)\n * - Counterfactual/undeployed smart wallets (EIP-6492)\n *\n * If not provided, only EOA signatures are verified using standalone\n * ECDSA recovery (no RPC calls required).\n */\n evmVerifier?: EVMMessageVerifier;\n}\n","/**\n * Solana Sign-In-With-X (SIWS) support\n *\n * Implements CAIP-122 compliant message format and Ed25519 signature verification\n * for Solana wallets.\n */\n\nimport { base58 } from \"@scure/base\";\nimport nacl from \"tweetnacl\";\nimport type { CompleteSIWxInfo } from \"./client\";\nimport type { SIWxSigner } from \"./sign\";\n\n/**\n * Common Solana network CAIP-2 identifiers.\n * Uses genesis hash as the chain reference per CAIP-30.\n */\nexport const SOLANA_MAINNET = \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\";\nexport const SOLANA_DEVNET = \"solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1\";\nexport const SOLANA_TESTNET = \"solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z\";\n\n/**\n * Extract chain reference from CAIP-2 Solana chainId.\n *\n * @param chainId - CAIP-2 format chain ID (e.g., \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\")\n * @returns Chain reference (genesis hash)\n *\n * @example\n * ```typescript\n * extractSolanaChainReference(\"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\") // \"5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\"\n * ```\n */\nexport function extractSolanaChainReference(chainId: string): string {\n const [, reference] = chainId.split(\":\");\n return reference;\n}\n\n/**\n * Format SIWS message following CAIP-122 ABNF specification.\n *\n * The message format is identical to SIWE (EIP-4361) but uses \"Solana account\"\n * instead of \"Ethereum account\" in the header line.\n *\n * @param info - Server-provided extension info\n * @param address - Client's Solana wallet address (Base58 encoded public key)\n * @returns Message string ready for signing\n *\n * @example\n * ```typescript\n * const message = formatSIWSMessage(serverInfo, \"BSmWDgE9ex6dZYbiTsJGcwMEgFp8q4aWh92hdErQPeVW\");\n * // Returns:\n * // \"api.example.com wants you to sign in with your Solana account:\n * // BSmWDgE9ex6dZYbiTsJGcwMEgFp8q4aWh92hdErQPeVW\n * //\n * // Sign in to access your content\n * //\n * // URI: https://api.example.com/data\n * // Version: 1\n * // Chain ID: mainnet\n * // Nonce: abc123\n * // Issued At: 2024-01-01T00:00:00.000Z\"\n * ```\n */\nexport function formatSIWSMessage(info: CompleteSIWxInfo, address: string): string {\n const lines: string[] = [\n `${info.domain} wants you to sign in with your Solana account:`,\n address,\n \"\",\n ];\n\n // Statement (optional, with blank line after)\n if (info.statement) {\n lines.push(info.statement, \"\");\n }\n\n // Required fields\n lines.push(\n `URI: ${info.uri}`,\n `Version: ${info.version}`,\n `Chain ID: ${extractSolanaChainReference(info.chainId)}`,\n `Nonce: ${info.nonce}`,\n `Issued At: ${info.issuedAt}`,\n );\n\n // Optional fields\n if (info.expirationTime) {\n lines.push(`Expiration Time: ${info.expirationTime}`);\n }\n if (info.notBefore) {\n lines.push(`Not Before: ${info.notBefore}`);\n }\n if (info.requestId) {\n lines.push(`Request ID: ${info.requestId}`);\n }\n\n // Resources (optional)\n if (info.resources && info.resources.length > 0) {\n lines.push(\"Resources:\");\n for (const resource of info.resources) {\n lines.push(`- ${resource}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Verify Ed25519 signature for SIWS.\n *\n * @param message - The SIWS message that was signed\n * @param signature - Ed25519 signature bytes\n * @param publicKey - Solana public key bytes (32 bytes)\n * @returns true if signature is valid\n *\n * @example\n * ```typescript\n * const messageBytes = new TextEncoder().encode(message);\n * const valid = verifySolanaSignature(message, signatureBytes, publicKeyBytes);\n * ```\n */\nexport function verifySolanaSignature(\n message: string,\n signature: Uint8Array,\n publicKey: Uint8Array,\n): boolean {\n const messageBytes = new TextEncoder().encode(message);\n return nacl.sign.detached.verify(messageBytes, signature, publicKey);\n}\n\n/**\n * Decode Base58 string to bytes.\n *\n * Solana uses Base58 encoding (Bitcoin alphabet) for addresses and signatures.\n *\n * @param encoded - Base58 encoded string\n * @returns Decoded bytes\n * @throws Error if string contains invalid Base58 characters\n *\n * @example\n * ```typescript\n * const publicKeyBytes = decodeBase58(\"BSmWDgE9ex6dZYbiTsJGcwMEgFp8q4aWh92hdErQPeVW\");\n * // Returns Uint8Array of 32 bytes\n * ```\n */\nexport function decodeBase58(encoded: string): Uint8Array {\n return base58.decode(encoded);\n}\n\n/**\n * Encode bytes to Base58 string.\n *\n * @param bytes - Bytes to encode\n * @returns Base58 encoded string\n */\nexport function encodeBase58(bytes: Uint8Array): string {\n return base58.encode(bytes);\n}\n\n/**\n * Detect if a signer is Solana-compatible.\n * Checks for Solana-specific properties that don't exist on EVM signers.\n *\n * @param signer - The signer to check\n * @returns true if the signer is a Solana signer\n */\nexport function isSolanaSigner(signer: SIWxSigner): boolean {\n // SolanaKitSigner has signMessages method (plural) - only Solana has this\n if (\"signMessages\" in signer && typeof signer.signMessages === \"function\") {\n return true;\n }\n // WalletAdapterSigner has publicKey property\n // But viem also has publicKey (as hex string), so we need to distinguish:\n // - Solana wallet adapter: publicKey has toBase58() method OR is a non-hex string\n // - viem: publicKey is a hex string starting with 0x\n if (\"publicKey\" in signer && signer.publicKey) {\n const pk = signer.publicKey;\n // Check for toBase58 method (Solana PublicKey object)\n if (typeof pk === \"object\" && pk !== null && \"toBase58\" in pk) {\n return true;\n }\n // Check for non-hex string (Solana base58 address)\n if (typeof pk === \"string\" && !pk.startsWith(\"0x\")) {\n return true;\n }\n }\n return false;\n}\n","/**\n * JSON Schema builder for SIWX extension\n *\n * Per CHANGELOG-v2.md lines 276-292\n */\n\nimport type { SIWxExtensionSchema } from \"./types\";\n\n/**\n * Build JSON Schema for SIWX extension validation.\n * This schema validates the client proof payload structure.\n *\n * @returns JSON Schema for validating SIWX client payloads\n */\nexport function buildSIWxSchema(): SIWxExtensionSchema {\n return {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n properties: {\n domain: { type: \"string\" },\n address: { type: \"string\" },\n statement: { type: \"string\" },\n uri: { type: \"string\", format: \"uri\" },\n version: { type: \"string\" },\n chainId: { type: \"string\" },\n type: { 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\", format: \"uri\" } },\n signature: { type: \"string\" },\n },\n required: [\n \"domain\",\n \"address\",\n \"uri\",\n \"version\",\n \"chainId\",\n \"type\",\n \"nonce\",\n \"issuedAt\",\n \"signature\",\n ],\n };\n}\n","/**\n * Server-side declaration helper for SIWX extension\n *\n * Helps servers declare SIWX authentication requirements in PaymentRequired responses.\n */\n\nimport type {\n SIWxExtension,\n SIWxExtensionInfo,\n DeclareSIWxOptions,\n SignatureType,\n SupportedChain,\n} from \"./types\";\nimport { SIGN_IN_WITH_X } from \"./types\";\nimport { buildSIWxSchema } from \"./schema\";\n\n/**\n * Derive signature type from network.\n *\n * @param network - CAIP-2 network identifier\n * @returns Signature algorithm type\n */\nexport function getSignatureType(network: string): SignatureType {\n return network.startsWith(\"solana:\") ? \"ed25519\" : \"eip191\";\n}\n\n/**\n * Internal type for SIWX declaration with stored options.\n * The _options field is used by enrichPaymentRequiredResponse to derive\n * values from request context.\n */\nexport interface SIWxDeclaration extends SIWxExtension {\n _options: DeclareSIWxOptions;\n}\n\n/**\n * Create SIWX extension declaration for PaymentRequired.extensions\n *\n * Most fields are derived automatically from request context when using\n * siwxResourceServerExtension:\n * - `network`: From payment requirements (accepts[].network)\n * - `resourceUri`: From request URL\n * - `domain`: Parsed from resourceUri\n *\n * Explicit values in options override automatic derivation.\n *\n * @param options - Configuration options (most are optional)\n * @returns Extension object ready for PaymentRequired.extensions\n *\n * @example\n * ```typescript\n * // Minimal - derives network, domain, resourceUri from context\n * const extensions = declareSIWxExtension({\n * statement: 'Sign in to access your purchased content',\n * });\n *\n * // With explicit network (overrides accepts)\n * const extensions = declareSIWxExtension({\n * network: 'eip155:8453',\n * statement: 'Sign in to access',\n * });\n *\n * // Full explicit config (no derivation)\n * const extensions = declareSIWxExtension({\n * domain: 'api.example.com',\n * resourceUri: 'https://api.example.com/data',\n * network: ['eip155:8453', 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'],\n * statement: 'Sign in to access',\n * expirationSeconds: 300,\n * });\n * ```\n */\nexport function declareSIWxExtension(\n options: DeclareSIWxOptions = {},\n): Record<string, SIWxDeclaration> {\n // Build partial info with static fields only\n // Time-based fields (nonce, issuedAt, expirationTime) are generated\n // per-request by enrichPaymentRequiredResponse in siwxResourceServerExtension\n const info: Partial<SIWxExtensionInfo> & { version: string } = {\n version: options.version ?? \"1\",\n };\n\n // Add fields that are provided\n if (options.domain) {\n info.domain = options.domain;\n }\n if (options.resourceUri) {\n info.uri = options.resourceUri;\n info.resources = [options.resourceUri];\n }\n if (options.statement) {\n info.statement = options.statement;\n }\n // Note: expirationSeconds is stored in _options and used by\n // enrichPaymentRequiredResponse to calculate expirationTime per-request\n\n // Build supportedChains if network is provided\n let supportedChains: SupportedChain[] = [];\n if (options.network) {\n const networks = Array.isArray(options.network) ? options.network : [options.network];\n supportedChains = networks.map(network => ({\n chainId: network,\n type: getSignatureType(network),\n }));\n }\n\n const declaration: SIWxDeclaration = {\n info: info as SIWxExtensionInfo,\n supportedChains,\n schema: buildSIWxSchema(),\n _options: options,\n };\n\n return { [SIGN_IN_WITH_X]: declaration };\n}\n","/**\n * Server-side ResourceServerExtension for SIWX\n *\n * Provides enrichPaymentRequiredResponse hook to:\n * - Derive missing fields from request context (network, resourceUri, domain)\n * - Refresh time-based fields per request (nonce, issuedAt, expirationTime)\n */\n\nimport { randomBytes } from \"crypto\";\nimport type { ResourceServerExtension, PaymentRequiredContext } from \"@x402/core/types\";\nimport type { SIWxExtension, SIWxExtensionInfo, SupportedChain, DeclareSIWxOptions } from \"./types\";\nimport { SIGN_IN_WITH_X } from \"./types\";\nimport { getSignatureType, type SIWxDeclaration } from \"./declare\";\nimport { buildSIWxSchema } from \"./schema\";\n\n/**\n * SIWX Resource Server Extension.\n *\n * Implements enrichPaymentRequiredResponse hook to:\n * 1. Derive missing fields from context (network from requirements, URL from resourceInfo)\n * 2. Refresh time-based fields (nonce, issuedAt, expirationTime) per request\n *\n * @example\n * ```typescript\n * import { siwxResourceServerExtension } from \"@x402/extensions/sign-in-with-x\";\n *\n * const resourceServer = new x402ResourceServer(facilitator)\n * .registerExtension(siwxResourceServerExtension)\n * .onAfterSettle(createSIWxSettleHook({ storage }));\n * ```\n */\nexport const siwxResourceServerExtension: ResourceServerExtension = {\n key: SIGN_IN_WITH_X,\n\n enrichPaymentRequiredResponse: async (\n declaration: unknown,\n context: PaymentRequiredContext,\n ): Promise<SIWxExtension> => {\n const decl = declaration as SIWxDeclaration;\n const opts: DeclareSIWxOptions = decl._options ?? {};\n\n // Derive resourceUri from context if not provided\n const resourceUri = opts.resourceUri ?? context.resourceInfo.url;\n\n // Derive domain from resourceUri\n let domain = opts.domain;\n if (!domain && resourceUri) {\n try {\n domain = new URL(resourceUri).hostname;\n } catch {\n // If URL parsing fails, leave domain undefined (will cause validation error)\n }\n }\n\n // Derive networks from payment requirements if not provided\n let networks: string[];\n if (opts.network) {\n networks = Array.isArray(opts.network) ? opts.network : [opts.network];\n } else {\n // Get unique networks from payment requirements\n networks = [...new Set(context.requirements.map(r => r.network))];\n }\n\n // Generate fresh time-based fields\n const nonce = randomBytes(16).toString(\"hex\");\n const issuedAt = new Date().toISOString();\n\n // Calculate expirationTime based on configured duration\n const expirationSeconds = opts.expirationSeconds;\n const expirationTime =\n expirationSeconds !== undefined\n ? new Date(Date.now() + expirationSeconds * 1000).toISOString()\n : undefined;\n\n // Build complete info\n const info: SIWxExtensionInfo = {\n domain: domain ?? \"\",\n uri: resourceUri,\n version: opts.version ?? \"1\",\n nonce,\n issuedAt,\n resources: [resourceUri],\n };\n\n if (expirationTime) {\n info.expirationTime = expirationTime;\n }\n if (opts.statement) {\n info.statement = opts.statement;\n }\n\n // Build supportedChains from networks\n const supportedChains: SupportedChain[] = networks.map(network => ({\n chainId: network,\n type: getSignatureType(network),\n }));\n\n return {\n info,\n supportedChains,\n schema: buildSIWxSchema(),\n };\n },\n};\n","/**\n * Header parsing for SIWX extension\n *\n * Parses the SIGN-IN-WITH-X header from client requests.\n * Requires base64-encoded JSON per x402 v2 spec.\n */\n\nimport { Base64EncodedRegex, safeBase64Decode } from \"@x402/core/utils\";\nimport { SIWxPayloadSchema, type SIWxPayload } from \"./types\";\n\n/**\n * Parse SIGN-IN-WITH-X header into structured payload.\n *\n * Expects base64-encoded JSON per x402 v2 spec (CHANGELOG-v2.md line 335).\n *\n * @param header - The SIGN-IN-WITH-X header value (base64-encoded JSON)\n * @returns Parsed SIWX payload\n * @throws Error if header is invalid or missing required fields\n *\n * @example\n * ```typescript\n * const header = request.headers.get('SIGN-IN-WITH-X');\n * if (header) {\n * const payload = parseSIWxHeader(header);\n * // payload.address, payload.signature, etc.\n * }\n * ```\n */\nexport function parseSIWxHeader(header: string): SIWxPayload {\n if (!Base64EncodedRegex.test(header)) {\n throw new Error(\"Invalid SIWX header: not valid base64\");\n }\n\n const jsonStr = safeBase64Decode(header);\n\n let rawPayload: unknown;\n try {\n rawPayload = JSON.parse(jsonStr);\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new Error(\"Invalid SIWX header: not valid JSON\");\n }\n throw error;\n }\n\n const parsed = SIWxPayloadSchema.safeParse(rawPayload);\n\n if (!parsed.success) {\n const issues = parsed.error.issues.map(i => `${i.path.join(\".\")}: ${i.message}`).join(\", \");\n throw new Error(`Invalid SIWX header: ${issues}`);\n }\n\n return parsed.data;\n}\n","/**\n * Message validation for SIWX extension\n *\n * Validates SIWX payload fields before cryptographic verification.\n * Per CHANGELOG-v2.md validation rules (lines 318-329).\n */\n\nimport type { SIWxPayload, SIWxValidationResult, SIWxValidationOptions } from \"./types\";\n\n/** Default maximum age for issuedAt: 5 minutes per spec */\nconst DEFAULT_MAX_AGE_MS = 5 * 60 * 1000;\n\n/**\n * Validate SIWX message fields.\n *\n * Performs validation per spec (CHANGELOG-v2.md lines 318-329):\n * - Domain binding: domain MUST match server's domain\n * - URI validation: uri must refer to base url of resource\n * - Temporal validation:\n * - issuedAt MUST be recent (< 5 minutes by default)\n * - expirationTime MUST be in the future\n * - notBefore (if present) MUST be in the past\n * - Nonce: MUST be unique (via optional checkNonce callback)\n *\n * @param message - The SIWX payload to validate\n * @param expectedResourceUri - Expected resource URI (for domain/URI matching)\n * @param options - Validation options\n * @returns Validation result\n *\n * @example\n * ```typescript\n * const payload = parseSIWxHeader(header);\n * const result = await validateSIWxMessage(\n * payload,\n * 'https://api.example.com/data',\n * { checkNonce: (n) => !usedNonces.has(n) }\n * );\n *\n * if (!result.valid) {\n * return { error: result.error };\n * }\n * ```\n */\nexport async function validateSIWxMessage(\n message: SIWxPayload,\n expectedResourceUri: string,\n options: SIWxValidationOptions = {},\n): Promise<SIWxValidationResult> {\n const expectedUrl = new URL(expectedResourceUri);\n const maxAge = options.maxAge ?? DEFAULT_MAX_AGE_MS;\n\n // 1. Domain binding (spec: \"domain field MUST match server's domain\")\n // Use hostname (without port) per EIP-4361 convention\n if (message.domain !== expectedUrl.hostname) {\n return {\n valid: false,\n error: `Domain mismatch: expected \"${expectedUrl.hostname}\", got \"${message.domain}\"`,\n };\n }\n\n // 2. URI validation (spec: \"uri and resources must refer to base url of resource\")\n // Allow the message URI to be the origin or the full resource URL\n if (!message.uri.startsWith(expectedUrl.origin)) {\n return {\n valid: false,\n error: `URI mismatch: expected origin \"${expectedUrl.origin}\", got \"${message.uri}\"`,\n };\n }\n\n // 3. issuedAt validation (spec: \"MUST be recent, recommended < 5 minutes\")\n const issuedAt = new Date(message.issuedAt);\n if (isNaN(issuedAt.getTime())) {\n return {\n valid: false,\n error: \"Invalid issuedAt timestamp\",\n };\n }\n\n const age = Date.now() - issuedAt.getTime();\n if (age > maxAge) {\n return {\n valid: false,\n error: `Message too old: ${Math.round(age / 1000)}s exceeds ${maxAge / 1000}s limit`,\n };\n }\n if (age < 0) {\n return {\n valid: false,\n error: \"issuedAt is in the future\",\n };\n }\n\n // 4. expirationTime validation (spec: \"MUST be in the future\")\n if (message.expirationTime) {\n const expiration = new Date(message.expirationTime);\n if (isNaN(expiration.getTime())) {\n return {\n valid: false,\n error: \"Invalid expirationTime timestamp\",\n };\n }\n if (expiration < new Date()) {\n return {\n valid: false,\n error: \"Message expired\",\n };\n }\n }\n\n // 5. notBefore validation (spec: \"if present, MUST be in the past\")\n if (message.notBefore) {\n const notBefore = new Date(message.notBefore);\n if (isNaN(notBefore.getTime())) {\n return {\n valid: false,\n error: \"Invalid notBefore timestamp\",\n };\n }\n if (new Date() < notBefore) {\n return {\n valid: false,\n error: \"Message not yet valid (notBefore is in the future)\",\n };\n }\n }\n\n // 6. Nonce validation (spec: \"MUST be unique per session to prevent replay attacks\")\n if (options.checkNonce) {\n const nonceValid = await options.checkNonce(message.nonce);\n if (!nonceValid) {\n return {\n valid: false,\n error: \"Nonce validation failed (possible replay attack)\",\n };\n }\n }\n\n return { valid: true };\n}\n","/**\n * EVM Sign-In-With-Ethereum (SIWE) support\n *\n * Implements EIP-4361 compliant message format and signature verification\n * for EVM chains (Ethereum, Base, Polygon, etc.)\n */\n\nimport { verifyMessage } from \"viem\";\nimport { SiweMessage } from \"siwe\";\nimport type { EVMMessageVerifier } from \"./types\";\nimport type { CompleteSIWxInfo } from \"./client\";\nimport type { SIWxSigner } from \"./sign\";\n\n/**\n * Extract numeric chain ID from CAIP-2 EVM chainId.\n *\n * @param chainId - CAIP-2 format chain ID (e.g., \"eip155:8453\")\n * @returns Numeric chain ID (e.g., 8453)\n * @throws Error if chainId format is invalid\n *\n * @example\n * ```typescript\n * extractEVMChainId(\"eip155:1\") // 1 (Ethereum mainnet)\n * extractEVMChainId(\"eip155:8453\") // 8453 (Base)\n * extractEVMChainId(\"eip155:137\") // 137 (Polygon)\n * ```\n */\nexport function extractEVMChainId(chainId: string): number {\n const match = /^eip155:(\\d+)$/.exec(chainId);\n if (!match) {\n throw new Error(`Invalid EVM chainId format: ${chainId}. Expected eip155:<number>`);\n }\n return parseInt(match[1], 10);\n}\n\n/**\n * Format SIWE message following EIP-4361 specification.\n *\n * Uses the siwe library to ensure message format matches verification.\n *\n * @param info - Server-provided extension info\n * @param address - Client's EVM wallet address (0x-prefixed)\n * @returns Message string ready for signing\n *\n * @example\n * ```typescript\n * const message = formatSIWEMessage(serverInfo, \"0x1234...abcd\");\n * // Returns EIP-4361 formatted message:\n * // \"api.example.com wants you to sign in with your Ethereum account:\n * // 0x1234...abcd\n * //\n * // Sign in to access your content\n * //\n * // URI: https://api.example.com/data\n * // Version: 1\n * // Chain ID: 8453\n * // Nonce: abc123\n * // Issued At: 2024-01-01T00:00:00.000Z\"\n * ```\n */\nexport function formatSIWEMessage(info: CompleteSIWxInfo, address: string): string {\n const numericChainId = extractEVMChainId(info.chainId);\n\n const siweMessage = new SiweMessage({\n domain: info.domain,\n address,\n statement: info.statement,\n uri: info.uri,\n version: info.version,\n chainId: numericChainId,\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 });\n\n return siweMessage.prepareMessage();\n}\n\n/**\n * Verify EVM signature.\n *\n * Supports:\n * - EOA signatures (standard ECDSA via EIP-191) - always available\n * - EIP-1271 (deployed smart contract wallets) - requires verifier\n * - EIP-6492 (counterfactual/pre-deploy smart wallets) - requires verifier\n *\n * @param message - The SIWE message that was signed\n * @param address - The claimed signer address\n * @param signature - The signature to verify\n * @param verifier - Optional message verifier for smart wallet support.\n * Pass publicClient.verifyMessage for EIP-1271/EIP-6492 support.\n * Without this, only EOA signatures are verified.\n * @returns true if signature is valid\n *\n * @example\n * ```typescript\n * // EOA-only verification (default, no RPC required)\n * const valid = await verifyEVMSignature(message, address, signature);\n *\n * // Smart wallet verification with viem PublicClient\n * import { createPublicClient, http } from 'viem';\n * import { base } from 'viem/chains';\n *\n * const publicClient = createPublicClient({ chain: base, transport: http() });\n * const valid = await verifyEVMSignature(\n * message,\n * address,\n * signature,\n * publicClient.verifyMessage\n * );\n * ```\n */\nexport async function verifyEVMSignature(\n message: string,\n address: string,\n signature: string,\n verifier?: EVMMessageVerifier,\n): Promise<boolean> {\n const args = {\n address: address as `0x${string}`,\n message,\n signature: signature as `0x${string}`,\n };\n\n if (verifier) {\n // Use provided verifier (supports EIP-1271/EIP-6492 via RPC)\n return verifier(args);\n }\n\n // Fallback to standalone verifyMessage (EOA only, no RPC)\n return verifyMessage(args);\n}\n\n/**\n * Detect if a signer is EVM-compatible.\n * Checks for EVM-specific properties.\n *\n * @param signer - The signer to check\n * @returns true if the signer is an EVM signer\n */\nexport function isEVMSigner(signer: SIWxSigner): boolean {\n // Check for Solana-specific properties first (to exclude them)\n // signMessages (plural) is only on @solana/kit signers\n if (\"signMessages\" in signer && typeof signer.signMessages === \"function\") {\n return false;\n }\n // Check for Solana wallet adapter publicKey (has toBase58 or is non-hex string)\n if (\"publicKey\" in signer && signer.publicKey) {\n const pk = signer.publicKey;\n if (typeof pk === \"object\" && pk !== null && \"toBase58\" in pk) {\n return false;\n }\n if (typeof pk === \"string\" && !pk.startsWith(\"0x\")) {\n return false;\n }\n }\n // EVM signers have account.address or direct address property (hex format)\n if (\"account\" in signer && signer.account && typeof signer.account === \"object\") {\n const account = signer.account as { address?: string };\n if (account.address && account.address.startsWith(\"0x\")) {\n return true;\n }\n }\n if (\n \"address\" in signer &&\n typeof signer.address === \"string\" &&\n signer.address.startsWith(\"0x\")\n ) {\n return true;\n }\n return false;\n}\n","/**\n * Signature verification for SIWX extension\n *\n * Routes to chain-specific verification based on chainId namespace:\n * - EVM (eip155:*): EOA by default, smart wallet (EIP-1271/EIP-6492) with verifier\n * - Solana (solana:*): Ed25519 signature verification via tweetnacl\n */\n\nimport { formatSIWEMessage, verifyEVMSignature } from \"./evm\";\nimport { formatSIWSMessage, verifySolanaSignature, decodeBase58 } from \"./solana\";\nimport type { SIWxPayload, SIWxVerifyResult, SIWxVerifyOptions, EVMMessageVerifier } from \"./types\";\n\n/**\n * Verify SIWX signature cryptographically.\n *\n * Routes to the appropriate chain-specific verification based on the\n * chainId namespace prefix:\n * - `eip155:*` → EVM verification (EOA by default, smart wallet with verifier)\n * - `solana:*` → Ed25519 signature verification\n *\n * @param payload - The SIWX payload containing signature\n * @param options - Optional verification options\n * @returns Verification result with recovered address if valid\n *\n * @example\n * ```typescript\n * // EOA-only verification (default)\n * const result = await verifySIWxSignature(payload);\n *\n * // Smart wallet verification\n * import { createPublicClient, http } from 'viem';\n * import { base } from 'viem/chains';\n *\n * const publicClient = createPublicClient({ chain: base, transport: http() });\n * const result = await verifySIWxSignature(payload, {\n * evmVerifier: publicClient.verifyMessage,\n * });\n *\n * if (result.valid) {\n * console.log('Verified wallet:', result.address);\n * } else {\n * console.error('Verification failed:', result.error);\n * }\n * ```\n */\nexport async function verifySIWxSignature(\n payload: SIWxPayload,\n options?: SIWxVerifyOptions,\n): Promise<SIWxVerifyResult> {\n try {\n // Route by chain namespace\n if (payload.chainId.startsWith(\"eip155:\")) {\n return verifyEVMPayload(payload, options?.evmVerifier);\n }\n\n if (payload.chainId.startsWith(\"solana:\")) {\n return verifySolanaPayload(payload);\n }\n\n return {\n valid: false,\n error: `Unsupported chain namespace: ${payload.chainId}. Supported: eip155:* (EVM), solana:* (Solana)`,\n };\n } catch (error) {\n return {\n valid: false,\n error: error instanceof Error ? error.message : \"Verification failed\",\n };\n }\n}\n\n/**\n * Verify EVM signature with optional smart wallet support.\n *\n * @param payload - The SIWX payload containing signature and message data\n * @param verifier - Optional message verifier for EIP-1271/EIP-6492 support\n * @returns Verification result with recovered address if valid\n */\nasync function verifyEVMPayload(\n payload: SIWxPayload,\n verifier?: EVMMessageVerifier,\n): Promise<SIWxVerifyResult> {\n // Reconstruct SIWE message for verification\n const message = formatSIWEMessage(\n {\n domain: payload.domain,\n uri: payload.uri,\n statement: payload.statement,\n version: payload.version,\n chainId: payload.chainId,\n type: payload.type,\n nonce: payload.nonce,\n issuedAt: payload.issuedAt,\n expirationTime: payload.expirationTime,\n notBefore: payload.notBefore,\n requestId: payload.requestId,\n resources: payload.resources,\n },\n payload.address,\n );\n\n try {\n const valid = await verifyEVMSignature(message, payload.address, payload.signature, verifier);\n\n if (!valid) {\n return {\n valid: false,\n error: \"Signature verification failed\",\n };\n }\n\n return {\n valid: true,\n address: payload.address,\n };\n } catch (error) {\n return {\n valid: false,\n error: error instanceof Error ? error.message : \"Signature verification failed\",\n };\n }\n}\n\n/**\n * Verify Solana Ed25519 signature.\n *\n * Reconstructs the SIWS message and verifies using tweetnacl.\n *\n * @param payload - The SIWX payload containing signature and message data\n * @returns Verification result with recovered address if valid\n */\nfunction verifySolanaPayload(payload: SIWxPayload): SIWxVerifyResult {\n // Reconstruct SIWS message\n const message = formatSIWSMessage(\n {\n domain: payload.domain,\n uri: payload.uri,\n statement: payload.statement,\n version: payload.version,\n chainId: payload.chainId,\n type: payload.type,\n nonce: payload.nonce,\n issuedAt: payload.issuedAt,\n expirationTime: payload.expirationTime,\n notBefore: payload.notBefore,\n requestId: payload.requestId,\n resources: payload.resources,\n },\n payload.address,\n );\n\n // Decode Base58 signature and public key\n let signature: Uint8Array;\n let publicKey: Uint8Array;\n\n try {\n signature = decodeBase58(payload.signature);\n publicKey = decodeBase58(payload.address);\n } catch (error) {\n return {\n valid: false,\n error: `Invalid Base58 encoding: ${error instanceof Error ? error.message : \"decode failed\"}`,\n };\n }\n\n // Validate signature length (Ed25519 signatures are 64 bytes)\n if (signature.length !== 64) {\n return {\n valid: false,\n error: `Invalid signature length: expected 64 bytes, got ${signature.length}`,\n };\n }\n\n // Validate public key length (Ed25519 public keys are 32 bytes)\n if (publicKey.length !== 32) {\n return {\n valid: false,\n error: `Invalid public key length: expected 32 bytes, got ${publicKey.length}`,\n };\n }\n\n // Verify Ed25519 signature\n const valid = verifySolanaSignature(message, signature, publicKey);\n\n if (!valid) {\n return {\n valid: false,\n error: \"Solana signature verification failed\",\n };\n }\n\n return {\n valid: true,\n address: payload.address,\n };\n}\n","/**\n * CAIP-122 message construction for SIWX extension\n *\n * Constructs the canonical message string for signing.\n * Routes to chain-specific formatters based on chainId namespace.\n */\n\nimport { formatSIWEMessage } from \"./evm\";\nimport { formatSIWSMessage } from \"./solana\";\nimport type { CompleteSIWxInfo } from \"./client\";\n\n/**\n * Construct CAIP-122 compliant message string for signing.\n *\n * Routes to the appropriate chain-specific message formatter based on the\n * chainId namespace prefix:\n * - `eip155:*` → SIWE (EIP-4361) format via siwe library\n * - `solana:*` → SIWS format\n *\n * @param serverInfo - Server extension info with chain selected (includes chainId)\n * @param address - Client wallet address\n * @returns Message string ready for signing\n * @throws Error if chainId namespace is not supported\n *\n * @example\n * ```typescript\n * // EVM (Ethereum, Base, etc.)\n * const completeInfo = { ...extension.info, chainId: \"eip155:8453\", type: \"eip191\" };\n * const evmMessage = createSIWxMessage(completeInfo, \"0x1234...\");\n * ```\n */\nexport function createSIWxMessage(serverInfo: CompleteSIWxInfo, address: string): string {\n // Route by chain namespace\n if (serverInfo.chainId.startsWith(\"eip155:\")) {\n return formatSIWEMessage(serverInfo, address);\n }\n\n if (serverInfo.chainId.startsWith(\"solana:\")) {\n return formatSIWSMessage(serverInfo, address);\n }\n\n throw new Error(\n `Unsupported chain namespace: ${serverInfo.chainId}. ` +\n `Supported: eip155:* (EVM), solana:* (Solana)`,\n );\n}\n","/**\n * Message signing for SIWX extension\n *\n * Client-side helpers for signing SIWX messages.\n * Supports both EVM (viem) and Solana wallet adapters.\n */\n\nimport { encodeBase58 } from \"./solana\";\n\n/**\n * Signer interface for EVM SIWX message signing.\n * Compatible with viem WalletClient and PrivateKeyAccount.\n */\nexport interface EVMSigner {\n /** Sign a message and return hex-encoded signature */\n signMessage: (args: { message: string; account?: unknown }) => Promise<string>;\n /** Account object (for WalletClient) */\n account?: { address: string };\n /** Direct address (for PrivateKeyAccount) */\n address?: string;\n}\n\n/**\n * Wallet adapter style Solana signer.\n * Compatible with @solana/wallet-adapter, Phantom/Solflare wallet APIs.\n */\nexport interface WalletAdapterSigner {\n /** Sign a message and return raw signature bytes */\n signMessage: (message: Uint8Array) => Promise<Uint8Array>;\n /** Solana public key (Base58 encoded string or PublicKey-like object) */\n publicKey: string | { toBase58: () => string };\n}\n\n/**\n * Solana Kit KeyPairSigner style.\n * Compatible with createKeyPairSignerFromBytes and generateKeyPairSigner from @solana/kit.\n */\nexport type SolanaKitSigner = {\n /** Solana address (Base58 encoded string) */\n address: string;\n /** Sign messages - accepts messages with content and signatures */\n signMessages: (\n messages: Array<{ content: Uint8Array; signatures: Record<string, unknown> }>,\n ) => Promise<Array<Record<string, Uint8Array>>>;\n};\n\n/**\n * Union type for Solana signers - supports both wallet adapter and @solana/kit.\n */\nexport type SolanaSigner = WalletAdapterSigner | SolanaKitSigner;\n\n/**\n * Union type for SIWX signers - supports both EVM and Solana wallets.\n */\nexport type SIWxSigner = EVMSigner | SolanaSigner;\n\n/**\n * Get address from an EVM signer.\n *\n * @param signer - EVM wallet signer instance\n * @returns The wallet address as a hex string\n */\nexport function getEVMAddress(signer: EVMSigner): string {\n if (signer.account?.address) {\n return signer.account.address;\n }\n if (signer.address) {\n return signer.address;\n }\n throw new Error(\"EVM signer missing address\");\n}\n\n/**\n * Get address from a Solana signer.\n * Supports both wallet adapter (publicKey) and @solana/kit (address) interfaces.\n *\n * @param signer - Solana wallet signer instance\n * @returns The wallet address as a Base58 string\n */\nexport function getSolanaAddress(signer: SolanaSigner): string {\n // Check for @solana/kit KeyPairSigner interface (address property)\n if (\"address\" in signer && signer.address) {\n return signer.address;\n }\n // Fall back to wallet adapter interface (publicKey property)\n if (\"publicKey\" in signer) {\n const pk = signer.publicKey;\n return typeof pk === \"string\" ? pk : pk.toBase58();\n }\n throw new Error(\"Solana signer missing address or publicKey\");\n}\n\n/**\n * Sign a message with an EVM wallet.\n * Returns hex-encoded signature.\n *\n * @param message - The message to sign\n * @param signer - EVM wallet signer instance\n * @returns Hex-encoded signature\n */\nexport async function signEVMMessage(message: string, signer: EVMSigner): Promise<string> {\n if (signer.account) {\n return signer.signMessage({ message, account: signer.account });\n }\n return signer.signMessage({ message });\n}\n\n/**\n * Sign a message with a Solana wallet.\n * Returns Base58-encoded signature.\n * Supports both wallet adapter (signMessage) and @solana/kit (signMessages) interfaces.\n *\n * @param message - The message to sign\n * @param signer - Solana wallet signer instance\n * @returns Base58-encoded signature\n */\nexport async function signSolanaMessage(message: string, signer: SolanaSigner): Promise<string> {\n const messageBytes = new TextEncoder().encode(message);\n\n // Check for @solana/kit signMessages interface\n if (\"signMessages\" in signer) {\n const results = await signer.signMessages([{ content: messageBytes, signatures: {} }]);\n // signMessages returns an array of signature dictionaries\n // The signature is keyed by the signer's address\n const sigDict = results[0] as { [key: string]: Uint8Array };\n // Get the first (and only) signature value from the dictionary\n const signatureBytes = Object.values(sigDict)[0];\n return encodeBase58(signatureBytes);\n }\n\n // Fall back to wallet adapter signMessage interface\n if (\"signMessage\" in signer) {\n const signatureBytes = await signer.signMessage(messageBytes);\n return encodeBase58(signatureBytes);\n }\n\n throw new Error(\"Solana signer missing signMessage or signMessages method\");\n}\n","/**\n * Complete client flow for SIWX extension\n *\n * Combines message construction, signing, and payload creation.\n * Supports both EVM and Solana wallets.\n */\n\nimport type { SIWxExtensionInfo, SIWxPayload, SignatureType, SignatureScheme } from \"./types\";\nimport type { SIWxSigner, EVMSigner, SolanaSigner } from \"./sign\";\nimport { getEVMAddress, getSolanaAddress, signEVMMessage, signSolanaMessage } from \"./sign\";\nimport { createSIWxMessage } from \"./message\";\n\n/**\n * Complete SIWX info with chain-specific fields.\n * Used by utility functions that need the selected chain information.\n */\nexport type CompleteSIWxInfo = SIWxExtensionInfo & {\n chainId: string;\n type: SignatureType;\n signatureScheme?: SignatureScheme;\n};\n\n/**\n * Create a complete SIWX payload from server extension info with selected chain.\n *\n * Routes to EVM or Solana signing based on the chainId prefix:\n * - `eip155:*` → EVM signing\n * - `solana:*` → Solana signing\n *\n * @param serverExtension - Server extension info with chain selected (includes chainId, type)\n * @param signer - Wallet that can sign messages (EVMSigner or SolanaSigner)\n * @returns Complete SIWX payload with signature\n *\n * @example\n * ```typescript\n * // EVM wallet\n * const completeInfo = { ...extension.info, chainId: \"eip155:8453\", type: \"eip191\" };\n * const payload = await createSIWxPayload(completeInfo, evmWallet);\n * ```\n */\nexport async function createSIWxPayload(\n serverExtension: CompleteSIWxInfo,\n signer: SIWxSigner,\n): Promise<SIWxPayload> {\n const isSolana = serverExtension.chainId.startsWith(\"solana:\");\n\n // Get address and sign based on chain type\n const address = isSolana\n ? getSolanaAddress(signer as SolanaSigner)\n : getEVMAddress(signer as EVMSigner);\n\n const message = createSIWxMessage(serverExtension, address);\n\n const signature = isSolana\n ? await signSolanaMessage(message, signer as SolanaSigner)\n : await signEVMMessage(message, signer as EVMSigner);\n\n return {\n domain: serverExtension.domain,\n address,\n statement: serverExtension.statement,\n uri: serverExtension.uri,\n version: serverExtension.version,\n chainId: serverExtension.chainId,\n type: serverExtension.type,\n nonce: serverExtension.nonce,\n issuedAt: serverExtension.issuedAt,\n expirationTime: serverExtension.expirationTime,\n notBefore: serverExtension.notBefore,\n requestId: serverExtension.requestId,\n resources: serverExtension.resources,\n signatureScheme: serverExtension.signatureScheme,\n signature,\n };\n}\n","/**\n * Header encoding for SIWX extension\n *\n * Encodes SIWX payload for the SIGN-IN-WITH-X HTTP header.\n * Per CHANGELOG-v2.md line 335: header should be base64-encoded.\n */\n\nimport { safeBase64Encode } from \"@x402/core/utils\";\nimport type { SIWxPayload } from \"./types\";\n\n/**\n * Encode SIWX payload for SIGN-IN-WITH-X header.\n *\n * Uses base64 encoding per x402 v2 spec (CHANGELOG-v2.md line 335).\n *\n * @param payload - Complete SIWX payload with signature\n * @returns Base64-encoded JSON string\n *\n * @example\n * ```typescript\n * const payload = await createSIWxPayload(serverInfo, signer);\n * const header = encodeSIWxHeader(payload);\n *\n * fetch(url, {\n * headers: { 'SIGN-IN-WITH-X': header }\n * });\n * ```\n */\nexport function encodeSIWxHeader(payload: SIWxPayload): string {\n return safeBase64Encode(JSON.stringify(payload));\n}\n","/**\n * Fetch wrapper for SIWX authentication.\n *\n * Provides a convenient wrapper around fetch that automatically handles\n * SIWX authentication when a 402 response includes SIWX extension info.\n */\n\nimport { decodePaymentRequiredHeader } from \"@x402/core/http\";\nimport type { SIWxSigner } from \"./sign\";\nimport type { SIWxExtension } from \"./types\";\nimport { SIGN_IN_WITH_X } from \"./types\";\nimport { createSIWxPayload } from \"./client\";\nimport { encodeSIWxHeader } from \"./encode\";\n\n/**\n * Wraps fetch to automatically handle SIWX authentication.\n *\n * When a 402 response is received with a SIWX extension:\n * 1. Extracts SIWX info from PAYMENT-REQUIRED header\n * 2. Creates signed SIWX proof using the provided signer\n * 3. Retries the request with the SIWX header\n *\n * If the 402 response doesn't include SIWX extension info, the original\n * response is returned unchanged (allowing payment handling to proceed).\n *\n * @param fetch - The fetch function to wrap (typically globalThis.fetch)\n * @param signer - Wallet signer (EVMSigner or SolanaSigner)\n * @returns A wrapped fetch function that handles SIWX authentication\n *\n * @example\n * ```typescript\n * import { wrapFetchWithSIWx } from '@x402/extensions/sign-in-with-x';\n * import { privateKeyToAccount } from 'viem/accounts';\n *\n * const signer = privateKeyToAccount(privateKey);\n * const fetchWithSIWx = wrapFetchWithSIWx(fetch, signer);\n *\n * // Request that may require SIWX auth (for returning paid users)\n * const response = await fetchWithSIWx('https://api.example.com/data');\n * ```\n */\nexport function wrapFetchWithSIWx(fetch: typeof globalThis.fetch, signer: SIWxSigner) {\n return async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n const request = new Request(input, init);\n const clonedRequest = request.clone();\n\n const response = await fetch(request);\n\n if (response.status !== 402) {\n return response;\n }\n\n // Extract SIWX info from 402 response\n const paymentRequiredHeader = response.headers.get(\"PAYMENT-REQUIRED\");\n if (!paymentRequiredHeader) {\n return response; // No PAYMENT-REQUIRED header, return original response\n }\n\n const paymentRequired = decodePaymentRequiredHeader(paymentRequiredHeader);\n const siwxExtension = paymentRequired.extensions?.[SIGN_IN_WITH_X] as SIWxExtension | undefined;\n\n if (!siwxExtension?.supportedChains) {\n return response; // Server doesn't support SIWX, return original 402\n }\n\n // Prevent infinite loops\n if (clonedRequest.headers.has(SIGN_IN_WITH_X)) {\n throw new Error(\"SIWX authentication already attempted\");\n }\n\n // Get network from payment requirements\n const paymentNetwork = paymentRequired.accepts?.[0]?.network;\n if (!paymentNetwork) {\n return response; // No network in payment requirements\n }\n\n // Find matching chain in supportedChains\n const matchingChain = siwxExtension.supportedChains.find(\n chain => chain.chainId === paymentNetwork,\n );\n\n if (!matchingChain) {\n return response; // Payment network not in SIWX supportedChains\n }\n\n // Build complete info with selected chain\n const completeInfo = {\n ...siwxExtension.info,\n chainId: matchingChain.chainId,\n type: matchingChain.type,\n };\n\n // Create and send SIWX proof\n const payload = await createSIWxPayload(completeInfo, signer);\n const siwxHeader = encodeSIWxHeader(payload);\n\n clonedRequest.headers.set(SIGN_IN_WITH_X, siwxHeader);\n\n return fetch(clonedRequest);\n };\n}\n","/**\n * Storage interface for SIWX payment tracking.\n *\n * Implementations track which addresses have paid for which resources,\n * enabling SIWX authentication to grant access without re-payment.\n *\n * Optionally supports nonce tracking to prevent signature replay attacks.\n */\nexport interface SIWxStorage {\n /**\n * Check if an address has paid for a resource.\n *\n * @param resource - The resource path (e.g., \"/weather\")\n * @param address - The wallet address to check\n * @returns True if the address has paid for the resource\n */\n hasPaid(resource: string, address: string): boolean | Promise<boolean>;\n\n /**\n * Record that an address has paid for a resource.\n *\n * @param resource - The resource path\n * @param address - The wallet address that paid\n */\n recordPayment(resource: string, address: string): void | Promise<void>;\n\n /**\n * Check if a nonce has already been used (optional).\n *\n * Implementing this method prevents signature replay attacks where\n * an intercepted SIWX header could be reused by an attacker.\n *\n * @param nonce - The nonce from the SIWX payload\n * @returns True if the nonce has been used\n */\n hasUsedNonce?(nonce: string): boolean | Promise<boolean>;\n\n /**\n * Record that a nonce has been used (optional).\n *\n * Called after successfully granting access via SIWX.\n * Implementations should consider adding expiration to avoid unbounded growth.\n *\n * @param nonce - The nonce to record as used\n */\n recordNonce?(nonce: string): void | Promise<void>;\n}\n\n/**\n * In-memory implementation of SIWxStorage.\n *\n * Suitable for development and single-instance deployments.\n * For production multi-instance deployments, use a persistent storage implementation.\n */\nexport class InMemorySIWxStorage implements SIWxStorage {\n private paidAddresses = new Map<string, Set<string>>();\n\n /**\n * Check if an address has paid for a resource.\n *\n * @param resource - The resource path\n * @param address - The wallet address to check\n * @returns True if the address has paid\n */\n hasPaid(resource: string, address: string): boolean {\n return this.paidAddresses.get(resource)?.has(address.toLowerCase()) ?? false;\n }\n\n /**\n * Record that an address has paid for a resource.\n *\n * @param resource - The resource path\n * @param address - The wallet address that paid\n */\n recordPayment(resource: string, address: string): void {\n if (!this.paidAddresses.has(resource)) {\n this.paidAddresses.set(resource, new Set());\n }\n this.paidAddresses.get(resource)!.add(address.toLowerCase());\n }\n}\n","/**\n * SIWX Lifecycle Hooks\n *\n * Pre-built hooks for integrating SIWX authentication with x402 servers and clients.\n */\n\nimport type { SIWxStorage } from \"./storage\";\nimport type { SIWxExtension, SIWxVerifyOptions, SignatureType } from \"./types\";\nimport type { SIWxSigner } from \"./sign\";\nimport { SIGN_IN_WITH_X } from \"./types\";\nimport { parseSIWxHeader } from \"./parse\";\nimport { validateSIWxMessage } from \"./validate\";\nimport { verifySIWxSignature } from \"./verify\";\nimport { createSIWxPayload } from \"./client\";\nimport { encodeSIWxHeader } from \"./encode\";\nimport { isSolanaSigner } from \"./solana\";\n\n/**\n * Options for creating server-side SIWX hooks.\n */\nexport interface CreateSIWxHookOptions {\n /** Storage for tracking paid addresses */\n storage: SIWxStorage;\n /** Options for signature verification (e.g., EVM smart wallet support) */\n verifyOptions?: SIWxVerifyOptions;\n /** Optional callback for logging/debugging */\n onEvent?: (event: SIWxHookEvent) => void;\n}\n\n/**\n * Events emitted by SIWX hooks for logging/debugging.\n */\nexport type SIWxHookEvent =\n | { type: \"payment_recorded\"; resource: string; address: string }\n | { type: \"access_granted\"; resource: string; address: string }\n | { type: \"validation_failed\"; resource: string; error?: string }\n | { type: \"nonce_reused\"; resource: string; nonce: string }\n | { type: \"siwx_header_sent\"; resource: string };\n\n/**\n * Creates an onAfterSettle hook that records payments for SIWX.\n *\n * @param options - Hook configuration\n * @returns Hook function for x402ResourceServer.onAfterSettle()\n *\n * @example\n * ```typescript\n * const storage = new InMemorySIWxStorage();\n * const resourceServer = new x402ResourceServer(facilitator)\n * .onAfterSettle(createSIWxSettleHook({ storage }));\n * ```\n */\nexport function createSIWxSettleHook(options: CreateSIWxHookOptions) {\n const { storage, onEvent } = options;\n\n return async (ctx: {\n paymentPayload: { payload: unknown; resource?: { url: string } };\n result: { success: boolean; payer?: string };\n }): Promise<void> => {\n // Only record payment if settlement succeeded\n if (!ctx.result.success) return;\n\n // Get payer from facilitator's settle result (works for all payment schemes)\n const address = ctx.result.payer;\n if (!address) return;\n\n // resource is optional per the v2 spec (section 5.2.2)\n const resourceUrl = ctx.paymentPayload.resource?.url;\n if (!resourceUrl) return;\n\n const resource = new URL(resourceUrl).pathname;\n await storage.recordPayment(resource, address);\n onEvent?.({ type: \"payment_recorded\", resource, address });\n };\n}\n\n/**\n * Creates an onProtectedRequest hook that validates SIWX auth before payment.\n *\n * @param options - Hook configuration\n * @returns Hook function for x402HTTPResourceServer.onProtectedRequest()\n *\n * @example\n * ```typescript\n * const storage = new InMemorySIWxStorage();\n * const httpServer = new x402HTTPResourceServer(resourceServer, routes)\n * .onProtectedRequest(createSIWxRequestHook({ storage }));\n * ```\n */\nexport function createSIWxRequestHook(options: CreateSIWxHookOptions) {\n const { storage, verifyOptions, onEvent } = options;\n\n // Validate nonce tracking is fully implemented or not at all\n const hasUsedNonce = typeof storage.hasUsedNonce === \"function\";\n const hasRecordNonce = typeof storage.recordNonce === \"function\";\n if (hasUsedNonce !== hasRecordNonce) {\n throw new Error(\n \"SIWxStorage nonce tracking requires both hasUsedNonce and recordNonce to be implemented\",\n );\n }\n\n return async (context: {\n adapter: { getHeader(name: string): string | undefined; getUrl(): string };\n path: string;\n }): Promise<void | { grantAccess: true }> => {\n // Try both cases for header (HTTP headers are case-insensitive)\n const header =\n context.adapter.getHeader(SIGN_IN_WITH_X) ||\n context.adapter.getHeader(SIGN_IN_WITH_X.toLowerCase());\n if (!header) return;\n\n try {\n const payload = parseSIWxHeader(header);\n const resourceUri = context.adapter.getUrl();\n\n const validation = await validateSIWxMessage(payload, resourceUri);\n if (!validation.valid) {\n onEvent?.({ type: \"validation_failed\", resource: context.path, error: validation.error });\n return;\n }\n\n const verification = await verifySIWxSignature(payload, verifyOptions);\n if (!verification.valid || !verification.address) {\n onEvent?.({ type: \"validation_failed\", resource: context.path, error: verification.error });\n return;\n }\n\n // Check if nonce was already used (prevents signature replay attacks)\n if (storage.hasUsedNonce) {\n const nonceUsed = await storage.hasUsedNonce(payload.nonce);\n if (nonceUsed) {\n onEvent?.({ type: \"nonce_reused\", resource: context.path, nonce: payload.nonce });\n return;\n }\n }\n\n const hasPaid = await storage.hasPaid(context.path, verification.address);\n if (hasPaid) {\n // Record nonce as used before granting access\n if (storage.recordNonce) {\n await storage.recordNonce(payload.nonce);\n }\n\n onEvent?.({\n type: \"access_granted\",\n resource: context.path,\n address: verification.address,\n });\n return { grantAccess: true };\n }\n } catch (err) {\n onEvent?.({\n type: \"validation_failed\",\n resource: context.path,\n error: err instanceof Error ? err.message : \"Unknown error\",\n });\n }\n };\n}\n\n/**\n * Creates an onPaymentRequired hook for client-side SIWX authentication.\n *\n * Matches the signer type to a compatible chain in supportedChains.\n * For EVM signers: matches any eip191 chain\n * For Solana signers: matches any ed25519 chain\n *\n * @param signer - Wallet signer for creating SIWX proofs\n * @returns Hook function for x402HTTPClient.onPaymentRequired()\n *\n * @example\n * ```typescript\n * const httpClient = new x402HTTPClient(client)\n * .onPaymentRequired(createSIWxClientHook(signer));\n * ```\n */\nexport function createSIWxClientHook(signer: SIWxSigner) {\n // Determine signer type once at hook creation\n const signerIsSolana = isSolanaSigner(signer);\n const expectedSignatureType: SignatureType = signerIsSolana ? \"ed25519\" : \"eip191\";\n\n return async (context: {\n paymentRequired: { accepts?: Array<{ network: string }>; extensions?: Record<string, unknown> };\n }): Promise<{ headers: Record<string, string> } | void> => {\n const extensions = context.paymentRequired.extensions ?? {};\n const siwxExtension = extensions[SIGN_IN_WITH_X] as SIWxExtension | undefined;\n\n if (!siwxExtension?.supportedChains) return;\n\n try {\n // Find a chain that matches the signer's signature type\n const matchingChain = siwxExtension.supportedChains.find(\n chain => chain.type === expectedSignatureType,\n );\n\n if (!matchingChain) {\n // No chain compatible with this signer type\n return;\n }\n\n // Build complete info with selected chain\n const completeInfo = {\n ...siwxExtension.info,\n chainId: matchingChain.chainId,\n type: matchingChain.type,\n };\n\n const payload = await createSIWxPayload(completeInfo, signer);\n const header = encodeSIWxHeader(payload);\n return { headers: { [SIGN_IN_WITH_X]: header } };\n } catch {\n // Failed to create SIWX payload, continue to payment\n }\n };\n}\n","/**\n * Type definitions for the Payment-Identifier Extension\n *\n * Enables clients to provide an idempotency key that resource servers\n * can use for deduplication of payment requests.\n */\n\n/**\n * Extension identifier constant for the payment-identifier extension\n */\nexport const PAYMENT_IDENTIFIER = \"payment-identifier\";\n\n/**\n * Minimum length for payment identifier\n */\nexport const PAYMENT_ID_MIN_LENGTH = 16;\n\n/**\n * Maximum length for payment identifier\n */\nexport const PAYMENT_ID_MAX_LENGTH = 128;\n\n/**\n * Pattern for valid payment identifier characters (alphanumeric, hyphens, underscores)\n */\nexport const PAYMENT_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;\n\n/**\n * Payment identifier info containing the required flag and client-provided ID\n */\nexport interface PaymentIdentifierInfo {\n /**\n * Whether the server requires clients to include a payment identifier.\n * When true, clients must provide an `id` or receive a 400 Bad Request.\n */\n required: boolean;\n\n /**\n * Client-provided unique identifier for idempotency.\n * Must be 16-128 characters, alphanumeric with hyphens and underscores allowed.\n */\n id?: string;\n}\n\n/**\n * Payment identifier extension with info and schema.\n *\n * Used both for server-side declarations (info without id) and\n * client-side payloads (info with id).\n */\nexport interface PaymentIdentifierExtension {\n /**\n * The payment identifier info.\n * Server declarations have required only, clients add the id.\n */\n info: PaymentIdentifierInfo;\n\n /**\n * JSON Schema validating the info structure\n */\n schema: PaymentIdentifierSchema;\n}\n\n/**\n * JSON Schema type for the payment-identifier extension\n */\nexport interface PaymentIdentifierSchema {\n $schema: \"https://json-schema.org/draft/2020-12/schema\";\n type: \"object\";\n properties: {\n required: {\n type: \"boolean\";\n };\n id: {\n type: \"string\";\n minLength: number;\n maxLength: number;\n pattern: string;\n };\n };\n required: [\"required\"];\n}\n","/**\n * JSON Schema definitions for the Payment-Identifier Extension\n */\n\nimport type { PaymentIdentifierSchema } from \"./types\";\nimport { PAYMENT_ID_MIN_LENGTH, PAYMENT_ID_MAX_LENGTH } from \"./types\";\n\n/**\n * JSON Schema for validating payment identifier info.\n * Compliant with JSON Schema Draft 2020-12.\n */\nexport const paymentIdentifierSchema: PaymentIdentifierSchema = {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n properties: {\n required: {\n type: \"boolean\",\n },\n id: {\n type: \"string\",\n minLength: PAYMENT_ID_MIN_LENGTH,\n maxLength: PAYMENT_ID_MAX_LENGTH,\n pattern: \"^[a-zA-Z0-9_-]+$\",\n },\n },\n required: [\"required\"],\n};\n","/**\n * Utility functions for the Payment-Identifier Extension\n */\n\nimport { PAYMENT_ID_MIN_LENGTH, PAYMENT_ID_MAX_LENGTH, PAYMENT_ID_PATTERN } from \"./types\";\n\n/**\n * Generates a unique payment identifier.\n *\n * @param prefix - Optional prefix for the ID (e.g., \"pay_\"). Defaults to \"pay_\".\n * @returns A unique payment identifier string\n *\n * @example\n * ```typescript\n * // With default prefix\n * const id = generatePaymentId(); // \"pay_7d5d747be160e280504c099d984bcfe0\"\n *\n * // With custom prefix\n * const id = generatePaymentId(\"txn_\"); // \"txn_7d5d747be160e280504c099d984bcfe0\"\n *\n * // Without prefix\n * const id = generatePaymentId(\"\"); // \"7d5d747be160e280504c099d984bcfe0\"\n * ```\n */\nexport function generatePaymentId(prefix: string = \"pay_\"): string {\n // Generate UUID v4 without hyphens (32 hex chars)\n const uuid = crypto.randomUUID().replace(/-/g, \"\");\n return `${prefix}${uuid}`;\n}\n\n/**\n * Validates that a payment ID meets the format requirements.\n *\n * @param id - The payment ID to validate\n * @returns True if the ID is valid, false otherwise\n *\n * @example\n * ```typescript\n * isValidPaymentId(\"pay_7d5d747be160e280\"); // true (exactly 16 chars after prefix removal check)\n * isValidPaymentId(\"abc\"); // false (too short)\n * isValidPaymentId(\"pay_abc!@#\"); // false (invalid characters)\n * ```\n */\nexport function isValidPaymentId(id: string): boolean {\n if (typeof id !== \"string\") {\n return false;\n }\n\n if (id.length < PAYMENT_ID_MIN_LENGTH || id.length > PAYMENT_ID_MAX_LENGTH) {\n return false;\n }\n\n return PAYMENT_ID_PATTERN.test(id);\n}\n","/**\n * Validation and extraction utilities for the Payment-Identifier Extension\n */\n\nimport Ajv from \"ajv/dist/2020.js\";\nimport type { PaymentPayload } from \"@x402/core/types\";\nimport type { PaymentIdentifierExtension, PaymentIdentifierInfo } from \"./types\";\nimport { PAYMENT_IDENTIFIER } from \"./types\";\nimport { paymentIdentifierSchema } from \"./schema\";\nimport { isValidPaymentId } from \"./utils\";\n\n/**\n * Type guard to check if an object is a valid payment-identifier extension structure.\n *\n * This checks for the basic structure (info object with required boolean),\n * but does not validate the id format if present.\n *\n * @param extension - The object to check\n * @returns True if the object has the expected payment-identifier extension structure\n *\n * @example\n * ```typescript\n * if (isPaymentIdentifierExtension(extensions[\"payment-identifier\"])) {\n * // TypeScript knows this is PaymentIdentifierExtension\n * console.log(extension.info.required);\n * }\n * ```\n */\nexport function isPaymentIdentifierExtension(\n extension: unknown,\n): extension is PaymentIdentifierExtension {\n if (!extension || typeof extension !== \"object\") {\n return false;\n }\n\n const ext = extension as Partial<PaymentIdentifierExtension>;\n\n if (!ext.info || typeof ext.info !== \"object\") {\n return false;\n }\n\n const info = ext.info as Partial<PaymentIdentifierInfo>;\n\n // Must have required boolean\n if (typeof info.required !== \"boolean\") {\n return false;\n }\n\n return true;\n}\n\n/**\n * Result of payment identifier validation\n */\nexport interface PaymentIdentifierValidationResult {\n /**\n * Whether the payment identifier is valid\n */\n valid: boolean;\n\n /**\n * Error messages if validation failed\n */\n errors?: string[];\n}\n\n/**\n * Validates a payment-identifier extension object.\n *\n * Checks both the structure (using JSON Schema) and the ID format.\n *\n * @param extension - The extension object to validate\n * @returns Validation result with errors if invalid\n *\n * @example\n * ```typescript\n * const result = validatePaymentIdentifier(paymentPayload.extensions?.[\"payment-identifier\"]);\n * if (!result.valid) {\n * console.error(\"Invalid payment identifier:\", result.errors);\n * }\n * ```\n */\nexport function validatePaymentIdentifier(extension: unknown): PaymentIdentifierValidationResult {\n if (!extension || typeof extension !== \"object\") {\n return {\n valid: false,\n errors: [\"Extension must be an object\"],\n };\n }\n\n const ext = extension as Partial<PaymentIdentifierExtension>;\n\n // Check info exists\n if (!ext.info || typeof ext.info !== \"object\") {\n return {\n valid: false,\n errors: [\"Extension must have an 'info' property\"],\n };\n }\n\n const info = ext.info as Partial<PaymentIdentifierInfo>;\n\n // Check required field exists and is a boolean\n if (typeof info.required !== \"boolean\") {\n return {\n valid: false,\n errors: [\"Extension info must have a 'required' boolean property\"],\n };\n }\n\n // Check id exists and is a string (if provided)\n if (info.id !== undefined && typeof info.id !== \"string\") {\n return {\n valid: false,\n errors: [\"Extension info 'id' must be a string if provided\"],\n };\n }\n\n // Validate ID format if provided\n if (info.id !== undefined && !isValidPaymentId(info.id)) {\n return {\n valid: false,\n errors: [\n `Invalid payment ID format. ID must be 16-128 characters and contain only alphanumeric characters, hyphens, and underscores.`,\n ],\n };\n }\n\n // If schema is provided, validate against it\n if (ext.schema) {\n try {\n const ajv = new Ajv({ strict: false, allErrors: true });\n const validate = ajv.compile(ext.schema);\n const valid = validate(ext.info);\n\n if (!valid && validate.errors) {\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 }\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 return { valid: true };\n}\n\n/**\n * Extracts the payment identifier from a PaymentPayload.\n *\n * @param paymentPayload - The payment payload to extract from\n * @param validate - Whether to validate the ID before returning (default: true)\n * @returns The payment ID string, or null if not present or invalid\n *\n * @example\n * ```typescript\n * const id = extractPaymentIdentifier(paymentPayload);\n * if (id) {\n * // Use for idempotency lookup\n * const cached = await idempotencyStore.get(id);\n * }\n * ```\n */\nexport function extractPaymentIdentifier(\n paymentPayload: PaymentPayload,\n validate: boolean = true,\n): string | null {\n if (!paymentPayload.extensions) {\n return null;\n }\n\n const extension = paymentPayload.extensions[PAYMENT_IDENTIFIER];\n\n if (!extension || typeof extension !== \"object\") {\n return null;\n }\n\n const ext = extension as Partial<PaymentIdentifierExtension>;\n\n if (!ext.info || typeof ext.info !== \"object\") {\n return null;\n }\n\n const info = ext.info as Partial<PaymentIdentifierInfo>;\n\n if (typeof info.id !== \"string\") {\n return null;\n }\n\n if (validate && !isValidPaymentId(info.id)) {\n return null;\n }\n\n return info.id;\n}\n\n/**\n * Extracts and validates the payment identifier from a PaymentPayload.\n *\n * @param paymentPayload - The payment payload to extract from\n * @returns Object with the ID and validation result\n *\n * @example\n * ```typescript\n * const { id, validation } = extractAndValidatePaymentIdentifier(paymentPayload);\n * if (!validation.valid) {\n * return res.status(400).json({ error: validation.errors });\n * }\n * if (id) {\n * // Use for idempotency\n * }\n * ```\n */\nexport function extractAndValidatePaymentIdentifier(paymentPayload: PaymentPayload): {\n id: string | null;\n validation: PaymentIdentifierValidationResult;\n} {\n if (!paymentPayload.extensions) {\n return { id: null, validation: { valid: true } };\n }\n\n const extension = paymentPayload.extensions[PAYMENT_IDENTIFIER];\n\n if (!extension) {\n return { id: null, validation: { valid: true } };\n }\n\n const validation = validatePaymentIdentifier(extension);\n\n if (!validation.valid) {\n return { id: null, validation };\n }\n\n const ext = extension as PaymentIdentifierExtension;\n return { id: ext.info.id ?? null, validation: { valid: true } };\n}\n\n/**\n * Checks if a PaymentPayload contains a payment-identifier extension.\n *\n * @param paymentPayload - The payment payload to check\n * @returns True if the extension is present\n */\nexport function hasPaymentIdentifier(paymentPayload: PaymentPayload): boolean {\n return !!(paymentPayload.extensions && paymentPayload.extensions[PAYMENT_IDENTIFIER]);\n}\n\n/**\n * Checks if the server requires a payment identifier based on the extension info.\n *\n * @param extension - The payment-identifier extension from PaymentRequired or PaymentPayload\n * @returns True if the server requires a payment identifier\n */\nexport function isPaymentIdentifierRequired(extension: unknown): boolean {\n if (!extension || typeof extension !== \"object\") {\n return false;\n }\n\n const ext = extension as Partial<PaymentIdentifierExtension>;\n\n if (!ext.info || typeof ext.info !== \"object\") {\n return false;\n }\n\n return (ext.info as Partial<PaymentIdentifierInfo>).required === true;\n}\n\n/**\n * Validates that a payment identifier is provided when required.\n *\n * Use this to check if a client's PaymentPayload satisfies the server's requirement.\n *\n * @param paymentPayload - The client's payment payload\n * @param serverRequired - Whether the server requires a payment identifier (from PaymentRequired)\n * @returns Validation result - invalid if required but not provided\n *\n * @example\n * ```typescript\n * const serverExtension = paymentRequired.extensions?.[\"payment-identifier\"];\n * const serverRequired = isPaymentIdentifierRequired(serverExtension);\n * const result = validatePaymentIdentifierRequirement(paymentPayload, serverRequired);\n * if (!result.valid) {\n * return res.status(400).json({ error: result.errors });\n * }\n * ```\n */\nexport function validatePaymentIdentifierRequirement(\n paymentPayload: PaymentPayload,\n serverRequired: boolean,\n): PaymentIdentifierValidationResult {\n if (!serverRequired) {\n return { valid: true };\n }\n\n const id = extractPaymentIdentifier(paymentPayload, false);\n\n if (!id) {\n return {\n valid: false,\n errors: [\"Server requires a payment identifier but none was provided\"],\n };\n }\n\n // Validate the ID format\n if (!isValidPaymentId(id)) {\n return {\n valid: false,\n errors: [\n `Invalid payment ID format. ID must be 16-128 characters and contain only alphanumeric characters, hyphens, and underscores.`,\n ],\n };\n }\n\n return { valid: true };\n}\n\nexport { paymentIdentifierSchema };\n","/**\n * Client-side utilities for the Payment-Identifier Extension\n */\n\nimport { PAYMENT_IDENTIFIER } from \"./types\";\nimport { generatePaymentId, isValidPaymentId } from \"./utils\";\nimport { isPaymentIdentifierExtension } from \"./validation\";\n\n/**\n * Appends a payment identifier to the extensions object if the server declared support.\n *\n * This function reads the server's `payment-identifier` declaration from the extensions,\n * and appends the client's ID to it. If the extension is not present (server didn't declare it),\n * the extensions are returned unchanged.\n *\n * @param extensions - The extensions object from PaymentRequired (will be modified in place)\n * @param id - Optional custom payment ID. If not provided, a new ID will be generated.\n * @returns The modified extensions object (same reference as input)\n * @throws Error if the provided ID is invalid\n *\n * @example\n * ```typescript\n * import { appendPaymentIdentifierToExtensions } from '@x402/extensions/payment-identifier';\n *\n * // Get extensions from server's PaymentRequired response\n * const extensions = paymentRequired.extensions ?? {};\n *\n * // Append a generated ID (only if server declared payment-identifier)\n * appendPaymentIdentifierToExtensions(extensions);\n *\n * // Or use a custom ID\n * appendPaymentIdentifierToExtensions(extensions, \"pay_my_custom_id_12345\");\n *\n * // Include in PaymentPayload\n * const paymentPayload = {\n * x402Version: 2,\n * resource: paymentRequired.resource,\n * accepted: selectedPaymentOption,\n * payload: { ... },\n * extensions\n * };\n * ```\n */\nexport function appendPaymentIdentifierToExtensions(\n extensions: Record<string, unknown>,\n id?: string,\n): Record<string, unknown> {\n const extension = extensions[PAYMENT_IDENTIFIER];\n\n // Only append if the server declared this extension with valid structure\n if (!isPaymentIdentifierExtension(extension)) {\n return extensions;\n }\n\n const paymentId = id ?? generatePaymentId();\n\n if (!isValidPaymentId(paymentId)) {\n throw new Error(\n `Invalid payment ID: \"${paymentId}\". ` +\n `ID must be 16-128 characters and contain only alphanumeric characters, hyphens, and underscores.`,\n );\n }\n\n // Append the ID to the existing extension info\n extension.info.id = paymentId;\n\n return extensions;\n}\n","/**\n * Resource Server utilities for the Payment-Identifier Extension\n */\n\nimport type { ResourceServerExtension } from \"@x402/core/types\";\nimport type { PaymentIdentifierExtension } from \"./types\";\nimport { PAYMENT_IDENTIFIER } from \"./types\";\nimport { paymentIdentifierSchema } from \"./schema\";\n\n/**\n * Declares the payment-identifier extension for inclusion in PaymentRequired.extensions.\n *\n * Resource servers call this function to advertise support for payment identifiers.\n * The declaration indicates whether a payment identifier is required and includes\n * the schema that clients must follow.\n *\n * @param required - Whether clients must provide a payment identifier. Defaults to false.\n * @returns A PaymentIdentifierExtension object ready for PaymentRequired.extensions\n *\n * @example\n * ```typescript\n * import { declarePaymentIdentifierExtension, PAYMENT_IDENTIFIER } from '@x402/extensions/payment-identifier';\n *\n * // Include in PaymentRequired response (optional identifier)\n * const paymentRequired = {\n * x402Version: 2,\n * resource: { ... },\n * accepts: [ ... ],\n * extensions: {\n * [PAYMENT_IDENTIFIER]: declarePaymentIdentifierExtension()\n * }\n * };\n *\n * // Require payment identifier\n * const paymentRequiredStrict = {\n * x402Version: 2,\n * resource: { ... },\n * accepts: [ ... ],\n * extensions: {\n * [PAYMENT_IDENTIFIER]: declarePaymentIdentifierExtension(true)\n * }\n * };\n * ```\n */\nexport function declarePaymentIdentifierExtension(\n required: boolean = false,\n): PaymentIdentifierExtension {\n return {\n info: { required },\n schema: paymentIdentifierSchema,\n };\n}\n\n/**\n * ResourceServerExtension implementation for payment-identifier.\n *\n * This extension doesn't require any enrichment hooks since the declaration\n * is static. It's provided for consistency with other extensions and for\n * potential future use with the extension registration system.\n *\n * @example\n * ```typescript\n * import { paymentIdentifierResourceServerExtension } from '@x402/extensions/payment-identifier';\n *\n * resourceServer.registerExtension(paymentIdentifierResourceServerExtension);\n * ```\n */\nexport const paymentIdentifierResourceServerExtension: ResourceServerExtension = {\n key: PAYMENT_IDENTIFIER,\n\n // No enrichment needed - the declaration is static\n // Future hooks for idempotency could be added here if needed\n};\n","/**\n * Type definitions for the EIP-2612 Gas Sponsoring Extension\n *\n * This extension enables gasless approval of the Permit2 contract for tokens\n * that implement EIP-2612. The client signs an off-chain permit, and the\n * facilitator submits it on-chain via `x402Permit2Proxy.settleWithPermit`.\n */\n\nimport type { FacilitatorExtension } from \"@x402/core/types\";\n\n/**\n * Extension identifier for the EIP-2612 gas sponsoring extension.\n */\nexport const EIP2612_GAS_SPONSORING: FacilitatorExtension = { key: \"eip2612GasSponsoring\" };\n\n/**\n * EIP-2612 gas sponsoring info populated by the client.\n *\n * Contains the EIP-2612 permit signature and parameters that the facilitator\n * needs to call `x402Permit2Proxy.settleWithPermit`.\n */\nexport interface Eip2612GasSponsoringInfo {\n /** Index signature for compatibility with Record<string, unknown> */\n [key: string]: unknown;\n /** The address of the sender (token owner). */\n from: string;\n /** The address of the ERC-20 token contract. */\n asset: string;\n /** The address of the spender (Canonical Permit2). */\n spender: string;\n /** The amount to approve (uint256 as decimal string). Typically MaxUint256. */\n amount: string;\n /** The current EIP-2612 nonce of the sender (decimal string). */\n nonce: string;\n /** The timestamp at which the permit signature expires (decimal string). */\n deadline: string;\n /** The 65-byte concatenated EIP-2612 permit signature (r, s, v) as a hex string. */\n signature: string;\n /** Schema version identifier. */\n version: string;\n}\n\n/**\n * Server-side EIP-2612 gas sponsoring info included in PaymentRequired.\n * Contains a description and version; the client populates the rest.\n */\nexport interface Eip2612GasSponsoringServerInfo {\n /** Index signature for compatibility with Record<string, unknown> */\n [key: string]: unknown;\n /** Human-readable description of the extension. */\n description: string;\n /** Schema version identifier. */\n version: string;\n}\n\n/**\n * The full extension object as it appears in PaymentRequired.extensions\n * and PaymentPayload.extensions.\n */\nexport interface Eip2612GasSponsoringExtension {\n /** Extension info - server-provided or client-enriched. */\n info: Eip2612GasSponsoringServerInfo | Eip2612GasSponsoringInfo;\n /** JSON Schema describing the expected structure of info. */\n schema: Record<string, unknown>;\n}\n","/**\n * Resource Service functions for declaring the EIP-2612 Gas Sponsoring extension.\n *\n * These functions help servers declare support for EIP-2612 gasless Permit2 approvals\n * in the PaymentRequired response extensions.\n */\n\nimport { EIP2612_GAS_SPONSORING, type Eip2612GasSponsoringExtension } from \"./types\";\n\n/**\n * The JSON Schema for the EIP-2612 gas sponsoring extension info.\n * Matches the schema defined in the spec.\n */\nconst eip2612GasSponsoringSchema: Record<string, unknown> = {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n properties: {\n from: {\n type: \"string\",\n pattern: \"^0x[a-fA-F0-9]{40}$\",\n description: \"The address of the sender.\",\n },\n asset: {\n type: \"string\",\n pattern: \"^0x[a-fA-F0-9]{40}$\",\n description: \"The address of the ERC-20 token contract.\",\n },\n spender: {\n type: \"string\",\n pattern: \"^0x[a-fA-F0-9]{40}$\",\n description: \"The address of the spender (Canonical Permit2).\",\n },\n amount: {\n type: \"string\",\n pattern: \"^[0-9]+$\",\n description: \"The amount to approve (uint256). Typically MaxUint.\",\n },\n nonce: {\n type: \"string\",\n pattern: \"^[0-9]+$\",\n description: \"The current nonce of the sender.\",\n },\n deadline: {\n type: \"string\",\n pattern: \"^[0-9]+$\",\n description: \"The timestamp at which the signature expires.\",\n },\n signature: {\n type: \"string\",\n pattern: \"^0x[a-fA-F0-9]+$\",\n description: \"The 65-byte concatenated signature (r, s, v) as a hex string.\",\n },\n version: {\n type: \"string\",\n pattern: \"^[0-9]+(\\\\.[0-9]+)*$\",\n description: \"Schema version identifier.\",\n },\n },\n required: [\"from\", \"asset\", \"spender\", \"amount\", \"nonce\", \"deadline\", \"signature\", \"version\"],\n};\n\n/**\n * Declares the EIP-2612 gas sponsoring extension for inclusion in\n * PaymentRequired.extensions.\n *\n * The server advertises that it (or its facilitator) supports EIP-2612\n * gasless Permit2 approval. The client will populate the info with the\n * actual permit signature data.\n *\n * @returns An object keyed by the extension identifier containing the extension declaration\n *\n * @example\n * ```typescript\n * import { declareEip2612GasSponsoringExtension } from '@x402/extensions';\n *\n * const routes = [\n * {\n * path: \"/api/data\",\n * price: \"$0.01\",\n * extensions: {\n * ...declareEip2612GasSponsoringExtension(),\n * },\n * },\n * ];\n * ```\n */\nexport function declareEip2612GasSponsoringExtension(): Record<\n string,\n Eip2612GasSponsoringExtension\n> {\n const key = EIP2612_GAS_SPONSORING.key;\n return {\n [key]: {\n info: {\n description:\n \"The facilitator accepts EIP-2612 gasless Permit to `Permit2` canonical contract.\",\n version: \"1\",\n },\n schema: eip2612GasSponsoringSchema,\n },\n };\n}\n","/**\n * Facilitator functions for extracting and validating EIP-2612 Gas Sponsoring extension data.\n *\n * These functions help facilitators extract the EIP-2612 permit data from payment\n * payloads and validate it before calling settleWithPermit.\n */\n\nimport type { PaymentPayload } from \"@x402/core/types\";\nimport {\n EIP2612_GAS_SPONSORING,\n type Eip2612GasSponsoringInfo,\n type Eip2612GasSponsoringExtension,\n} from \"./types\";\n\n/**\n * Extracts the EIP-2612 gas sponsoring info from a payment payload's extensions.\n *\n * Returns the info if the extension is present and contains the required client-populated\n * fields (from, asset, spender, amount, nonce, deadline, signature, version).\n *\n * @param paymentPayload - The payment payload to extract from\n * @returns The EIP-2612 gas sponsoring info, or null if not present\n */\nexport function extractEip2612GasSponsoringInfo(\n paymentPayload: PaymentPayload,\n): Eip2612GasSponsoringInfo | null {\n if (!paymentPayload.extensions) {\n return null;\n }\n\n const extension = paymentPayload.extensions[EIP2612_GAS_SPONSORING.key] as\n | Eip2612GasSponsoringExtension\n | undefined;\n\n if (!extension?.info) {\n return null;\n }\n\n const info = extension.info as Record<string, unknown>;\n\n // Check that the client has populated the required fields\n if (\n !info.from ||\n !info.asset ||\n !info.spender ||\n !info.amount ||\n !info.nonce ||\n !info.deadline ||\n !info.signature ||\n !info.version\n ) {\n return null;\n }\n\n return info as unknown as Eip2612GasSponsoringInfo;\n}\n\n/**\n * Validates that the EIP-2612 gas sponsoring info has valid format.\n *\n * Performs basic validation on the info fields:\n * - Addresses are valid hex (0x + 40 hex chars)\n * - Amount, nonce, deadline are numeric strings\n * - Signature is a hex string\n * - Version is a numeric version string\n *\n * @param info - The EIP-2612 gas sponsoring info to validate\n * @returns True if the info is valid, false otherwise\n */\nexport function validateEip2612GasSponsoringInfo(info: Eip2612GasSponsoringInfo): boolean {\n const addressPattern = /^0x[a-fA-F0-9]{40}$/;\n const numericPattern = /^[0-9]+$/;\n const hexPattern = /^0x[a-fA-F0-9]+$/;\n const versionPattern = /^[0-9]+(\\.[0-9]+)*$/;\n\n return (\n addressPattern.test(info.from) &&\n addressPattern.test(info.asset) &&\n addressPattern.test(info.spender) &&\n numericPattern.test(info.amount) &&\n numericPattern.test(info.nonce) &&\n numericPattern.test(info.deadline) &&\n hexPattern.test(info.signature) &&\n versionPattern.test(info.version)\n );\n}\n","/**\n * Type definitions for the ERC-20 Approval Gas Sponsoring Extension\n *\n * This extension enables gasless Permit2 approval for generic ERC-20 tokens\n * that do NOT implement EIP-2612. The client signs (but does not broadcast) a\n * raw `approve(Permit2, MaxUint256)` transaction, and the facilitator broadcasts\n * it atomically before settling the Permit2 payment.\n */\n\nimport type { FacilitatorExtension } from \"@x402/core/types\";\n\n/**\n * Signer capability carried by the ERC-20 approval extension when registered in a facilitator.\n *\n * Mirrors FacilitatorEvmSigner (from @x402/evm) plus `sendRawTransaction`.\n * The extension signer owns the full approve+settle flow: it broadcasts the\n * pre-signed approval transaction AND executes the Permit2 settle call, enabling\n * production implementations to bundle both atomically (e.g., Flashbots, multicall).\n *\n * The method signatures are duplicated here (rather than extending FacilitatorEvmSigner)\n * to avoid a circular dependency between @x402/extensions and @x402/evm.\n */\nexport interface Erc20ApprovalGasSponsoringSigner {\n getAddresses(): readonly `0x${string}`[];\n readContract(args: {\n address: `0x${string}`;\n abi: readonly unknown[];\n functionName: string;\n args?: readonly unknown[];\n }): Promise<unknown>;\n verifyTypedData(args: {\n address: `0x${string}`;\n domain: Record<string, unknown>;\n types: Record<string, unknown>;\n primaryType: string;\n message: Record<string, unknown>;\n signature: `0x${string}`;\n }): Promise<boolean>;\n writeContract(args: {\n address: `0x${string}`;\n abi: readonly unknown[];\n functionName: string;\n args: readonly unknown[];\n }): Promise<`0x${string}`>;\n sendTransaction(args: { to: `0x${string}`; data: `0x${string}` }): Promise<`0x${string}`>;\n waitForTransactionReceipt(args: { hash: `0x${string}` }): Promise<{ status: string }>;\n getCode(args: { address: `0x${string}` }): Promise<`0x${string}` | undefined>;\n sendRawTransaction(args: { serializedTransaction: `0x${string}` }): Promise<`0x${string}`>;\n}\n\n/**\n * Extension identifier for the ERC-20 approval gas sponsoring extension.\n */\nexport const ERC20_APPROVAL_GAS_SPONSORING = {\n key: \"erc20ApprovalGasSponsoring\",\n} as const satisfies FacilitatorExtension;\n\n/** Current schema version for the ERC-20 approval gas sponsoring extension info. */\nexport const ERC20_APPROVAL_GAS_SPONSORING_VERSION = \"1\";\n\n/**\n * Extended extension object registered in a facilitator via registerExtension().\n * Carries the signer that owns the full approve+settle flow for ERC-20 tokens\n * that lack EIP-2612. The signer must have all FacilitatorEvmSigner capabilities\n * plus `sendRawTransaction` for broadcasting the pre-signed approval tx.\n *\n * @example\n * ```typescript\n * import { createErc20ApprovalGasSponsoringExtension } from '@x402/extensions';\n *\n * facilitator.registerExtension(\n * createErc20ApprovalGasSponsoringExtension(evmSigner, viemClient),\n * );\n * ```\n */\nexport interface Erc20ApprovalGasSponsoringFacilitatorExtension extends FacilitatorExtension {\n key: \"erc20ApprovalGasSponsoring\";\n /** Signer with broadcast + settle capability. Optional — settlement fails gracefully if absent. */\n signer?: Erc20ApprovalGasSponsoringSigner;\n}\n\n/**\n * Signer input for {@link createErc20ApprovalGasSponsoringExtension}.\n * Matches the FacilitatorEvmSigner shape from @x402/evm (duplicated to avoid circular dep).\n */\nexport type Erc20ApprovalGasSponsoringBaseSigner = Omit<\n Erc20ApprovalGasSponsoringSigner,\n \"sendRawTransaction\"\n>;\n\n/**\n * Create an ERC-20 approval gas sponsoring extension ready to register in a facilitator.\n *\n * @param signer - The EVM facilitator signer (e.g. from `toFacilitatorEvmSigner()`)\n * @param client - Object providing `sendRawTransaction` (e.g. a viem WalletClient)\n * @param client.sendRawTransaction - Broadcasts a signed transaction to the network\n * @returns A fully configured extension to pass to `facilitator.registerExtension()`\n */\nexport function createErc20ApprovalGasSponsoringExtension(\n signer: Erc20ApprovalGasSponsoringBaseSigner,\n client: {\n sendRawTransaction: (args: { serializedTransaction: `0x${string}` }) => Promise<`0x${string}`>;\n },\n): Erc20ApprovalGasSponsoringFacilitatorExtension {\n return {\n ...ERC20_APPROVAL_GAS_SPONSORING,\n signer: {\n ...signer,\n sendRawTransaction: client.sendRawTransaction.bind(client),\n },\n };\n}\n\n/**\n * ERC-20 approval gas sponsoring info populated by the client.\n *\n * Contains the RLP-encoded signed `approve(Permit2, MaxUint256)` transaction\n * that the facilitator broadcasts before settling the Permit2 payment.\n *\n * Note: Unlike EIP-2612, there is no nonce/deadline/signature — instead the\n * entire signed transaction is included as `signedTransaction`.\n */\nexport interface Erc20ApprovalGasSponsoringInfo {\n /** Index signature for compatibility with Record<string, unknown> */\n [key: string]: unknown;\n /** The address of the sender (token owner who signed the tx). */\n from: `0x${string}`;\n /** The address of the ERC-20 token contract. */\n asset: `0x${string}`;\n /** The address of the spender (Canonical Permit2). */\n spender: `0x${string}`;\n /** The amount approved (uint256 as decimal string). Always MaxUint256. */\n amount: string;\n /** The RLP-encoded signed EIP-1559 transaction as a hex string. */\n signedTransaction: `0x${string}`;\n /** Schema version identifier. */\n version: string;\n}\n\n/**\n * Server-side ERC-20 approval gas sponsoring info included in PaymentRequired.\n * Contains a description and version; the client populates the rest.\n */\nexport interface Erc20ApprovalGasSponsoringServerInfo {\n /** Index signature for compatibility with Record<string, unknown> */\n [key: string]: unknown;\n /** Human-readable description of the extension. */\n description: string;\n /** Schema version identifier. */\n version: string;\n}\n\n/**\n * The full extension object as it appears in PaymentRequired.extensions\n * and PaymentPayload.extensions.\n */\nexport interface Erc20ApprovalGasSponsoringExtension {\n /** Extension info - server-provided or client-enriched. */\n info: Erc20ApprovalGasSponsoringServerInfo | Erc20ApprovalGasSponsoringInfo;\n /** JSON Schema describing the expected structure of info. */\n schema: Record<string, unknown>;\n}\n","/**\n * Resource Service functions for declaring the ERC-20 Approval Gas Sponsoring extension.\n *\n * These functions help servers declare support for ERC-20 approval gas sponsoring\n * in the PaymentRequired response extensions. Use this for tokens that do NOT\n * implement EIP-2612 (generic ERC-20 tokens).\n */\n\nimport {\n ERC20_APPROVAL_GAS_SPONSORING,\n ERC20_APPROVAL_GAS_SPONSORING_VERSION,\n type Erc20ApprovalGasSponsoringExtension,\n} from \"./types\";\n\n/**\n * The JSON Schema for the ERC-20 approval gas sponsoring extension info.\n * Matches the schema defined in the spec.\n */\nexport const erc20ApprovalGasSponsoringSchema: Record<string, unknown> = {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n properties: {\n from: {\n type: \"string\",\n pattern: \"^0x[a-fA-F0-9]{40}$\",\n description: \"The address of the sender (token owner).\",\n },\n asset: {\n type: \"string\",\n pattern: \"^0x[a-fA-F0-9]{40}$\",\n description: \"The address of the ERC-20 token contract.\",\n },\n spender: {\n type: \"string\",\n pattern: \"^0x[a-fA-F0-9]{40}$\",\n description: \"The address of the spender (Canonical Permit2).\",\n },\n amount: {\n type: \"string\",\n pattern: \"^[0-9]+$\",\n description: \"The amount approved (uint256). Always MaxUint256.\",\n },\n signedTransaction: {\n type: \"string\",\n pattern: \"^0x[a-fA-F0-9]+$\",\n description: \"The RLP-encoded signed EIP-1559 transaction as a hex string.\",\n },\n version: {\n type: \"string\",\n pattern: \"^[0-9]+(\\\\.[0-9]+)*$\",\n description: \"Schema version identifier.\",\n },\n },\n required: [\"from\", \"asset\", \"spender\", \"amount\", \"signedTransaction\", \"version\"],\n};\n\n/**\n * Declares the ERC-20 approval gas sponsoring extension for inclusion in\n * PaymentRequired.extensions.\n *\n * The server advertises that it (or its facilitator) supports broadcasting\n * a pre-signed `approve(Permit2, MaxUint256)` transaction on the client's behalf.\n * Use this for tokens that do NOT implement EIP-2612.\n *\n * @returns An object keyed by the extension identifier containing the extension declaration\n *\n * @example\n * ```typescript\n * import { declareErc20ApprovalGasSponsoringExtension } from '@x402/extensions';\n *\n * const routes = [\n * {\n * path: \"/api/data\",\n * price: { amount: \"1000\", asset: \"0x...\", extra: { assetTransferMethod: \"permit2\" } },\n * extensions: {\n * ...declareErc20ApprovalGasSponsoringExtension(),\n * },\n * },\n * ];\n * ```\n */\nexport function declareErc20ApprovalGasSponsoringExtension(): Record<\n string,\n Erc20ApprovalGasSponsoringExtension\n> {\n const key = ERC20_APPROVAL_GAS_SPONSORING.key;\n return {\n [key]: {\n info: {\n description:\n \"The facilitator broadcasts a pre-signed ERC-20 approve() transaction to grant Permit2 allowance.\",\n version: ERC20_APPROVAL_GAS_SPONSORING_VERSION,\n },\n schema: erc20ApprovalGasSponsoringSchema,\n },\n };\n}\n","/**\n * Facilitator functions for extracting and validating ERC-20 Approval Gas Sponsoring\n * extension data.\n *\n * These functions help facilitators extract the pre-signed approve() transaction\n * from payment payloads and validate it before broadcasting and settling.\n */\n\nimport Ajv from \"ajv/dist/2020.js\";\nimport type { PaymentPayload } from \"@x402/core/types\";\nimport {\n ERC20_APPROVAL_GAS_SPONSORING,\n type Erc20ApprovalGasSponsoringInfo,\n type Erc20ApprovalGasSponsoringExtension,\n} from \"./types\";\nimport { erc20ApprovalGasSponsoringSchema } from \"./resourceService\";\n\n/**\n * Extracts the ERC-20 approval gas sponsoring info from a payment payload's extensions.\n *\n * Performs structural extraction only — checks that the extension is present and\n * contains all required fields. Does NOT validate field formats (use\n * validateErc20ApprovalGasSponsoringInfo for that).\n *\n * @param paymentPayload - The payment payload to extract from\n * @returns The ERC-20 approval gas sponsoring info, or null if not present\n */\nexport function extractErc20ApprovalGasSponsoringInfo(\n paymentPayload: PaymentPayload,\n): Erc20ApprovalGasSponsoringInfo | null {\n if (!paymentPayload.extensions) {\n return null;\n }\n\n const extension = paymentPayload.extensions[ERC20_APPROVAL_GAS_SPONSORING.key] as\n | Erc20ApprovalGasSponsoringExtension\n | undefined;\n\n if (!extension?.info) {\n return null;\n }\n\n const info = extension.info as Record<string, unknown>;\n\n if (\n !info.from ||\n !info.asset ||\n !info.spender ||\n !info.amount ||\n !info.signedTransaction ||\n !info.version\n ) {\n return null;\n }\n\n return info as unknown as Erc20ApprovalGasSponsoringInfo;\n}\n\n/**\n * Validates that the ERC-20 approval gas sponsoring info has valid format.\n *\n * Validates the info against the canonical JSON Schema, checking:\n * - All required fields are present\n * - Addresses are valid hex (0x + 40 hex chars)\n * - Amount is a numeric string\n * - signedTransaction is a hex string\n * - Version is a numeric version string\n *\n * @param info - The ERC-20 approval gas sponsoring info to validate\n * @returns True if the info is valid, false otherwise\n */\nexport function validateErc20ApprovalGasSponsoringInfo(\n info: Erc20ApprovalGasSponsoringInfo,\n): boolean {\n const ajv = new Ajv({ strict: false, allErrors: true });\n const validate = ajv.compile(erc20ApprovalGasSponsoringSchema);\n return validate(info) as boolean;\n}\n"],"mappings":"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","names":["extension","isBodyMethod","Ajv","nacl","import_utils","fetch","import__","Ajv","import__","Ajv"]}
1
+ {"version":3,"sources":["../../src/index.ts","../../src/bazaar/http/types.ts","../../src/bazaar/mcp/types.ts","../../src/bazaar/types.ts","../../src/bazaar/http/resourceService.ts","../../src/bazaar/mcp/resourceService.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/types.ts","../../src/sign-in-with-x/solana.ts","../../src/sign-in-with-x/schema.ts","../../src/sign-in-with-x/declare.ts","../../src/sign-in-with-x/server.ts","../../src/sign-in-with-x/parse.ts","../../src/sign-in-with-x/validate.ts","../../src/sign-in-with-x/evm.ts","../../src/sign-in-with-x/verify.ts","../../src/sign-in-with-x/message.ts","../../src/sign-in-with-x/sign.ts","../../src/sign-in-with-x/client.ts","../../src/sign-in-with-x/encode.ts","../../src/sign-in-with-x/fetch.ts","../../src/sign-in-with-x/storage.ts","../../src/sign-in-with-x/hooks.ts","../../src/offer-receipt/types.ts","../../src/offer-receipt/signing.ts","../../src/offer-receipt/did.ts","../../src/offer-receipt/server.ts","../../src/offer-receipt/client.ts","../../src/payment-identifier/types.ts","../../src/payment-identifier/schema.ts","../../src/payment-identifier/utils.ts","../../src/payment-identifier/validation.ts","../../src/payment-identifier/client.ts","../../src/payment-identifier/resourceServer.ts","../../src/eip2612-gas-sponsoring/types.ts","../../src/eip2612-gas-sponsoring/resourceService.ts","../../src/eip2612-gas-sponsoring/facilitator.ts","../../src/erc20-approval-gas-sponsoring/types.ts","../../src/erc20-approval-gas-sponsoring/resourceService.ts","../../src/erc20-approval-gas-sponsoring/facilitator.ts"],"sourcesContent":["// Shared extension utilities\nexport { 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// Offer/Receipt extension\nexport * from \"./offer-receipt\";\n\n// Payment-identifier extension\nexport * from \"./payment-identifier\";\nexport { paymentIdentifierResourceServerExtension } from \"./payment-identifier/resourceServer\";\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 * HTTP-specific type definitions for the Bazaar Discovery Extension\n */\n\nimport type { BodyMethods, QueryParamMethods } from \"@x402/core/http\";\nimport type { DiscoveryInfo } from \"../types\";\n\n/**\n * Discovery info for query parameter methods (GET, HEAD, DELETE)\n */\nexport interface QueryDiscoveryInfo {\n input: {\n type: \"http\";\n /** Absent at declaration time; set by bazaarResourceServerExtension.enrichDeclaration */\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 /** Absent at declaration time; set by bazaarResourceServerExtension.enrichDeclaration */\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 * 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\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 interface DiscoveredHTTPResource {\n resourceUrl: string;\n description?: string;\n mimeType?: string;\n /** Present after server extension enrichment; may be absent for pre-enrichment data */\n method?: string;\n x402Version: number;\n discoveryInfo: DiscoveryInfo;\n}\n\nexport const isQueryExtensionConfig = (\n config: DeclareQueryDiscoveryExtensionConfig | DeclareBodyDiscoveryExtensionConfig,\n): config is DeclareQueryDiscoveryExtensionConfig => {\n return !(\"bodyType\" in config) && !(\"toolName\" in config);\n};\n\nexport const isBodyExtensionConfig = (\n config: DeclareQueryDiscoveryExtensionConfig | DeclareBodyDiscoveryExtensionConfig,\n): config is DeclareBodyDiscoveryExtensionConfig => {\n return \"bodyType\" in config;\n};\n","/**\n * MCP-specific type definitions for the Bazaar Discovery Extension\n */\n\nimport type { DiscoveryInfo } from \"../types\";\n\n/**\n * Discovery info for MCP tools\n */\nexport interface McpDiscoveryInfo {\n input: {\n type: \"mcp\";\n toolName: string;\n description?: string;\n transport?: \"streamable-http\" | \"sse\";\n inputSchema: Record<string, unknown>;\n example?: Record<string, unknown>;\n };\n output?: {\n type?: string;\n format?: string;\n example?: unknown;\n };\n}\n\n/**\n * Discovery extension for MCP tools\n */\nexport interface McpDiscoveryExtension {\n info: McpDiscoveryInfo;\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: \"mcp\";\n };\n toolName: {\n type: \"string\";\n };\n description?: {\n type: \"string\";\n };\n transport?: {\n type: \"string\";\n enum: [\"streamable-http\", \"sse\"];\n };\n inputSchema: Record<string, unknown>;\n example?: Record<string, unknown>;\n };\n required: (\"type\" | \"toolName\" | \"inputSchema\")[];\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\nexport interface DeclareMcpDiscoveryExtensionConfig {\n toolName: string;\n description?: string;\n transport?: \"streamable-http\" | \"sse\";\n inputSchema: Record<string, unknown>;\n example?: Record<string, unknown>;\n output?: {\n example?: unknown;\n schema?: Record<string, unknown>;\n };\n}\n\nexport interface DiscoveredMCPResource {\n resourceUrl: string;\n description?: string;\n mimeType?: string;\n toolName: string;\n x402Version: number;\n discoveryInfo: DiscoveryInfo;\n}\n\nexport const isMcpExtensionConfig = (\n config: DeclareMcpDiscoveryExtensionConfig | Record<string, unknown>,\n): config is DeclareMcpDiscoveryExtensionConfig => {\n return \"toolName\" in config;\n};\n","/**\n * Shared type definitions for the Bazaar Discovery Extension\n *\n * Protocol-specific types live in their own directories (http/, mcp/).\n * This file defines the shared unions, constants, and utility types,\n * and re-exports all protocol-specific types for backwards compatibility.\n */\n\nimport type { FacilitatorExtension } from \"@x402/core/types\";\n\n// --- Shared union types ---\n\nimport type { QueryDiscoveryInfo, BodyDiscoveryInfo } from \"./http/types\";\nimport type { McpDiscoveryInfo } from \"./mcp/types\";\nimport type { QueryDiscoveryExtension, BodyDiscoveryExtension } from \"./http/types\";\nimport type { McpDiscoveryExtension } from \"./mcp/types\";\nimport type {\n DeclareQueryDiscoveryExtensionConfig,\n DeclareBodyDiscoveryExtensionConfig,\n} from \"./http/types\";\nimport type { DeclareMcpDiscoveryExtensionConfig } from \"./mcp/types\";\n\n// Re-export protocol-specific types\nexport type {\n QueryDiscoveryInfo,\n BodyDiscoveryInfo,\n QueryDiscoveryExtension,\n BodyDiscoveryExtension,\n DeclareQueryDiscoveryExtensionConfig,\n DeclareBodyDiscoveryExtensionConfig,\n DiscoveredHTTPResource,\n} from \"./http/types\";\n\nexport { isQueryExtensionConfig, isBodyExtensionConfig } from \"./http/types\";\n\nexport type {\n McpDiscoveryInfo,\n McpDiscoveryExtension,\n DeclareMcpDiscoveryExtensionConfig,\n DiscoveredMCPResource,\n} from \"./mcp/types\";\n\nexport { isMcpExtensionConfig } from \"./mcp/types\";\n\n// --- Shared constants ---\n\n/**\n * Extension identifier for the Bazaar discovery extension.\n */\nexport const BAZAAR: FacilitatorExtension = { key: \"bazaar\" };\n\n/**\n * Combined discovery info type\n */\nexport type DiscoveryInfo = QueryDiscoveryInfo | BodyDiscoveryInfo | McpDiscoveryInfo;\n\n/**\n * Combined discovery extension type\n */\nexport type DiscoveryExtension =\n | QueryDiscoveryExtension\n | BodyDiscoveryExtension\n | McpDiscoveryExtension;\n\nexport type DeclareDiscoveryExtensionConfig =\n | DeclareQueryDiscoveryExtensionConfig\n | DeclareBodyDiscoveryExtensionConfig\n | DeclareMcpDiscoveryExtensionConfig;\n\n/**\n * Distributive Omit - properly distributes Omit over union types.\n *\n * Standard `Omit<A | B, K>` collapses to common properties only,\n * losing discriminant properties like `bodyType`.\n *\n * This type uses conditional type distribution to preserve the union:\n * `DistributiveOmit<A | B, K>` = `Omit<A, K> | Omit<B, K>`\n */\nexport type DistributiveOmit<T, K extends keyof T> = T extends T ? Omit<T, K> : never;\n\n/**\n * Config type for declareDiscoveryExtension function.\n * Uses DistributiveOmit to preserve bodyType discriminant in the union for HTTP configs.\n * MCP config has no `method` field so it's included directly.\n */\nexport type DeclareDiscoveryExtensionInput =\n | DistributiveOmit<DeclareQueryDiscoveryExtensionConfig, \"method\">\n | DistributiveOmit<DeclareBodyDiscoveryExtensionConfig, \"method\">\n | DeclareMcpDiscoveryExtensionConfig;\n","/**\n * HTTP resource service functions for creating Bazaar discovery extensions\n */\n\nimport type {\n QueryDiscoveryExtension,\n BodyDiscoveryExtension,\n DeclareQueryDiscoveryExtensionConfig,\n DeclareBodyDiscoveryExtensionConfig,\n} from \"./types\";\n\n/**\n * Create a query discovery extension (GET, HEAD, DELETE)\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 */\nexport function createQueryDiscoveryExtension({\n method,\n input = {},\n inputSchema = { properties: {} },\n output,\n}: DeclareQueryDiscoveryExtensionConfig): QueryDiscoveryExtension {\n return {\n info: {\n input: {\n type: \"http\" as const,\n ...(method ? { method } : {}),\n ...(input ? { queryParams: input } : {}),\n },\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 * Create a body discovery extension (POST, PUT, PATCH)\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-data, text)\n * @param root0.output - Output specification with example\n * @returns BodyDiscoveryExtension with info and schema\n */\nexport function createBodyDiscoveryExtension({\n method,\n input = {},\n inputSchema = { properties: {} },\n bodyType,\n output,\n}: DeclareBodyDiscoveryExtensionConfig): BodyDiscoveryExtension {\n return {\n info: {\n input: {\n type: \"http\" as const,\n ...(method ? { method } : {}),\n bodyType,\n body: input,\n },\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 * MCP resource service functions for creating Bazaar discovery extensions\n */\n\nimport type { McpDiscoveryExtension, DeclareMcpDiscoveryExtensionConfig } from \"./types\";\n\n/**\n * Create an MCP tool discovery extension\n *\n * @param root0 - Configuration object for MCP discovery extension\n * @param root0.toolName - MCP tool name\n * @param root0.description - Tool description\n * @param root0.inputSchema - JSON Schema for tool arguments\n * @param root0.example - Example tool arguments\n * @param root0.output - Output specification with example\n * @param root0.transport - MCP transport type (streamable-http or sse)\n * @returns McpDiscoveryExtension with info and schema\n */\nexport function createMcpDiscoveryExtension({\n toolName,\n description,\n transport,\n inputSchema,\n example,\n output,\n}: DeclareMcpDiscoveryExtensionConfig): McpDiscoveryExtension {\n return {\n info: {\n input: {\n type: \"mcp\",\n toolName,\n ...(description !== undefined ? { description } : {}),\n ...(transport !== undefined ? { transport } : {}),\n inputSchema,\n ...(example !== undefined ? { example } : {}),\n },\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: \"mcp\",\n },\n toolName: {\n type: \"string\",\n },\n ...(description !== undefined\n ? {\n description: {\n type: \"string\" as const,\n },\n }\n : {}),\n ...(transport !== undefined\n ? {\n transport: {\n type: \"string\" as const,\n enum: [\"streamable-http\", \"sse\"],\n },\n }\n : {}),\n inputSchema: {\n type: \"object\" as const,\n },\n ...(example !== undefined\n ? {\n example: {\n type: \"object\" as const,\n },\n }\n : {}),\n },\n required: [\"type\", \"toolName\", \"inputSchema\"] as (\"type\" | \"toolName\" | \"inputSchema\")[],\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 * Resource Service entry point for creating Bazaar discovery extensions\n *\n * This module provides the unified `declareDiscoveryExtension` function that\n * routes to protocol-specific builders in http/ and mcp/.\n */\n\nimport type { DiscoveryExtension, DeclareDiscoveryExtensionInput } from \"./types\";\nimport type {\n DeclareQueryDiscoveryExtensionConfig,\n DeclareBodyDiscoveryExtensionConfig,\n} from \"./http/types\";\nimport type { DeclareMcpDiscoveryExtensionConfig } from \"./mcp/types\";\nimport {\n createQueryDiscoveryExtension,\n createBodyDiscoveryExtension,\n} from \"./http/resourceService\";\nimport { createMcpDiscoveryExtension } from \"./mcp/resourceService\";\n\n/**\n * Create a discovery extension for any HTTP method or MCP tool\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 * // For an MCP tool\n * const mcpExtension = declareDiscoveryExtension({\n * toolName: \"financial_analysis\",\n * description: \"Analyze financial data for a given ticker\",\n * inputSchema: {\n * type: \"object\",\n * properties: {\n * ticker: { type: \"string\" },\n * },\n * required: [\"ticker\"],\n * },\n * output: {\n * example: { pe_ratio: 28.5, recommendation: \"hold\" }\n * }\n * });\n * ```\n */\nexport function declareDiscoveryExtension(\n config: DeclareDiscoveryExtensionInput,\n): Record<string, DiscoveryExtension> {\n if (\"toolName\" in config) {\n const extension = createMcpDiscoveryExtension(config as DeclareMcpDiscoveryExtensionConfig);\n return { bazaar: extension as DiscoveryExtension };\n }\n\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 \"@x402/core/types\";\nimport type { HTTPRequestContext } from \"@x402/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 properties?: {\n [key: string]: unknown;\n method?: Record<string, unknown>;\n };\n required?: string[];\n };\n };\n };\n}\n\nexport const bazaarResourceServerExtension: ResourceServerExtension = {\n key: BAZAAR.key,\n\n enrichDeclaration: (declaration, transportContext) => {\n if (!isHTTPRequestContext(transportContext)) {\n return declaration;\n }\n\n const extension = declaration as ExtensionDeclaration;\n\n // MCP extensions don't need HTTP method enrichment\n if (extension.info?.input?.type === \"mcp\") {\n return declaration;\n }\n\n const method = transportContext.method;\n\n // At declaration time, the schema uses a broad enum ([\"GET\", \"HEAD\", \"DELETE\"] or [\"POST\", \"PUT\", \"PATCH\"])\n // because the method isn't known until the HTTP context is available.\n // Here we narrow it to the actual method for precise schema validation.\n const existingInputProps = extension.schema?.properties?.input?.properties || {};\n const updatedInputProps = {\n ...existingInputProps,\n method: {\n type: \"string\",\n enum: [method],\n },\n };\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 properties: updatedInputProps,\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.js\";\nimport type { PaymentPayload, PaymentRequirements, PaymentRequirementsV1 } from \"@x402/core/types\";\nimport type { DiscoveryExtension, DiscoveryInfo } from \"./types\";\nimport type { McpDiscoveryInfo } from \"./mcp/types\";\nimport type { DiscoveredHTTPResource } from \"./http/types\";\nimport type { DiscoveredMCPResource } from \"./mcp/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 type { DiscoveredHTTPResource } from \"./http/types\";\nexport type { DiscoveredMCPResource } from \"./mcp/types\";\n\nexport type DiscoveredResource = DiscoveredHTTPResource | DiscoveredMCPResource;\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.x402Version === 2) {\n resourceUrl = paymentPayload.resource?.url ?? \"\";\n\n if (paymentPayload.extensions) {\n const bazaarExtension = paymentPayload.extensions[BAZAAR.key];\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.x402Version === 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 // Strip query params (?) and hash sections (#) for discovery cataloging\n const url = new URL(resourceUrl);\n const normalizedResourceUrl = `${url.origin}${url.pathname}`;\n\n // Extract description and mimeType from resource info (v2) or requirements (v1)\n let description: string | undefined;\n let mimeType: string | undefined;\n\n if (paymentPayload.x402Version === 2) {\n description = paymentPayload.resource?.description;\n mimeType = paymentPayload.resource?.mimeType;\n } else if (paymentPayload.x402Version === 1) {\n const requirementsV1 = paymentRequirements as PaymentRequirementsV1;\n description = requirementsV1.description;\n mimeType = requirementsV1.mimeType;\n }\n\n const base = {\n resourceUrl: normalizedResourceUrl,\n description,\n mimeType,\n x402Version: paymentPayload.x402Version,\n discoveryInfo,\n };\n\n if (discoveryInfo.input.type === \"mcp\") {\n return { ...base, toolName: (discoveryInfo as McpDiscoveryInfo).input.toolName };\n }\n\n return { ...base, method: discoveryInfo.input.method };\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 \"@x402/core/types\";\nimport type { BodyMethods, QueryParamMethods } from \"@x402/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 \"@x402/core/http\";\nimport type { PaymentRequirements } from \"@x402/core/types\";\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 */\n type?: string;\n\n /**\n * The number of discovered x402 resources to return per page.\n */\n limit?: number;\n\n /**\n * The offset of the first discovered x402 resource to return.\n */\n offset?: number;\n}\n\n/**\n * A discovered x402 resource from the bazaar.\n */\nexport interface DiscoveryResource {\n /** The URL or identifier of the discovered resource */\n resource: string;\n /** The protocol type of the resource (e.g., \"http\") */\n type: string;\n /** The x402 protocol version supported by this resource */\n x402Version: number;\n /** Array of accepted payment methods for this resource */\n accepts: PaymentRequirements[];\n /** ISO 8601 timestamp of when the resource was last updated */\n lastUpdated: 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 x402 protocol version of this response */\n x402Version: number;\n /** The list of discovered resources */\n items: DiscoveryResource[];\n /** Pagination information for the response */\n pagination: {\n /** Maximum number of results returned */\n limit: number;\n /** Number of results skipped */\n offset: number;\n /** Total count of resources matching the query */\n total: number;\n };\n}\n\n/**\n * Bazaar client extension interface providing discovery query functionality.\n */\nexport interface BazaarClientExtension {\n discovery: {\n /**\n * List x402 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 * Type definitions for the Sign-In-With-X (SIWX) extension\n *\n * Implements CAIP-122 standard for chain-agnostic wallet-based identity assertions.\n * Per x402 v2 spec: typescript/site/CHANGELOG-v2.md lines 237-341\n */\n\nimport { z } from \"zod\";\n\n/**\n * Extension identifier constant\n */\nexport const SIGN_IN_WITH_X = \"sign-in-with-x\";\n\n/**\n * Supported signature schemes per CHANGELOG-v2.md line 271.\n *\n * NOTE: This is primarily informational. Actual signature verification\n * is determined by the chainId prefix, not this field:\n * - `eip155:*` chains use EVM verification (handles eip191, eip712, eip1271, eip6492 automatically)\n * - `solana:*` chains use Ed25519 verification (siws)\n *\n * The signatureScheme field serves as a hint for clients to select\n * the appropriate signing UX.\n */\nexport type SignatureScheme =\n | \"eip191\" // personal_sign (default for EVM EOAs)\n | \"eip1271\" // smart contract wallet verification\n | \"eip6492\" // counterfactual smart wallet verification\n | \"siws\"; // Sign-In-With-Solana\n\n/** Signature algorithm type per CAIP-122 */\nexport type SignatureType = \"eip191\" | \"ed25519\";\n\n/**\n * Supported chain configuration in supportedChains array.\n * Specifies which chains the server accepts for authentication.\n */\nexport interface SupportedChain {\n /** CAIP-2 chain identifier (e.g., \"eip155:8453\", \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\") */\n chainId: string;\n /** Signature algorithm type per CAIP-122 */\n type: SignatureType;\n /** Optional signature scheme hint (informational) */\n signatureScheme?: SignatureScheme;\n}\n\n/**\n * Server-declared extension info included in PaymentRequired.extensions.\n * Contains message metadata shared across all supported chains.\n * Per CHANGELOG-v2.md lines 263-272\n */\nexport interface SIWxExtensionInfo {\n /** Server's domain */\n domain: string;\n /** Full resource URI */\n uri: string;\n /** Human-readable purpose for signing */\n statement?: string;\n /** CAIP-122 version, always \"1\" */\n version: string;\n /** Cryptographic nonce (SDK auto-generates) */\n nonce: string;\n /** ISO 8601 timestamp (SDK auto-generates) */\n issuedAt: string;\n /** Optional expiry (default: +5 min) */\n expirationTime?: string;\n /** Optional validity start */\n notBefore?: string;\n /** Optional correlation ID */\n requestId?: string;\n /** Associated resources */\n resources?: string[];\n}\n\n/**\n * JSON Schema for SIWX extension validation\n * Per CHANGELOG-v2.md lines 276-292\n */\nexport interface SIWxExtensionSchema {\n $schema: string;\n type: \"object\";\n properties: {\n domain: { type: \"string\" };\n address: { type: \"string\" };\n statement?: { type: \"string\" };\n uri: { type: \"string\"; format: \"uri\" };\n version: { type: \"string\" };\n chainId: { type: \"string\" };\n type: { 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\"; format: \"uri\" } };\n signature: { type: \"string\" };\n };\n required: string[];\n}\n\n/**\n * Complete SIWX extension structure (info + supportedChains + schema).\n * Follows standard x402 v2 extension pattern with multi-chain support.\n */\nexport interface SIWxExtension {\n info: SIWxExtensionInfo;\n supportedChains: SupportedChain[];\n schema: SIWxExtensionSchema;\n}\n\n/**\n * Zod schema for SIWX payload validation\n * Client proof payload sent in SIGN-IN-WITH-X header\n * Per CHANGELOG-v2.md lines 301-315\n */\nexport const SIWxPayloadSchema = z.object({\n domain: z.string(),\n address: z.string(),\n statement: z.string().optional(),\n uri: z.string(),\n version: z.string(),\n chainId: z.string(),\n type: z.enum([\"eip191\", \"ed25519\"]),\n nonce: z.string(),\n issuedAt: z.string(),\n expirationTime: z.string().optional(),\n notBefore: z.string().optional(),\n requestId: z.string().optional(),\n resources: z.array(z.string()).optional(),\n signatureScheme: z.enum([\"eip191\", \"eip1271\", \"eip6492\", \"siws\"]).optional(),\n signature: z.string(),\n});\n\n/**\n * Client proof payload type (inferred from zod schema)\n */\nexport type SIWxPayload = z.infer<typeof SIWxPayloadSchema>;\n\n/**\n * Options for declaring SIWX extension on server.\n *\n * Most fields are optional and derived automatically from request context:\n * - `domain`: Parsed from resourceUri or request URL\n * - `resourceUri`: From request URL\n * - `network`: From payment requirements (accepts[].network)\n *\n * Explicit values override automatic derivation.\n */\nexport interface DeclareSIWxOptions {\n /** Server's domain. If omitted, derived from resourceUri or request URL. */\n domain?: string;\n /** Full resource URI. If omitted, derived from request URL. */\n resourceUri?: string;\n /** Human-readable purpose */\n statement?: string;\n /** CAIP-122 version (default: \"1\") */\n version?: string;\n /**\n * Network(s) to support. If omitted, derived from payment requirements.\n * - Single chain: \"eip155:8453\" or \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\"\n * - Multi-chain: [\"eip155:8453\", \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\"]\n */\n network?: string | string[];\n /**\n * Optional expiration duration in seconds.\n * - Number (e.g., 300): Signature expires after this many seconds\n * - undefined: Infinite expiration (no expirationTime field in wire format)\n */\n expirationSeconds?: number;\n}\n\n/**\n * Validation result from validateSIWxMessage\n */\nexport interface SIWxValidationResult {\n valid: boolean;\n error?: string;\n}\n\n/**\n * Options for message validation\n */\nexport interface SIWxValidationOptions {\n /** Maximum age for issuedAt in milliseconds (default: 5 minutes) */\n maxAge?: number;\n /** Custom nonce validation function */\n checkNonce?: (nonce: string) => boolean | Promise<boolean>;\n}\n\n/**\n * Result from signature verification\n */\nexport interface SIWxVerifyResult {\n valid: boolean;\n /** Recovered/verified address (checksummed) */\n address?: string;\n error?: string;\n}\n\n/**\n * EVM message verifier function type.\n * Compatible with viem's publicClient.verifyMessage().\n *\n * When provided to verifySIWxSignature, enables:\n * - EIP-1271 (deployed smart contract wallets)\n * - EIP-6492 (counterfactual/pre-deploy smart wallets)\n *\n * Without a verifier, only EOA signatures (EIP-191) can be verified.\n *\n * @example\n * ```typescript\n * import { createPublicClient, http } from 'viem';\n * import { base } from 'viem/chains';\n *\n * const publicClient = createPublicClient({ chain: base, transport: http() });\n * // publicClient.verifyMessage satisfies EVMMessageVerifier\n * ```\n */\nexport type EVMMessageVerifier = (args: {\n address: `0x${string}`;\n message: string;\n signature: `0x${string}`;\n}) => Promise<boolean>;\n\n/**\n * Options for SIWX signature verification\n */\nexport interface SIWxVerifyOptions {\n /**\n * EVM message verifier for smart wallet support.\n *\n * Pass `publicClient.verifyMessage` from viem to enable verification of:\n * - Smart contract wallets (EIP-1271)\n * - Counterfactual/undeployed smart wallets (EIP-6492)\n *\n * If not provided, only EOA signatures are verified using standalone\n * ECDSA recovery (no RPC calls required).\n */\n evmVerifier?: EVMMessageVerifier;\n}\n","/**\n * Solana Sign-In-With-X (SIWS) support\n *\n * Implements CAIP-122 compliant message format and Ed25519 signature verification\n * for Solana wallets.\n */\n\nimport { base58 } from \"@scure/base\";\nimport nacl from \"tweetnacl\";\nimport type { CompleteSIWxInfo } from \"./client\";\nimport type { SIWxSigner } from \"./sign\";\n\n/**\n * Common Solana network CAIP-2 identifiers.\n * Uses genesis hash as the chain reference per CAIP-30.\n */\nexport const SOLANA_MAINNET = \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\";\nexport const SOLANA_DEVNET = \"solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1\";\nexport const SOLANA_TESTNET = \"solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z\";\n\n/**\n * Extract chain reference from CAIP-2 Solana chainId.\n *\n * @param chainId - CAIP-2 format chain ID (e.g., \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\")\n * @returns Chain reference (genesis hash)\n *\n * @example\n * ```typescript\n * extractSolanaChainReference(\"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\") // \"5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\"\n * ```\n */\nexport function extractSolanaChainReference(chainId: string): string {\n const [, reference] = chainId.split(\":\");\n return reference;\n}\n\n/**\n * Format SIWS message following CAIP-122 ABNF specification.\n *\n * The message format is identical to SIWE (EIP-4361) but uses \"Solana account\"\n * instead of \"Ethereum account\" in the header line.\n *\n * @param info - Server-provided extension info\n * @param address - Client's Solana wallet address (Base58 encoded public key)\n * @returns Message string ready for signing\n *\n * @example\n * ```typescript\n * const message = formatSIWSMessage(serverInfo, \"BSmWDgE9ex6dZYbiTsJGcwMEgFp8q4aWh92hdErQPeVW\");\n * // Returns:\n * // \"api.example.com wants you to sign in with your Solana account:\n * // BSmWDgE9ex6dZYbiTsJGcwMEgFp8q4aWh92hdErQPeVW\n * //\n * // Sign in to access your content\n * //\n * // URI: https://api.example.com/data\n * // Version: 1\n * // Chain ID: mainnet\n * // Nonce: abc123\n * // Issued At: 2024-01-01T00:00:00.000Z\"\n * ```\n */\nexport function formatSIWSMessage(info: CompleteSIWxInfo, address: string): string {\n const lines: string[] = [\n `${info.domain} wants you to sign in with your Solana account:`,\n address,\n \"\",\n ];\n\n // Statement (optional, with blank line after)\n if (info.statement) {\n lines.push(info.statement, \"\");\n }\n\n // Required fields\n lines.push(\n `URI: ${info.uri}`,\n `Version: ${info.version}`,\n `Chain ID: ${extractSolanaChainReference(info.chainId)}`,\n `Nonce: ${info.nonce}`,\n `Issued At: ${info.issuedAt}`,\n );\n\n // Optional fields\n if (info.expirationTime) {\n lines.push(`Expiration Time: ${info.expirationTime}`);\n }\n if (info.notBefore) {\n lines.push(`Not Before: ${info.notBefore}`);\n }\n if (info.requestId) {\n lines.push(`Request ID: ${info.requestId}`);\n }\n\n // Resources (optional)\n if (info.resources && info.resources.length > 0) {\n lines.push(\"Resources:\");\n for (const resource of info.resources) {\n lines.push(`- ${resource}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Verify Ed25519 signature for SIWS.\n *\n * @param message - The SIWS message that was signed\n * @param signature - Ed25519 signature bytes\n * @param publicKey - Solana public key bytes (32 bytes)\n * @returns true if signature is valid\n *\n * @example\n * ```typescript\n * const messageBytes = new TextEncoder().encode(message);\n * const valid = verifySolanaSignature(message, signatureBytes, publicKeyBytes);\n * ```\n */\nexport function verifySolanaSignature(\n message: string,\n signature: Uint8Array,\n publicKey: Uint8Array,\n): boolean {\n const messageBytes = new TextEncoder().encode(message);\n return nacl.sign.detached.verify(messageBytes, signature, publicKey);\n}\n\n/**\n * Decode Base58 string to bytes.\n *\n * Solana uses Base58 encoding (Bitcoin alphabet) for addresses and signatures.\n *\n * @param encoded - Base58 encoded string\n * @returns Decoded bytes\n * @throws Error if string contains invalid Base58 characters\n *\n * @example\n * ```typescript\n * const publicKeyBytes = decodeBase58(\"BSmWDgE9ex6dZYbiTsJGcwMEgFp8q4aWh92hdErQPeVW\");\n * // Returns Uint8Array of 32 bytes\n * ```\n */\nexport function decodeBase58(encoded: string): Uint8Array {\n return base58.decode(encoded);\n}\n\n/**\n * Encode bytes to Base58 string.\n *\n * @param bytes - Bytes to encode\n * @returns Base58 encoded string\n */\nexport function encodeBase58(bytes: Uint8Array): string {\n return base58.encode(bytes);\n}\n\n/**\n * Detect if a signer is Solana-compatible.\n * Checks for Solana-specific properties that don't exist on EVM signers.\n *\n * @param signer - The signer to check\n * @returns true if the signer is a Solana signer\n */\nexport function isSolanaSigner(signer: SIWxSigner): boolean {\n // SolanaKitSigner has signMessages method (plural) - only Solana has this\n if (\"signMessages\" in signer && typeof signer.signMessages === \"function\") {\n return true;\n }\n // WalletAdapterSigner has publicKey property\n // But viem also has publicKey (as hex string), so we need to distinguish:\n // - Solana wallet adapter: publicKey has toBase58() method OR is a non-hex string\n // - viem: publicKey is a hex string starting with 0x\n if (\"publicKey\" in signer && signer.publicKey) {\n const pk = signer.publicKey;\n // Check for toBase58 method (Solana PublicKey object)\n if (typeof pk === \"object\" && pk !== null && \"toBase58\" in pk) {\n return true;\n }\n // Check for non-hex string (Solana base58 address)\n if (typeof pk === \"string\" && !pk.startsWith(\"0x\")) {\n return true;\n }\n }\n return false;\n}\n","/**\n * JSON Schema builder for SIWX extension\n *\n * Per CHANGELOG-v2.md lines 276-292\n */\n\nimport type { SIWxExtensionSchema } from \"./types\";\n\n/**\n * Build JSON Schema for SIWX extension validation.\n * This schema validates the client proof payload structure.\n *\n * @returns JSON Schema for validating SIWX client payloads\n */\nexport function buildSIWxSchema(): SIWxExtensionSchema {\n return {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n properties: {\n domain: { type: \"string\" },\n address: { type: \"string\" },\n statement: { type: \"string\" },\n uri: { type: \"string\", format: \"uri\" },\n version: { type: \"string\" },\n chainId: { type: \"string\" },\n type: { 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\", format: \"uri\" } },\n signature: { type: \"string\" },\n },\n required: [\n \"domain\",\n \"address\",\n \"uri\",\n \"version\",\n \"chainId\",\n \"type\",\n \"nonce\",\n \"issuedAt\",\n \"signature\",\n ],\n };\n}\n","/**\n * Server-side declaration helper for SIWX extension\n *\n * Helps servers declare SIWX authentication requirements in PaymentRequired responses.\n */\n\nimport type {\n SIWxExtension,\n SIWxExtensionInfo,\n DeclareSIWxOptions,\n SignatureType,\n SupportedChain,\n} from \"./types\";\nimport { SIGN_IN_WITH_X } from \"./types\";\nimport { buildSIWxSchema } from \"./schema\";\n\n/**\n * Derive signature type from network.\n *\n * @param network - CAIP-2 network identifier\n * @returns Signature algorithm type\n */\nexport function getSignatureType(network: string): SignatureType {\n return network.startsWith(\"solana:\") ? \"ed25519\" : \"eip191\";\n}\n\n/**\n * Internal type for SIWX declaration with stored options.\n * The _options field is used by enrichPaymentRequiredResponse to derive\n * values from request context.\n */\nexport interface SIWxDeclaration extends SIWxExtension {\n _options: DeclareSIWxOptions;\n}\n\n/**\n * Create SIWX extension declaration for PaymentRequired.extensions\n *\n * Most fields are derived automatically from request context when using\n * siwxResourceServerExtension:\n * - `network`: From payment requirements (accepts[].network)\n * - `resourceUri`: From request URL\n * - `domain`: Parsed from resourceUri\n *\n * Explicit values in options override automatic derivation.\n *\n * @param options - Configuration options (most are optional)\n * @returns Extension object ready for PaymentRequired.extensions\n *\n * @example\n * ```typescript\n * // Minimal - derives network, domain, resourceUri from context\n * const extensions = declareSIWxExtension({\n * statement: 'Sign in to access your purchased content',\n * });\n *\n * // With explicit network (overrides accepts)\n * const extensions = declareSIWxExtension({\n * network: 'eip155:8453',\n * statement: 'Sign in to access',\n * });\n *\n * // Full explicit config (no derivation)\n * const extensions = declareSIWxExtension({\n * domain: 'api.example.com',\n * resourceUri: 'https://api.example.com/data',\n * network: ['eip155:8453', 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'],\n * statement: 'Sign in to access',\n * expirationSeconds: 300,\n * });\n * ```\n */\nexport function declareSIWxExtension(\n options: DeclareSIWxOptions = {},\n): Record<string, SIWxDeclaration> {\n // Build partial info with static fields only\n // Time-based fields (nonce, issuedAt, expirationTime) are generated\n // per-request by enrichPaymentRequiredResponse in siwxResourceServerExtension\n const info: Partial<SIWxExtensionInfo> & { version: string } = {\n version: options.version ?? \"1\",\n };\n\n // Add fields that are provided\n if (options.domain) {\n info.domain = options.domain;\n }\n if (options.resourceUri) {\n info.uri = options.resourceUri;\n info.resources = [options.resourceUri];\n }\n if (options.statement) {\n info.statement = options.statement;\n }\n // Note: expirationSeconds is stored in _options and used by\n // enrichPaymentRequiredResponse to calculate expirationTime per-request\n\n // Build supportedChains if network is provided\n let supportedChains: SupportedChain[] = [];\n if (options.network) {\n const networks = Array.isArray(options.network) ? options.network : [options.network];\n supportedChains = networks.map(network => ({\n chainId: network,\n type: getSignatureType(network),\n }));\n }\n\n const declaration: SIWxDeclaration = {\n info: info as SIWxExtensionInfo,\n supportedChains,\n schema: buildSIWxSchema(),\n _options: options,\n };\n\n return { [SIGN_IN_WITH_X]: declaration };\n}\n","/**\n * Server-side ResourceServerExtension for SIWX\n *\n * Provides enrichPaymentRequiredResponse hook to:\n * - Derive missing fields from request context (network, resourceUri, domain)\n * - Refresh time-based fields per request (nonce, issuedAt, expirationTime)\n */\n\nimport type { ResourceServerExtension, PaymentRequiredContext } from \"@x402/core/types\";\nimport type { SIWxExtension, SIWxExtensionInfo, SupportedChain, DeclareSIWxOptions } from \"./types\";\nimport { SIGN_IN_WITH_X } from \"./types\";\nimport { getSignatureType, type SIWxDeclaration } from \"./declare\";\nimport { buildSIWxSchema } from \"./schema\";\n\n/**\n * SIWX Resource Server Extension.\n *\n * Implements enrichPaymentRequiredResponse hook to:\n * 1. Derive missing fields from context (network from requirements, URL from resourceInfo)\n * 2. Refresh time-based fields (nonce, issuedAt, expirationTime) per request\n *\n * @example\n * ```typescript\n * import { siwxResourceServerExtension } from \"@x402/extensions/sign-in-with-x\";\n *\n * const resourceServer = new x402ResourceServer(facilitator)\n * .registerExtension(siwxResourceServerExtension)\n * .onAfterSettle(createSIWxSettleHook({ storage }));\n * ```\n */\nexport const siwxResourceServerExtension: ResourceServerExtension = {\n key: SIGN_IN_WITH_X,\n\n enrichPaymentRequiredResponse: async (\n declaration: unknown,\n context: PaymentRequiredContext,\n ): Promise<SIWxExtension> => {\n const decl = declaration as SIWxDeclaration;\n const opts: DeclareSIWxOptions = decl._options ?? {};\n\n // Derive resourceUri from context if not provided\n const resourceUri = opts.resourceUri ?? context.resourceInfo.url;\n\n // Derive domain from resourceUri\n let domain = opts.domain;\n if (!domain && resourceUri) {\n try {\n domain = new URL(resourceUri).hostname;\n } catch {\n // If URL parsing fails, leave domain undefined (will cause validation error)\n }\n }\n\n // Derive networks from payment requirements if not provided\n let networks: string[];\n if (opts.network) {\n networks = Array.isArray(opts.network) ? opts.network : [opts.network];\n } else {\n // Get unique networks from payment requirements\n networks = [...new Set(context.requirements.map(r => r.network))];\n }\n\n // Generate fresh time-based fields\n const nonce = Array.from(globalThis.crypto.getRandomValues(new Uint8Array(16)))\n .map(b => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n const issuedAt = new Date().toISOString();\n\n // Calculate expirationTime based on configured duration\n const expirationSeconds = opts.expirationSeconds;\n const expirationTime =\n expirationSeconds !== undefined\n ? new Date(Date.now() + expirationSeconds * 1000).toISOString()\n : undefined;\n\n // Build complete info\n const info: SIWxExtensionInfo = {\n domain: domain ?? \"\",\n uri: resourceUri,\n version: opts.version ?? \"1\",\n nonce,\n issuedAt,\n resources: [resourceUri],\n };\n\n if (expirationTime) {\n info.expirationTime = expirationTime;\n }\n if (opts.statement) {\n info.statement = opts.statement;\n }\n\n // Build supportedChains from networks\n const supportedChains: SupportedChain[] = networks.map(network => ({\n chainId: network,\n type: getSignatureType(network),\n }));\n\n return {\n info,\n supportedChains,\n schema: buildSIWxSchema(),\n };\n },\n};\n","/**\n * Header parsing for SIWX extension\n *\n * Parses the SIGN-IN-WITH-X header from client requests.\n * Requires base64-encoded JSON per x402 v2 spec.\n */\n\nimport { Base64EncodedRegex, safeBase64Decode } from \"@x402/core/utils\";\nimport { SIWxPayloadSchema, type SIWxPayload } from \"./types\";\n\n/**\n * Parse SIGN-IN-WITH-X header into structured payload.\n *\n * Expects base64-encoded JSON per x402 v2 spec (CHANGELOG-v2.md line 335).\n *\n * @param header - The SIGN-IN-WITH-X header value (base64-encoded JSON)\n * @returns Parsed SIWX payload\n * @throws Error if header is invalid or missing required fields\n *\n * @example\n * ```typescript\n * const header = request.headers.get('SIGN-IN-WITH-X');\n * if (header) {\n * const payload = parseSIWxHeader(header);\n * // payload.address, payload.signature, etc.\n * }\n * ```\n */\nexport function parseSIWxHeader(header: string): SIWxPayload {\n if (!Base64EncodedRegex.test(header)) {\n throw new Error(\"Invalid SIWX header: not valid base64\");\n }\n\n const jsonStr = safeBase64Decode(header);\n\n let rawPayload: unknown;\n try {\n rawPayload = JSON.parse(jsonStr);\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new Error(\"Invalid SIWX header: not valid JSON\");\n }\n throw error;\n }\n\n const parsed = SIWxPayloadSchema.safeParse(rawPayload);\n\n if (!parsed.success) {\n const issues = parsed.error.issues.map(i => `${i.path.join(\".\")}: ${i.message}`).join(\", \");\n throw new Error(`Invalid SIWX header: ${issues}`);\n }\n\n return parsed.data;\n}\n","/**\n * Message validation for SIWX extension\n *\n * Validates SIWX payload fields before cryptographic verification.\n * Per CHANGELOG-v2.md validation rules (lines 318-329).\n */\n\nimport type { SIWxPayload, SIWxValidationResult, SIWxValidationOptions } from \"./types\";\n\n/** Default maximum age for issuedAt: 5 minutes per spec */\nconst DEFAULT_MAX_AGE_MS = 5 * 60 * 1000;\n\n/**\n * Validate SIWX message fields.\n *\n * Performs validation per spec (CHANGELOG-v2.md lines 318-329):\n * - Domain binding: domain MUST match server's domain\n * - URI validation: uri must refer to base url of resource\n * - Temporal validation:\n * - issuedAt MUST be recent (< 5 minutes by default)\n * - expirationTime MUST be in the future\n * - notBefore (if present) MUST be in the past\n * - Nonce: MUST be unique (via optional checkNonce callback)\n *\n * @param message - The SIWX payload to validate\n * @param expectedResourceUri - Expected resource URI (for domain/URI matching)\n * @param options - Validation options\n * @returns Validation result\n *\n * @example\n * ```typescript\n * const payload = parseSIWxHeader(header);\n * const result = await validateSIWxMessage(\n * payload,\n * 'https://api.example.com/data',\n * { checkNonce: (n) => !usedNonces.has(n) }\n * );\n *\n * if (!result.valid) {\n * return { error: result.error };\n * }\n * ```\n */\nexport async function validateSIWxMessage(\n message: SIWxPayload,\n expectedResourceUri: string,\n options: SIWxValidationOptions = {},\n): Promise<SIWxValidationResult> {\n const expectedUrl = new URL(expectedResourceUri);\n const maxAge = options.maxAge ?? DEFAULT_MAX_AGE_MS;\n\n // 1. Domain binding (spec: \"domain field MUST match server's domain\")\n // Use hostname (without port) per EIP-4361 convention\n if (message.domain !== expectedUrl.hostname) {\n return {\n valid: false,\n error: `Domain mismatch: expected \"${expectedUrl.hostname}\", got \"${message.domain}\"`,\n };\n }\n\n // 2. URI validation (spec: \"uri and resources must refer to base url of resource\")\n // Allow the message URI to be the origin or the full resource URL\n if (!message.uri.startsWith(expectedUrl.origin)) {\n return {\n valid: false,\n error: `URI mismatch: expected origin \"${expectedUrl.origin}\", got \"${message.uri}\"`,\n };\n }\n\n // 3. issuedAt validation (spec: \"MUST be recent, recommended < 5 minutes\")\n const issuedAt = new Date(message.issuedAt);\n if (isNaN(issuedAt.getTime())) {\n return {\n valid: false,\n error: \"Invalid issuedAt timestamp\",\n };\n }\n\n const age = Date.now() - issuedAt.getTime();\n if (age > maxAge) {\n return {\n valid: false,\n error: `Message too old: ${Math.round(age / 1000)}s exceeds ${maxAge / 1000}s limit`,\n };\n }\n if (age < 0) {\n return {\n valid: false,\n error: \"issuedAt is in the future\",\n };\n }\n\n // 4. expirationTime validation (spec: \"MUST be in the future\")\n if (message.expirationTime) {\n const expiration = new Date(message.expirationTime);\n if (isNaN(expiration.getTime())) {\n return {\n valid: false,\n error: \"Invalid expirationTime timestamp\",\n };\n }\n if (expiration < new Date()) {\n return {\n valid: false,\n error: \"Message expired\",\n };\n }\n }\n\n // 5. notBefore validation (spec: \"if present, MUST be in the past\")\n if (message.notBefore) {\n const notBefore = new Date(message.notBefore);\n if (isNaN(notBefore.getTime())) {\n return {\n valid: false,\n error: \"Invalid notBefore timestamp\",\n };\n }\n if (new Date() < notBefore) {\n return {\n valid: false,\n error: \"Message not yet valid (notBefore is in the future)\",\n };\n }\n }\n\n // 6. Nonce validation (spec: \"MUST be unique per session to prevent replay attacks\")\n if (options.checkNonce) {\n const nonceValid = await options.checkNonce(message.nonce);\n if (!nonceValid) {\n return {\n valid: false,\n error: \"Nonce validation failed (possible replay attack)\",\n };\n }\n }\n\n return { valid: true };\n}\n","/**\n * EVM Sign-In-With-Ethereum (SIWE) support\n *\n * Implements EIP-4361 compliant message format and signature verification\n * for EVM chains (Ethereum, Base, Polygon, etc.)\n */\n\nimport { verifyMessage } from \"viem\";\nimport { SiweMessage } from \"siwe\";\nimport type { EVMMessageVerifier } from \"./types\";\nimport type { CompleteSIWxInfo } from \"./client\";\nimport type { SIWxSigner } from \"./sign\";\n\n/**\n * Extract numeric chain ID from CAIP-2 EVM chainId.\n *\n * @param chainId - CAIP-2 format chain ID (e.g., \"eip155:8453\")\n * @returns Numeric chain ID (e.g., 8453)\n * @throws Error if chainId format is invalid\n *\n * @example\n * ```typescript\n * extractEVMChainId(\"eip155:1\") // 1 (Ethereum mainnet)\n * extractEVMChainId(\"eip155:8453\") // 8453 (Base)\n * extractEVMChainId(\"eip155:137\") // 137 (Polygon)\n * ```\n */\nexport function extractEVMChainId(chainId: string): number {\n const match = /^eip155:(\\d+)$/.exec(chainId);\n if (!match) {\n throw new Error(`Invalid EVM chainId format: ${chainId}. Expected eip155:<number>`);\n }\n return parseInt(match[1], 10);\n}\n\n/**\n * Format SIWE message following EIP-4361 specification.\n *\n * Uses the siwe library to ensure message format matches verification.\n *\n * @param info - Server-provided extension info\n * @param address - Client's EVM wallet address (0x-prefixed)\n * @returns Message string ready for signing\n *\n * @example\n * ```typescript\n * const message = formatSIWEMessage(serverInfo, \"0x1234...abcd\");\n * // Returns EIP-4361 formatted message:\n * // \"api.example.com wants you to sign in with your Ethereum account:\n * // 0x1234...abcd\n * //\n * // Sign in to access your content\n * //\n * // URI: https://api.example.com/data\n * // Version: 1\n * // Chain ID: 8453\n * // Nonce: abc123\n * // Issued At: 2024-01-01T00:00:00.000Z\"\n * ```\n */\nexport function formatSIWEMessage(info: CompleteSIWxInfo, address: string): string {\n const numericChainId = extractEVMChainId(info.chainId);\n\n const siweMessage = new SiweMessage({\n domain: info.domain,\n address,\n statement: info.statement,\n uri: info.uri,\n version: info.version,\n chainId: numericChainId,\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 });\n\n return siweMessage.prepareMessage();\n}\n\n/**\n * Verify EVM signature.\n *\n * Supports:\n * - EOA signatures (standard ECDSA via EIP-191) - always available\n * - EIP-1271 (deployed smart contract wallets) - requires verifier\n * - EIP-6492 (counterfactual/pre-deploy smart wallets) - requires verifier\n *\n * @param message - The SIWE message that was signed\n * @param address - The claimed signer address\n * @param signature - The signature to verify\n * @param verifier - Optional message verifier for smart wallet support.\n * Pass publicClient.verifyMessage for EIP-1271/EIP-6492 support.\n * Without this, only EOA signatures are verified.\n * @returns true if signature is valid\n *\n * @example\n * ```typescript\n * // EOA-only verification (default, no RPC required)\n * const valid = await verifyEVMSignature(message, address, signature);\n *\n * // Smart wallet verification with viem PublicClient\n * import { createPublicClient, http } from 'viem';\n * import { base } from 'viem/chains';\n *\n * const publicClient = createPublicClient({ chain: base, transport: http() });\n * const valid = await verifyEVMSignature(\n * message,\n * address,\n * signature,\n * publicClient.verifyMessage\n * );\n * ```\n */\nexport async function verifyEVMSignature(\n message: string,\n address: string,\n signature: string,\n verifier?: EVMMessageVerifier,\n): Promise<boolean> {\n const args = {\n address: address as `0x${string}`,\n message,\n signature: signature as `0x${string}`,\n };\n\n if (verifier) {\n // Use provided verifier (supports EIP-1271/EIP-6492 via RPC)\n return verifier(args);\n }\n\n // Fallback to standalone verifyMessage (EOA only, no RPC)\n return verifyMessage(args);\n}\n\n/**\n * Detect if a signer is EVM-compatible.\n * Checks for EVM-specific properties.\n *\n * @param signer - The signer to check\n * @returns true if the signer is an EVM signer\n */\nexport function isEVMSigner(signer: SIWxSigner): boolean {\n // Check for Solana-specific properties first (to exclude them)\n // signMessages (plural) is only on @solana/kit signers\n if (\"signMessages\" in signer && typeof signer.signMessages === \"function\") {\n return false;\n }\n // Check for Solana wallet adapter publicKey (has toBase58 or is non-hex string)\n if (\"publicKey\" in signer && signer.publicKey) {\n const pk = signer.publicKey;\n if (typeof pk === \"object\" && pk !== null && \"toBase58\" in pk) {\n return false;\n }\n if (typeof pk === \"string\" && !pk.startsWith(\"0x\")) {\n return false;\n }\n }\n // EVM signers have account.address or direct address property (hex format)\n if (\"account\" in signer && signer.account && typeof signer.account === \"object\") {\n const account = signer.account as { address?: string };\n if (account.address && account.address.startsWith(\"0x\")) {\n return true;\n }\n }\n if (\n \"address\" in signer &&\n typeof signer.address === \"string\" &&\n signer.address.startsWith(\"0x\")\n ) {\n return true;\n }\n return false;\n}\n","/**\n * Signature verification for SIWX extension\n *\n * Routes to chain-specific verification based on chainId namespace:\n * - EVM (eip155:*): EOA by default, smart wallet (EIP-1271/EIP-6492) with verifier\n * - Solana (solana:*): Ed25519 signature verification via tweetnacl\n */\n\nimport { formatSIWEMessage, verifyEVMSignature } from \"./evm\";\nimport { formatSIWSMessage, verifySolanaSignature, decodeBase58 } from \"./solana\";\nimport type { SIWxPayload, SIWxVerifyResult, SIWxVerifyOptions, EVMMessageVerifier } from \"./types\";\n\n/**\n * Verify SIWX signature cryptographically.\n *\n * Routes to the appropriate chain-specific verification based on the\n * chainId namespace prefix:\n * - `eip155:*` → EVM verification (EOA by default, smart wallet with verifier)\n * - `solana:*` → Ed25519 signature verification\n *\n * @param payload - The SIWX payload containing signature\n * @param options - Optional verification options\n * @returns Verification result with recovered address if valid\n *\n * @example\n * ```typescript\n * // EOA-only verification (default)\n * const result = await verifySIWxSignature(payload);\n *\n * // Smart wallet verification\n * import { createPublicClient, http } from 'viem';\n * import { base } from 'viem/chains';\n *\n * const publicClient = createPublicClient({ chain: base, transport: http() });\n * const result = await verifySIWxSignature(payload, {\n * evmVerifier: publicClient.verifyMessage,\n * });\n *\n * if (result.valid) {\n * console.log('Verified wallet:', result.address);\n * } else {\n * console.error('Verification failed:', result.error);\n * }\n * ```\n */\nexport async function verifySIWxSignature(\n payload: SIWxPayload,\n options?: SIWxVerifyOptions,\n): Promise<SIWxVerifyResult> {\n try {\n // Route by chain namespace\n if (payload.chainId.startsWith(\"eip155:\")) {\n return verifyEVMPayload(payload, options?.evmVerifier);\n }\n\n if (payload.chainId.startsWith(\"solana:\")) {\n return verifySolanaPayload(payload);\n }\n\n return {\n valid: false,\n error: `Unsupported chain namespace: ${payload.chainId}. Supported: eip155:* (EVM), solana:* (Solana)`,\n };\n } catch (error) {\n return {\n valid: false,\n error: error instanceof Error ? error.message : \"Verification failed\",\n };\n }\n}\n\n/**\n * Verify EVM signature with optional smart wallet support.\n *\n * @param payload - The SIWX payload containing signature and message data\n * @param verifier - Optional message verifier for EIP-1271/EIP-6492 support\n * @returns Verification result with recovered address if valid\n */\nasync function verifyEVMPayload(\n payload: SIWxPayload,\n verifier?: EVMMessageVerifier,\n): Promise<SIWxVerifyResult> {\n // Reconstruct SIWE message for verification\n const message = formatSIWEMessage(\n {\n domain: payload.domain,\n uri: payload.uri,\n statement: payload.statement,\n version: payload.version,\n chainId: payload.chainId,\n type: payload.type,\n nonce: payload.nonce,\n issuedAt: payload.issuedAt,\n expirationTime: payload.expirationTime,\n notBefore: payload.notBefore,\n requestId: payload.requestId,\n resources: payload.resources,\n },\n payload.address,\n );\n\n try {\n const valid = await verifyEVMSignature(message, payload.address, payload.signature, verifier);\n\n if (!valid) {\n return {\n valid: false,\n error: \"Signature verification failed\",\n };\n }\n\n return {\n valid: true,\n address: payload.address,\n };\n } catch (error) {\n return {\n valid: false,\n error: error instanceof Error ? error.message : \"Signature verification failed\",\n };\n }\n}\n\n/**\n * Verify Solana Ed25519 signature.\n *\n * Reconstructs the SIWS message and verifies using tweetnacl.\n *\n * @param payload - The SIWX payload containing signature and message data\n * @returns Verification result with recovered address if valid\n */\nfunction verifySolanaPayload(payload: SIWxPayload): SIWxVerifyResult {\n // Reconstruct SIWS message\n const message = formatSIWSMessage(\n {\n domain: payload.domain,\n uri: payload.uri,\n statement: payload.statement,\n version: payload.version,\n chainId: payload.chainId,\n type: payload.type,\n nonce: payload.nonce,\n issuedAt: payload.issuedAt,\n expirationTime: payload.expirationTime,\n notBefore: payload.notBefore,\n requestId: payload.requestId,\n resources: payload.resources,\n },\n payload.address,\n );\n\n // Decode Base58 signature and public key\n let signature: Uint8Array;\n let publicKey: Uint8Array;\n\n try {\n signature = decodeBase58(payload.signature);\n publicKey = decodeBase58(payload.address);\n } catch (error) {\n return {\n valid: false,\n error: `Invalid Base58 encoding: ${error instanceof Error ? error.message : \"decode failed\"}`,\n };\n }\n\n // Validate signature length (Ed25519 signatures are 64 bytes)\n if (signature.length !== 64) {\n return {\n valid: false,\n error: `Invalid signature length: expected 64 bytes, got ${signature.length}`,\n };\n }\n\n // Validate public key length (Ed25519 public keys are 32 bytes)\n if (publicKey.length !== 32) {\n return {\n valid: false,\n error: `Invalid public key length: expected 32 bytes, got ${publicKey.length}`,\n };\n }\n\n // Verify Ed25519 signature\n const valid = verifySolanaSignature(message, signature, publicKey);\n\n if (!valid) {\n return {\n valid: false,\n error: \"Solana signature verification failed\",\n };\n }\n\n return {\n valid: true,\n address: payload.address,\n };\n}\n","/**\n * CAIP-122 message construction for SIWX extension\n *\n * Constructs the canonical message string for signing.\n * Routes to chain-specific formatters based on chainId namespace.\n */\n\nimport { formatSIWEMessage } from \"./evm\";\nimport { formatSIWSMessage } from \"./solana\";\nimport type { CompleteSIWxInfo } from \"./client\";\n\n/**\n * Construct CAIP-122 compliant message string for signing.\n *\n * Routes to the appropriate chain-specific message formatter based on the\n * chainId namespace prefix:\n * - `eip155:*` → SIWE (EIP-4361) format via siwe library\n * - `solana:*` → SIWS format\n *\n * @param serverInfo - Server extension info with chain selected (includes chainId)\n * @param address - Client wallet address\n * @returns Message string ready for signing\n * @throws Error if chainId namespace is not supported\n *\n * @example\n * ```typescript\n * // EVM (Ethereum, Base, etc.)\n * const completeInfo = { ...extension.info, chainId: \"eip155:8453\", type: \"eip191\" };\n * const evmMessage = createSIWxMessage(completeInfo, \"0x1234...\");\n * ```\n */\nexport function createSIWxMessage(serverInfo: CompleteSIWxInfo, address: string): string {\n // Route by chain namespace\n if (serverInfo.chainId.startsWith(\"eip155:\")) {\n return formatSIWEMessage(serverInfo, address);\n }\n\n if (serverInfo.chainId.startsWith(\"solana:\")) {\n return formatSIWSMessage(serverInfo, address);\n }\n\n throw new Error(\n `Unsupported chain namespace: ${serverInfo.chainId}. ` +\n `Supported: eip155:* (EVM), solana:* (Solana)`,\n );\n}\n","/**\n * Message signing for SIWX extension\n *\n * Client-side helpers for signing SIWX messages.\n * Supports both EVM (viem) and Solana wallet adapters.\n */\n\nimport { encodeBase58 } from \"./solana\";\n\n/**\n * Signer interface for EVM SIWX message signing.\n * Compatible with viem WalletClient and PrivateKeyAccount.\n */\nexport interface EVMSigner {\n /** Sign a message and return hex-encoded signature */\n signMessage: (args: { message: string; account?: unknown }) => Promise<string>;\n /** Account object (for WalletClient) */\n account?: { address: string };\n /** Direct address (for PrivateKeyAccount) */\n address?: string;\n}\n\n/**\n * Wallet adapter style Solana signer.\n * Compatible with @solana/wallet-adapter, Phantom/Solflare wallet APIs.\n */\nexport interface WalletAdapterSigner {\n /** Sign a message and return raw signature bytes */\n signMessage: (message: Uint8Array) => Promise<Uint8Array>;\n /** Solana public key (Base58 encoded string or PublicKey-like object) */\n publicKey: string | { toBase58: () => string };\n}\n\n/**\n * Solana Kit KeyPairSigner style.\n * Compatible with createKeyPairSignerFromBytes and generateKeyPairSigner from @solana/kit.\n */\nexport type SolanaKitSigner = {\n /** Solana address (Base58 encoded string) */\n address: string;\n /** Sign messages - accepts messages with content and signatures */\n signMessages: (\n messages: Array<{ content: Uint8Array; signatures: Record<string, unknown> }>,\n ) => Promise<Array<Record<string, Uint8Array>>>;\n};\n\n/**\n * Union type for Solana signers - supports both wallet adapter and @solana/kit.\n */\nexport type SolanaSigner = WalletAdapterSigner | SolanaKitSigner;\n\n/**\n * Union type for SIWX signers - supports both EVM and Solana wallets.\n */\nexport type SIWxSigner = EVMSigner | SolanaSigner;\n\n/**\n * Get address from an EVM signer.\n *\n * @param signer - EVM wallet signer instance\n * @returns The wallet address as a hex string\n */\nexport function getEVMAddress(signer: EVMSigner): string {\n if (signer.account?.address) {\n return signer.account.address;\n }\n if (signer.address) {\n return signer.address;\n }\n throw new Error(\"EVM signer missing address\");\n}\n\n/**\n * Get address from a Solana signer.\n * Supports both wallet adapter (publicKey) and @solana/kit (address) interfaces.\n *\n * @param signer - Solana wallet signer instance\n * @returns The wallet address as a Base58 string\n */\nexport function getSolanaAddress(signer: SolanaSigner): string {\n // Check for @solana/kit KeyPairSigner interface (address property)\n if (\"address\" in signer && signer.address) {\n return signer.address;\n }\n // Fall back to wallet adapter interface (publicKey property)\n if (\"publicKey\" in signer) {\n const pk = signer.publicKey;\n return typeof pk === \"string\" ? pk : pk.toBase58();\n }\n throw new Error(\"Solana signer missing address or publicKey\");\n}\n\n/**\n * Sign a message with an EVM wallet.\n * Returns hex-encoded signature.\n *\n * @param message - The message to sign\n * @param signer - EVM wallet signer instance\n * @returns Hex-encoded signature\n */\nexport async function signEVMMessage(message: string, signer: EVMSigner): Promise<string> {\n if (signer.account) {\n return signer.signMessage({ message, account: signer.account });\n }\n return signer.signMessage({ message });\n}\n\n/**\n * Sign a message with a Solana wallet.\n * Returns Base58-encoded signature.\n * Supports both wallet adapter (signMessage) and @solana/kit (signMessages) interfaces.\n *\n * @param message - The message to sign\n * @param signer - Solana wallet signer instance\n * @returns Base58-encoded signature\n */\nexport async function signSolanaMessage(message: string, signer: SolanaSigner): Promise<string> {\n const messageBytes = new TextEncoder().encode(message);\n\n // Check for @solana/kit signMessages interface\n if (\"signMessages\" in signer) {\n const results = await signer.signMessages([{ content: messageBytes, signatures: {} }]);\n // signMessages returns an array of signature dictionaries\n // The signature is keyed by the signer's address\n const sigDict = results[0] as { [key: string]: Uint8Array };\n // Get the first (and only) signature value from the dictionary\n const signatureBytes = Object.values(sigDict)[0];\n return encodeBase58(signatureBytes);\n }\n\n // Fall back to wallet adapter signMessage interface\n if (\"signMessage\" in signer) {\n const signatureBytes = await signer.signMessage(messageBytes);\n return encodeBase58(signatureBytes);\n }\n\n throw new Error(\"Solana signer missing signMessage or signMessages method\");\n}\n","/**\n * Complete client flow for SIWX extension\n *\n * Combines message construction, signing, and payload creation.\n * Supports both EVM and Solana wallets.\n */\n\nimport type { SIWxExtensionInfo, SIWxPayload, SignatureType, SignatureScheme } from \"./types\";\nimport type { SIWxSigner, EVMSigner, SolanaSigner } from \"./sign\";\nimport { getEVMAddress, getSolanaAddress, signEVMMessage, signSolanaMessage } from \"./sign\";\nimport { createSIWxMessage } from \"./message\";\n\n/**\n * Complete SIWX info with chain-specific fields.\n * Used by utility functions that need the selected chain information.\n */\nexport type CompleteSIWxInfo = SIWxExtensionInfo & {\n chainId: string;\n type: SignatureType;\n signatureScheme?: SignatureScheme;\n};\n\n/**\n * Create a complete SIWX payload from server extension info with selected chain.\n *\n * Routes to EVM or Solana signing based on the chainId prefix:\n * - `eip155:*` → EVM signing\n * - `solana:*` → Solana signing\n *\n * @param serverExtension - Server extension info with chain selected (includes chainId, type)\n * @param signer - Wallet that can sign messages (EVMSigner or SolanaSigner)\n * @returns Complete SIWX payload with signature\n *\n * @example\n * ```typescript\n * // EVM wallet\n * const completeInfo = { ...extension.info, chainId: \"eip155:8453\", type: \"eip191\" };\n * const payload = await createSIWxPayload(completeInfo, evmWallet);\n * ```\n */\nexport async function createSIWxPayload(\n serverExtension: CompleteSIWxInfo,\n signer: SIWxSigner,\n): Promise<SIWxPayload> {\n const isSolana = serverExtension.chainId.startsWith(\"solana:\");\n\n // Get address and sign based on chain type\n const address = isSolana\n ? getSolanaAddress(signer as SolanaSigner)\n : getEVMAddress(signer as EVMSigner);\n\n const message = createSIWxMessage(serverExtension, address);\n\n const signature = isSolana\n ? await signSolanaMessage(message, signer as SolanaSigner)\n : await signEVMMessage(message, signer as EVMSigner);\n\n return {\n domain: serverExtension.domain,\n address,\n statement: serverExtension.statement,\n uri: serverExtension.uri,\n version: serverExtension.version,\n chainId: serverExtension.chainId,\n type: serverExtension.type,\n nonce: serverExtension.nonce,\n issuedAt: serverExtension.issuedAt,\n expirationTime: serverExtension.expirationTime,\n notBefore: serverExtension.notBefore,\n requestId: serverExtension.requestId,\n resources: serverExtension.resources,\n signatureScheme: serverExtension.signatureScheme,\n signature,\n };\n}\n","/**\n * Header encoding for SIWX extension\n *\n * Encodes SIWX payload for the SIGN-IN-WITH-X HTTP header.\n * Per CHANGELOG-v2.md line 335: header should be base64-encoded.\n */\n\nimport { safeBase64Encode } from \"@x402/core/utils\";\nimport type { SIWxPayload } from \"./types\";\n\n/**\n * Encode SIWX payload for SIGN-IN-WITH-X header.\n *\n * Uses base64 encoding per x402 v2 spec (CHANGELOG-v2.md line 335).\n *\n * @param payload - Complete SIWX payload with signature\n * @returns Base64-encoded JSON string\n *\n * @example\n * ```typescript\n * const payload = await createSIWxPayload(serverInfo, signer);\n * const header = encodeSIWxHeader(payload);\n *\n * fetch(url, {\n * headers: { 'SIGN-IN-WITH-X': header }\n * });\n * ```\n */\nexport function encodeSIWxHeader(payload: SIWxPayload): string {\n return safeBase64Encode(JSON.stringify(payload));\n}\n","/**\n * Fetch wrapper for SIWX authentication.\n *\n * Provides a convenient wrapper around fetch that automatically handles\n * SIWX authentication when a 402 response includes SIWX extension info.\n */\n\nimport { decodePaymentRequiredHeader } from \"@x402/core/http\";\nimport type { SIWxSigner } from \"./sign\";\nimport type { SIWxExtension } from \"./types\";\nimport { SIGN_IN_WITH_X } from \"./types\";\nimport { createSIWxPayload } from \"./client\";\nimport { encodeSIWxHeader } from \"./encode\";\n\n/**\n * Wraps fetch to automatically handle SIWX authentication.\n *\n * When a 402 response is received with a SIWX extension:\n * 1. Extracts SIWX info from PAYMENT-REQUIRED header\n * 2. Creates signed SIWX proof using the provided signer\n * 3. Retries the request with the SIWX header\n *\n * If the 402 response doesn't include SIWX extension info, the original\n * response is returned unchanged (allowing payment handling to proceed).\n *\n * @param fetch - The fetch function to wrap (typically globalThis.fetch)\n * @param signer - Wallet signer (EVMSigner or SolanaSigner)\n * @returns A wrapped fetch function that handles SIWX authentication\n *\n * @example\n * ```typescript\n * import { wrapFetchWithSIWx } from '@x402/extensions/sign-in-with-x';\n * import { privateKeyToAccount } from 'viem/accounts';\n *\n * const signer = privateKeyToAccount(privateKey);\n * const fetchWithSIWx = wrapFetchWithSIWx(fetch, signer);\n *\n * // Request that may require SIWX auth (for returning paid users)\n * const response = await fetchWithSIWx('https://api.example.com/data');\n * ```\n */\nexport function wrapFetchWithSIWx(fetch: typeof globalThis.fetch, signer: SIWxSigner) {\n return async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n const request = new Request(input, init);\n const clonedRequest = request.clone();\n\n const response = await fetch(request);\n\n if (response.status !== 402) {\n return response;\n }\n\n // Extract SIWX info from 402 response\n const paymentRequiredHeader = response.headers.get(\"PAYMENT-REQUIRED\");\n if (!paymentRequiredHeader) {\n return response; // No PAYMENT-REQUIRED header, return original response\n }\n\n const paymentRequired = decodePaymentRequiredHeader(paymentRequiredHeader);\n const siwxExtension = paymentRequired.extensions?.[SIGN_IN_WITH_X] as SIWxExtension | undefined;\n\n if (!siwxExtension?.supportedChains) {\n return response; // Server doesn't support SIWX, return original 402\n }\n\n // Prevent infinite loops\n if (clonedRequest.headers.has(SIGN_IN_WITH_X)) {\n throw new Error(\"SIWX authentication already attempted\");\n }\n\n // Get network from payment requirements\n const paymentNetwork = paymentRequired.accepts?.[0]?.network;\n if (!paymentNetwork) {\n return response; // No network in payment requirements\n }\n\n // Find matching chain in supportedChains\n const matchingChain = siwxExtension.supportedChains.find(\n chain => chain.chainId === paymentNetwork,\n );\n\n if (!matchingChain) {\n return response; // Payment network not in SIWX supportedChains\n }\n\n // Build complete info with selected chain\n const completeInfo = {\n ...siwxExtension.info,\n chainId: matchingChain.chainId,\n type: matchingChain.type,\n };\n\n // Create and send SIWX proof\n const payload = await createSIWxPayload(completeInfo, signer);\n const siwxHeader = encodeSIWxHeader(payload);\n\n clonedRequest.headers.set(SIGN_IN_WITH_X, siwxHeader);\n\n return fetch(clonedRequest);\n };\n}\n","/**\n * Storage interface for SIWX payment tracking.\n *\n * Implementations track which addresses have paid for which resources,\n * enabling SIWX authentication to grant access without re-payment.\n *\n * Optionally supports nonce tracking to prevent signature replay attacks.\n */\nexport interface SIWxStorage {\n /**\n * Check if an address has paid for a resource.\n *\n * @param resource - The resource path (e.g., \"/weather\")\n * @param address - The wallet address to check\n * @returns True if the address has paid for the resource\n */\n hasPaid(resource: string, address: string): boolean | Promise<boolean>;\n\n /**\n * Record that an address has paid for a resource.\n *\n * @param resource - The resource path\n * @param address - The wallet address that paid\n */\n recordPayment(resource: string, address: string): void | Promise<void>;\n\n /**\n * Check if a nonce has already been used (optional).\n *\n * Implementing this method prevents signature replay attacks where\n * an intercepted SIWX header could be reused by an attacker.\n *\n * @param nonce - The nonce from the SIWX payload\n * @returns True if the nonce has been used\n */\n hasUsedNonce?(nonce: string): boolean | Promise<boolean>;\n\n /**\n * Record that a nonce has been used (optional).\n *\n * Called after successfully granting access via SIWX.\n * Implementations should consider adding expiration to avoid unbounded growth.\n *\n * @param nonce - The nonce to record as used\n */\n recordNonce?(nonce: string): void | Promise<void>;\n}\n\n/**\n * In-memory implementation of SIWxStorage.\n *\n * Suitable for development and single-instance deployments.\n * For production multi-instance deployments, use a persistent storage implementation.\n */\nexport class InMemorySIWxStorage implements SIWxStorage {\n private paidAddresses = new Map<string, Set<string>>();\n\n /**\n * Check if an address has paid for a resource.\n *\n * @param resource - The resource path\n * @param address - The wallet address to check\n * @returns True if the address has paid\n */\n hasPaid(resource: string, address: string): boolean {\n return this.paidAddresses.get(resource)?.has(address.toLowerCase()) ?? false;\n }\n\n /**\n * Record that an address has paid for a resource.\n *\n * @param resource - The resource path\n * @param address - The wallet address that paid\n */\n recordPayment(resource: string, address: string): void {\n if (!this.paidAddresses.has(resource)) {\n this.paidAddresses.set(resource, new Set());\n }\n this.paidAddresses.get(resource)!.add(address.toLowerCase());\n }\n}\n","/**\n * SIWX Lifecycle Hooks\n *\n * Pre-built hooks for integrating SIWX authentication with x402 servers and clients.\n */\n\nimport type { SIWxStorage } from \"./storage\";\nimport type { SIWxExtension, SIWxVerifyOptions, SignatureType } from \"./types\";\nimport type { SIWxSigner } from \"./sign\";\nimport { SIGN_IN_WITH_X } from \"./types\";\nimport { parseSIWxHeader } from \"./parse\";\nimport { validateSIWxMessage } from \"./validate\";\nimport { verifySIWxSignature } from \"./verify\";\nimport { createSIWxPayload } from \"./client\";\nimport { encodeSIWxHeader } from \"./encode\";\nimport { isSolanaSigner } from \"./solana\";\n\n/**\n * Options for creating server-side SIWX hooks.\n */\nexport interface CreateSIWxHookOptions {\n /** Storage for tracking paid addresses */\n storage: SIWxStorage;\n /** Options for signature verification (e.g., EVM smart wallet support) */\n verifyOptions?: SIWxVerifyOptions;\n /** Optional callback for logging/debugging */\n onEvent?: (event: SIWxHookEvent) => void;\n}\n\n/**\n * Events emitted by SIWX hooks for logging/debugging.\n */\nexport type SIWxHookEvent =\n | { type: \"payment_recorded\"; resource: string; address: string }\n | { type: \"access_granted\"; resource: string; address: string }\n | { type: \"validation_failed\"; resource: string; error?: string }\n | { type: \"nonce_reused\"; resource: string; nonce: string }\n | { type: \"siwx_header_sent\"; resource: string };\n\n/**\n * Creates an onAfterSettle hook that records payments for SIWX.\n *\n * @param options - Hook configuration\n * @returns Hook function for x402ResourceServer.onAfterSettle()\n *\n * @example\n * ```typescript\n * const storage = new InMemorySIWxStorage();\n * const resourceServer = new x402ResourceServer(facilitator)\n * .onAfterSettle(createSIWxSettleHook({ storage }));\n * ```\n */\nexport function createSIWxSettleHook(options: CreateSIWxHookOptions) {\n const { storage, onEvent } = options;\n\n return async (ctx: {\n paymentPayload: { payload: unknown; resource?: { url: string } };\n result: { success: boolean; payer?: string };\n }): Promise<void> => {\n // Only record payment if settlement succeeded\n if (!ctx.result.success) return;\n\n // Get payer from facilitator's settle result (works for all payment schemes)\n const address = ctx.result.payer;\n if (!address) return;\n\n // resource is optional per the v2 spec (section 5.2.2)\n const resourceUrl = ctx.paymentPayload.resource?.url;\n if (!resourceUrl) return;\n\n const resource = new URL(resourceUrl).pathname;\n await storage.recordPayment(resource, address);\n onEvent?.({ type: \"payment_recorded\", resource, address });\n };\n}\n\n/**\n * Creates an onProtectedRequest hook that validates SIWX auth before payment.\n *\n * @param options - Hook configuration\n * @returns Hook function for x402HTTPResourceServer.onProtectedRequest()\n *\n * @example\n * ```typescript\n * const storage = new InMemorySIWxStorage();\n * const httpServer = new x402HTTPResourceServer(resourceServer, routes)\n * .onProtectedRequest(createSIWxRequestHook({ storage }));\n * ```\n */\nexport function createSIWxRequestHook(options: CreateSIWxHookOptions) {\n const { storage, verifyOptions, onEvent } = options;\n\n // Validate nonce tracking is fully implemented or not at all\n const hasUsedNonce = typeof storage.hasUsedNonce === \"function\";\n const hasRecordNonce = typeof storage.recordNonce === \"function\";\n if (hasUsedNonce !== hasRecordNonce) {\n throw new Error(\n \"SIWxStorage nonce tracking requires both hasUsedNonce and recordNonce to be implemented\",\n );\n }\n\n return async (context: {\n adapter: { getHeader(name: string): string | undefined; getUrl(): string };\n path: string;\n }): Promise<void | { grantAccess: true }> => {\n // Try both cases for header (HTTP headers are case-insensitive)\n const header =\n context.adapter.getHeader(SIGN_IN_WITH_X) ||\n context.adapter.getHeader(SIGN_IN_WITH_X.toLowerCase());\n if (!header) return;\n\n try {\n const payload = parseSIWxHeader(header);\n const resourceUri = context.adapter.getUrl();\n\n const validation = await validateSIWxMessage(payload, resourceUri);\n if (!validation.valid) {\n onEvent?.({ type: \"validation_failed\", resource: context.path, error: validation.error });\n return;\n }\n\n const verification = await verifySIWxSignature(payload, verifyOptions);\n if (!verification.valid || !verification.address) {\n onEvent?.({ type: \"validation_failed\", resource: context.path, error: verification.error });\n return;\n }\n\n // Check if nonce was already used (prevents signature replay attacks)\n if (storage.hasUsedNonce) {\n const nonceUsed = await storage.hasUsedNonce(payload.nonce);\n if (nonceUsed) {\n onEvent?.({ type: \"nonce_reused\", resource: context.path, nonce: payload.nonce });\n return;\n }\n }\n\n const hasPaid = await storage.hasPaid(context.path, verification.address);\n if (hasPaid) {\n // Record nonce as used before granting access\n if (storage.recordNonce) {\n await storage.recordNonce(payload.nonce);\n }\n\n onEvent?.({\n type: \"access_granted\",\n resource: context.path,\n address: verification.address,\n });\n return { grantAccess: true };\n }\n } catch (err) {\n onEvent?.({\n type: \"validation_failed\",\n resource: context.path,\n error: err instanceof Error ? err.message : \"Unknown error\",\n });\n }\n };\n}\n\n/**\n * Creates an onPaymentRequired hook for client-side SIWX authentication.\n *\n * Matches the signer type to a compatible chain in supportedChains.\n * For EVM signers: matches any eip191 chain\n * For Solana signers: matches any ed25519 chain\n *\n * @param signer - Wallet signer for creating SIWX proofs\n * @returns Hook function for x402HTTPClient.onPaymentRequired()\n *\n * @example\n * ```typescript\n * const httpClient = new x402HTTPClient(client)\n * .onPaymentRequired(createSIWxClientHook(signer));\n * ```\n */\nexport function createSIWxClientHook(signer: SIWxSigner) {\n // Determine signer type once at hook creation\n const signerIsSolana = isSolanaSigner(signer);\n const expectedSignatureType: SignatureType = signerIsSolana ? \"ed25519\" : \"eip191\";\n\n return async (context: {\n paymentRequired: { accepts?: Array<{ network: string }>; extensions?: Record<string, unknown> };\n }): Promise<{ headers: Record<string, string> } | void> => {\n const extensions = context.paymentRequired.extensions ?? {};\n const siwxExtension = extensions[SIGN_IN_WITH_X] as SIWxExtension | undefined;\n\n if (!siwxExtension?.supportedChains) return;\n\n try {\n // Find a chain that matches the signer's signature type\n const matchingChain = siwxExtension.supportedChains.find(\n chain => chain.type === expectedSignatureType,\n );\n\n if (!matchingChain) {\n // No chain compatible with this signer type\n return;\n }\n\n // Build complete info with selected chain\n const completeInfo = {\n ...siwxExtension.info,\n chainId: matchingChain.chainId,\n type: matchingChain.type,\n };\n\n const payload = await createSIWxPayload(completeInfo, signer);\n const header = encodeSIWxHeader(payload);\n return { headers: { [SIGN_IN_WITH_X]: header } };\n } catch {\n // Failed to create SIWX payload, continue to payment\n }\n };\n}\n","/**\n * Type definitions for the x402 Offer/Receipt Extension\n *\n * Based on: x402/specs/extensions/extension-offer-and-receipt.md (v1.0)\n *\n * Offers prove payment requirements originated from a resource server.\n * Receipts prove service was delivered after payment.\n */\n\n/**\n * Extension identifier constant\n */\nexport const OFFER_RECEIPT = \"offer-receipt\";\n\n/**\n * Supported signature formats (§3.1)\n */\nexport type SignatureFormat = \"jws\" | \"eip712\";\n\n// ============================================================================\n// Low-Level Signer Interfaces\n// ============================================================================\n\n/**\n * Base signer interface for pluggable signing backends\n */\nexport interface Signer {\n /** Key identifier DID (e.g., did:web:api.example.com#key-1) */\n kid: string;\n /** Sign payload and return signature string */\n sign: (payload: Uint8Array) => Promise<string>;\n /** Signature format */\n format: SignatureFormat;\n}\n\n/**\n * JWS-specific signer with algorithm info\n */\nexport interface JWSSigner extends Signer {\n format: \"jws\";\n /** JWS algorithm (e.g., ES256K, EdDSA) */\n algorithm: string;\n}\n\n/**\n * EIP-712 specific signer\n */\nexport interface EIP712Signer extends Signer {\n format: \"eip712\";\n /** Chain ID for EIP-712 domain */\n chainId: number;\n}\n\n// ============================================================================\n// Offer Types (§4)\n// ============================================================================\n\n/**\n * Offer payload fields (§4.2)\n *\n * Required: version, resourceUrl, scheme, network, asset, payTo, amount\n * Optional: validUntil\n */\nexport interface OfferPayload {\n /** Offer payload schema version (currently 1) */\n version: number;\n /** The paid resource URL */\n resourceUrl: string;\n /** Payment scheme identifier (e.g., \"exact\") */\n scheme: string;\n /** Blockchain network identifier (CAIP-2 format, e.g., \"eip155:8453\") */\n network: string;\n /** Token contract address or \"native\" */\n asset: string;\n /** Recipient wallet address */\n payTo: string;\n /** Required payment amount */\n amount: string;\n /** Unix timestamp (seconds) when the offer expires (optional) */\n validUntil: number;\n}\n\n/**\n * Signed offer in JWS format (§3.1.1)\n *\n * \"When format = 'jws': payload MUST be omitted\"\n */\nexport interface JWSSignedOffer {\n format: \"jws\";\n /** Index into accepts[] array (unsigned envelope field, §4.1.1) */\n acceptIndex?: number;\n /** JWS Compact Serialization string (header.payload.signature) */\n signature: string;\n}\n\n/**\n * Signed offer in EIP-712 format (§3.1.1)\n *\n * \"When format = 'eip712': payload is REQUIRED\"\n */\nexport interface EIP712SignedOffer {\n format: \"eip712\";\n /** Index into accepts[] array (unsigned envelope field, §4.1.1) */\n acceptIndex?: number;\n /** The canonical payload fields */\n payload: OfferPayload;\n /** Hex-encoded ECDSA signature (0x-prefixed, 65 bytes: r+s+v) */\n signature: string;\n}\n\n/**\n * Union type for signed offers\n */\nexport type SignedOffer = JWSSignedOffer | EIP712SignedOffer;\n\n// ============================================================================\n// Receipt Types (§5)\n// ============================================================================\n\n/**\n * Receipt payload fields (§5.2)\n *\n * Required: version, network, resourceUrl, payer, issuedAt\n * Optional: transaction (for verifiability over privacy)\n */\nexport interface ReceiptPayload {\n /** Receipt payload schema version (currently 1) */\n version: number;\n /** Blockchain network identifier (CAIP-2 format, e.g., \"eip155:8453\") */\n network: string;\n /** The paid resource URL */\n resourceUrl: string;\n /** Payer identifier (commonly a wallet address) */\n payer: string;\n /** Unix timestamp (seconds) when receipt was issued */\n issuedAt: number;\n /** Blockchain transaction hash (optional - for verifiability over privacy) */\n transaction: string;\n}\n\n/**\n * Signed receipt in JWS format (§3.1.1)\n */\nexport interface JWSSignedReceipt {\n format: \"jws\";\n /** JWS Compact Serialization string */\n signature: string;\n}\n\n/**\n * Signed receipt in EIP-712 format (§3.1.1)\n */\nexport interface EIP712SignedReceipt {\n format: \"eip712\";\n /** The receipt payload */\n payload: ReceiptPayload;\n /** Hex-encoded ECDSA signature */\n signature: string;\n}\n\n/**\n * Union type for signed receipts\n */\nexport type SignedReceipt = JWSSignedReceipt | EIP712SignedReceipt;\n\n// ============================================================================\n// Extension Configuration Types\n// ============================================================================\n\n/**\n * Declaration for the offer-receipt extension in route config\n * Used by servers to declare that a route uses offer-receipt\n */\nexport interface OfferReceiptDeclaration {\n /** Include transaction hash in receipt (default: false for privacy). Set to true for verifiability. */\n includeTxHash?: boolean;\n /** Offer validity duration in seconds. Default: 300 (see x402ResourceServer.ts) */\n offerValiditySeconds?: number;\n}\n\n/**\n * Input for creating an offer (derived from PaymentRequirements)\n */\nexport interface OfferInput {\n /** Index into accepts[] array this offer corresponds to (0-based) */\n acceptIndex: number;\n /** Payment scheme identifier */\n scheme: string;\n /** Blockchain network identifier (CAIP-2 format) */\n network: string;\n /** Token contract address or \"native\" */\n asset: string;\n /** Recipient wallet address */\n payTo: string;\n /** Required payment amount */\n amount: string;\n /** Offer validity duration in seconds. Default: 300 (see x402ResourceServer.ts) */\n offerValiditySeconds?: number;\n}\n\n/**\n * High-level issuer interface for the offer-receipt extension.\n * Creates and signs offers and receipts.\n * Used by createOfferReceiptExtension()\n */\nexport interface OfferReceiptIssuer {\n /** Key identifier DID */\n kid: string;\n /** Signature format */\n format: SignatureFormat;\n /** Create and sign an offer for a resource */\n issueOffer(resourceUrl: string, input: OfferInput): Promise<SignedOffer>;\n /** Create and sign a receipt for a completed payment */\n issueReceipt(\n resourceUrl: string,\n payer: string,\n network: string,\n transaction?: string,\n ): Promise<SignedReceipt>;\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\n/**\n * Check if an offer is JWS format\n *\n * @param offer - The signed offer to check\n * @returns True if the offer uses JWS format\n */\nexport function isJWSSignedOffer(offer: SignedOffer): offer is JWSSignedOffer {\n return offer.format === \"jws\";\n}\n\n/**\n * Check if an offer is EIP-712 format\n *\n * @param offer - The signed offer to check\n * @returns True if the offer uses EIP-712 format\n */\nexport function isEIP712SignedOffer(offer: SignedOffer): offer is EIP712SignedOffer {\n return offer.format === \"eip712\";\n}\n\n/**\n * Check if a receipt is JWS format\n *\n * @param receipt - The signed receipt to check\n * @returns True if the receipt uses JWS format\n */\nexport function isJWSSignedReceipt(receipt: SignedReceipt): receipt is JWSSignedReceipt {\n return receipt.format === \"jws\";\n}\n\n/**\n * Check if a receipt is EIP-712 format\n *\n * @param receipt - The signed receipt to check\n * @returns True if the receipt uses EIP-712 format\n */\nexport function isEIP712SignedReceipt(receipt: SignedReceipt): receipt is EIP712SignedReceipt {\n return receipt.format === \"eip712\";\n}\n\n/**\n * Check if a signer is JWS format\n *\n * @param signer - The signer to check\n * @returns True if the signer uses JWS format\n */\nexport function isJWSSigner(signer: Signer): signer is JWSSigner {\n return signer.format === \"jws\";\n}\n\n/**\n * Check if a signer is EIP-712 format\n *\n * @param signer - The signer to check\n * @returns True if the signer uses EIP-712 format\n */\nexport function isEIP712Signer(signer: Signer): signer is EIP712Signer {\n return signer.format === \"eip712\";\n}\n\n// ============================================================================\n// Receipt Input Type\n// ============================================================================\n\n/**\n * Input for creating a receipt\n */\nexport interface ReceiptInput {\n /** The resource URL that was paid for */\n resourceUrl: string;\n /** The payer identifier (wallet address) */\n payer: string;\n /** The blockchain network (CAIP-2 format) */\n network: string;\n /** The transaction hash (optional, for verifiability) */\n transaction?: string;\n}\n","/**\n * Signing utilities for x402 Offer/Receipt Extension\n *\n * This module provides:\n * - JCS (JSON Canonicalization Scheme) per RFC 8785\n * - JWS (JSON Web Signature) signing and extraction\n * - EIP-712 typed data signing\n * - Offer/Receipt creation utilities\n * - Signature verification utilities\n *\n * Based on: x402/specs/extensions/extension-offer-and-receipt.md (v1.0) §3\n */\n\nimport * as jose from \"jose\";\nimport { hashTypedData, recoverTypedDataAddress, type Hex, type TypedDataDomain } from \"viem\";\nimport type {\n JWSSigner,\n OfferPayload,\n ReceiptPayload,\n SignedOffer,\n SignedReceipt,\n OfferInput,\n ReceiptInput,\n} from \"./types\";\nimport {\n isJWSSignedOffer,\n isEIP712SignedOffer,\n isJWSSignedReceipt,\n isEIP712SignedReceipt,\n type JWSSignedOffer,\n type EIP712SignedOffer,\n type JWSSignedReceipt,\n type EIP712SignedReceipt,\n} from \"./types\";\nimport { extractPublicKeyFromKid } from \"./did\";\n\n// ============================================================================\n// JCS Canonicalization (RFC 8785)\n// ============================================================================\n\n/**\n * Canonicalize a JSON object using JCS (RFC 8785)\n *\n * Rules:\n * 1. Object keys are sorted lexicographically by UTF-16 code units\n * 2. No whitespace between tokens\n * 3. Numbers use shortest representation (no trailing zeros)\n * 4. Strings use minimal escaping\n * 5. null, true, false are lowercase literals\n *\n * @param value - The object to canonicalize\n * @returns The canonicalized JSON string\n */\nexport function canonicalize(value: unknown): string {\n return serializeValue(value);\n}\n\n/**\n * Serialize a value to canonical JSON\n *\n * @param value - The value to serialize\n * @returns The serialized string\n */\nfunction serializeValue(value: unknown): string {\n if (value === null) return \"null\";\n if (value === undefined) return \"null\";\n\n const type = typeof value;\n if (type === \"boolean\") return value ? \"true\" : \"false\";\n if (type === \"number\") return serializeNumber(value as number);\n if (type === \"string\") return serializeString(value as string);\n if (Array.isArray(value)) return serializeArray(value);\n if (type === \"object\") return serializeObject(value as Record<string, unknown>);\n\n throw new Error(`Cannot canonicalize value of type ${type}`);\n}\n\n/**\n * Serialize a number to canonical JSON\n *\n * @param num - The number to serialize\n * @returns The serialized string\n */\nfunction serializeNumber(num: number): string {\n if (!Number.isFinite(num)) throw new Error(\"Cannot canonicalize Infinity or NaN\");\n if (Object.is(num, -0)) return \"0\";\n return String(num);\n}\n\n/**\n * Serialize a string to canonical JSON\n *\n * @param str - The string to serialize\n * @returns The serialized string with proper escaping\n */\nfunction serializeString(str: string): string {\n let result = '\"';\n for (let i = 0; i < str.length; i++) {\n const char = str[i];\n const code = str.charCodeAt(i);\n if (code < 0x20) {\n result += \"\\\\u\" + code.toString(16).padStart(4, \"0\");\n } else if (char === '\"') {\n result += '\\\\\"';\n } else if (char === \"\\\\\") {\n result += \"\\\\\\\\\";\n } else {\n result += char;\n }\n }\n return result + '\"';\n}\n\n/**\n * Serialize an array to canonical JSON\n *\n * @param arr - The array to serialize\n * @returns The serialized string\n */\nfunction serializeArray(arr: unknown[]): string {\n return \"[\" + arr.map(serializeValue).join(\",\") + \"]\";\n}\n\n/**\n * Serialize an object to canonical JSON with sorted keys\n *\n * @param obj - The object to serialize\n * @returns The serialized string with sorted keys\n */\nfunction serializeObject(obj: Record<string, unknown>): string {\n const keys = Object.keys(obj).sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));\n const pairs: string[] = [];\n for (const key of keys) {\n const value = obj[key];\n if (value !== undefined) {\n pairs.push(serializeString(key) + \":\" + serializeValue(value));\n }\n }\n return \"{\" + pairs.join(\",\") + \"}\";\n}\n\n/**\n * Hash a canonicalized object using SHA-256\n *\n * @param obj - The object to hash\n * @returns The SHA-256 hash as Uint8Array\n */\nexport async function hashCanonical(obj: unknown): Promise<Uint8Array> {\n const canonical = canonicalize(obj);\n const data = new TextEncoder().encode(canonical);\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", data);\n return new Uint8Array(hashBuffer);\n}\n\n/**\n * Get canonical bytes of an object (UTF-8 encoded)\n *\n * @param obj - The object to encode\n * @returns The UTF-8 encoded canonical JSON\n */\nexport function getCanonicalBytes(obj: unknown): Uint8Array {\n return new TextEncoder().encode(canonicalize(obj));\n}\n\n// ============================================================================\n// JWS Signing (§3.3)\n// ============================================================================\n\n/**\n * Create a JWS Compact Serialization from a payload\n *\n * Assembles the full JWS structure (header.payload.signature) using the\n * signer's algorithm and kid. The signer only needs to sign bytes and\n * return the base64url-encoded signature.\n *\n * @param payload - The payload object to sign\n * @param signer - The JWS signer\n * @returns The JWS compact serialization string\n */\nexport async function createJWS<T extends object>(payload: T, signer: JWSSigner): Promise<string> {\n const headerObj = { alg: signer.algorithm, kid: signer.kid };\n const headerB64 = jose.base64url.encode(new TextEncoder().encode(JSON.stringify(headerObj)));\n const canonical = canonicalize(payload);\n const payloadB64 = jose.base64url.encode(new TextEncoder().encode(canonical));\n const signingInput = new TextEncoder().encode(`${headerB64}.${payloadB64}`);\n const signatureB64 = await signer.sign(signingInput);\n return `${headerB64}.${payloadB64}.${signatureB64}`;\n}\n\n/**\n * Extract JWS header without verification\n *\n * @param jws - The JWS compact serialization string\n * @returns The decoded header object\n */\nexport function extractJWSHeader(jws: string): { alg: string; kid?: string } {\n const parts = jws.split(\".\");\n if (parts.length !== 3) throw new Error(\"Invalid JWS format\");\n const headerJson = jose.base64url.decode(parts[0]);\n return JSON.parse(new TextDecoder().decode(headerJson));\n}\n\n/**\n * Extract JWS payload\n *\n * Note: This extracts the payload without verifying the signature or\n * checking signer authorization. Signature verification requires resolving\n * key bindings (did:web documents, attestations, etc.) which is outside\n * the scope of x402 client utilities.\n *\n * @param jws - The JWS compact serialization string\n * @returns The decoded payload\n */\nexport function extractJWSPayload<T>(jws: string): T {\n const parts = jws.split(\".\");\n if (parts.length !== 3) throw new Error(\"Invalid JWS format\");\n const payloadJson = jose.base64url.decode(parts[1]);\n return JSON.parse(new TextDecoder().decode(payloadJson));\n}\n\n// ============================================================================\n// EIP-712 Domain Configuration (§3.2)\n// ============================================================================\n\n/**\n * Create EIP-712 domain for offer signing\n *\n * @returns The EIP-712 domain object\n */\nexport function createOfferDomain(): TypedDataDomain {\n return { name: \"x402 offer\", version: \"1\", chainId: 1 };\n}\n\n/**\n * Create EIP-712 domain for receipt signing\n *\n * @returns The EIP-712 domain object\n */\nexport function createReceiptDomain(): TypedDataDomain {\n return { name: \"x402 receipt\", version: \"1\", chainId: 1 };\n}\n\n/**\n * EIP-712 types for Offer (§4.3)\n */\nexport const OFFER_TYPES = {\n Offer: [\n { name: \"version\", type: \"uint256\" },\n { name: \"resourceUrl\", type: \"string\" },\n { name: \"scheme\", type: \"string\" },\n { name: \"network\", type: \"string\" },\n { name: \"asset\", type: \"string\" },\n { name: \"payTo\", type: \"string\" },\n { name: \"amount\", type: \"string\" },\n { name: \"validUntil\", type: \"uint256\" },\n ],\n};\n\n/**\n * EIP-712 types for Receipt (§5.3)\n */\nexport const RECEIPT_TYPES = {\n Receipt: [\n { name: \"version\", type: \"uint256\" },\n { name: \"network\", type: \"string\" },\n { name: \"resourceUrl\", type: \"string\" },\n { name: \"payer\", type: \"string\" },\n { name: \"issuedAt\", type: \"uint256\" },\n { name: \"transaction\", type: \"string\" },\n ],\n};\n\n// ============================================================================\n// EIP-712 Payload Preparation\n// ============================================================================\n\n/**\n * Prepare offer payload for EIP-712 signing\n *\n * @param payload - The offer payload\n * @returns The prepared message object for EIP-712\n */\nexport function prepareOfferForEIP712(payload: OfferPayload): {\n version: bigint;\n resourceUrl: string;\n scheme: string;\n network: string;\n asset: string;\n payTo: string;\n amount: string;\n validUntil: bigint;\n} {\n return {\n version: BigInt(payload.version),\n resourceUrl: payload.resourceUrl,\n scheme: payload.scheme,\n network: payload.network,\n asset: payload.asset,\n payTo: payload.payTo,\n amount: payload.amount,\n validUntil: BigInt(payload.validUntil),\n };\n}\n\n/**\n * Prepare receipt payload for EIP-712 signing\n *\n * @param payload - The receipt payload\n * @returns The prepared message object for EIP-712\n */\nexport function prepareReceiptForEIP712(payload: ReceiptPayload): {\n version: bigint;\n network: string;\n resourceUrl: string;\n payer: string;\n issuedAt: bigint;\n transaction: string;\n} {\n return {\n version: BigInt(payload.version),\n network: payload.network,\n resourceUrl: payload.resourceUrl,\n payer: payload.payer,\n issuedAt: BigInt(payload.issuedAt),\n transaction: payload.transaction,\n };\n}\n\n// ============================================================================\n// EIP-712 Hashing\n// ============================================================================\n\n/**\n * Hash offer typed data for EIP-712\n *\n * @param payload - The offer payload\n * @returns The EIP-712 hash\n */\nexport function hashOfferTypedData(payload: OfferPayload): Hex {\n return hashTypedData({\n domain: createOfferDomain(),\n types: OFFER_TYPES,\n primaryType: \"Offer\",\n message: prepareOfferForEIP712(payload),\n });\n}\n\n/**\n * Hash receipt typed data for EIP-712\n *\n * @param payload - The receipt payload\n * @returns The EIP-712 hash\n */\nexport function hashReceiptTypedData(payload: ReceiptPayload): Hex {\n return hashTypedData({\n domain: createReceiptDomain(),\n types: RECEIPT_TYPES,\n primaryType: \"Receipt\",\n message: prepareReceiptForEIP712(payload),\n });\n}\n\n// ============================================================================\n// EIP-712 Signing\n// ============================================================================\n\n/**\n * Function type for signing EIP-712 typed data\n */\nexport type SignTypedDataFn = (params: {\n domain: TypedDataDomain;\n types: Record<string, Array<{ name: string; type: string }>>;\n primaryType: string;\n message: Record<string, unknown>;\n}) => Promise<Hex>;\n\n/**\n * Sign an offer using EIP-712\n *\n * @param payload - The offer payload\n * @param signTypedData - The signing function\n * @returns The signature hex string\n */\nexport async function signOfferEIP712(\n payload: OfferPayload,\n signTypedData: SignTypedDataFn,\n): Promise<Hex> {\n return signTypedData({\n domain: createOfferDomain(),\n types: OFFER_TYPES,\n primaryType: \"Offer\",\n message: prepareOfferForEIP712(payload) as unknown as Record<string, unknown>,\n });\n}\n\n/**\n * Sign a receipt using EIP-712\n *\n * @param payload - The receipt payload\n * @param signTypedData - The signing function\n * @returns The signature hex string\n */\nexport async function signReceiptEIP712(\n payload: ReceiptPayload,\n signTypedData: SignTypedDataFn,\n): Promise<Hex> {\n return signTypedData({\n domain: createReceiptDomain(),\n types: RECEIPT_TYPES,\n primaryType: \"Receipt\",\n message: prepareReceiptForEIP712(payload) as unknown as Record<string, unknown>,\n });\n}\n\n// ============================================================================\n// Network Utilities\n// ============================================================================\n\n/**\n * Extract chain ID from an EIP-155 network string (strict format)\n *\n * @param network - The network string in \"eip155:<chainId>\" format\n * @returns The chain ID number\n * @throws Error if network is not in \"eip155:<chainId>\" format\n */\nexport function extractEIP155ChainId(network: string): number {\n const match = network.match(/^eip155:(\\d+)$/);\n if (!match) {\n throw new Error(`Invalid network format: ${network}. Expected \"eip155:<chainId>\"`);\n }\n return parseInt(match[1], 10);\n}\n\n/**\n * V1 EVM network name to chain ID mapping\n * Based on x402 v1 protocol network identifiers\n */\nconst V1_EVM_NETWORK_CHAIN_IDS: Record<string, number> = {\n ethereum: 1,\n sepolia: 11155111,\n abstract: 2741,\n \"abstract-testnet\": 11124,\n \"base-sepolia\": 84532,\n base: 8453,\n \"avalanche-fuji\": 43113,\n avalanche: 43114,\n iotex: 4689,\n sei: 1329,\n \"sei-testnet\": 1328,\n polygon: 137,\n \"polygon-amoy\": 80002,\n peaq: 3338,\n story: 1514,\n educhain: 41923,\n \"skale-base-sepolia\": 324705682,\n};\n\n/**\n * V1 Solana network name to CAIP-2 mapping\n */\nconst V1_SOLANA_NETWORKS: Record<string, string> = {\n solana: \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\",\n \"solana-devnet\": \"solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1\",\n \"solana-testnet\": \"solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z\",\n};\n\n/**\n * Convert a network string to CAIP-2 format\n *\n * Handles both CAIP-2 format and legacy x402 v1 network strings:\n * - CAIP-2: \"eip155:8453\" → \"eip155:8453\" (passed through)\n * - V1 EVM: \"base\" → \"eip155:8453\", \"base-sepolia\" → \"eip155:84532\"\n * - V1 Solana: \"solana\" → \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\"\n *\n * @param network - The network string to convert\n * @returns The CAIP-2 formatted network string\n * @throws Error if network is not a recognized v1 identifier or CAIP-2 format\n */\nexport function convertNetworkStringToCAIP2(network: string): string {\n // Already CAIP-2 format\n if (network.includes(\":\")) return network;\n\n // Check V1 EVM networks\n const chainId = V1_EVM_NETWORK_CHAIN_IDS[network.toLowerCase()];\n if (chainId !== undefined) {\n return `eip155:${chainId}`;\n }\n\n // Check V1 Solana networks\n const solanaNetwork = V1_SOLANA_NETWORKS[network.toLowerCase()];\n if (solanaNetwork) {\n return solanaNetwork;\n }\n\n throw new Error(\n `Unknown network identifier: \"${network}\". Expected CAIP-2 format (e.g., \"eip155:8453\") or v1 name (e.g., \"base\", \"solana\").`,\n );\n}\n\n/**\n * Extract chain ID from a CAIP-2 network string (EVM only)\n *\n * @param network - The CAIP-2 network string\n * @returns Chain ID number, or undefined for non-EVM networks\n */\nexport function extractChainIdFromCAIP2(network: string): number | undefined {\n const [namespace, reference] = network.split(\":\");\n if (namespace === \"eip155\" && reference) {\n const chainId = parseInt(reference, 10);\n return isNaN(chainId) ? undefined : chainId;\n }\n return undefined;\n}\n\n// ============================================================================\n// Offer Creation (§4)\n// ============================================================================\n\n/** Default offer validity in seconds (matches x402ResourceServer.ts) */\nconst DEFAULT_MAX_TIMEOUT_SECONDS = 300;\n\n/** Current extension version */\nconst EXTENSION_VERSION = 1;\n\n/**\n * Create an offer payload from input\n *\n * @param resourceUrl - The resource URL being paid for\n * @param input - The offer input parameters\n * @returns The offer payload\n */\nfunction createOfferPayload(resourceUrl: string, input: OfferInput): OfferPayload {\n const now = Math.floor(Date.now() / 1000);\n const offerValiditySeconds = input.offerValiditySeconds ?? DEFAULT_MAX_TIMEOUT_SECONDS;\n\n return {\n version: EXTENSION_VERSION,\n resourceUrl,\n scheme: input.scheme,\n network: input.network,\n asset: input.asset,\n payTo: input.payTo,\n amount: input.amount,\n validUntil: now + offerValiditySeconds,\n };\n}\n\n/**\n * Create a signed offer using JWS\n *\n * @param resourceUrl - The resource URL being paid for\n * @param input - The offer input parameters\n * @param signer - The JWS signer\n * @returns The signed offer with JWS format\n */\nexport async function createOfferJWS(\n resourceUrl: string,\n input: OfferInput,\n signer: JWSSigner,\n): Promise<JWSSignedOffer> {\n const payload = createOfferPayload(resourceUrl, input);\n const jws = await createJWS(payload, signer);\n return {\n format: \"jws\",\n acceptIndex: input.acceptIndex,\n signature: jws,\n };\n}\n\n/**\n * Create a signed offer using EIP-712\n *\n * @param resourceUrl - The resource URL being paid for\n * @param input - The offer input parameters\n * @param signTypedData - The signing function\n * @returns The signed offer with EIP-712 format\n */\nexport async function createOfferEIP712(\n resourceUrl: string,\n input: OfferInput,\n signTypedData: SignTypedDataFn,\n): Promise<EIP712SignedOffer> {\n const payload = createOfferPayload(resourceUrl, input);\n const signature = await signOfferEIP712(payload, signTypedData);\n return {\n format: \"eip712\",\n acceptIndex: input.acceptIndex,\n payload,\n signature,\n };\n}\n\n/**\n * Extract offer payload\n *\n * Note: This extracts the payload without verifying the signature or\n * checking signer authorization. Signer authorization requires resolving\n * key bindings (did:web documents, attestations, etc.) which is outside\n * the scope of x402 client utilities. See spec §4.5.1.\n *\n * @param offer - The signed offer\n * @returns The offer payload\n */\nexport function extractOfferPayload(offer: SignedOffer): OfferPayload {\n if (isJWSSignedOffer(offer)) {\n return extractJWSPayload<OfferPayload>(offer.signature);\n } else if (isEIP712SignedOffer(offer)) {\n return offer.payload;\n }\n throw new Error(`Unknown offer format: ${(offer as SignedOffer).format}`);\n}\n\n// ============================================================================\n// Receipt Creation (§5)\n// ============================================================================\n\n/**\n * Create a receipt payload for EIP-712 (requires all fields per spec §5.3)\n *\n * Per spec: \"implementations MUST set unused fields to empty string\"\n * for EIP-712 signing where fixed schemas require all fields.\n *\n * @param input - The receipt input parameters\n * @returns The receipt payload with all fields\n */\nfunction createReceiptPayloadForEIP712(input: ReceiptInput): ReceiptPayload {\n return {\n version: EXTENSION_VERSION,\n network: input.network,\n resourceUrl: input.resourceUrl,\n payer: input.payer,\n issuedAt: Math.floor(Date.now() / 1000),\n transaction: input.transaction ?? \"\",\n };\n}\n\n/**\n * Create a receipt payload for JWS (omits optional fields when not provided)\n *\n * Per spec §5.2: transaction is optional and should be omitted in JWS\n * when not provided (privacy-minimal by default).\n *\n * @param input - The receipt input parameters\n * @returns The receipt payload with optional fields omitted if not provided\n */\nfunction createReceiptPayloadForJWS(\n input: ReceiptInput,\n): Omit<ReceiptPayload, \"transaction\"> & { transaction?: string } {\n const payload: Omit<ReceiptPayload, \"transaction\"> & { transaction?: string } = {\n version: EXTENSION_VERSION,\n network: input.network,\n resourceUrl: input.resourceUrl,\n payer: input.payer,\n issuedAt: Math.floor(Date.now() / 1000),\n };\n if (input.transaction) {\n payload.transaction = input.transaction;\n }\n return payload;\n}\n\n/**\n * Create a signed receipt using JWS\n *\n * @param input - The receipt input parameters\n * @param signer - The JWS signer\n * @returns The signed receipt with JWS format\n */\nexport async function createReceiptJWS(\n input: ReceiptInput,\n signer: JWSSigner,\n): Promise<JWSSignedReceipt> {\n const payload = createReceiptPayloadForJWS(input);\n const jws = await createJWS(payload, signer);\n return { format: \"jws\", signature: jws };\n}\n\n/**\n * Create a signed receipt using EIP-712\n *\n * @param input - The receipt input parameters\n * @param signTypedData - The signing function\n * @returns The signed receipt with EIP-712 format\n */\nexport async function createReceiptEIP712(\n input: ReceiptInput,\n signTypedData: SignTypedDataFn,\n): Promise<EIP712SignedReceipt> {\n const payload = createReceiptPayloadForEIP712(input);\n const signature = await signReceiptEIP712(payload, signTypedData);\n return { format: \"eip712\", payload, signature };\n}\n\n/**\n * Extract receipt payload\n *\n * Note: This extracts the payload without verifying the signature or\n * checking signer authorization. Signer authorization requires resolving\n * key bindings (did:web documents, attestations, etc.) which is outside\n * the scope of x402 client utilities. See spec §5.5.\n *\n * @param receipt - The signed receipt\n * @returns The receipt payload\n */\nexport function extractReceiptPayload(receipt: SignedReceipt): ReceiptPayload {\n if (isJWSSignedReceipt(receipt)) {\n return extractJWSPayload<ReceiptPayload>(receipt.signature);\n } else if (isEIP712SignedReceipt(receipt)) {\n return receipt.payload;\n }\n throw new Error(`Unknown receipt format: ${(receipt as SignedReceipt).format}`);\n}\n\n// ============================================================================\n// Signature Verification\n// ============================================================================\n\n/**\n * Result of EIP-712 signature verification\n */\nexport interface EIP712VerificationResult<T> {\n signer: Hex;\n payload: T;\n}\n\n/**\n * Verify an EIP-712 signed offer and recover the signer address.\n * Does NOT verify signer authorization for the resourceUrl - see spec §4.5.1.\n *\n * @param offer - The EIP-712 signed offer\n * @returns The recovered signer address and payload\n */\nexport async function verifyOfferSignatureEIP712(\n offer: EIP712SignedOffer,\n): Promise<EIP712VerificationResult<OfferPayload>> {\n if (offer.format !== \"eip712\") {\n throw new Error(`Expected eip712 format, got ${offer.format}`);\n }\n if (!offer.payload || !(\"scheme\" in offer.payload)) {\n throw new Error(\"Invalid offer: missing or malformed payload\");\n }\n\n const signer = await recoverTypedDataAddress({\n domain: createOfferDomain(),\n types: OFFER_TYPES,\n primaryType: \"Offer\",\n message: prepareOfferForEIP712(offer.payload),\n signature: offer.signature as Hex,\n });\n\n return { signer, payload: offer.payload };\n}\n\n/**\n * Verify an EIP-712 signed receipt and recover the signer address.\n * Does NOT verify signer authorization for the resourceUrl - see spec §4.5.1.\n *\n * @param receipt - The EIP-712 signed receipt\n * @returns The recovered signer address and payload\n */\nexport async function verifyReceiptSignatureEIP712(\n receipt: EIP712SignedReceipt,\n): Promise<EIP712VerificationResult<ReceiptPayload>> {\n if (receipt.format !== \"eip712\") {\n throw new Error(`Expected eip712 format, got ${receipt.format}`);\n }\n if (!receipt.payload || !(\"payer\" in receipt.payload)) {\n throw new Error(\"Invalid receipt: missing or malformed payload\");\n }\n\n const signer = await recoverTypedDataAddress({\n domain: createReceiptDomain(),\n types: RECEIPT_TYPES,\n primaryType: \"Receipt\",\n message: prepareReceiptForEIP712(receipt.payload),\n signature: receipt.signature as Hex,\n });\n\n return { signer, payload: receipt.payload };\n}\n\n/**\n * Verify a JWS signed offer.\n * Does NOT verify signer authorization for the resourceUrl - see spec §4.5.1.\n * If no publicKey provided, extracts from kid (supports did:key, did:jwk, did:web).\n *\n * @param offer - The JWS signed offer\n * @param publicKey - Optional public key (JWK or KeyLike). If not provided, extracted from kid.\n * @returns The verified payload\n */\nexport async function verifyOfferSignatureJWS(\n offer: JWSSignedOffer,\n publicKey?: jose.KeyLike | jose.JWK,\n): Promise<OfferPayload> {\n if (offer.format !== \"jws\") {\n throw new Error(`Expected jws format, got ${offer.format}`);\n }\n const key = await resolveVerificationKey(offer.signature, publicKey);\n const { payload } = await jose.compactVerify(offer.signature, key);\n return JSON.parse(new TextDecoder().decode(payload)) as OfferPayload;\n}\n\n/**\n * Verify a JWS signed receipt.\n * Does NOT verify signer authorization for the resourceUrl - see spec §4.5.1.\n * If no publicKey provided, extracts from kid (supports did:key, did:jwk, did:web).\n *\n * @param receipt - The JWS signed receipt\n * @param publicKey - Optional public key (JWK or KeyLike). If not provided, extracted from kid.\n * @returns The verified payload\n */\nexport async function verifyReceiptSignatureJWS(\n receipt: JWSSignedReceipt,\n publicKey?: jose.KeyLike | jose.JWK,\n): Promise<ReceiptPayload> {\n if (receipt.format !== \"jws\") {\n throw new Error(`Expected jws format, got ${receipt.format}`);\n }\n const key = await resolveVerificationKey(receipt.signature, publicKey);\n const { payload } = await jose.compactVerify(receipt.signature, key);\n return JSON.parse(new TextDecoder().decode(payload)) as ReceiptPayload;\n}\n\n/**\n * Resolve the verification key for JWS verification\n *\n * @param jws - The JWS compact serialization string\n * @param providedKey - Optional explicit public key\n * @returns The resolved public key\n */\nasync function resolveVerificationKey(\n jws: string,\n providedKey?: jose.KeyLike | jose.JWK,\n): Promise<jose.KeyLike> {\n if (providedKey) {\n if (\"kty\" in providedKey) {\n const key = await jose.importJWK(providedKey);\n if (key instanceof Uint8Array) {\n throw new Error(\"Symmetric keys are not supported for JWS verification\");\n }\n return key;\n }\n return providedKey;\n }\n\n const header = extractJWSHeader(jws);\n if (!header.kid) {\n throw new Error(\"No public key provided and JWS header missing kid\");\n }\n\n return extractPublicKeyFromKid(header.kid);\n}\n","/**\n * DID Resolution Utilities\n *\n * Extracts public keys from DID key identifiers. Supports did:key, did:jwk, did:web.\n * Uses @noble/curves and @scure/base for cryptographic operations.\n */\n\nimport * as jose from \"jose\";\nimport { base58 } from \"@scure/base\";\nimport { secp256k1 } from \"@noble/curves/secp256k1\";\nimport { p256 } from \"@noble/curves/nist\";\n\n// Multicodec prefixes for supported key types\nconst MULTICODEC_ED25519_PUB = 0xed;\nconst MULTICODEC_SECP256K1_PUB = 0xe7;\nconst MULTICODEC_P256_PUB = 0x1200;\n\n/**\n * Extract a public key from a DID key identifier (kid).\n * Supports did:key, did:jwk, did:web.\n *\n * @param kid - The key identifier (DID URL, e.g., did:key:z6Mk..., did:web:example.com#key-1)\n * @returns The extracted public key\n */\nexport async function extractPublicKeyFromKid(kid: string): Promise<jose.KeyLike> {\n const [didPart, fragment] = kid.split(\"#\");\n const parts = didPart.split(\":\");\n\n if (parts.length < 3 || parts[0] !== \"did\") {\n throw new Error(`Invalid DID format: ${kid}`);\n }\n\n const method = parts[1];\n const identifier = parts.slice(2).join(\":\");\n\n switch (method) {\n case \"key\":\n return extractKeyFromDidKey(identifier);\n case \"jwk\":\n return extractKeyFromDidJwk(identifier);\n case \"web\":\n return resolveDidWeb(identifier, fragment);\n default:\n throw new Error(\n `Unsupported DID method \"${method}\". Supported: did:key, did:jwk, did:web. ` +\n `Provide the public key directly for other methods.`,\n );\n }\n}\n\n/**\n * Extract public key from did:key identifier (multibase-encoded)\n *\n * @param identifier - The did:key identifier (without the \"did:key:\" prefix)\n * @returns The extracted public key\n */\nasync function extractKeyFromDidKey(identifier: string): Promise<jose.KeyLike> {\n if (!identifier.startsWith(\"z\")) {\n throw new Error(`Unsupported multibase encoding. Expected 'z' (base58-btc).`);\n }\n\n const decoded = base58.decode(identifier.slice(1));\n const { codec, keyBytes } = readMulticodec(decoded);\n\n switch (codec) {\n case MULTICODEC_ED25519_PUB:\n return importAsymmetricJWK({\n kty: \"OKP\",\n crv: \"Ed25519\",\n x: jose.base64url.encode(keyBytes),\n });\n\n case MULTICODEC_SECP256K1_PUB: {\n const point = secp256k1.Point.fromHex(keyBytes);\n const uncompressed = point.toBytes(false);\n return importAsymmetricJWK({\n kty: \"EC\",\n crv: \"secp256k1\",\n x: jose.base64url.encode(uncompressed.slice(1, 33)),\n y: jose.base64url.encode(uncompressed.slice(33, 65)),\n });\n }\n\n case MULTICODEC_P256_PUB: {\n const point = p256.Point.fromHex(keyBytes);\n const uncompressed = point.toBytes(false);\n return importAsymmetricJWK({\n kty: \"EC\",\n crv: \"P-256\",\n x: jose.base64url.encode(uncompressed.slice(1, 33)),\n y: jose.base64url.encode(uncompressed.slice(33, 65)),\n });\n }\n\n default:\n throw new Error(\n `Unsupported key type in did:key (multicodec: 0x${codec.toString(16)}). ` +\n `Supported: Ed25519, secp256k1, P-256.`,\n );\n }\n}\n\n/**\n * Extract public key from did:jwk identifier (base64url-encoded JWK)\n *\n * @param identifier - The did:jwk identifier (without the \"did:jwk:\" prefix)\n * @returns The extracted public key\n */\nasync function extractKeyFromDidJwk(identifier: string): Promise<jose.KeyLike> {\n const jwkJson = new TextDecoder().decode(jose.base64url.decode(identifier));\n const jwk = JSON.parse(jwkJson) as jose.JWK;\n return importAsymmetricJWK(jwk);\n}\n\n/**\n * Resolve did:web by fetching DID document from .well-known/did.json\n *\n * @param identifier - The did:web identifier (without the \"did:web:\" prefix)\n * @param fragment - Optional fragment to identify specific key\n * @returns The extracted public key\n */\nasync function resolveDidWeb(identifier: string, fragment?: string): Promise<jose.KeyLike> {\n const parts = identifier.split(\":\");\n const domain = decodeURIComponent(parts[0]);\n const path = parts.slice(1).map(decodeURIComponent).join(\"/\");\n\n // did:web spec allows HTTP for localhost (https://w3c-ccg.github.io/did-method-web/#read-resolve)\n const host = domain.split(\":\")[0];\n const scheme = host === \"localhost\" || host === \"127.0.0.1\" ? \"http\" : \"https\";\n\n const url = path\n ? `${scheme}://${domain}/${path}/did.json`\n : `${scheme}://${domain}/.well-known/did.json`;\n\n let didDocument: DIDDocument;\n try {\n const response = await fetch(url, {\n headers: { Accept: \"application/did+json, application/json\" },\n });\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`);\n }\n didDocument = (await response.json()) as DIDDocument;\n } catch (error) {\n throw new Error(\n `Failed to resolve did:web:${identifier}: ${error instanceof Error ? error.message : error}`,\n );\n }\n\n const fullDid = `did:web:${identifier}`;\n const keyId = fragment ? `${fullDid}#${fragment}` : undefined;\n const method = findVerificationMethod(didDocument, keyId);\n\n if (!method) {\n throw new Error(`No verification method found for ${keyId || fullDid}`);\n }\n\n if (method.publicKeyJwk) {\n return importAsymmetricJWK(method.publicKeyJwk);\n }\n if (method.publicKeyMultibase) {\n return extractKeyFromDidKey(method.publicKeyMultibase);\n }\n\n throw new Error(`Verification method ${method.id} has no supported key format`);\n}\n\n/**\n * Read multicodec varint prefix from bytes\n *\n * @param bytes - The encoded bytes\n * @returns The codec identifier and remaining key bytes\n */\nfunction readMulticodec(bytes: Uint8Array): { codec: number; keyBytes: Uint8Array } {\n let codec = 0;\n let shift = 0;\n let offset = 0;\n\n for (const byte of bytes) {\n codec |= (byte & 0x7f) << shift;\n offset++;\n if ((byte & 0x80) === 0) break;\n shift += 7;\n }\n\n return { codec, keyBytes: bytes.slice(offset) };\n}\n\n/**\n * Import an asymmetric JWK as a KeyLike\n *\n * @param jwk - The JWK to import\n * @returns The imported key\n */\nasync function importAsymmetricJWK(jwk: jose.JWK): Promise<jose.KeyLike> {\n const key = await jose.importJWK(jwk);\n if (key instanceof Uint8Array) {\n throw new Error(\"Symmetric keys are not supported\");\n }\n return key;\n}\n\ninterface DIDDocument {\n id: string;\n verificationMethod?: VerificationMethod[];\n assertionMethod?: (string | VerificationMethod)[];\n authentication?: (string | VerificationMethod)[];\n}\n\ninterface VerificationMethod {\n id: string;\n type: string;\n controller: string;\n publicKeyJwk?: jose.JWK;\n publicKeyMultibase?: string;\n}\n\n/**\n * Find a verification method in a DID document\n *\n * @param doc - The DID document\n * @param keyId - Optional specific key ID to find\n * @returns The verification method or undefined\n */\nfunction findVerificationMethod(doc: DIDDocument, keyId?: string): VerificationMethod | undefined {\n const methods = doc.verificationMethod || [];\n\n if (keyId) {\n return methods.find(m => m.id === keyId);\n }\n\n // Prefer assertionMethod, then authentication, then any\n for (const ref of doc.assertionMethod || []) {\n if (typeof ref === \"string\") {\n const m = methods.find(m => m.id === ref);\n if (m) return m;\n } else {\n return ref;\n }\n }\n\n for (const ref of doc.authentication || []) {\n if (typeof ref === \"string\") {\n const m = methods.find(m => m.id === ref);\n if (m) return m;\n } else {\n return ref;\n }\n }\n\n return methods[0];\n}\n","/**\n * Offer-Receipt Extension for x402ResourceServer\n *\n * This module provides the ResourceServerExtension implementation that uses\n * the extension hooks (enrichPaymentRequiredResponse, enrichSettlementResponse)\n * to add signed offers and receipts to x402 payment flows.\n *\n * Based on: x402/specs/extensions/extension-offer-and-receipt.md (v1.0)\n */\n\nimport type {\n ResourceServerExtension,\n PaymentRequiredContext,\n SettleResultContext,\n} from \"@x402/core/types\";\nimport type { PaymentRequirements } from \"@x402/core/types\";\nimport type { HTTPTransportContext } from \"@x402/core/http\";\nimport {\n OFFER_RECEIPT,\n type OfferReceiptIssuer,\n type OfferReceiptDeclaration,\n type OfferInput,\n type SignedOffer,\n type SignedReceipt,\n type JWSSigner,\n} from \"./types\";\nimport {\n createOfferJWS,\n createOfferEIP712,\n createReceiptJWS,\n createReceiptEIP712,\n type SignTypedDataFn,\n} from \"./signing\";\n\n// ============================================================================\n// JSON Schemas for Extension Responses\n// ============================================================================\n\n/**\n * JSON Schema for offer extension data (§6.1)\n */\nconst OFFER_SCHEMA = {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n properties: {\n offers: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n format: { type: \"string\" },\n acceptIndex: { type: \"integer\" },\n payload: {\n type: \"object\",\n properties: {\n version: { type: \"integer\" },\n resourceUrl: { type: \"string\" },\n scheme: { type: \"string\" },\n network: { type: \"string\" },\n asset: { type: \"string\" },\n payTo: { type: \"string\" },\n amount: { type: \"string\" },\n validUntil: { type: \"integer\" },\n },\n required: [\"version\", \"resourceUrl\", \"scheme\", \"network\", \"asset\", \"payTo\", \"amount\"],\n },\n signature: { type: \"string\" },\n },\n required: [\"format\", \"signature\"],\n },\n },\n },\n required: [\"offers\"],\n};\n\n/**\n * JSON Schema for receipt extension data (§6.5)\n */\nconst RECEIPT_SCHEMA = {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n properties: {\n receipt: {\n type: \"object\",\n properties: {\n format: { type: \"string\" },\n payload: {\n type: \"object\",\n properties: {\n version: { type: \"integer\" },\n network: { type: \"string\" },\n resourceUrl: { type: \"string\" },\n payer: { type: \"string\" },\n issuedAt: { type: \"integer\" },\n transaction: { type: \"string\" },\n },\n required: [\"version\", \"network\", \"resourceUrl\", \"payer\", \"issuedAt\"],\n },\n signature: { type: \"string\" },\n },\n required: [\"format\", \"signature\"],\n },\n },\n required: [\"receipt\"],\n};\n\n// ============================================================================\n// Extension Factory\n// ============================================================================\n\n/**\n * Convert PaymentRequirements to OfferInput\n *\n * @param requirements - The payment requirements\n * @param acceptIndex - Index into accepts[] array\n * @param offerValiditySeconds - Optional validity duration override\n * @returns The offer input object\n */\nfunction requirementsToOfferInput(\n requirements: PaymentRequirements,\n acceptIndex: number,\n offerValiditySeconds?: number,\n): OfferInput {\n return {\n acceptIndex,\n scheme: requirements.scheme,\n network: requirements.network,\n asset: requirements.asset,\n payTo: requirements.payTo,\n amount: requirements.amount,\n offerValiditySeconds: offerValiditySeconds ?? requirements.maxTimeoutSeconds,\n };\n}\n\n/**\n * Creates an offer-receipt extension for use with x402ResourceServer.\n *\n * The extension uses the hook system to:\n * 1. Add signed offers to each PaymentRequirements in 402 responses\n * 2. Add signed receipts to settlement responses after successful payment\n *\n * @param issuer - The issuer to use for creating and signing offers and receipts\n * @returns ResourceServerExtension that can be registered with x402ResourceServer\n */\nexport function createOfferReceiptExtension(issuer: OfferReceiptIssuer): ResourceServerExtension {\n return {\n key: OFFER_RECEIPT,\n\n // Add signed offers to 402 PaymentRequired response\n enrichPaymentRequiredResponse: async (\n declaration: unknown,\n context: PaymentRequiredContext,\n ): Promise<unknown> => {\n const config = declaration as OfferReceiptDeclaration | undefined;\n\n // Get resource URL from transport context or payment required response\n const resourceUrl =\n context.paymentRequiredResponse.resource?.url ||\n (context.transportContext as HTTPTransportContext)?.request?.adapter?.getUrl?.();\n\n if (!resourceUrl) {\n console.warn(\"[offer-receipt] No resource URL available for signing offers\");\n return undefined;\n }\n\n // Sign offers for each payment requirement\n const offers: SignedOffer[] = [];\n\n for (let i = 0; i < context.requirements.length; i++) {\n const requirement = context.requirements[i];\n try {\n const offerInput = requirementsToOfferInput(requirement, i, config?.offerValiditySeconds);\n const signedOffer = await issuer.issueOffer(resourceUrl, offerInput);\n offers.push(signedOffer);\n } catch (error) {\n console.error(`[offer-receipt] Failed to sign offer for requirement ${i}:`, error);\n }\n }\n\n if (offers.length === 0) {\n return undefined;\n }\n\n // Return extension data per spec structure\n return {\n info: {\n offers,\n },\n schema: OFFER_SCHEMA,\n };\n },\n\n // Add signed receipt to settlement response\n enrichSettlementResponse: async (\n declaration: unknown,\n context: SettleResultContext,\n ): Promise<unknown> => {\n const config = declaration as OfferReceiptDeclaration | undefined;\n\n // Skip if settlement failed\n if (!context.result.success) {\n return undefined;\n }\n\n // Get payer from settlement result\n const payer = context.result.payer;\n if (!payer) {\n console.warn(\"[offer-receipt] No payer available for signing receipt\");\n return undefined;\n }\n\n // Get network and transaction from settlement result\n const network = context.result.network;\n if (!network) {\n console.warn(\"[offer-receipt] No network available for signing receipt\");\n return undefined;\n }\n const transaction = context.result.transaction;\n\n // Get resource URL from transport context\n const resourceUrl = (\n context.transportContext as HTTPTransportContext\n )?.request?.adapter?.getUrl?.();\n\n if (!resourceUrl) {\n console.warn(\"[offer-receipt] No resource URL available for signing receipt\");\n return undefined;\n }\n\n // Determine whether to include transaction hash (default: false for privacy)\n const includeTxHash = config?.includeTxHash === true;\n\n try {\n const signedReceipt: SignedReceipt = await issuer.issueReceipt(\n resourceUrl,\n payer,\n network,\n includeTxHash ? transaction || undefined : undefined,\n );\n // Return extension data per spec structure\n return {\n info: {\n receipt: signedReceipt,\n },\n schema: RECEIPT_SCHEMA,\n };\n } catch (error) {\n console.error(\"[offer-receipt] Failed to sign receipt:\", error);\n return undefined;\n }\n },\n };\n}\n\n/**\n * Declare offer-receipt extension for a route\n *\n * Use this in route configuration to enable offer-receipt for a specific endpoint.\n *\n * @param config - Optional configuration for the extension\n * @returns Extension declaration object to spread into route config\n */\nexport function declareOfferReceiptExtension(\n config?: OfferReceiptDeclaration,\n): Record<string, OfferReceiptDeclaration> {\n return {\n [OFFER_RECEIPT]: {\n includeTxHash: config?.includeTxHash,\n offerValiditySeconds: config?.offerValiditySeconds,\n },\n };\n}\n\n// ============================================================================\n// Issuer Factory Functions\n// ============================================================================\n\n/**\n * Create an OfferReceiptIssuer that uses JWS format\n *\n * @param kid - Key identifier DID (e.g., did:web:api.example.com#key-1)\n * @param jwsSigner - JWS signer with sign() function and algorithm\n * @returns OfferReceiptIssuer for use with createOfferReceiptExtension\n */\nexport function createJWSOfferReceiptIssuer(kid: string, jwsSigner: JWSSigner): OfferReceiptIssuer {\n return {\n kid,\n format: \"jws\",\n\n async issueOffer(resourceUrl: string, input: OfferInput) {\n return createOfferJWS(resourceUrl, input, jwsSigner);\n },\n\n async issueReceipt(resourceUrl: string, payer: string, network: string, transaction?: string) {\n return createReceiptJWS({ resourceUrl, payer, network, transaction }, jwsSigner);\n },\n };\n}\n\n/**\n * Create an OfferReceiptIssuer that uses EIP-712 format\n *\n * @param kid - Key identifier DID (e.g., did:pkh:eip155:1:0x...)\n * @param signTypedData - Function to sign EIP-712 typed data\n * @returns OfferReceiptIssuer for use with createOfferReceiptExtension\n */\nexport function createEIP712OfferReceiptIssuer(\n kid: string,\n signTypedData: SignTypedDataFn,\n): OfferReceiptIssuer {\n return {\n kid,\n format: \"eip712\",\n\n async issueOffer(resourceUrl: string, input: OfferInput) {\n return createOfferEIP712(resourceUrl, input, signTypedData);\n },\n\n async issueReceipt(resourceUrl: string, payer: string, network: string, transaction?: string) {\n return createReceiptEIP712({ resourceUrl, payer, network, transaction }, signTypedData);\n },\n };\n}\n","/**\n * Client-side utilities for extracting offers and receipts from x402 responses\n *\n * Provides utilities for clients who want to access signed offers and receipts\n * from x402 payment flows. Useful for verified reviews, audit trails, and dispute resolution.\n *\n * @see README.md for usage examples (raw and wrapper flows)\n * @see examples/typescript/clients/offer-receipt/ for complete example\n */\n\nimport { decodePaymentResponseHeader } from \"@x402/core/http\";\nimport type { PaymentRequired, PaymentRequirements, SettleResponse } from \"@x402/core/types\";\nimport { OFFER_RECEIPT, type OfferPayload, type SignedOffer, type SignedReceipt } from \"./types\";\nimport { extractOfferPayload, extractReceiptPayload } from \"./signing\";\n\n/**\n * A signed offer with its decoded payload fields at the top level.\n * Combines the signed offer metadata with the decoded payload for easy access.\n */\nexport interface DecodedOffer extends OfferPayload {\n /** The original signed offer (for passing to other functions or downstream systems) */\n signedOffer: SignedOffer;\n /** The signature format used */\n format: \"jws\" | \"eip712\";\n /** Index into accepts[] array (hint for matching), may be undefined */\n acceptIndex?: number;\n}\n\n/**\n * Structure of offer-receipt extension data in PaymentRequired.extensions\n */\ninterface OfferReceiptExtensionInfo {\n info?: {\n offers?: SignedOffer[];\n receipt?: SignedReceipt;\n };\n}\n\n// ============================================================================\n// Exported Functions\n// ============================================================================\n\n/**\n * Verify that a receipt's payload matches the offer and payer.\n *\n * This performs basic payload field verification:\n * - resourceUrl matches the offer\n * - network matches the offer\n * - payer matches one of the client's wallet addresses\n * - issuedAt is recent (within maxAgeSeconds)\n *\n * NOTE: This does NOT verify the signature or key binding. See the comment\n * in the offer-receipt example for guidance on full verification.\n *\n * @param receipt - The signed receipt from the server\n * @param offer - The decoded offer that was accepted\n * @param payerAddresses - Array of the client's wallet addresses (EVM, SVM, etc.)\n * @param maxAgeSeconds - Maximum age of receipt in seconds (default: 3600 = 1 hour)\n * @returns true if all checks pass, false otherwise\n */\nexport function verifyReceiptMatchesOffer(\n receipt: SignedReceipt,\n offer: DecodedOffer,\n payerAddresses: string[],\n maxAgeSeconds: number = 3600,\n): boolean {\n const payload = extractReceiptPayload(receipt);\n\n const resourceUrlMatch = payload.resourceUrl === offer.resourceUrl;\n const networkMatch = payload.network === offer.network;\n const payerMatch = payerAddresses.some(\n addr => payload.payer.toLowerCase() === addr.toLowerCase(),\n );\n const issuedRecently = Math.floor(Date.now() / 1000) - payload.issuedAt < maxAgeSeconds;\n\n return resourceUrlMatch && networkMatch && payerMatch && issuedRecently;\n}\n\n/**\n * Extract signed offers from a PaymentRequired response.\n *\n * Call this immediately after receiving a 402 response to save the offers.\n * If the settlement response doesn't include a receipt, you'll still have\n * the offers for attestation purposes.\n *\n * @param paymentRequired - The PaymentRequired object from the 402 response\n * @returns Array of signed offers, or empty array if none present\n */\nexport function extractOffersFromPaymentRequired(paymentRequired: PaymentRequired): SignedOffer[] {\n const extData = paymentRequired.extensions?.[OFFER_RECEIPT] as\n | OfferReceiptExtensionInfo\n | undefined;\n return extData?.info?.offers ?? [];\n}\n\n/**\n * Decode all signed offers and return them with payload fields at the top level.\n *\n * Use this to inspect offer details (network, amount, etc.) for selection.\n * JWS decoding is cheap (base64 decode, no crypto), so decoding all offers\n * upfront is fine even with multiple offers.\n *\n * @param offers - Array of signed offers from extractOffersFromPaymentRequired\n * @returns Array of decoded offers with payload fields at top level\n */\nexport function decodeSignedOffers(offers: SignedOffer[]): DecodedOffer[] {\n return offers.map(offer => {\n const payload = extractOfferPayload(offer);\n return {\n // Spread payload fields at top level\n ...payload,\n // Include metadata\n signedOffer: offer,\n format: offer.format,\n acceptIndex: offer.acceptIndex,\n };\n });\n}\n\n/**\n * Find the accepts[] entry that matches a signed or decoded offer.\n *\n * Use this after selecting an offer to get the PaymentRequirements\n * object needed for createPaymentPayload.\n *\n * Uses the offer's acceptIndex as a hint for faster lookup, but verifies\n * the payload matches in case indices got out of sync.\n *\n * @param offer - A DecodedOffer (from decodeSignedOffers) or SignedOffer\n * @param accepts - Array of payment requirements from paymentRequired.accepts\n * @returns The matching PaymentRequirements, or undefined if not found\n */\nexport function findAcceptsObjectFromSignedOffer(\n offer: DecodedOffer | SignedOffer,\n accepts: PaymentRequirements[],\n): PaymentRequirements | undefined {\n // Check if it's a DecodedOffer (has signedOffer property) or SignedOffer\n const isDecoded = \"signedOffer\" in offer;\n const payload = isDecoded ? offer : extractOfferPayload(offer);\n const acceptIndex = isDecoded ? offer.acceptIndex : offer.acceptIndex;\n\n // Use acceptIndex as a hint - check that index first\n if (acceptIndex !== undefined && acceptIndex < accepts.length) {\n const hinted = accepts[acceptIndex];\n if (\n hinted.network === payload.network &&\n hinted.scheme === payload.scheme &&\n hinted.asset === payload.asset &&\n hinted.payTo === payload.payTo &&\n hinted.amount === payload.amount\n ) {\n return hinted;\n }\n }\n\n // Fall back to searching all accepts\n return accepts.find(\n req =>\n req.network === payload.network &&\n req.scheme === payload.scheme &&\n req.asset === payload.asset &&\n req.payTo === payload.payTo &&\n req.amount === payload.amount,\n );\n}\n\n/**\n * Extract signed receipt from a successful payment response.\n *\n * Call this after a successful payment to get the server's signed receipt.\n * The receipt proves the service was delivered after payment.\n *\n * @param response - The Response object from the successful request\n * @returns The signed receipt, or undefined if not present\n */\nexport function extractReceiptFromResponse(response: Response): SignedReceipt | undefined {\n const paymentResponseHeader =\n response.headers.get(\"PAYMENT-RESPONSE\") || response.headers.get(\"X-PAYMENT-RESPONSE\");\n\n if (!paymentResponseHeader) {\n return undefined;\n }\n\n try {\n const settlementResponse = decodePaymentResponseHeader(paymentResponseHeader) as SettleResponse;\n const receiptExtData = settlementResponse.extensions?.[OFFER_RECEIPT] as\n | OfferReceiptExtensionInfo\n | undefined;\n return receiptExtData?.info?.receipt;\n } catch {\n return undefined;\n }\n}\n","/**\n * Type definitions for the Payment-Identifier Extension\n *\n * Enables clients to provide an idempotency key that resource servers\n * can use for deduplication of payment requests.\n */\n\n/**\n * Extension identifier constant for the payment-identifier extension\n */\nexport const PAYMENT_IDENTIFIER = \"payment-identifier\";\n\n/**\n * Minimum length for payment identifier\n */\nexport const PAYMENT_ID_MIN_LENGTH = 16;\n\n/**\n * Maximum length for payment identifier\n */\nexport const PAYMENT_ID_MAX_LENGTH = 128;\n\n/**\n * Pattern for valid payment identifier characters (alphanumeric, hyphens, underscores)\n */\nexport const PAYMENT_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;\n\n/**\n * Payment identifier info containing the required flag and client-provided ID\n */\nexport interface PaymentIdentifierInfo {\n /**\n * Whether the server requires clients to include a payment identifier.\n * When true, clients must provide an `id` or receive a 400 Bad Request.\n */\n required: boolean;\n\n /**\n * Client-provided unique identifier for idempotency.\n * Must be 16-128 characters, alphanumeric with hyphens and underscores allowed.\n */\n id?: string;\n}\n\n/**\n * Payment identifier extension with info and schema.\n *\n * Used both for server-side declarations (info without id) and\n * client-side payloads (info with id).\n */\nexport interface PaymentIdentifierExtension {\n /**\n * The payment identifier info.\n * Server declarations have required only, clients add the id.\n */\n info: PaymentIdentifierInfo;\n\n /**\n * JSON Schema validating the info structure\n */\n schema: PaymentIdentifierSchema;\n}\n\n/**\n * JSON Schema type for the payment-identifier extension\n */\nexport interface PaymentIdentifierSchema {\n $schema: \"https://json-schema.org/draft/2020-12/schema\";\n type: \"object\";\n properties: {\n required: {\n type: \"boolean\";\n };\n id: {\n type: \"string\";\n minLength: number;\n maxLength: number;\n pattern: string;\n };\n };\n required: [\"required\"];\n}\n","/**\n * JSON Schema definitions for the Payment-Identifier Extension\n */\n\nimport type { PaymentIdentifierSchema } from \"./types\";\nimport { PAYMENT_ID_MIN_LENGTH, PAYMENT_ID_MAX_LENGTH } from \"./types\";\n\n/**\n * JSON Schema for validating payment identifier info.\n * Compliant with JSON Schema Draft 2020-12.\n */\nexport const paymentIdentifierSchema: PaymentIdentifierSchema = {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n properties: {\n required: {\n type: \"boolean\",\n },\n id: {\n type: \"string\",\n minLength: PAYMENT_ID_MIN_LENGTH,\n maxLength: PAYMENT_ID_MAX_LENGTH,\n pattern: \"^[a-zA-Z0-9_-]+$\",\n },\n },\n required: [\"required\"],\n};\n","/**\n * Utility functions for the Payment-Identifier Extension\n */\n\nimport { PAYMENT_ID_MIN_LENGTH, PAYMENT_ID_MAX_LENGTH, PAYMENT_ID_PATTERN } from \"./types\";\n\n/**\n * Generates a unique payment identifier.\n *\n * @param prefix - Optional prefix for the ID (e.g., \"pay_\"). Defaults to \"pay_\".\n * @returns A unique payment identifier string\n *\n * @example\n * ```typescript\n * // With default prefix\n * const id = generatePaymentId(); // \"pay_7d5d747be160e280504c099d984bcfe0\"\n *\n * // With custom prefix\n * const id = generatePaymentId(\"txn_\"); // \"txn_7d5d747be160e280504c099d984bcfe0\"\n *\n * // Without prefix\n * const id = generatePaymentId(\"\"); // \"7d5d747be160e280504c099d984bcfe0\"\n * ```\n */\nexport function generatePaymentId(prefix: string = \"pay_\"): string {\n // Generate UUID v4 without hyphens (32 hex chars)\n const uuid = crypto.randomUUID().replace(/-/g, \"\");\n return `${prefix}${uuid}`;\n}\n\n/**\n * Validates that a payment ID meets the format requirements.\n *\n * @param id - The payment ID to validate\n * @returns True if the ID is valid, false otherwise\n *\n * @example\n * ```typescript\n * isValidPaymentId(\"pay_7d5d747be160e280\"); // true (exactly 16 chars after prefix removal check)\n * isValidPaymentId(\"abc\"); // false (too short)\n * isValidPaymentId(\"pay_abc!@#\"); // false (invalid characters)\n * ```\n */\nexport function isValidPaymentId(id: string): boolean {\n if (typeof id !== \"string\") {\n return false;\n }\n\n if (id.length < PAYMENT_ID_MIN_LENGTH || id.length > PAYMENT_ID_MAX_LENGTH) {\n return false;\n }\n\n return PAYMENT_ID_PATTERN.test(id);\n}\n","/**\n * Validation and extraction utilities for the Payment-Identifier Extension\n */\n\nimport Ajv from \"ajv/dist/2020.js\";\nimport type { PaymentPayload } from \"@x402/core/types\";\nimport type { PaymentIdentifierExtension, PaymentIdentifierInfo } from \"./types\";\nimport { PAYMENT_IDENTIFIER } from \"./types\";\nimport { paymentIdentifierSchema } from \"./schema\";\nimport { isValidPaymentId } from \"./utils\";\n\n/**\n * Type guard to check if an object is a valid payment-identifier extension structure.\n *\n * This checks for the basic structure (info object with required boolean),\n * but does not validate the id format if present.\n *\n * @param extension - The object to check\n * @returns True if the object has the expected payment-identifier extension structure\n *\n * @example\n * ```typescript\n * if (isPaymentIdentifierExtension(extensions[\"payment-identifier\"])) {\n * // TypeScript knows this is PaymentIdentifierExtension\n * console.log(extension.info.required);\n * }\n * ```\n */\nexport function isPaymentIdentifierExtension(\n extension: unknown,\n): extension is PaymentIdentifierExtension {\n if (!extension || typeof extension !== \"object\") {\n return false;\n }\n\n const ext = extension as Partial<PaymentIdentifierExtension>;\n\n if (!ext.info || typeof ext.info !== \"object\") {\n return false;\n }\n\n const info = ext.info as Partial<PaymentIdentifierInfo>;\n\n // Must have required boolean\n if (typeof info.required !== \"boolean\") {\n return false;\n }\n\n return true;\n}\n\n/**\n * Result of payment identifier validation\n */\nexport interface PaymentIdentifierValidationResult {\n /**\n * Whether the payment identifier is valid\n */\n valid: boolean;\n\n /**\n * Error messages if validation failed\n */\n errors?: string[];\n}\n\n/**\n * Validates a payment-identifier extension object.\n *\n * Checks both the structure (using JSON Schema) and the ID format.\n *\n * @param extension - The extension object to validate\n * @returns Validation result with errors if invalid\n *\n * @example\n * ```typescript\n * const result = validatePaymentIdentifier(paymentPayload.extensions?.[\"payment-identifier\"]);\n * if (!result.valid) {\n * console.error(\"Invalid payment identifier:\", result.errors);\n * }\n * ```\n */\nexport function validatePaymentIdentifier(extension: unknown): PaymentIdentifierValidationResult {\n if (!extension || typeof extension !== \"object\") {\n return {\n valid: false,\n errors: [\"Extension must be an object\"],\n };\n }\n\n const ext = extension as Partial<PaymentIdentifierExtension>;\n\n // Check info exists\n if (!ext.info || typeof ext.info !== \"object\") {\n return {\n valid: false,\n errors: [\"Extension must have an 'info' property\"],\n };\n }\n\n const info = ext.info as Partial<PaymentIdentifierInfo>;\n\n // Check required field exists and is a boolean\n if (typeof info.required !== \"boolean\") {\n return {\n valid: false,\n errors: [\"Extension info must have a 'required' boolean property\"],\n };\n }\n\n // Check id exists and is a string (if provided)\n if (info.id !== undefined && typeof info.id !== \"string\") {\n return {\n valid: false,\n errors: [\"Extension info 'id' must be a string if provided\"],\n };\n }\n\n // Validate ID format if provided\n if (info.id !== undefined && !isValidPaymentId(info.id)) {\n return {\n valid: false,\n errors: [\n `Invalid payment ID format. ID must be 16-128 characters and contain only alphanumeric characters, hyphens, and underscores.`,\n ],\n };\n }\n\n // If schema is provided, validate against it\n if (ext.schema) {\n try {\n const ajv = new Ajv({ strict: false, allErrors: true });\n const validate = ajv.compile(ext.schema);\n const valid = validate(ext.info);\n\n if (!valid && validate.errors) {\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 }\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 return { valid: true };\n}\n\n/**\n * Extracts the payment identifier from a PaymentPayload.\n *\n * @param paymentPayload - The payment payload to extract from\n * @param validate - Whether to validate the ID before returning (default: true)\n * @returns The payment ID string, or null if not present or invalid\n *\n * @example\n * ```typescript\n * const id = extractPaymentIdentifier(paymentPayload);\n * if (id) {\n * // Use for idempotency lookup\n * const cached = await idempotencyStore.get(id);\n * }\n * ```\n */\nexport function extractPaymentIdentifier(\n paymentPayload: PaymentPayload,\n validate: boolean = true,\n): string | null {\n if (!paymentPayload.extensions) {\n return null;\n }\n\n const extension = paymentPayload.extensions[PAYMENT_IDENTIFIER];\n\n if (!extension || typeof extension !== \"object\") {\n return null;\n }\n\n const ext = extension as Partial<PaymentIdentifierExtension>;\n\n if (!ext.info || typeof ext.info !== \"object\") {\n return null;\n }\n\n const info = ext.info as Partial<PaymentIdentifierInfo>;\n\n if (typeof info.id !== \"string\") {\n return null;\n }\n\n if (validate && !isValidPaymentId(info.id)) {\n return null;\n }\n\n return info.id;\n}\n\n/**\n * Extracts and validates the payment identifier from a PaymentPayload.\n *\n * @param paymentPayload - The payment payload to extract from\n * @returns Object with the ID and validation result\n *\n * @example\n * ```typescript\n * const { id, validation } = extractAndValidatePaymentIdentifier(paymentPayload);\n * if (!validation.valid) {\n * return res.status(400).json({ error: validation.errors });\n * }\n * if (id) {\n * // Use for idempotency\n * }\n * ```\n */\nexport function extractAndValidatePaymentIdentifier(paymentPayload: PaymentPayload): {\n id: string | null;\n validation: PaymentIdentifierValidationResult;\n} {\n if (!paymentPayload.extensions) {\n return { id: null, validation: { valid: true } };\n }\n\n const extension = paymentPayload.extensions[PAYMENT_IDENTIFIER];\n\n if (!extension) {\n return { id: null, validation: { valid: true } };\n }\n\n const validation = validatePaymentIdentifier(extension);\n\n if (!validation.valid) {\n return { id: null, validation };\n }\n\n const ext = extension as PaymentIdentifierExtension;\n return { id: ext.info.id ?? null, validation: { valid: true } };\n}\n\n/**\n * Checks if a PaymentPayload contains a payment-identifier extension.\n *\n * @param paymentPayload - The payment payload to check\n * @returns True if the extension is present\n */\nexport function hasPaymentIdentifier(paymentPayload: PaymentPayload): boolean {\n return !!(paymentPayload.extensions && paymentPayload.extensions[PAYMENT_IDENTIFIER]);\n}\n\n/**\n * Checks if the server requires a payment identifier based on the extension info.\n *\n * @param extension - The payment-identifier extension from PaymentRequired or PaymentPayload\n * @returns True if the server requires a payment identifier\n */\nexport function isPaymentIdentifierRequired(extension: unknown): boolean {\n if (!extension || typeof extension !== \"object\") {\n return false;\n }\n\n const ext = extension as Partial<PaymentIdentifierExtension>;\n\n if (!ext.info || typeof ext.info !== \"object\") {\n return false;\n }\n\n return (ext.info as Partial<PaymentIdentifierInfo>).required === true;\n}\n\n/**\n * Validates that a payment identifier is provided when required.\n *\n * Use this to check if a client's PaymentPayload satisfies the server's requirement.\n *\n * @param paymentPayload - The client's payment payload\n * @param serverRequired - Whether the server requires a payment identifier (from PaymentRequired)\n * @returns Validation result - invalid if required but not provided\n *\n * @example\n * ```typescript\n * const serverExtension = paymentRequired.extensions?.[\"payment-identifier\"];\n * const serverRequired = isPaymentIdentifierRequired(serverExtension);\n * const result = validatePaymentIdentifierRequirement(paymentPayload, serverRequired);\n * if (!result.valid) {\n * return res.status(400).json({ error: result.errors });\n * }\n * ```\n */\nexport function validatePaymentIdentifierRequirement(\n paymentPayload: PaymentPayload,\n serverRequired: boolean,\n): PaymentIdentifierValidationResult {\n if (!serverRequired) {\n return { valid: true };\n }\n\n const id = extractPaymentIdentifier(paymentPayload, false);\n\n if (!id) {\n return {\n valid: false,\n errors: [\"Server requires a payment identifier but none was provided\"],\n };\n }\n\n // Validate the ID format\n if (!isValidPaymentId(id)) {\n return {\n valid: false,\n errors: [\n `Invalid payment ID format. ID must be 16-128 characters and contain only alphanumeric characters, hyphens, and underscores.`,\n ],\n };\n }\n\n return { valid: true };\n}\n\nexport { paymentIdentifierSchema };\n","/**\n * Client-side utilities for the Payment-Identifier Extension\n */\n\nimport { PAYMENT_IDENTIFIER } from \"./types\";\nimport { generatePaymentId, isValidPaymentId } from \"./utils\";\nimport { isPaymentIdentifierExtension } from \"./validation\";\n\n/**\n * Appends a payment identifier to the extensions object if the server declared support.\n *\n * This function reads the server's `payment-identifier` declaration from the extensions,\n * and appends the client's ID to it. If the extension is not present (server didn't declare it),\n * the extensions are returned unchanged.\n *\n * @param extensions - The extensions object from PaymentRequired (will be modified in place)\n * @param id - Optional custom payment ID. If not provided, a new ID will be generated.\n * @returns The modified extensions object (same reference as input)\n * @throws Error if the provided ID is invalid\n *\n * @example\n * ```typescript\n * import { appendPaymentIdentifierToExtensions } from '@x402/extensions/payment-identifier';\n *\n * // Get extensions from server's PaymentRequired response\n * const extensions = paymentRequired.extensions ?? {};\n *\n * // Append a generated ID (only if server declared payment-identifier)\n * appendPaymentIdentifierToExtensions(extensions);\n *\n * // Or use a custom ID\n * appendPaymentIdentifierToExtensions(extensions, \"pay_my_custom_id_12345\");\n *\n * // Include in PaymentPayload\n * const paymentPayload = {\n * x402Version: 2,\n * resource: paymentRequired.resource,\n * accepted: selectedPaymentOption,\n * payload: { ... },\n * extensions\n * };\n * ```\n */\nexport function appendPaymentIdentifierToExtensions(\n extensions: Record<string, unknown>,\n id?: string,\n): Record<string, unknown> {\n const extension = extensions[PAYMENT_IDENTIFIER];\n\n // Only append if the server declared this extension with valid structure\n if (!isPaymentIdentifierExtension(extension)) {\n return extensions;\n }\n\n const paymentId = id ?? generatePaymentId();\n\n if (!isValidPaymentId(paymentId)) {\n throw new Error(\n `Invalid payment ID: \"${paymentId}\". ` +\n `ID must be 16-128 characters and contain only alphanumeric characters, hyphens, and underscores.`,\n );\n }\n\n // Append the ID to the existing extension info\n extension.info.id = paymentId;\n\n return extensions;\n}\n","/**\n * Resource Server utilities for the Payment-Identifier Extension\n */\n\nimport type { ResourceServerExtension } from \"@x402/core/types\";\nimport type { PaymentIdentifierExtension } from \"./types\";\nimport { PAYMENT_IDENTIFIER } from \"./types\";\nimport { paymentIdentifierSchema } from \"./schema\";\n\n/**\n * Declares the payment-identifier extension for inclusion in PaymentRequired.extensions.\n *\n * Resource servers call this function to advertise support for payment identifiers.\n * The declaration indicates whether a payment identifier is required and includes\n * the schema that clients must follow.\n *\n * @param required - Whether clients must provide a payment identifier. Defaults to false.\n * @returns A PaymentIdentifierExtension object ready for PaymentRequired.extensions\n *\n * @example\n * ```typescript\n * import { declarePaymentIdentifierExtension, PAYMENT_IDENTIFIER } from '@x402/extensions/payment-identifier';\n *\n * // Include in PaymentRequired response (optional identifier)\n * const paymentRequired = {\n * x402Version: 2,\n * resource: { ... },\n * accepts: [ ... ],\n * extensions: {\n * [PAYMENT_IDENTIFIER]: declarePaymentIdentifierExtension()\n * }\n * };\n *\n * // Require payment identifier\n * const paymentRequiredStrict = {\n * x402Version: 2,\n * resource: { ... },\n * accepts: [ ... ],\n * extensions: {\n * [PAYMENT_IDENTIFIER]: declarePaymentIdentifierExtension(true)\n * }\n * };\n * ```\n */\nexport function declarePaymentIdentifierExtension(\n required: boolean = false,\n): PaymentIdentifierExtension {\n return {\n info: { required },\n schema: paymentIdentifierSchema,\n };\n}\n\n/**\n * ResourceServerExtension implementation for payment-identifier.\n *\n * This extension doesn't require any enrichment hooks since the declaration\n * is static. It's provided for consistency with other extensions and for\n * potential future use with the extension registration system.\n *\n * @example\n * ```typescript\n * import { paymentIdentifierResourceServerExtension } from '@x402/extensions/payment-identifier';\n *\n * resourceServer.registerExtension(paymentIdentifierResourceServerExtension);\n * ```\n */\nexport const paymentIdentifierResourceServerExtension: ResourceServerExtension = {\n key: PAYMENT_IDENTIFIER,\n\n // No enrichment needed - the declaration is static\n // Future hooks for idempotency could be added here if needed\n};\n","/**\n * Type definitions for the EIP-2612 Gas Sponsoring Extension\n *\n * This extension enables gasless approval of the Permit2 contract for tokens\n * that implement EIP-2612. The client signs an off-chain permit, and the\n * facilitator submits it on-chain via `x402Permit2Proxy.settleWithPermit`.\n */\n\nimport type { FacilitatorExtension } from \"@x402/core/types\";\n\n/**\n * Extension identifier for the EIP-2612 gas sponsoring extension.\n */\nexport const EIP2612_GAS_SPONSORING: FacilitatorExtension = { key: \"eip2612GasSponsoring\" };\n\n/**\n * EIP-2612 gas sponsoring info populated by the client.\n *\n * Contains the EIP-2612 permit signature and parameters that the facilitator\n * needs to call `x402Permit2Proxy.settleWithPermit`.\n */\nexport interface Eip2612GasSponsoringInfo {\n /** Index signature for compatibility with Record<string, unknown> */\n [key: string]: unknown;\n /** The address of the sender (token owner). */\n from: string;\n /** The address of the ERC-20 token contract. */\n asset: string;\n /** The address of the spender (Canonical Permit2). */\n spender: string;\n /** The amount to approve (uint256 as decimal string). Typically MaxUint256. */\n amount: string;\n /** The current EIP-2612 nonce of the sender (decimal string). */\n nonce: string;\n /** The timestamp at which the permit signature expires (decimal string). */\n deadline: string;\n /** The 65-byte concatenated EIP-2612 permit signature (r, s, v) as a hex string. */\n signature: string;\n /** Schema version identifier. */\n version: string;\n}\n\n/**\n * Server-side EIP-2612 gas sponsoring info included in PaymentRequired.\n * Contains a description and version; the client populates the rest.\n */\nexport interface Eip2612GasSponsoringServerInfo {\n /** Index signature for compatibility with Record<string, unknown> */\n [key: string]: unknown;\n /** Human-readable description of the extension. */\n description: string;\n /** Schema version identifier. */\n version: string;\n}\n\n/**\n * The full extension object as it appears in PaymentRequired.extensions\n * and PaymentPayload.extensions.\n */\nexport interface Eip2612GasSponsoringExtension {\n /** Extension info - server-provided or client-enriched. */\n info: Eip2612GasSponsoringServerInfo | Eip2612GasSponsoringInfo;\n /** JSON Schema describing the expected structure of info. */\n schema: Record<string, unknown>;\n}\n","/**\n * Resource Service functions for declaring the EIP-2612 Gas Sponsoring extension.\n *\n * These functions help servers declare support for EIP-2612 gasless Permit2 approvals\n * in the PaymentRequired response extensions.\n */\n\nimport { EIP2612_GAS_SPONSORING, type Eip2612GasSponsoringExtension } from \"./types\";\n\n/**\n * The JSON Schema for the EIP-2612 gas sponsoring extension info.\n * Matches the schema defined in the spec.\n */\nconst eip2612GasSponsoringSchema: Record<string, unknown> = {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n properties: {\n from: {\n type: \"string\",\n pattern: \"^0x[a-fA-F0-9]{40}$\",\n description: \"The address of the sender.\",\n },\n asset: {\n type: \"string\",\n pattern: \"^0x[a-fA-F0-9]{40}$\",\n description: \"The address of the ERC-20 token contract.\",\n },\n spender: {\n type: \"string\",\n pattern: \"^0x[a-fA-F0-9]{40}$\",\n description: \"The address of the spender (Canonical Permit2).\",\n },\n amount: {\n type: \"string\",\n pattern: \"^[0-9]+$\",\n description: \"The amount to approve (uint256). Typically MaxUint.\",\n },\n nonce: {\n type: \"string\",\n pattern: \"^[0-9]+$\",\n description: \"The current nonce of the sender.\",\n },\n deadline: {\n type: \"string\",\n pattern: \"^[0-9]+$\",\n description: \"The timestamp at which the signature expires.\",\n },\n signature: {\n type: \"string\",\n pattern: \"^0x[a-fA-F0-9]+$\",\n description: \"The 65-byte concatenated signature (r, s, v) as a hex string.\",\n },\n version: {\n type: \"string\",\n pattern: \"^[0-9]+(\\\\.[0-9]+)*$\",\n description: \"Schema version identifier.\",\n },\n },\n required: [\"from\", \"asset\", \"spender\", \"amount\", \"nonce\", \"deadline\", \"signature\", \"version\"],\n};\n\n/**\n * Declares the EIP-2612 gas sponsoring extension for inclusion in\n * PaymentRequired.extensions.\n *\n * The server advertises that it (or its facilitator) supports EIP-2612\n * gasless Permit2 approval. The client will populate the info with the\n * actual permit signature data.\n *\n * @returns An object keyed by the extension identifier containing the extension declaration\n *\n * @example\n * ```typescript\n * import { declareEip2612GasSponsoringExtension } from '@x402/extensions';\n *\n * const routes = [\n * {\n * path: \"/api/data\",\n * price: \"$0.01\",\n * extensions: {\n * ...declareEip2612GasSponsoringExtension(),\n * },\n * },\n * ];\n * ```\n */\nexport function declareEip2612GasSponsoringExtension(): Record<\n string,\n Eip2612GasSponsoringExtension\n> {\n const key = EIP2612_GAS_SPONSORING.key;\n return {\n [key]: {\n info: {\n description:\n \"The facilitator accepts EIP-2612 gasless Permit to `Permit2` canonical contract.\",\n version: \"1\",\n },\n schema: eip2612GasSponsoringSchema,\n },\n };\n}\n","/**\n * Facilitator functions for extracting and validating EIP-2612 Gas Sponsoring extension data.\n *\n * These functions help facilitators extract the EIP-2612 permit data from payment\n * payloads and validate it before calling settleWithPermit.\n */\n\nimport type { PaymentPayload } from \"@x402/core/types\";\nimport {\n EIP2612_GAS_SPONSORING,\n type Eip2612GasSponsoringInfo,\n type Eip2612GasSponsoringExtension,\n} from \"./types\";\n\n/**\n * Extracts the EIP-2612 gas sponsoring info from a payment payload's extensions.\n *\n * Returns the info if the extension is present and contains the required client-populated\n * fields (from, asset, spender, amount, nonce, deadline, signature, version).\n *\n * @param paymentPayload - The payment payload to extract from\n * @returns The EIP-2612 gas sponsoring info, or null if not present\n */\nexport function extractEip2612GasSponsoringInfo(\n paymentPayload: PaymentPayload,\n): Eip2612GasSponsoringInfo | null {\n if (!paymentPayload.extensions) {\n return null;\n }\n\n const extension = paymentPayload.extensions[EIP2612_GAS_SPONSORING.key] as\n | Eip2612GasSponsoringExtension\n | undefined;\n\n if (!extension?.info) {\n return null;\n }\n\n const info = extension.info as Record<string, unknown>;\n\n // Check that the client has populated the required fields\n if (\n !info.from ||\n !info.asset ||\n !info.spender ||\n !info.amount ||\n !info.nonce ||\n !info.deadline ||\n !info.signature ||\n !info.version\n ) {\n return null;\n }\n\n return info as unknown as Eip2612GasSponsoringInfo;\n}\n\n/**\n * Validates that the EIP-2612 gas sponsoring info has valid format.\n *\n * Performs basic validation on the info fields:\n * - Addresses are valid hex (0x + 40 hex chars)\n * - Amount, nonce, deadline are numeric strings\n * - Signature is a hex string\n * - Version is a numeric version string\n *\n * @param info - The EIP-2612 gas sponsoring info to validate\n * @returns True if the info is valid, false otherwise\n */\nexport function validateEip2612GasSponsoringInfo(info: Eip2612GasSponsoringInfo): boolean {\n const addressPattern = /^0x[a-fA-F0-9]{40}$/;\n const numericPattern = /^[0-9]+$/;\n const hexPattern = /^0x[a-fA-F0-9]+$/;\n const versionPattern = /^[0-9]+(\\.[0-9]+)*$/;\n\n return (\n addressPattern.test(info.from) &&\n addressPattern.test(info.asset) &&\n addressPattern.test(info.spender) &&\n numericPattern.test(info.amount) &&\n numericPattern.test(info.nonce) &&\n numericPattern.test(info.deadline) &&\n hexPattern.test(info.signature) &&\n versionPattern.test(info.version)\n );\n}\n","/**\n * Type definitions for the ERC-20 Approval Gas Sponsoring Extension\n *\n * This extension enables gasless Permit2 approval for generic ERC-20 tokens\n * that do NOT implement EIP-2612. The client signs (but does not broadcast) a\n * raw `approve(Permit2, MaxUint256)` transaction, and the facilitator broadcasts\n * it atomically before settling the Permit2 payment.\n */\n\nimport type { FacilitatorExtension } from \"@x402/core/types\";\n\n/**\n * A single transaction to be executed by the signer.\n * - `0x${string}`: a pre-signed serialized transaction (broadcast as-is via sendRawTransaction)\n * - `{ to, data, gas? }`: an unsigned call intent (signer signs and broadcasts)\n */\nexport type TransactionRequest =\n | `0x${string}`\n | { to: `0x${string}`; data: `0x${string}`; gas?: bigint };\n\n/**\n * Signer capability carried by the ERC-20 approval extension when registered in a facilitator.\n *\n * Mirrors FacilitatorEvmSigner (from @x402/evm) plus `sendTransactions`.\n * The signer owns execution of multiple transactions, enabling production implementations\n * to bundle them atomically (e.g., Flashbots, multicall, smart account batching)\n * while simpler implementations can execute them sequentially.\n *\n * The method signatures are duplicated here (rather than extending FacilitatorEvmSigner)\n * to avoid a circular dependency between @x402/extensions and @x402/evm.\n */\nexport interface Erc20ApprovalGasSponsoringSigner {\n getAddresses(): readonly `0x${string}`[];\n readContract(args: {\n address: `0x${string}`;\n abi: readonly unknown[];\n functionName: string;\n args?: readonly unknown[];\n }): Promise<unknown>;\n verifyTypedData(args: {\n address: `0x${string}`;\n domain: Record<string, unknown>;\n types: Record<string, unknown>;\n primaryType: string;\n message: Record<string, unknown>;\n signature: `0x${string}`;\n }): Promise<boolean>;\n writeContract(args: {\n address: `0x${string}`;\n abi: readonly unknown[];\n functionName: string;\n args: readonly unknown[];\n gas?: bigint;\n }): Promise<`0x${string}`>;\n sendTransaction(args: { to: `0x${string}`; data: `0x${string}` }): Promise<`0x${string}`>;\n waitForTransactionReceipt(args: { hash: `0x${string}` }): Promise<{ status: string }>;\n getCode(args: { address: `0x${string}` }): Promise<`0x${string}` | undefined>;\n sendTransactions(transactions: TransactionRequest[]): Promise<`0x${string}`[]>;\n}\n\n/**\n * Extension identifier for the ERC-20 approval gas sponsoring extension.\n */\nexport const ERC20_APPROVAL_GAS_SPONSORING = {\n key: \"erc20ApprovalGasSponsoring\",\n} as const satisfies FacilitatorExtension;\n\n/** Current schema version for the ERC-20 approval gas sponsoring extension info. */\nexport const ERC20_APPROVAL_GAS_SPONSORING_VERSION = \"1\";\n\n/**\n * Extended extension object registered in a facilitator via registerExtension().\n * Carries the signer that owns the full approve+settle flow for ERC-20 tokens\n * that lack EIP-2612.\n *\n * @example\n * ```typescript\n * import { createErc20ApprovalGasSponsoringExtension } from '@x402/extensions';\n *\n * facilitator.registerExtension(\n * createErc20ApprovalGasSponsoringExtension(signer),\n * );\n * ```\n */\nexport interface Erc20ApprovalGasSponsoringFacilitatorExtension extends FacilitatorExtension {\n key: \"erc20ApprovalGasSponsoring\";\n /** Default signer with approve+settle capability. Optional — settlement fails gracefully if absent. */\n signer?: Erc20ApprovalGasSponsoringSigner;\n /** Network-specific signer resolver. Takes precedence over `signer` when provided. */\n signerForNetwork?: (network: string) => Erc20ApprovalGasSponsoringSigner | undefined;\n}\n\n/**\n * Base signer shape without `sendTransactions`.\n * Matches the FacilitatorEvmSigner shape from @x402/evm (duplicated to avoid circular dep).\n */\nexport type Erc20ApprovalGasSponsoringBaseSigner = Omit<\n Erc20ApprovalGasSponsoringSigner,\n \"sendTransactions\"\n>;\n\n/**\n * Create an ERC-20 approval gas sponsoring extension ready to register in a facilitator.\n *\n * @param signer - A complete signer with `sendTransactions` already implemented.\n * The signer decides how to execute the transactions (sequentially, batched, or atomically).\n * @param signerForNetwork - Optional network-specific signer resolver. When provided,\n * takes precedence over `signer` and allows different settlement signers per network.\n * @returns A fully configured extension to pass to `facilitator.registerExtension()`\n */\nexport function createErc20ApprovalGasSponsoringExtension(\n signer: Erc20ApprovalGasSponsoringSigner,\n signerForNetwork?: (network: string) => Erc20ApprovalGasSponsoringSigner | undefined,\n): Erc20ApprovalGasSponsoringFacilitatorExtension {\n return { ...ERC20_APPROVAL_GAS_SPONSORING, signer, signerForNetwork };\n}\n\n/**\n * ERC-20 approval gas sponsoring info populated by the client.\n *\n * Contains the RLP-encoded signed `approve(Permit2, MaxUint256)` transaction\n * that the facilitator broadcasts before settling the Permit2 payment.\n *\n * Note: Unlike EIP-2612, there is no nonce/deadline/signature — instead the\n * entire signed transaction is included as `signedTransaction`.\n */\nexport interface Erc20ApprovalGasSponsoringInfo {\n /** Index signature for compatibility with Record<string, unknown> */\n [key: string]: unknown;\n /** The address of the sender (token owner who signed the tx). */\n from: `0x${string}`;\n /** The address of the ERC-20 token contract. */\n asset: `0x${string}`;\n /** The address of the spender (Canonical Permit2). */\n spender: `0x${string}`;\n /** The amount approved (uint256 as decimal string). Always MaxUint256. */\n amount: string;\n /** The RLP-encoded signed EIP-1559 transaction as a hex string. */\n signedTransaction: `0x${string}`;\n /** Schema version identifier. */\n version: string;\n}\n\n/**\n * Server-side ERC-20 approval gas sponsoring info included in PaymentRequired.\n * Contains a description and version; the client populates the rest.\n */\nexport interface Erc20ApprovalGasSponsoringServerInfo {\n /** Index signature for compatibility with Record<string, unknown> */\n [key: string]: unknown;\n /** Human-readable description of the extension. */\n description: string;\n /** Schema version identifier. */\n version: string;\n}\n\n/**\n * The full extension object as it appears in PaymentRequired.extensions\n * and PaymentPayload.extensions.\n */\nexport interface Erc20ApprovalGasSponsoringExtension {\n /** Extension info - server-provided or client-enriched. */\n info: Erc20ApprovalGasSponsoringServerInfo | Erc20ApprovalGasSponsoringInfo;\n /** JSON Schema describing the expected structure of info. */\n schema: Record<string, unknown>;\n}\n","/**\n * Resource Service functions for declaring the ERC-20 Approval Gas Sponsoring extension.\n *\n * These functions help servers declare support for ERC-20 approval gas sponsoring\n * in the PaymentRequired response extensions. Use this for tokens that do NOT\n * implement EIP-2612 (generic ERC-20 tokens).\n */\n\nimport {\n ERC20_APPROVAL_GAS_SPONSORING,\n ERC20_APPROVAL_GAS_SPONSORING_VERSION,\n type Erc20ApprovalGasSponsoringExtension,\n} from \"./types\";\n\n/**\n * The JSON Schema for the ERC-20 approval gas sponsoring extension info.\n * Matches the schema defined in the spec.\n */\nexport const erc20ApprovalGasSponsoringSchema: Record<string, unknown> = {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n properties: {\n from: {\n type: \"string\",\n pattern: \"^0x[a-fA-F0-9]{40}$\",\n description: \"The address of the sender (token owner).\",\n },\n asset: {\n type: \"string\",\n pattern: \"^0x[a-fA-F0-9]{40}$\",\n description: \"The address of the ERC-20 token contract.\",\n },\n spender: {\n type: \"string\",\n pattern: \"^0x[a-fA-F0-9]{40}$\",\n description: \"The address of the spender (Canonical Permit2).\",\n },\n amount: {\n type: \"string\",\n pattern: \"^[0-9]+$\",\n description: \"The amount approved (uint256). Always MaxUint256.\",\n },\n signedTransaction: {\n type: \"string\",\n pattern: \"^0x[a-fA-F0-9]+$\",\n description: \"The RLP-encoded signed EIP-1559 transaction as a hex string.\",\n },\n version: {\n type: \"string\",\n pattern: \"^[0-9]+(\\\\.[0-9]+)*$\",\n description: \"Schema version identifier.\",\n },\n },\n required: [\"from\", \"asset\", \"spender\", \"amount\", \"signedTransaction\", \"version\"],\n};\n\n/**\n * Declares the ERC-20 approval gas sponsoring extension for inclusion in\n * PaymentRequired.extensions.\n *\n * The server advertises that it (or its facilitator) supports broadcasting\n * a pre-signed `approve(Permit2, MaxUint256)` transaction on the client's behalf.\n * Use this for tokens that do NOT implement EIP-2612.\n *\n * @returns An object keyed by the extension identifier containing the extension declaration\n *\n * @example\n * ```typescript\n * import { declareErc20ApprovalGasSponsoringExtension } from '@x402/extensions';\n *\n * const routes = [\n * {\n * path: \"/api/data\",\n * price: { amount: \"1000\", asset: \"0x...\", extra: { assetTransferMethod: \"permit2\" } },\n * extensions: {\n * ...declareErc20ApprovalGasSponsoringExtension(),\n * },\n * },\n * ];\n * ```\n */\nexport function declareErc20ApprovalGasSponsoringExtension(): Record<\n string,\n Erc20ApprovalGasSponsoringExtension\n> {\n const key = ERC20_APPROVAL_GAS_SPONSORING.key;\n return {\n [key]: {\n info: {\n description:\n \"The facilitator broadcasts a pre-signed ERC-20 approve() transaction to grant Permit2 allowance.\",\n version: ERC20_APPROVAL_GAS_SPONSORING_VERSION,\n },\n schema: erc20ApprovalGasSponsoringSchema,\n },\n };\n}\n","/**\n * Facilitator functions for extracting and validating ERC-20 Approval Gas Sponsoring\n * extension data.\n *\n * These functions help facilitators extract the pre-signed approve() transaction\n * from payment payloads and validate it before broadcasting and settling.\n */\n\nimport Ajv from \"ajv/dist/2020.js\";\nimport type { PaymentPayload } from \"@x402/core/types\";\nimport {\n ERC20_APPROVAL_GAS_SPONSORING,\n type Erc20ApprovalGasSponsoringInfo,\n type Erc20ApprovalGasSponsoringExtension,\n} from \"./types\";\nimport { erc20ApprovalGasSponsoringSchema } from \"./resourceService\";\n\n/**\n * Extracts the ERC-20 approval gas sponsoring info from a payment payload's extensions.\n *\n * Performs structural extraction only — checks that the extension is present and\n * contains all required fields. Does NOT validate field formats (use\n * validateErc20ApprovalGasSponsoringInfo for that).\n *\n * @param paymentPayload - The payment payload to extract from\n * @returns The ERC-20 approval gas sponsoring info, or null if not present\n */\nexport function extractErc20ApprovalGasSponsoringInfo(\n paymentPayload: PaymentPayload,\n): Erc20ApprovalGasSponsoringInfo | null {\n if (!paymentPayload.extensions) {\n return null;\n }\n\n const extension = paymentPayload.extensions[ERC20_APPROVAL_GAS_SPONSORING.key] as\n | Erc20ApprovalGasSponsoringExtension\n | undefined;\n\n if (!extension?.info) {\n return null;\n }\n\n const info = extension.info as Record<string, unknown>;\n\n if (\n !info.from ||\n !info.asset ||\n !info.spender ||\n !info.amount ||\n !info.signedTransaction ||\n !info.version\n ) {\n return null;\n }\n\n return info as unknown as Erc20ApprovalGasSponsoringInfo;\n}\n\n/**\n * Validates that the ERC-20 approval gas sponsoring info has valid format.\n *\n * Validates the info against the canonical JSON Schema, checking:\n * - All required fields are present\n * - Addresses are valid hex (0x + 40 hex chars)\n * - Amount is a numeric string\n * - signedTransaction is a hex string\n * - Version is a numeric version string\n *\n * @param info - The ERC-20 approval gas sponsoring info to validate\n * @returns True if the info is valid, false otherwise\n */\nexport function validateErc20ApprovalGasSponsoringInfo(\n info: Erc20ApprovalGasSponsoringInfo,\n): boolean {\n const ajv = new Ajv({ strict: false, allErrors: true });\n const validate = ajv.compile(erc20ApprovalGasSponsoringSchema);\n return validate(info) as boolean;\n}\n"],"mappings":"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","names":["extension","isBodyMethod","Ajv","nacl","import_utils","fetch","jose","import_viem","import_base","m","import_http","import__","Ajv","import__","Ajv"]}