@x402/extensions 2.2.0 → 2.3.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 (33) hide show
  1. package/README.md +322 -93
  2. package/dist/cjs/bazaar/index.d.ts +3 -562
  3. package/dist/cjs/bazaar/index.js +12 -0
  4. package/dist/cjs/bazaar/index.js.map +1 -1
  5. package/dist/cjs/index-DvDlinmy.d.ts +575 -0
  6. package/dist/cjs/index.d.ts +4 -1
  7. package/dist/cjs/index.js +1008 -2
  8. package/dist/cjs/index.js.map +1 -1
  9. package/dist/cjs/payment-identifier/index.d.ts +345 -0
  10. package/dist/cjs/payment-identifier/index.js +285 -0
  11. package/dist/cjs/payment-identifier/index.js.map +1 -0
  12. package/dist/cjs/sign-in-with-x/index.d.ts +1054 -1
  13. package/dist/cjs/sign-in-with-x/index.js +766 -0
  14. package/dist/cjs/sign-in-with-x/index.js.map +1 -1
  15. package/dist/esm/bazaar/index.d.mts +3 -562
  16. package/dist/esm/bazaar/index.mjs +1 -1
  17. package/dist/esm/chunk-73HCOE6N.mjs +233 -0
  18. package/dist/esm/chunk-73HCOE6N.mjs.map +1 -0
  19. package/dist/esm/{chunk-WB72GLC2.mjs → chunk-DFJ4ZQFO.mjs} +13 -1
  20. package/dist/esm/chunk-DFJ4ZQFO.mjs.map +1 -0
  21. package/dist/esm/chunk-E3F2XHTI.mjs +719 -0
  22. package/dist/esm/chunk-E3F2XHTI.mjs.map +1 -0
  23. package/dist/esm/index-DvDlinmy.d.mts +575 -0
  24. package/dist/esm/index.d.mts +4 -1
  25. package/dist/esm/index.mjs +102 -3
  26. package/dist/esm/payment-identifier/index.d.mts +345 -0
  27. package/dist/esm/payment-identifier/index.mjs +39 -0
  28. package/dist/esm/sign-in-with-x/index.d.mts +1054 -1
  29. package/dist/esm/sign-in-with-x/index.mjs +66 -1
  30. package/package.json +16 -2
  31. package/dist/esm/chunk-MKFJ5AA3.mjs +0 -1
  32. package/dist/esm/chunk-WB72GLC2.mjs.map +0 -1
  33. /package/dist/esm/{chunk-MKFJ5AA3.mjs.map → payment-identifier/index.mjs.map} +0 -0
@@ -0,0 +1,233 @@
1
+ // src/payment-identifier/types.ts
2
+ var PAYMENT_IDENTIFIER = "payment-identifier";
3
+ var PAYMENT_ID_MIN_LENGTH = 16;
4
+ var PAYMENT_ID_MAX_LENGTH = 128;
5
+ var PAYMENT_ID_PATTERN = /^[a-zA-Z0-9_-]+$/;
6
+
7
+ // src/payment-identifier/schema.ts
8
+ var paymentIdentifierSchema = {
9
+ $schema: "https://json-schema.org/draft/2020-12/schema",
10
+ type: "object",
11
+ properties: {
12
+ required: {
13
+ type: "boolean"
14
+ },
15
+ id: {
16
+ type: "string",
17
+ minLength: PAYMENT_ID_MIN_LENGTH,
18
+ maxLength: PAYMENT_ID_MAX_LENGTH,
19
+ pattern: "^[a-zA-Z0-9_-]+$"
20
+ }
21
+ },
22
+ required: ["required"]
23
+ };
24
+
25
+ // src/payment-identifier/utils.ts
26
+ function generatePaymentId(prefix = "pay_") {
27
+ const uuid = crypto.randomUUID().replace(/-/g, "");
28
+ return `${prefix}${uuid}`;
29
+ }
30
+ function isValidPaymentId(id) {
31
+ if (typeof id !== "string") {
32
+ return false;
33
+ }
34
+ if (id.length < PAYMENT_ID_MIN_LENGTH || id.length > PAYMENT_ID_MAX_LENGTH) {
35
+ return false;
36
+ }
37
+ return PAYMENT_ID_PATTERN.test(id);
38
+ }
39
+
40
+ // src/payment-identifier/validation.ts
41
+ import Ajv from "ajv/dist/2020.js";
42
+ function isPaymentIdentifierExtension(extension) {
43
+ if (!extension || typeof extension !== "object") {
44
+ return false;
45
+ }
46
+ const ext = extension;
47
+ if (!ext.info || typeof ext.info !== "object") {
48
+ return false;
49
+ }
50
+ const info = ext.info;
51
+ if (typeof info.required !== "boolean") {
52
+ return false;
53
+ }
54
+ return true;
55
+ }
56
+ function validatePaymentIdentifier(extension) {
57
+ if (!extension || typeof extension !== "object") {
58
+ return {
59
+ valid: false,
60
+ errors: ["Extension must be an object"]
61
+ };
62
+ }
63
+ const ext = extension;
64
+ if (!ext.info || typeof ext.info !== "object") {
65
+ return {
66
+ valid: false,
67
+ errors: ["Extension must have an 'info' property"]
68
+ };
69
+ }
70
+ const info = ext.info;
71
+ if (typeof info.required !== "boolean") {
72
+ return {
73
+ valid: false,
74
+ errors: ["Extension info must have a 'required' boolean property"]
75
+ };
76
+ }
77
+ if (info.id !== void 0 && typeof info.id !== "string") {
78
+ return {
79
+ valid: false,
80
+ errors: ["Extension info 'id' must be a string if provided"]
81
+ };
82
+ }
83
+ if (info.id !== void 0 && !isValidPaymentId(info.id)) {
84
+ return {
85
+ valid: false,
86
+ errors: [
87
+ `Invalid payment ID format. ID must be 16-128 characters and contain only alphanumeric characters, hyphens, and underscores.`
88
+ ]
89
+ };
90
+ }
91
+ if (ext.schema) {
92
+ try {
93
+ const ajv = new Ajv({ strict: false, allErrors: true });
94
+ const validate = ajv.compile(ext.schema);
95
+ const valid = validate(ext.info);
96
+ if (!valid && validate.errors) {
97
+ const errors = validate.errors?.map((err) => {
98
+ const path = err.instancePath || "(root)";
99
+ return `${path}: ${err.message}`;
100
+ }) || ["Unknown validation error"];
101
+ return { valid: false, errors };
102
+ }
103
+ } catch (error) {
104
+ return {
105
+ valid: false,
106
+ errors: [
107
+ `Schema validation failed: ${error instanceof Error ? error.message : String(error)}`
108
+ ]
109
+ };
110
+ }
111
+ }
112
+ return { valid: true };
113
+ }
114
+ function extractPaymentIdentifier(paymentPayload, validate = true) {
115
+ if (!paymentPayload.extensions) {
116
+ return null;
117
+ }
118
+ const extension = paymentPayload.extensions[PAYMENT_IDENTIFIER];
119
+ if (!extension || typeof extension !== "object") {
120
+ return null;
121
+ }
122
+ const ext = extension;
123
+ if (!ext.info || typeof ext.info !== "object") {
124
+ return null;
125
+ }
126
+ const info = ext.info;
127
+ if (typeof info.id !== "string") {
128
+ return null;
129
+ }
130
+ if (validate && !isValidPaymentId(info.id)) {
131
+ return null;
132
+ }
133
+ return info.id;
134
+ }
135
+ function extractAndValidatePaymentIdentifier(paymentPayload) {
136
+ if (!paymentPayload.extensions) {
137
+ return { id: null, validation: { valid: true } };
138
+ }
139
+ const extension = paymentPayload.extensions[PAYMENT_IDENTIFIER];
140
+ if (!extension) {
141
+ return { id: null, validation: { valid: true } };
142
+ }
143
+ const validation = validatePaymentIdentifier(extension);
144
+ if (!validation.valid) {
145
+ return { id: null, validation };
146
+ }
147
+ const ext = extension;
148
+ return { id: ext.info.id ?? null, validation: { valid: true } };
149
+ }
150
+ function hasPaymentIdentifier(paymentPayload) {
151
+ return !!(paymentPayload.extensions && paymentPayload.extensions[PAYMENT_IDENTIFIER]);
152
+ }
153
+ function isPaymentIdentifierRequired(extension) {
154
+ if (!extension || typeof extension !== "object") {
155
+ return false;
156
+ }
157
+ const ext = extension;
158
+ if (!ext.info || typeof ext.info !== "object") {
159
+ return false;
160
+ }
161
+ return ext.info.required === true;
162
+ }
163
+ function validatePaymentIdentifierRequirement(paymentPayload, serverRequired) {
164
+ if (!serverRequired) {
165
+ return { valid: true };
166
+ }
167
+ const id = extractPaymentIdentifier(paymentPayload, false);
168
+ if (!id) {
169
+ return {
170
+ valid: false,
171
+ errors: ["Server requires a payment identifier but none was provided"]
172
+ };
173
+ }
174
+ if (!isValidPaymentId(id)) {
175
+ return {
176
+ valid: false,
177
+ errors: [
178
+ `Invalid payment ID format. ID must be 16-128 characters and contain only alphanumeric characters, hyphens, and underscores.`
179
+ ]
180
+ };
181
+ }
182
+ return { valid: true };
183
+ }
184
+
185
+ // src/payment-identifier/client.ts
186
+ function appendPaymentIdentifierToExtensions(extensions, id) {
187
+ const extension = extensions[PAYMENT_IDENTIFIER];
188
+ if (!isPaymentIdentifierExtension(extension)) {
189
+ return extensions;
190
+ }
191
+ const paymentId = id ?? generatePaymentId();
192
+ if (!isValidPaymentId(paymentId)) {
193
+ throw new Error(
194
+ `Invalid payment ID: "${paymentId}". ID must be 16-128 characters and contain only alphanumeric characters, hyphens, and underscores.`
195
+ );
196
+ }
197
+ extension.info.id = paymentId;
198
+ return extensions;
199
+ }
200
+
201
+ // src/payment-identifier/resourceServer.ts
202
+ function declarePaymentIdentifierExtension(required = false) {
203
+ return {
204
+ info: { required },
205
+ schema: paymentIdentifierSchema
206
+ };
207
+ }
208
+ var paymentIdentifierResourceServerExtension = {
209
+ key: PAYMENT_IDENTIFIER
210
+ // No enrichment needed - the declaration is static
211
+ // Future hooks for idempotency could be added here if needed
212
+ };
213
+
214
+ export {
215
+ PAYMENT_IDENTIFIER,
216
+ PAYMENT_ID_MIN_LENGTH,
217
+ PAYMENT_ID_MAX_LENGTH,
218
+ PAYMENT_ID_PATTERN,
219
+ paymentIdentifierSchema,
220
+ generatePaymentId,
221
+ isValidPaymentId,
222
+ isPaymentIdentifierExtension,
223
+ validatePaymentIdentifier,
224
+ extractPaymentIdentifier,
225
+ extractAndValidatePaymentIdentifier,
226
+ hasPaymentIdentifier,
227
+ isPaymentIdentifierRequired,
228
+ validatePaymentIdentifierRequirement,
229
+ appendPaymentIdentifierToExtensions,
230
+ declarePaymentIdentifierExtension,
231
+ paymentIdentifierResourceServerExtension
232
+ };
233
+ //# sourceMappingURL=chunk-73HCOE6N.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../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"],"sourcesContent":["/**\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"],"mappings":"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","names":[]}
@@ -366,8 +366,20 @@ function extractDiscoveryInfo(paymentPayload, paymentRequirements, validate = tr
366
366
  }
367
367
  const url = new URL(resourceUrl);
368
368
  const normalizedResourceUrl = `${url.origin}${url.pathname}`;
369
+ let description;
370
+ let mimeType;
371
+ if (paymentPayload.x402Version === 2) {
372
+ description = paymentPayload.resource?.description;
373
+ mimeType = paymentPayload.resource?.mimeType;
374
+ } else if (paymentPayload.x402Version === 1) {
375
+ const requirementsV1 = paymentRequirements;
376
+ description = requirementsV1.description;
377
+ mimeType = requirementsV1.mimeType;
378
+ }
369
379
  return {
370
380
  resourceUrl: normalizedResourceUrl,
381
+ description,
382
+ mimeType,
371
383
  method: discoveryInfo.input.method,
372
384
  x402Version: paymentPayload.x402Version,
373
385
  discoveryInfo
@@ -453,4 +465,4 @@ export {
453
465
  validateAndExtract,
454
466
  withBazaar
455
467
  };
456
- //# sourceMappingURL=chunk-WB72GLC2.mjs.map
468
+ //# sourceMappingURL=chunk-DFJ4ZQFO.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/bazaar/types.ts","../../src/bazaar/resourceService.ts","../../src/bazaar/server.ts","../../src/bazaar/facilitator.ts","../../src/bazaar/v1/facilitator.ts","../../src/bazaar/facilitatorClient.ts"],"sourcesContent":["/**\n * Type definitions for the Bazaar Discovery Extension\n */\n\nimport type { BodyMethods, QueryParamMethods } from \"@x402/core/http\";\n\n/**\n * Extension identifier constant for the Bazaar discovery extension\n */\nexport const BAZAAR = \"bazaar\";\n\n/**\n * Discovery info for query parameter methods (GET, HEAD, DELETE)\n */\nexport interface QueryDiscoveryInfo {\n input: {\n type: \"http\";\n method: QueryParamMethods;\n queryParams?: Record<string, unknown>;\n headers?: Record<string, string>;\n };\n output?: {\n type?: string;\n format?: string;\n example?: unknown;\n };\n}\n\n/**\n * Discovery info for body methods (POST, PUT, PATCH)\n */\nexport interface BodyDiscoveryInfo {\n input: {\n type: \"http\";\n method: BodyMethods;\n bodyType: \"json\" | \"form-data\" | \"text\";\n body: Record<string, unknown>;\n queryParams?: Record<string, unknown>;\n headers?: Record<string, string>;\n };\n output?: {\n type?: string;\n format?: string;\n example?: unknown;\n };\n}\n\n/**\n * Combined discovery info type\n */\nexport type DiscoveryInfo = QueryDiscoveryInfo | BodyDiscoveryInfo;\n\n/**\n * Discovery extension for query parameter methods (GET, HEAD, DELETE)\n */\nexport interface QueryDiscoveryExtension {\n info: QueryDiscoveryInfo;\n\n schema: {\n $schema: \"https://json-schema.org/draft/2020-12/schema\";\n type: \"object\";\n properties: {\n input: {\n type: \"object\";\n properties: {\n type: {\n type: \"string\";\n const: \"http\";\n };\n method: {\n type: \"string\";\n enum: QueryParamMethods[];\n };\n queryParams?: {\n type: \"object\";\n properties?: Record<string, unknown>;\n required?: string[];\n additionalProperties?: boolean;\n };\n headers?: {\n type: \"object\";\n additionalProperties: {\n type: \"string\";\n };\n };\n };\n required: (\"type\" | \"method\")[];\n additionalProperties?: boolean;\n };\n output?: {\n type: \"object\";\n properties?: Record<string, unknown>;\n required?: readonly string[];\n additionalProperties?: boolean;\n };\n };\n required: [\"input\"];\n };\n}\n\n/**\n * Discovery extension for body methods (POST, PUT, PATCH)\n */\nexport interface BodyDiscoveryExtension {\n info: BodyDiscoveryInfo;\n\n schema: {\n $schema: \"https://json-schema.org/draft/2020-12/schema\";\n type: \"object\";\n properties: {\n input: {\n type: \"object\";\n properties: {\n type: {\n type: \"string\";\n const: \"http\";\n };\n method: {\n type: \"string\";\n enum: BodyMethods[];\n };\n bodyType: {\n type: \"string\";\n enum: [\"json\", \"form-data\", \"text\"];\n };\n body: Record<string, unknown>;\n queryParams?: {\n type: \"object\";\n properties?: Record<string, unknown>;\n required?: string[];\n additionalProperties?: boolean;\n };\n headers?: {\n type: \"object\";\n additionalProperties: {\n type: \"string\";\n };\n };\n };\n required: (\"type\" | \"method\" | \"bodyType\" | \"body\")[];\n additionalProperties?: boolean;\n };\n output?: {\n type: \"object\";\n properties?: Record<string, unknown>;\n required?: readonly string[];\n additionalProperties?: boolean;\n };\n };\n required: [\"input\"];\n };\n}\n\n/**\n * Combined discovery extension type\n */\nexport type DiscoveryExtension = QueryDiscoveryExtension | BodyDiscoveryExtension;\n\nexport interface DeclareQueryDiscoveryExtensionConfig {\n method?: QueryParamMethods;\n input?: Record<string, unknown>;\n inputSchema?: Record<string, unknown>;\n output?: {\n example?: unknown;\n schema?: Record<string, unknown>;\n };\n}\n\nexport interface DeclareBodyDiscoveryExtensionConfig {\n method?: BodyMethods;\n input?: Record<string, unknown>;\n inputSchema?: Record<string, unknown>;\n bodyType: \"json\" | \"form-data\" | \"text\";\n output?: {\n example?: unknown;\n schema?: Record<string, unknown>;\n };\n}\n\nexport type DeclareDiscoveryExtensionConfig =\n | DeclareQueryDiscoveryExtensionConfig\n | DeclareBodyDiscoveryExtensionConfig;\n\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.\n */\nexport type DeclareDiscoveryExtensionInput = DistributiveOmit<\n DeclareDiscoveryExtensionConfig,\n \"method\"\n>;\n\nexport const isQueryExtensionConfig = (\n config: DeclareDiscoveryExtensionConfig,\n): config is DeclareQueryDiscoveryExtensionConfig => {\n return !(\"bodyType\" in config);\n};\n\nexport const isBodyExtensionConfig = (\n config: DeclareDiscoveryExtensionConfig,\n): config is DeclareBodyDiscoveryExtensionConfig => {\n return \"bodyType\" in config;\n};\n","/**\n * Resource Service functions for creating Bazaar discovery extensions\n *\n * These functions help servers declare the shape of their endpoints\n * for facilitator discovery and cataloging in the Bazaar.\n */\n\nimport {\n type DiscoveryExtension,\n type QueryDiscoveryExtension,\n type BodyDiscoveryExtension,\n type DeclareDiscoveryExtensionInput,\n type DeclareQueryDiscoveryExtensionConfig,\n type DeclareBodyDiscoveryExtensionConfig,\n} from \"./types\";\n\n/**\n * Internal helper to create a query discovery extension\n *\n * @param root0 - Configuration object for query discovery extension\n * @param root0.method - HTTP method (GET, HEAD, DELETE)\n * @param root0.input - Query parameters\n * @param root0.inputSchema - JSON schema for query parameters\n * @param root0.output - Output specification with example\n * @returns QueryDiscoveryExtension with info and schema\n */\nfunction createQueryDiscoveryExtension({\n method,\n input = {},\n inputSchema = { properties: {} },\n output,\n}: DeclareQueryDiscoveryExtensionConfig): QueryDiscoveryExtension {\n return {\n info: {\n input: {\n type: \"http\",\n ...(method ? { method } : {}),\n ...(input ? { queryParams: input } : {}),\n } as QueryDiscoveryExtension[\"info\"][\"input\"],\n ...(output?.example\n ? {\n output: {\n type: \"json\",\n example: output.example,\n },\n }\n : {}),\n },\n schema: {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n properties: {\n input: {\n type: \"object\",\n properties: {\n type: {\n type: \"string\",\n const: \"http\",\n },\n method: {\n type: \"string\",\n enum: [\"GET\", \"HEAD\", \"DELETE\"],\n },\n ...(inputSchema\n ? {\n queryParams: {\n type: \"object\" as const,\n ...(typeof inputSchema === \"object\" ? inputSchema : {}),\n },\n }\n : {}),\n },\n required: [\"type\"] as (\"type\" | \"method\")[],\n additionalProperties: false,\n },\n ...(output?.example\n ? {\n output: {\n type: \"object\" as const,\n properties: {\n type: {\n type: \"string\" as const,\n },\n example: {\n type: \"object\" as const,\n ...(output.schema && typeof output.schema === \"object\" ? output.schema : {}),\n },\n },\n required: [\"type\"] as const,\n },\n }\n : {}),\n },\n required: [\"input\"],\n },\n };\n}\n\n/**\n * Internal helper to create a body discovery extension\n *\n * @param root0 - Configuration object for body discovery extension\n * @param root0.method - HTTP method (POST, PUT, PATCH)\n * @param root0.input - Request body specification\n * @param root0.inputSchema - JSON schema for request body\n * @param root0.bodyType - Content type of body (json, form-data, text) - required for body methods\n * @param root0.output - Output specification with example\n * @returns BodyDiscoveryExtension with info and schema\n */\nfunction createBodyDiscoveryExtension({\n method,\n input = {},\n inputSchema = { properties: {} },\n bodyType,\n output,\n}: DeclareBodyDiscoveryExtensionConfig): BodyDiscoveryExtension {\n return {\n info: {\n input: {\n type: \"http\",\n ...(method ? { method } : {}),\n bodyType,\n body: input,\n } as BodyDiscoveryExtension[\"info\"][\"input\"],\n ...(output?.example\n ? {\n output: {\n type: \"json\",\n example: output.example,\n },\n }\n : {}),\n },\n schema: {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n properties: {\n input: {\n type: \"object\",\n properties: {\n type: {\n type: \"string\",\n const: \"http\",\n },\n method: {\n type: \"string\",\n enum: [\"POST\", \"PUT\", \"PATCH\"],\n },\n bodyType: {\n type: \"string\",\n enum: [\"json\", \"form-data\", \"text\"],\n },\n body: inputSchema,\n },\n required: [\"type\", \"bodyType\", \"body\"] as (\"type\" | \"method\" | \"bodyType\" | \"body\")[],\n additionalProperties: false,\n },\n ...(output?.example\n ? {\n output: {\n type: \"object\" as const,\n properties: {\n type: {\n type: \"string\" as const,\n },\n example: {\n type: \"object\" as const,\n ...(output.schema && typeof output.schema === \"object\" ? output.schema : {}),\n },\n },\n required: [\"type\"] as const,\n },\n }\n : {}),\n },\n required: [\"input\"],\n },\n };\n}\n\n/**\n * Create a discovery extension for any HTTP method\n *\n * This function helps servers declare how their endpoint should be called,\n * including the expected input parameters/body and output format.\n *\n * @param config - Configuration object for the discovery extension\n * @returns A discovery extension object with both info and schema\n *\n * @example\n * ```typescript\n * // For a GET endpoint with no input\n * const getExtension = declareDiscoveryExtension({\n * method: \"GET\",\n * output: {\n * example: { message: \"Success\", timestamp: \"2024-01-01T00:00:00Z\" }\n * }\n * });\n *\n * // For a GET endpoint with query params\n * const getWithParams = declareDiscoveryExtension({\n * method: \"GET\",\n * input: { query: \"example\" },\n * inputSchema: {\n * properties: {\n * query: { type: \"string\" }\n * },\n * required: [\"query\"]\n * }\n * });\n *\n * // For a POST endpoint with JSON body\n * const postExtension = declareDiscoveryExtension({\n * method: \"POST\",\n * input: { name: \"John\", age: 30 },\n * inputSchema: {\n * properties: {\n * name: { type: \"string\" },\n * age: { type: \"number\" }\n * },\n * required: [\"name\"]\n * },\n * bodyType: \"json\",\n * output: {\n * example: { success: true, id: \"123\" }\n * }\n * });\n * ```\n */\nexport function declareDiscoveryExtension(\n config: DeclareDiscoveryExtensionInput,\n): Record<string, DiscoveryExtension> {\n const bodyType = (config as DeclareBodyDiscoveryExtensionConfig).bodyType;\n const isBodyMethod = bodyType !== undefined;\n\n const extension = isBodyMethod\n ? createBodyDiscoveryExtension(config as DeclareBodyDiscoveryExtensionConfig)\n : createQueryDiscoveryExtension(config as DeclareQueryDiscoveryExtensionConfig);\n\n return { bazaar: extension as DiscoveryExtension };\n}\n","import type { ResourceServerExtension } from \"@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,\n\n enrichDeclaration: (declaration, transportContext) => {\n if (!isHTTPRequestContext(transportContext)) {\n return declaration;\n }\n\n const extension = declaration as ExtensionDeclaration;\n const method = transportContext.method;\n\n // 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 { BAZAAR } from \"./types\";\nimport { extractDiscoveryInfoV1 } from \"./v1/facilitator\";\n\n/**\n * Validation result for discovery extensions\n */\nexport interface ValidationResult {\n valid: boolean;\n errors?: string[];\n}\n\n/**\n * Validates a discovery extension's info against its schema\n *\n * @param extension - The discovery extension containing info and schema\n * @returns Validation result indicating if the info matches the schema\n *\n * @example\n * ```typescript\n * const extension = declareDiscoveryExtension(...);\n * const result = validateDiscoveryExtension(extension);\n *\n * if (result.valid) {\n * console.log(\"Extension is valid\");\n * } else {\n * console.error(\"Validation errors:\", result.errors);\n * }\n * ```\n */\nexport function validateDiscoveryExtension(extension: DiscoveryExtension): ValidationResult {\n try {\n const ajv = new Ajv({ strict: false, allErrors: true });\n const validate = ajv.compile(extension.schema);\n\n // The schema describes the structure of info directly\n // Schema has properties: { input: {...}, output: {...} }\n // So we validate extension.info which has { input: {...}, output: {...} }\n const valid = validate(extension.info);\n\n if (valid) {\n return { valid: true };\n }\n\n const errors = validate.errors?.map(err => {\n const path = err.instancePath || \"(root)\";\n return `${path}: ${err.message}`;\n }) || [\"Unknown validation error\"];\n\n return { valid: false, errors };\n } catch (error) {\n return {\n valid: false,\n errors: [\n `Schema validation failed: ${error instanceof Error ? error.message : String(error)}`,\n ],\n };\n }\n}\n\n/**\n * Extracts the discovery info from payment payload and requirements\n *\n * This function handles both v2 (extensions) and v1 (outputSchema) formats.\n *\n * For v2: Discovery info is in PaymentPayload.extensions (client copied it from PaymentRequired)\n * For v1: Discovery info is in PaymentRequirements.outputSchema\n *\n * V1 data is automatically transformed to v2 DiscoveryInfo format, making smart\n * assumptions about field names (queryParams/query/params for GET, bodyFields/body/data for POST, etc.)\n *\n * @param paymentPayload - The payment payload containing extensions (v2) and version info\n * @param paymentRequirements - The payment requirements (contains outputSchema for v1)\n * @param validate - Whether to validate v2 extensions before extracting (default: true)\n * @returns The discovery info in v2 format if present, or null if not discoverable\n *\n * @example\n * ```typescript\n * // V2 - extensions are in PaymentPayload\n * const info = extractDiscoveryInfo(paymentPayload, paymentRequirements);\n *\n * // V1 - discovery info is in PaymentRequirements.outputSchema\n * const info = extractDiscoveryInfo(paymentPayloadV1, paymentRequirementsV1);\n *\n * if (info) {\n * // Both v1 and v2 return the same DiscoveryInfo structure\n * console.log(\"Method:\", info.input.method);\n * }\n * ```\n */\nexport interface DiscoveredResource {\n resourceUrl: string;\n description?: string;\n mimeType?: string;\n method: string;\n x402Version: number;\n discoveryInfo: DiscoveryInfo;\n}\n\n/**\n * Extracts discovery information from payment payload and requirements.\n * Combines resource URL, HTTP method, version, and discovery info into a single object.\n *\n * @param paymentPayload - The payment payload containing extensions and resource info\n * @param paymentRequirements - The payment requirements to validate against\n * @param validate - Whether to validate the discovery info against the schema (default: true)\n * @returns Discovered resource info with URL, method, version and discovery data, or null if not found\n */\nexport function extractDiscoveryInfo(\n paymentPayload: PaymentPayload,\n paymentRequirements: PaymentRequirements | PaymentRequirementsV1,\n validate: boolean = true,\n): DiscoveredResource | null {\n let discoveryInfo: DiscoveryInfo | null = null;\n let resourceUrl: string;\n\n if (paymentPayload.x402Version === 2) {\n resourceUrl = paymentPayload.resource?.url ?? \"\";\n\n if (paymentPayload.extensions) {\n const bazaarExtension = paymentPayload.extensions[BAZAAR];\n\n if (bazaarExtension && typeof bazaarExtension === \"object\") {\n try {\n const extension = bazaarExtension as DiscoveryExtension;\n\n if (validate) {\n const result = validateDiscoveryExtension(extension);\n if (!result.valid) {\n console.warn(\n `V2 discovery extension validation failed: ${result.errors?.join(\", \")}`,\n );\n } else {\n discoveryInfo = extension.info;\n }\n } else {\n discoveryInfo = extension.info;\n }\n } catch (error) {\n console.warn(`V2 discovery extension extraction failed: ${error}`);\n }\n }\n }\n } else if (paymentPayload.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 return {\n resourceUrl: normalizedResourceUrl,\n description,\n mimeType,\n method: discoveryInfo.input.method,\n x402Version: paymentPayload.x402Version,\n discoveryInfo,\n };\n}\n\n/**\n * Extracts discovery info from a v2 extension directly\n *\n * This is a lower-level function for when you already have the extension object.\n * For general use, prefer the main extractDiscoveryInfo function.\n *\n * @param extension - The discovery extension to extract info from\n * @param validate - Whether to validate before extracting (default: true)\n * @returns The discovery info if valid\n * @throws Error if validation fails and validate is true\n */\nexport function extractDiscoveryInfoFromExtension(\n extension: DiscoveryExtension,\n validate: boolean = true,\n): DiscoveryInfo {\n if (validate) {\n const result = validateDiscoveryExtension(extension);\n if (!result.valid) {\n throw new Error(\n `Invalid discovery extension: ${result.errors?.join(\", \") || \"Unknown error\"}`,\n );\n }\n }\n\n return extension.info;\n}\n\n/**\n * Validates and extracts discovery info in one step\n *\n * This is a convenience function that combines validation and extraction,\n * returning both the validation result and the info if valid.\n *\n * @param extension - The discovery extension to validate and extract\n * @returns Object containing validation result and info (if valid)\n *\n * @example\n * ```typescript\n * const extension = declareDiscoveryExtension(...);\n * const { valid, info, errors } = validateAndExtract(extension);\n *\n * if (valid && info) {\n * // Store info in Bazaar catalog\n * } else {\n * console.error(\"Validation errors:\", errors);\n * }\n * ```\n */\nexport function validateAndExtract(extension: DiscoveryExtension): {\n valid: boolean;\n info?: DiscoveryInfo;\n errors?: string[];\n} {\n const result = validateDiscoveryExtension(extension);\n\n if (result.valid) {\n return {\n valid: true,\n info: extension.info,\n };\n }\n\n return {\n valid: false,\n errors: result.errors,\n };\n}\n","/**\n * V1 Facilitator functions for extracting Bazaar discovery information\n *\n * In v1, discovery information is stored in the `outputSchema` field\n * of PaymentRequirements, which has a different structure than v2.\n *\n * This module transforms v1 data into v2 DiscoveryInfo format.\n */\n\nimport type { PaymentRequirementsV1 } from \"@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 * Currently, the only supported protocol type is \"http\".\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"],"mappings":"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","names":["isBodyMethod"]}