@bankofai/x402-extensions 1.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +28 -0
  2. package/dist/cjs/bazaar/index.d.ts +4 -0
  3. package/dist/cjs/bazaar/index.js +1048 -0
  4. package/dist/cjs/bazaar/index.js.map +1 -0
  5. package/dist/cjs/builder-code/index.d.ts +225 -0
  6. package/dist/cjs/builder-code/index.js +369 -0
  7. package/dist/cjs/builder-code/index.js.map +1 -0
  8. package/dist/cjs/index-B8S563vv.d.ts +929 -0
  9. package/dist/cjs/index-BUV9B9f8.d.ts +929 -0
  10. package/dist/cjs/index.d.ts +373 -0
  11. package/dist/cjs/index.js +3536 -0
  12. package/dist/cjs/index.js.map +1 -0
  13. package/dist/cjs/offer-receipt/index.d.ts +702 -0
  14. package/dist/cjs/offer-receipt/index.js +909 -0
  15. package/dist/cjs/offer-receipt/index.js.map +1 -0
  16. package/dist/cjs/payment-identifier/index.d.ts +345 -0
  17. package/dist/cjs/payment-identifier/index.js +285 -0
  18. package/dist/cjs/payment-identifier/index.js.map +1 -0
  19. package/dist/cjs/sign-in-with-x/index.d.ts +1117 -0
  20. package/dist/cjs/sign-in-with-x/index.js +876 -0
  21. package/dist/cjs/sign-in-with-x/index.js.map +1 -0
  22. package/dist/esm/bazaar/index.d.mts +4 -0
  23. package/dist/esm/bazaar/index.mjs +51 -0
  24. package/dist/esm/bazaar/index.mjs.map +1 -0
  25. package/dist/esm/builder-code/index.d.mts +225 -0
  26. package/dist/esm/builder-code/index.mjs +27 -0
  27. package/dist/esm/builder-code/index.mjs.map +1 -0
  28. package/dist/esm/chunk-4IPDE3NS.mjs +990 -0
  29. package/dist/esm/chunk-4IPDE3NS.mjs.map +1 -0
  30. package/dist/esm/chunk-N74HQTNO.mjs +807 -0
  31. package/dist/esm/chunk-N74HQTNO.mjs.map +1 -0
  32. package/dist/esm/chunk-OWZP4CUR.mjs +333 -0
  33. package/dist/esm/chunk-OWZP4CUR.mjs.map +1 -0
  34. package/dist/esm/chunk-RERA4OZZ.mjs +233 -0
  35. package/dist/esm/chunk-RERA4OZZ.mjs.map +1 -0
  36. package/dist/esm/chunk-TIVMC3ZS.mjs +828 -0
  37. package/dist/esm/chunk-TIVMC3ZS.mjs.map +1 -0
  38. package/dist/esm/index-B8S563vv.d.mts +929 -0
  39. package/dist/esm/index-BUV9B9f8.d.mts +929 -0
  40. package/dist/esm/index.d.mts +373 -0
  41. package/dist/esm/index.mjs +455 -0
  42. package/dist/esm/index.mjs.map +1 -0
  43. package/dist/esm/offer-receipt/index.d.mts +702 -0
  44. package/dist/esm/offer-receipt/index.mjs +97 -0
  45. package/dist/esm/offer-receipt/index.mjs.map +1 -0
  46. package/dist/esm/payment-identifier/index.d.mts +345 -0
  47. package/dist/esm/payment-identifier/index.mjs +39 -0
  48. package/dist/esm/payment-identifier/index.mjs.map +1 -0
  49. package/dist/esm/sign-in-with-x/index.d.mts +1117 -0
  50. package/dist/esm/sign-in-with-x/index.mjs +73 -0
  51. package/dist/esm/sign-in-with-x/index.mjs.map +1 -0
  52. package/package.json +124 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../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/startupValidation.ts","../../src/bazaar/facilitatorClient.ts"],"sourcesContent":["/**\n * HTTP-specific type definitions for the Bazaar Discovery Extension\n */\n\nimport type { BodyMethods, QueryParamMethods } from \"@bankofai/x402-core/http\";\nimport type { DiscoveryInfo } from \"../types\";\n\n/** Shared schema definition for an object-typed parameter map (queryParams, pathParams, etc.) */\ninterface ParamMapSchemaProperty {\n type: \"object\";\n properties?: Record<string, unknown>;\n additionalProperties?: boolean;\n}\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 pathParams?: 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 pathParams?: 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 routeTemplate?: string;\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?: ParamMapSchemaProperty & { required?: string[] };\n pathParams?: ParamMapSchemaProperty;\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 routeTemplate?: string;\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?: ParamMapSchemaProperty & { required?: string[] };\n pathParams?: ParamMapSchemaProperty;\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 pathParams?: Record<string, unknown>;\n pathParamsSchema?: 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 pathParams?: Record<string, unknown>;\n pathParamsSchema?: 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 /** Sanitized service metadata. See `sanitizeResourceServiceMetadata` for rules. */\n serviceName?: string;\n tags?: string[];\n iconUrl?: string;\n /** Present after server extension enrichment; may be absent for pre-enrichment data */\n method?: string;\n routeTemplate?: string;\n x402Version: number;\n discoveryInfo: DiscoveryInfo;\n /** Extension payloads for catalog echo (v2: payload.extensions; v1: synthesized extensions.bazaar) */\n extensions?: Record<string, unknown>;\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?: string;\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?: string[];\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?: string;\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 /** Sanitized service metadata. See `sanitizeResourceServiceMetadata` for rules. */\n serviceName?: string;\n tags?: string[];\n iconUrl?: string;\n toolName: string;\n x402Version: number;\n discoveryInfo: DiscoveryInfo;\n /** Extension payloads for catalog echo (v2: payload.extensions; v1: synthesized extensions.bazaar) */\n extensions?: Record<string, unknown>;\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 \"@bankofai/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 * @param root0.pathParams - Concrete path parameter values extracted from the request\n * @param root0.pathParamsSchema - JSON schema for path parameters\n * @returns QueryDiscoveryExtension with info and schema\n */\nexport function createQueryDiscoveryExtension({\n method,\n input = {},\n inputSchema = { properties: {} },\n pathParams,\n pathParamsSchema,\n output,\n}: DeclareQueryDiscoveryExtensionConfig): QueryDiscoveryExtension {\n return {\n info: {\n input: {\n type: \"http\" as const,\n ...(method ? { method } : {}),\n ...(input ? { queryParams: input } : {}),\n ...(pathParams ? { pathParams } : {}),\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 ...(pathParamsSchema\n ? {\n pathParams: {\n type: \"object\" as const,\n ...(typeof pathParamsSchema === \"object\" ? pathParamsSchema : {}),\n },\n }\n : {}),\n },\n required: [\"type\", \"method\"] as (\"type\" | \"method\")[],\n // pathParams are not declared here at schema build time --\n // the server extension's enrichDeclaration adds them to both info and schema\n // atomically at request time, keeping data and schema consistent.\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 * @param root0.pathParams - Concrete path parameter values extracted from the request\n * @param root0.pathParamsSchema - JSON schema for path parameters\n * @returns BodyDiscoveryExtension with info and schema\n */\nexport function createBodyDiscoveryExtension({\n method,\n input = {},\n inputSchema = { properties: {} },\n pathParams,\n pathParamsSchema,\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 ...(pathParams ? { pathParams } : {}),\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 ...(pathParamsSchema\n ? {\n pathParams: {\n type: \"object\" as const,\n ...(typeof pathParamsSchema === \"object\" ? pathParamsSchema : {}),\n },\n }\n : {}),\n },\n required: [\"type\", \"method\", \"bodyType\", \"body\"] as (\n | \"type\"\n | \"method\"\n | \"bodyType\"\n | \"body\"\n )[],\n // pathParams are not declared here at schema build time --\n // the server extension's enrichDeclaration adds them to both info and schema\n // atomically at request time, keeping data and schema consistent.\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 ...(transport === \"streamable-http\" || transport === \"sse\"\n ? { enum: [transport] }\n : {}),\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 \"@bankofai/x402-core/types\";\nimport type { HTTPRequestContext } from \"@bankofai/x402-core/http\";\nimport { BAZAAR } from \"./types\";\n\n// Non-global: safe for test/split (no stateful lastIndex side-effects).\nconst BRACKET_PARAM_REGEX = /\\[([^\\]]+)\\]/;\n// Global variant required for String.replace to substitute ALL occurrences.\n// JS String.replace with a non-global regex replaces only the first match.\n// (String.replaceAll with a non-global regex would work in ES2021+, but the\n// target lib is ES2020 — keep this separate constant to avoid that constraint.)\nconst BRACKET_PARAM_REGEX_ALL = /\\[([^\\]]+)\\]/g;\n\nconst COLON_PARAM_REGEX = /:([a-zA-Z_][a-zA-Z0-9_]*)/;\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\n/**\n * Converts wildcard segments in a route pattern to named :varN parameters\n * so they can be treated as dynamic routes for discovery catalog normalization.\n *\n * @param pattern - Route pattern that may contain wildcard segments\n * @returns The pattern with wildcard segments replaced by :var1, :var2, etc.\n */\nfunction normalizeWildcardPattern(pattern: string): string {\n if (!pattern.includes(\"*\")) {\n return pattern;\n }\n let counter = 0;\n return pattern\n .split(\"/\")\n .map(seg => {\n if (seg === \"*\") {\n counter++;\n return `:var${counter}`;\n }\n return seg;\n })\n .join(\"/\");\n}\n\n/**\n * Converts a parameterized route pattern into a :param template and extracts concrete\n * param values from the URL path in a single call.\n *\n * Supports both [param] (Next.js) and :param (Express) syntax. The output routeTemplate\n * always uses :param syntax regardless of input format.\n *\n * @param routePattern - Route pattern (e.g. \"/users/[userId]\" or \"/users/:userId\")\n * @param urlPath - Concrete URL path (e.g. \"/users/123\")\n * @returns Object with routeTemplate and pathParams, or null if no params detected\n */\nfunction extractDynamicRouteInfo(\n routePattern: string,\n urlPath: string,\n): { routeTemplate: string; pathParams: Record<string, string> } | null {\n const hasBracket = BRACKET_PARAM_REGEX.test(routePattern);\n const hasColon = COLON_PARAM_REGEX.test(routePattern);\n if (!hasBracket && !hasColon) {\n return null;\n }\n // When both [param] and :param are present, normalize brackets to colons first\n // so all params are extracted uniformly.\n const normalizedPattern = hasBracket\n ? routePattern.replace(BRACKET_PARAM_REGEX_ALL, \":$1\")\n : routePattern;\n const pathParams = extractPathParams(normalizedPattern, urlPath, false);\n return { routeTemplate: normalizedPattern, pathParams };\n}\n\n/**\n * Extracts concrete path parameter values by matching a URL path against a route pattern.\n *\n * @param routePattern - Route pattern with [paramName] or :paramName segments\n * @param urlPath - Concrete URL path (e.g. \"/users/123\")\n * @param isBracket - True if pattern uses [param] syntax, false for :param\n * @returns Record mapping param names to their values\n */\nfunction extractPathParams(\n routePattern: string,\n urlPath: string,\n isBracket: boolean,\n): Record<string, string> {\n const paramNames: string[] = [];\n const splitRegex = isBracket ? BRACKET_PARAM_REGEX : COLON_PARAM_REGEX;\n // Split on param markers so literal segments can be regex-escaped independently.\n // Without escaping, a route like /api/v1.0/[id] would produce a regex where '.' matches\n // any character (e.g. /api/v1X0/123 would incorrectly match).\n const parts = routePattern.split(splitRegex);\n const regexParts: string[] = [];\n parts.forEach((part, i) => {\n if (i % 2 === 0) {\n // Literal segment – escape all regex metacharacters\n regexParts.push(part.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"));\n } else {\n // Param name\n paramNames.push(part);\n regexParts.push(\"([^/]+)\");\n }\n });\n\n const regex = new RegExp(`^${regexParts.join(\"\")}$`);\n const match = urlPath.match(regex);\n\n if (!match) return {};\n\n const result: Record<string, string> = {};\n paramNames.forEach((name, idx) => {\n result[name] = match[idx + 1];\n });\n return result;\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 const enrichedResult = {\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 // Dynamic routes: translate [param]/:param → :param for the routeTemplate catalog key;\n // pathParams carries runtime values (distinct from pathParamsSchema in the declaration).\n // Wildcard * segments are auto-converted to :var1, :var2, etc. for catalog normalization.\n const rawRoutePattern = (transportContext as HTTPRequestContext).routePattern;\n const routePattern = rawRoutePattern ? normalizeWildcardPattern(rawRoutePattern) : undefined;\n const dynamicRoute = routePattern\n ? extractDynamicRouteInfo(routePattern, transportContext.adapter.getPath())\n : null;\n if (dynamicRoute) {\n const inputSchemaProps = enrichedResult.schema?.properties?.input?.properties || {};\n const hasPathParamsInSchema = \"pathParams\" in inputSchemaProps;\n return {\n ...enrichedResult,\n routeTemplate: dynamicRoute.routeTemplate,\n info: {\n ...enrichedResult.info,\n input: { ...enrichedResult.info.input, pathParams: dynamicRoute.pathParams },\n },\n ...(!hasPathParamsInSchema\n ? {\n schema: {\n ...enrichedResult.schema,\n properties: {\n ...enrichedResult.schema?.properties,\n input: {\n ...enrichedResult.schema?.properties?.input,\n properties: {\n ...inputSchemaProps,\n pathParams: { type: \"object\" },\n },\n },\n },\n },\n }\n : {}),\n };\n }\n\n return enrichedResult;\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 { domainToASCII } from \"node:url\";\nimport Ajv from \"ajv/dist/2020.js\";\nimport type {\n PaymentPayload,\n PaymentRequirements,\n PaymentRequirementsV1,\n ResourceInfo,\n} from \"@bankofai/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 { buildV1CatalogExtensions, extractDiscoveryInfoV1 } from \"./v1/facilitator\";\n\n/**\n * Valid routeTemplate pattern: must start with \"/\", contain only safe URL path characters\n * and :param identifiers, and not include traversal sequences or scheme markers.\n *\n * Allowed: /users/:userId, /weather/:country/:city, /api/v1/items\n */\nconst ROUTE_TEMPLATE_REGEX = /^\\/[a-zA-Z0-9_/:.\\-~%]+$/;\n\n/**\n * Checks whether a routeTemplate value is structurally valid.\n *\n * Expected format: \"/:param\" segments using colon-prefixed identifiers\n * (e.g. \"/users/:userId\", \"/weather/:country/:city\").\n *\n * The facilitator is a trust boundary: clients control the payment payload and\n * can modify routeTemplate before submission. A malicious value could cause the\n * facilitator to catalog the payment under an arbitrary URL (catalog poisoning).\n * This function enforces minimal structural requirements:\n * - Must be a non-empty string starting with \"/\"\n * - Must match the safe URL path character set (alphanumeric, _, :, /, ., -, ~, %)\n * - Must not contain \"..\" (path traversal)\n * - Must not contain \"://\" (URL injection)\n *\n * @param value - The raw routeTemplate string from the client payload\n * @returns true if the value is a valid routeTemplate, false otherwise\n *\n * @internal Exported for facilitator use.\n */\nexport function isValidRouteTemplate(value: string | undefined): value is string {\n if (!value) return false;\n if (!ROUTE_TEMPLATE_REGEX.test(value)) return false;\n // Decode percent-encoding before traversal checks so that %2e%2e is caught.\n let decoded: string;\n try {\n decoded = decodeURIComponent(value);\n } catch {\n return false;\n }\n if (decoded.includes(\"..\")) return false;\n if (decoded.includes(\"://\")) return false;\n return true;\n}\n\n/**\n * Validates a routeTemplate and returns it if valid, undefined otherwise.\n *\n * @param value - The raw routeTemplate string to validate\n * @returns The validated value, or undefined if invalid\n * @deprecated Use `isValidRouteTemplate` instead.\n */\nexport function validateRouteTemplate(value: string | undefined): string | undefined {\n return isValidRouteTemplate(value) ? value : undefined;\n}\n\n/**\n * Maximum lengths for resource service metadata fields. Spec: see\n * `specs/extensions/bazaar.md` \"Service Metadata on `resource`\".\n */\nconst MAX_SERVICE_NAME_LEN = 32;\nconst MAX_TAG_LEN = 32;\nconst MAX_TAGS = 5;\nconst MAX_ICON_URL_LEN = 2048;\n// Matches ASCII control characters (C0 + DEL).\nconst CONTROL_CHAR_REGEX = /[\\x00-\\x1f\\x7f]/;\n// Printable ASCII range (U+0020–U+007E). `serviceName` and `tags` are\n// constrained to this range so that String.length (UTF-16 code units),\n// len() in Python (code points), and len() in Go (UTF-8 bytes) all agree\n// on the character count. Same convention as paymentidentifier.id.\nconst PRINTABLE_ASCII_REGEX = /^[\\x20-\\x7e]+$/;\n// Unicode control characters (category Cc). Defense-in-depth: the printable\n// ASCII regex already rejects every control character, but this explicit\n// check documents intent and would survive any future relaxation of the\n// ASCII restriction. Mirrors `unicode.IsControl` (Go).\nconst UNICODE_CONTROL_REGEX = /\\p{Cc}/u;\n\n// Loopback hostnames that must be rejected for SSRF defense. Includes the\n// common /etc/hosts aliases on Linux/macOS (`localhost.localdomain`,\n// `ip6-localhost`, `ip6-loopback`) — without these, a hostile provider could\n// route the facilitator's image fetcher to its own loopback interface.\nconst LOOPBACK_HOSTNAMES = new Set([\n \"localhost\",\n \"localhost.localdomain\",\n \"ip6-localhost\",\n \"ip6-loopback\",\n]);\n// Matches a bare IPv4 dotted-quad. IPv6 literals are detected via hostname brackets.\nconst IPV4_REGEX = /^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/;\n// SSRF defense: any all-digit hostname is suspect because no legitimate DNS name\n// is purely numeric. Catches decimal-encoded IPs (`http://2130706433/` → 127.0.0.1)\n// and short-form IPs (`http://0/` → 0.0.0.0, treated as loopback on Linux).\nconst ALL_DIGITS_REGEX = /^\\d+$/;\n// SSRF defense: hex-encoded IPs (`http://0x7f000001/` → 127.0.0.1) — same family\n// of bypasses as the decimal form above.\nconst HEX_LITERAL_REGEX = /^0x[0-9a-f]+$/i;\n\n/**\n * Checks whether a serviceName value is structurally valid for the bazaar\n * `resource.serviceName` field. Non-empty string of printable ASCII\n * (U+0020–U+007E), length ≤ 32.\n *\n * The ASCII restriction matches the `paymentidentifier.id` convention and\n * keeps `len()` semantics identical across TS / Python / Go.\n *\n * Mirrors `_is_valid_service_name` (Python) and `isValidServiceName` (Go).\n * All three implementations must stay in sync.\n *\n * @param value - The raw serviceName string from the resource object\n * @returns true if the value is a valid serviceName, false otherwise\n *\n * @internal Exported for facilitator use.\n */\nexport function isValidServiceName(value: string | undefined): value is string {\n if (typeof value !== \"string\") return false;\n if (value.length === 0 || value.length > MAX_SERVICE_NAME_LEN) return false;\n if (UNICODE_CONTROL_REGEX.test(value)) return false;\n if (!PRINTABLE_ASCII_REGEX.test(value)) return false;\n return true;\n}\n\n/**\n * Sanitizes a tags array for the bazaar `resource.tags` field. Drops entries\n * that are not non-empty printable-ASCII strings of at most 32 characters,\n * then truncates to the first 5 valid entries. Returns undefined when no\n * entries survive (so the field can be omitted from the catalog).\n *\n * The ASCII restriction matches the `paymentidentifier.id` convention and\n * keeps `len()` semantics identical across TS / Python / Go.\n *\n * Mirrors `_sanitize_tags` (Python) and `sanitizeTags` (Go).\n * All three implementations must stay in sync.\n *\n * @param value - The raw tags value from the resource object (typed as unknown\n * because callers pass it directly from a parsed JSON payload)\n * @returns The sanitized tags array, or undefined if no entries survive\n *\n * @internal Exported for facilitator use.\n */\nexport function sanitizeTags(value: unknown): string[] | undefined {\n if (!Array.isArray(value)) return undefined;\n const out: string[] = [];\n // Case-insensitive dedup: keeps the first occurrence's casing.\n // Prevents catalog noise like [\"Weather\", \"weather\", \"WEATHER\"].\n const seen = new Set<string>();\n for (const entry of value) {\n if (typeof entry !== \"string\") continue;\n if (entry.length === 0 || entry.length > MAX_TAG_LEN) continue;\n if (UNICODE_CONTROL_REGEX.test(entry)) continue;\n if (!PRINTABLE_ASCII_REGEX.test(entry)) continue;\n const key = entry.toLowerCase();\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(entry);\n if (out.length === MAX_TAGS) break;\n }\n return out.length > 0 ? out : undefined;\n}\n\n/**\n * Checks whether an iconUrl value is structurally safe for the bazaar\n * `resource.iconUrl` field.\n *\n * Rules (see `specs/extensions/bazaar.md` \"Service Metadata on `resource`\"):\n * - String of length ≤ 2048\n * - No ASCII control characters\n * - Parses as an absolute http:// or https:// URL\n * - No userinfo (user@host)\n * - Host is IDN-normalized (UTS #46) before checks, so confusable\n * full-width / Unicode forms (e.g. `localhost`) collapse to their\n * ASCII canonical and get caught by the loopback check\n * - Host is not an IP literal (v4 or v6), not in the loopback set\n * (`localhost`, `localhost.localdomain`, `ip6-localhost`, `ip6-loopback`)\n * - Host is not a decimal IP encoding (e.g. `2130706433` → 127.0.0.1) or\n * hex literal (e.g. `0x7f000001`) — common SSRF bypass forms\n *\n * Percent-decoding is applied to the hostname before IDN normalization, and\n * IDN normalization runs before the IP / loopback checks (parallel to the\n * routeTemplate decoder).\n *\n * Mirrors `_is_valid_icon_url` (Python) and `isValidIconUrl` (Go).\n * All three implementations must stay in sync.\n *\n * @param value - The raw iconUrl string from the resource object\n * @returns true if the value is a structurally safe iconUrl, false otherwise\n *\n * @internal Exported for facilitator use.\n */\nexport function isValidIconUrl(value: string | undefined): value is string {\n if (typeof value !== \"string\") return false;\n if (value.length === 0 || value.length > MAX_ICON_URL_LEN) return false;\n if (CONTROL_CHAR_REGEX.test(value)) return false;\n let parsed: URL;\n try {\n parsed = new URL(value);\n } catch {\n return false;\n }\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") return false;\n if (parsed.username !== \"\" || parsed.password !== \"\") return false;\n // URL.hostname strips IPv6 brackets, so detect IPv6 from the bracketed host instead.\n if (parsed.host.startsWith(\"[\")) return false;\n let hostname: string;\n try {\n hostname = decodeURIComponent(parsed.hostname);\n } catch {\n return false;\n }\n // IDN/full-width normalization: e.g. \"localhost\" (full-width Latin)\n // → \"localhost\". Without this the loopback alias check would miss\n // confusable Unicode hostnames. domainToASCII applies the same WHATWG /\n // UTS #46 mapping that idna.Lookup.ToASCII (Go) and idna.encode (Python)\n // use; returns \"\" on failure.\n const asciiHost = domainToASCII(hostname);\n if (asciiHost === \"\") return false;\n hostname = asciiHost.toLowerCase();\n if (hostname === \"\") return false;\n if (LOOPBACK_HOSTNAMES.has(hostname)) return false;\n if (IPV4_REGEX.test(hostname)) return false;\n if (ALL_DIGITS_REGEX.test(hostname)) return false;\n if (HEX_LITERAL_REGEX.test(hostname)) return false;\n return true;\n}\n\n/**\n * Sanitized service metadata extracted from a `resource` object.\n */\nexport interface SanitizedResourceServiceMetadata {\n serviceName?: string;\n tags?: string[];\n iconUrl?: string;\n}\n\n/**\n * Applies the bazaar service-metadata validation rules to a `resource` object\n * and returns only the fields that survive. Missing or invalid fields are\n * dropped silently (soft-drop semantics — see spec).\n *\n * @param resource - The raw `resource` object from a PaymentRequired or\n * PaymentPayload, or undefined.\n * @returns An object containing only the valid serviceName / tags / iconUrl.\n *\n * @internal Exported for facilitator use.\n */\nexport function sanitizeResourceServiceMetadata(\n resource: ResourceInfo | undefined | null,\n): SanitizedResourceServiceMetadata {\n if (!resource) return {};\n const out: SanitizedResourceServiceMetadata = {};\n if (isValidServiceName(resource.serviceName)) {\n out.serviceName = resource.serviceName;\n }\n const tags = sanitizeTags(resource.tags);\n if (tags) {\n out.tags = tags;\n }\n if (isValidIconUrl(resource.iconUrl)) {\n out.iconUrl = resource.iconUrl;\n }\n return out;\n}\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\nconst VALID_QUERY_METHODS = new Set([\"GET\", \"HEAD\", \"DELETE\"]);\nconst VALID_BODY_METHODS = new Set([\"POST\", \"PUT\", \"PATCH\"]);\nconst VALID_METHODS = new Set([...VALID_QUERY_METHODS, ...VALID_BODY_METHODS]);\nconst VALID_BODY_TYPES = new Set([\"json\", \"form-data\", \"text\"]);\nconst VALID_MCP_TRANSPORTS = new Set([\"streamable-http\", \"sse\"]);\n\n/**\n * Validates a discovery extension against the Bazaar protocol specification.\n *\n * Unlike `validateDiscoveryExtension` which checks internal consistency (info vs schema),\n * this function enforces protocol-level invariants:\n * - `info.input.type` must be \"http\" or \"mcp\"\n * - HTTP: if `method` is present it must be GET/POST/PUT/PATCH/DELETE/HEAD\n * - HTTP body methods: `bodyType` must be \"json\" | \"form-data\" | \"text\"\n * - MCP: `toolName` (string) and `inputSchema` (object) are required\n * - MCP: if `transport` is present it must be \"streamable-http\" | \"sse\"\n *\n * Designed to be safe for pre-enrichment HTTP extensions where `method` may be absent.\n *\n * @param extension - The discovery extension to validate\n * @returns Validation result with spec-level errors\n */\nexport function validateDiscoveryExtensionSpec(\n extension: Record<string, unknown>,\n): ValidationResult {\n const errors: string[] = [];\n\n const info = extension.info;\n if (!info || typeof info !== \"object\") {\n return { valid: false, errors: [\"Missing or invalid 'info' field\"] };\n }\n\n const input = (info as Record<string, unknown>).input;\n if (!input || typeof input !== \"object\") {\n return { valid: false, errors: [\"Missing or invalid 'info.input' field\"] };\n }\n\n const inputObj = input as Record<string, unknown>;\n const inputType = inputObj.type;\n\n if (inputType !== \"http\" && inputType !== \"mcp\") {\n errors.push(`info.input.type must be \"http\" or \"mcp\", got \"${String(inputType)}\"`);\n return { valid: false, errors };\n }\n\n if (inputType === \"http\") {\n const method = inputObj.method;\n if (method !== undefined && !VALID_METHODS.has(method as string)) {\n errors.push(\n `info.input.method must be one of ${[...VALID_METHODS].join(\", \")}, got \"${String(method)}\"`,\n );\n }\n\n const bodyType = inputObj.bodyType;\n if (bodyType !== undefined) {\n if (!VALID_BODY_TYPES.has(bodyType as string)) {\n errors.push(\n `info.input.bodyType must be one of ${[...VALID_BODY_TYPES].join(\", \")}, got \"${String(bodyType)}\"`,\n );\n }\n if (method !== undefined && !VALID_BODY_METHODS.has(method as string)) {\n errors.push(\n `info.input.bodyType is set but method \"${String(method)}\" is not a body method (POST, PUT, PATCH)`,\n );\n }\n }\n }\n\n if (inputType === \"mcp\") {\n if (typeof inputObj.toolName !== \"string\" || inputObj.toolName.length === 0) {\n errors.push(\n \"info.input.toolName is required and must be a non-empty string for MCP extensions\",\n );\n }\n if (!inputObj.inputSchema || typeof inputObj.inputSchema !== \"object\") {\n errors.push(\"info.input.inputSchema is required and must be an object for MCP extensions\");\n }\n const transport = inputObj.transport;\n if (transport !== undefined && !VALID_MCP_TRANSPORTS.has(transport as string)) {\n errors.push(\n `info.input.transport must be one of ${[...VALID_MCP_TRANSPORTS].join(\", \")}, got \"${String(transport)}\"`,\n );\n }\n }\n\n return errors.length === 0 ? { valid: true } : { valid: false, errors };\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, discovery data, and catalog\n * extensions echo (v2: `paymentPayload.extensions`; v1: synthesized `extensions.bazaar`\n * from requirements outputSchema), 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 let routeTemplate: string | undefined;\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 // routeTemplate uses :param syntax (e.g. \"/users/:userId\", \"/weather/:country/:city\").\n // Must start with \"/\", must not contain \"..\" or \"://\".\n // Validate before use: the client controls this field in the payment payload.\n const rawExt = bazaarExtension as Record<string, unknown>;\n const rawTemplate =\n typeof rawExt.routeTemplate === \"string\" ? rawExt.routeTemplate : undefined;\n if (isValidRouteTemplate(rawTemplate)) {\n routeTemplate = rawTemplate;\n }\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 // If a routeTemplate is present (dynamic route), use it as the canonical path\n const canonicalUrl = routeTemplate\n ? `${url.origin}${routeTemplate}`\n : `${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 let serviceMetadata: SanitizedResourceServiceMetadata = {};\n\n if (paymentPayload.x402Version === 2) {\n description = paymentPayload.resource?.description;\n mimeType = paymentPayload.resource?.mimeType;\n // Service metadata only exists in v2; v1 had no equivalent.\n serviceMetadata = sanitizeResourceServiceMetadata(paymentPayload.resource);\n } else if (paymentPayload.x402Version === 1) {\n const requirementsV1 = paymentRequirements as PaymentRequirementsV1;\n description = requirementsV1.description;\n mimeType = requirementsV1.mimeType;\n }\n\n let extensions: Record<string, unknown> | undefined;\n if (paymentPayload.x402Version === 2) {\n extensions = paymentPayload.extensions;\n } else if (paymentPayload.x402Version === 1) {\n extensions = buildV1CatalogExtensions(paymentPayload.extensions, discoveryInfo);\n }\n\n const base = {\n resourceUrl: canonicalUrl,\n description,\n mimeType,\n ...serviceMetadata,\n x402Version: paymentPayload.x402Version,\n discoveryInfo,\n extensions,\n };\n\n if (discoveryInfo.input.type === \"mcp\") {\n // MCP routes are not parameterized; routeTemplate is not applicable.\n return { ...base, toolName: (discoveryInfo as McpDiscoveryInfo).input.toolName };\n }\n\n return { ...base, routeTemplate, 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 \"@bankofai/x402-core/types\";\nimport type { BodyMethods, QueryParamMethods } from \"@bankofai/x402-core/http\";\nimport type {\n DiscoveryExtension,\n DiscoveryInfo,\n QueryDiscoveryInfo,\n BodyDiscoveryInfo,\n} from \"../types\";\nimport { BAZAAR } 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/**\n * Builds a v2 bazaar extension from extracted v1 discovery info.\n *\n * V1 had no formal schema validation, so the synthesized schema is permissive.\n *\n * @param discoveryInfo - Discovery info extracted from v1 payment requirements\n * @returns A bazaar extension suitable for catalog echo\n */\nexport function buildBazaarExtensionFromDiscoveryInfo(\n discoveryInfo: DiscoveryInfo,\n): DiscoveryExtension {\n // V1 had no formal schema; use a permissive envelope for catalog echo only.\n return {\n info: discoveryInfo,\n schema: {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n properties: {\n input: { type: \"object\" },\n output: { type: \"object\" },\n },\n required: [\"input\"],\n },\n } as DiscoveryExtension;\n}\n\n/**\n * Normalizes v1 catalog extension payloads to v2 bazaar format.\n *\n * Preserves non-bazaar extensions from the payment payload. Replaces legacy\n * `outputSchema` entries with a synthesized `bazaar` extension.\n *\n * @param existingExtensions - Extension payloads from the v1 payment payload, if any\n * @param discoveryInfo - Discovery info extracted from v1 payment requirements\n * @returns Normalized extension payloads with a `bazaar` entry\n */\nexport function buildV1CatalogExtensions(\n existingExtensions: Record<string, unknown> | undefined,\n discoveryInfo: DiscoveryInfo,\n): Record<string, unknown> {\n if (existingExtensions?.[BAZAAR.key]) {\n return existingExtensions;\n }\n\n const extensions: Record<string, unknown> = existingExtensions ? { ...existingExtensions } : {};\n delete extensions.outputSchema;\n extensions[BAZAAR.key] = buildBazaarExtensionFromDiscoveryInfo(discoveryInfo);\n return extensions;\n}\n","/**\n * Shared startup-time validation utilities for bazaar extensions in route configs.\n *\n * Used by middleware packages (Express, Hono, Next) to validate bazaar extensions\n * at server startup without duplicating the iteration and warning logic.\n */\n\nimport type { RoutesConfig } from \"@bankofai/x402-core/server\";\nimport type { DiscoveryExtension } from \"./types\";\nimport { validateDiscoveryExtension, validateDiscoveryExtensionSpec } from \"./facilitator\";\n\nexport { checkIfBazaarNeeded } from \"@bankofai/x402-core/server\";\n\nconst HTTP_VERB_RE = /^(GET|POST|PUT|PATCH|DELETE|HEAD)\\b/i;\n\n/**\n * Inject a synthetic method into a pre-enrichment extension so the schema's\n * required:[\"method\"] check doesn't produce a false-positive warning at startup.\n * Priority: (1) route pattern verb (e.g. \"GET /api\"), (2) body vs query inference.\n * Returns the same object unchanged if method is already present.\n *\n * @param ext - The raw bazaar extension object\n * @param pattern - The route pattern key (e.g. \"GET /api\" or \"*\")\n * @returns The extension with a synthetic method injected into info.input if needed\n */\nfunction withSyntheticMethod(\n ext: Record<string, unknown>,\n pattern: string,\n): Record<string, unknown> {\n const info = ext.info as Record<string, unknown> | undefined;\n const input = info?.input as Record<string, unknown> | undefined;\n if (!input || (typeof input.method === \"string\" && input.method)) {\n return ext;\n }\n const verbMatch = pattern.match(HTTP_VERB_RE);\n const method = verbMatch\n ? verbMatch[1].toUpperCase()\n : input.body !== undefined || input.bodyType !== undefined\n ? \"POST\"\n : \"GET\";\n return { ...ext, info: { ...info, input: { ...input, method } } };\n}\n\n/**\n * Validate bazaar extensions on all routes using JSON-schema validation.\n * Emits console warnings for invalid extensions but does not throw.\n *\n * @param routes - Route configuration to scan for bazaar extensions\n */\nexport function validateBazaarRouteExtensions(routes: RoutesConfig): void {\n const entries: [string, { extensions?: Record<string, unknown> }][] =\n \"accepts\" in routes ? [[\"*\", routes]] : Object.entries(routes);\n\n for (const [pattern, config] of entries) {\n const bazaarExt = config.extensions?.[\"bazaar\"];\n if (!bazaarExt) continue;\n if (\n typeof bazaarExt === \"object\" &&\n bazaarExt !== null &&\n \"info\" in (bazaarExt as Record<string, unknown>) &&\n \"schema\" in (bazaarExt as Record<string, unknown>)\n ) {\n const specResult = validateDiscoveryExtensionSpec(bazaarExt as Record<string, unknown>);\n if (!specResult.valid) {\n console.warn(\n `x402: Route \"${pattern}\" has an invalid bazaar extension: ${specResult.errors?.join(\", \")}`,\n );\n continue;\n }\n const extForSchema = withSyntheticMethod(bazaarExt as Record<string, unknown>, pattern);\n const schemaResult = validateDiscoveryExtension(\n extForSchema as unknown as DiscoveryExtension,\n );\n if (!schemaResult.valid) {\n console.warn(\n `x402: Route \"${pattern}\" has an invalid bazaar extension: ${schemaResult.errors?.join(\", \")}`,\n );\n }\n } else {\n console.warn(\n `x402: Route \"${pattern}\" declares a bazaar extension but it is malformed ` +\n `(expected an object with \"info\" and \"schema\" fields)`,\n );\n }\n }\n}\n","/**\n * Client extensions for querying Bazaar discovery resources\n */\n\nimport { HTTPFacilitatorClient } from \"@bankofai/x402-core/http\";\nimport type { PaymentRequirements } from \"@bankofai/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 * Filter by payment recipient address.\n */\n payTo?: string;\n\n /**\n * Filter by payment scheme (e.g., \"exact\").\n */\n scheme?: string;\n\n /**\n * Filter by payment network (e.g., \"eip155:8453\").\n */\n network?: string;\n\n /**\n * Filter by extension key present on the discovered resource.\n */\n extensions?: 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 * Parameters for searching discovery resources.\n */\nexport interface SearchDiscoveryResourcesParams {\n /**\n * Natural-language search query.\n */\n query: string;\n\n /**\n * Filter by protocol type (e.g., \"http\", \"mcp\").\n */\n type?: string;\n\n /**\n * Filter by payment recipient address.\n */\n payTo?: string;\n\n /**\n * Filter by payment scheme (e.g., \"exact\").\n */\n scheme?: string;\n\n /**\n * Filter by payment network (e.g., \"eip155:8453\").\n */\n network?: string;\n\n /**\n * Filter by extension key present on the discovered resource.\n */\n extensions?: string;\n\n /**\n * Advisory maximum number of results. The server may return fewer or ignore this.\n */\n limit?: number;\n\n /**\n * Advisory continuation cursor from a previous response. The server may ignore this.\n */\n cursor?: string;\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 /** Human-readable description of the resource */\n description?: string;\n /** MIME type of the resource response */\n mimeType?: string;\n /** Human-readable name for the service hosting the resource */\n serviceName?: string;\n /** Short topical tags for discovery search */\n tags?: string[];\n /** Absolute http(s) URL to a service icon */\n iconUrl?: string;\n /** Extension payloads echoed from discovery (e.g. bazaar info/schema) */\n extensions?: 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 * Response from searching discovery resources.\n */\nexport interface SearchDiscoveryResourcesResponse {\n /** The x402 protocol version of this response */\n x402Version: number;\n /** The list of matching discovered resources */\n resources: DiscoveryResource[];\n /** Whether additional matches were truncated by facilitator */\n partialResults?: boolean;\n /** Optional pagination details when a paginated response is returned */\n pagination?: {\n /** Number of results in this page */\n limit: number;\n /** Continuation cursor for the next page; may be null */\n cursor: string | null;\n } | null;\n}\n\n/**\n * Bazaar client extension interface providing discovery query functionality.\n */\nexport interface BazaarClientExtension {\n bazaar: {\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 * Search x402 discovery resources from the bazaar using a natural-language query.\n *\n * Pagination is optional: facilitators may ignore `limit` and `cursor`, or include\n * `response.pagination` when pagination is used.\n *\n * @param params - Search parameters including the required query string\n * @returns A promise resolving to the search response\n */\n search(params: SearchDiscoveryResourcesParams): Promise<SearchDiscoveryResourcesResponse>;\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.bazaar.listResources({ type: \"http\" });\n *\n * // Search\n * const results = await client.extensions.bazaar.search({ query: \"weather APIs\" });\n *\n * // Chaining with other extensions\n * const client = withBazaar(withOtherExtension(new HTTPFacilitatorClient()));\n * await client.extensions.other.someMethod();\n * await client.extensions.bazaar.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 bazaar: {\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(\"bazaar\");\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?.payTo !== undefined) {\n queryParams.set(\"payTo\", params.payTo);\n }\n if (params?.scheme !== undefined) {\n queryParams.set(\"scheme\", params.scheme);\n }\n if (params?.network !== undefined) {\n queryParams.set(\"network\", params.network);\n }\n if (params?.extensions !== undefined) {\n queryParams.set(\"extensions\", params.extensions);\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 async search(\n params: SearchDiscoveryResourcesParams,\n ): Promise<SearchDiscoveryResourcesResponse> {\n let headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n\n const authHeaders = await client.createAuthHeaders(\"bazaar\");\n headers = { ...headers, ...authHeaders.headers };\n\n const queryParams = new URLSearchParams();\n queryParams.set(\"query\", params.query);\n if (params.type !== undefined) {\n queryParams.set(\"type\", params.type);\n }\n if (params.payTo !== undefined) {\n queryParams.set(\"payTo\", params.payTo);\n }\n if (params.scheme !== undefined) {\n queryParams.set(\"scheme\", params.scheme);\n }\n if (params.network !== undefined) {\n queryParams.set(\"network\", params.network);\n }\n if (params.extensions !== undefined) {\n queryParams.set(\"extensions\", params.extensions);\n }\n if (params.limit !== undefined) {\n queryParams.set(\"limit\", params.limit.toString());\n }\n if (params.cursor !== undefined) {\n queryParams.set(\"cursor\", params.cursor);\n }\n\n const endpoint = `${client.url}/discovery/search?${queryParams.toString()}`;\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 searchDiscoveryResources failed (${response.status}): ${errorText}`,\n );\n }\n\n return (await response.json()) as SearchDiscoveryResourcesResponse;\n },\n },\n } as WithExtensions<T, BazaarClientExtension>[\"extensions\"];\n\n return extended;\n}\n"],"mappings":"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","names":["extension","isBodyMethod"]}