@x402/mcp 2.3.0-alpha

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.
@@ -0,0 +1,826 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ MCP_PAYMENT_META_KEY: () => MCP_PAYMENT_META_KEY,
24
+ MCP_PAYMENT_REQUIRED_CODE: () => MCP_PAYMENT_REQUIRED_CODE,
25
+ MCP_PAYMENT_RESPONSE_META_KEY: () => MCP_PAYMENT_RESPONSE_META_KEY,
26
+ attachPaymentResponseToMeta: () => attachPaymentResponseToMeta,
27
+ attachPaymentToMeta: () => attachPaymentToMeta,
28
+ createPaymentRequiredError: () => createPaymentRequiredError,
29
+ createPaymentWrapper: () => createPaymentWrapper,
30
+ createToolResourceUrl: () => createToolResourceUrl,
31
+ createx402MCPClient: () => createx402MCPClient,
32
+ extractPaymentFromMeta: () => extractPaymentFromMeta,
33
+ extractPaymentRequiredFromError: () => extractPaymentRequiredFromError,
34
+ extractPaymentResponseFromMeta: () => extractPaymentResponseFromMeta,
35
+ isPaymentRequiredError: () => isPaymentRequiredError,
36
+ wrapMCPClientWithPayment: () => wrapMCPClientWithPayment,
37
+ wrapMCPClientWithPaymentFromConfig: () => wrapMCPClientWithPaymentFromConfig,
38
+ x402Client: () => import_client4.x402Client,
39
+ x402MCPClient: () => x402MCPClient,
40
+ x402ResourceServer: () => import_server2.x402ResourceServer
41
+ });
42
+ module.exports = __toCommonJS(src_exports);
43
+
44
+ // src/client/x402MCPClient.ts
45
+ var import_schemas = require("@x402/core/schemas");
46
+ var import_client = require("@x402/core/client");
47
+ var import_client2 = require("@modelcontextprotocol/sdk/client/index.js");
48
+
49
+ // src/utils/encoding.ts
50
+ function isObject(value) {
51
+ return typeof value === "object" && value !== null;
52
+ }
53
+ function isPaymentPayloadStructure(value) {
54
+ if (!isObject(value)) {
55
+ return false;
56
+ }
57
+ return "x402Version" in value && "payload" in value;
58
+ }
59
+ function isSettleResponseStructure(value) {
60
+ if (!isObject(value)) {
61
+ return false;
62
+ }
63
+ return "success" in value;
64
+ }
65
+ function isPaymentRequiredStructure(value) {
66
+ if (!isObject(value)) {
67
+ return false;
68
+ }
69
+ return "x402Version" in value && "accepts" in value && Array.isArray(value.accepts);
70
+ }
71
+ function extractPaymentFromMeta(params) {
72
+ if (!(params == null ? void 0 : params._meta)) {
73
+ return null;
74
+ }
75
+ const payment = params._meta[MCP_PAYMENT_META_KEY];
76
+ if (!isPaymentPayloadStructure(payment)) {
77
+ return null;
78
+ }
79
+ return payment;
80
+ }
81
+ function attachPaymentToMeta(params, paymentPayload) {
82
+ return {
83
+ ...params,
84
+ _meta: {
85
+ [MCP_PAYMENT_META_KEY]: paymentPayload
86
+ }
87
+ };
88
+ }
89
+ function extractPaymentResponseFromMeta(result) {
90
+ if (!(result == null ? void 0 : result._meta)) {
91
+ return null;
92
+ }
93
+ const response = result._meta[MCP_PAYMENT_RESPONSE_META_KEY];
94
+ if (!isSettleResponseStructure(response)) {
95
+ return null;
96
+ }
97
+ return response;
98
+ }
99
+ function attachPaymentResponseToMeta(result, settleResponse) {
100
+ return {
101
+ ...result,
102
+ _meta: {
103
+ [MCP_PAYMENT_RESPONSE_META_KEY]: settleResponse
104
+ }
105
+ };
106
+ }
107
+ function createPaymentRequiredError(paymentRequired, message) {
108
+ return {
109
+ code: MCP_PAYMENT_REQUIRED_CODE,
110
+ message: message || "Payment required",
111
+ data: paymentRequired
112
+ };
113
+ }
114
+ function extractPaymentRequiredFromError(error) {
115
+ if (!isObject(error)) {
116
+ return null;
117
+ }
118
+ if (error.code !== MCP_PAYMENT_REQUIRED_CODE) {
119
+ return null;
120
+ }
121
+ const data = error.data;
122
+ if (!isPaymentRequiredStructure(data)) {
123
+ return null;
124
+ }
125
+ return data;
126
+ }
127
+ function createToolResourceUrl(toolName, customUrl) {
128
+ if (customUrl) {
129
+ return customUrl;
130
+ }
131
+ return `mcp://tool/${toolName}`;
132
+ }
133
+
134
+ // src/types/mcp.ts
135
+ var MCP_PAYMENT_REQUIRED_CODE = 402;
136
+ var MCP_PAYMENT_META_KEY = "x402/payment";
137
+ var MCP_PAYMENT_RESPONSE_META_KEY = "x402/payment-response";
138
+ function isPaymentRequiredError(error) {
139
+ if (!isObject(error)) {
140
+ return false;
141
+ }
142
+ if (error.code !== MCP_PAYMENT_REQUIRED_CODE || typeof error.message !== "string") {
143
+ return false;
144
+ }
145
+ if (!isObject(error.data)) {
146
+ return false;
147
+ }
148
+ return "x402Version" in error.data && "accepts" in error.data;
149
+ }
150
+
151
+ // src/client/x402MCPClient.ts
152
+ function isMCPTextContent(content) {
153
+ return content.type === "text" && typeof content.text === "string";
154
+ }
155
+ function isMCPCallToolResult(result) {
156
+ if (typeof result !== "object" || result === null) {
157
+ return false;
158
+ }
159
+ const obj = result;
160
+ return Array.isArray(obj.content);
161
+ }
162
+ var x402MCPClient = class {
163
+ /**
164
+ * Creates a new x402MCPClient instance.
165
+ *
166
+ * @param mcpClient - The underlying MCP client instance
167
+ * @param paymentClient - The x402 client for creating payment payloads
168
+ * @param options - Configuration options
169
+ */
170
+ constructor(mcpClient, paymentClient, options = {}) {
171
+ this.paymentRequiredHooks = [];
172
+ this.beforePaymentHooks = [];
173
+ this.afterPaymentHooks = [];
174
+ this.mcpClient = mcpClient;
175
+ this._paymentClient = paymentClient;
176
+ this.options = {
177
+ autoPayment: options.autoPayment ?? true,
178
+ onPaymentRequested: options.onPaymentRequested ?? (() => true)
179
+ };
180
+ }
181
+ /**
182
+ * Get the underlying MCP client instance.
183
+ *
184
+ * @returns The MCP client instance
185
+ */
186
+ get client() {
187
+ return this.mcpClient;
188
+ }
189
+ /**
190
+ * Get the underlying x402 payment client instance.
191
+ *
192
+ * @returns The x402 client instance
193
+ */
194
+ get paymentClient() {
195
+ return this._paymentClient;
196
+ }
197
+ /**
198
+ * Connect to an MCP server transport.
199
+ * Passthrough to the underlying MCP client.
200
+ *
201
+ * @param transport - The transport to connect to
202
+ * @returns Promise that resolves when connected
203
+ */
204
+ async connect(transport) {
205
+ await this.mcpClient.connect(transport);
206
+ }
207
+ /**
208
+ * Close the MCP connection.
209
+ * Passthrough to the underlying MCP client.
210
+ *
211
+ * @returns Promise that resolves when closed
212
+ */
213
+ async close() {
214
+ await this.mcpClient.close();
215
+ }
216
+ /**
217
+ * List available tools from the server.
218
+ * Passthrough to the underlying MCP client.
219
+ *
220
+ * @returns Promise resolving to the list of tools
221
+ */
222
+ async listTools() {
223
+ return this.mcpClient.listTools();
224
+ }
225
+ /**
226
+ * List available resources from the server.
227
+ * Passthrough to the underlying MCP client.
228
+ *
229
+ * @returns Promise resolving to the list of resources
230
+ */
231
+ async listResources() {
232
+ return this.mcpClient.listResources();
233
+ }
234
+ /**
235
+ * List available prompts from the server.
236
+ * Passthrough to the underlying MCP client.
237
+ *
238
+ * @returns Promise resolving to the list of prompts
239
+ */
240
+ async listPrompts() {
241
+ return this.mcpClient.listPrompts();
242
+ }
243
+ /**
244
+ * Get a specific prompt from the server.
245
+ * Passthrough to the underlying MCP client.
246
+ *
247
+ * @param args - Arguments for getPrompt method
248
+ * @returns Promise resolving to the prompt
249
+ */
250
+ async getPrompt(...args) {
251
+ return this.mcpClient.getPrompt(...args);
252
+ }
253
+ /**
254
+ * Read a resource from the server.
255
+ * Passthrough to the underlying MCP client.
256
+ *
257
+ * @param args - Arguments for readResource method
258
+ * @returns Promise resolving to the resource content
259
+ */
260
+ async readResource(...args) {
261
+ return this.mcpClient.readResource(...args);
262
+ }
263
+ /**
264
+ * List resource templates from the server.
265
+ * Passthrough to the underlying MCP client.
266
+ *
267
+ * @param args - Arguments for listResourceTemplates method
268
+ * @returns Promise resolving to the list of resource templates
269
+ */
270
+ async listResourceTemplates(...args) {
271
+ return this.mcpClient.listResourceTemplates(...args);
272
+ }
273
+ /**
274
+ * Subscribe to resource updates.
275
+ * Passthrough to the underlying MCP client.
276
+ *
277
+ * @param args - Arguments for subscribeResource method
278
+ * @returns Promise resolving when subscribed
279
+ */
280
+ async subscribeResource(...args) {
281
+ return this.mcpClient.subscribeResource(...args);
282
+ }
283
+ /**
284
+ * Unsubscribe from resource updates.
285
+ * Passthrough to the underlying MCP client.
286
+ *
287
+ * @param args - Arguments for unsubscribeResource method
288
+ * @returns Promise resolving when unsubscribed
289
+ */
290
+ async unsubscribeResource(...args) {
291
+ return this.mcpClient.unsubscribeResource(...args);
292
+ }
293
+ /**
294
+ * Ping the server.
295
+ * Passthrough to the underlying MCP client.
296
+ *
297
+ * @param args - Arguments for ping method
298
+ * @returns Promise resolving to ping response
299
+ */
300
+ async ping(...args) {
301
+ return this.mcpClient.ping(...args);
302
+ }
303
+ /**
304
+ * Request completion suggestions.
305
+ * Passthrough to the underlying MCP client.
306
+ *
307
+ * @param args - Arguments for complete method
308
+ * @returns Promise resolving to completion suggestions
309
+ */
310
+ async complete(...args) {
311
+ return this.mcpClient.complete(...args);
312
+ }
313
+ /**
314
+ * Set the logging level on the server.
315
+ * Passthrough to the underlying MCP client.
316
+ *
317
+ * @param args - Arguments for setLoggingLevel method
318
+ * @returns Promise resolving when level is set
319
+ */
320
+ async setLoggingLevel(...args) {
321
+ return this.mcpClient.setLoggingLevel(...args);
322
+ }
323
+ /**
324
+ * Get server capabilities after initialization.
325
+ * Passthrough to the underlying MCP client.
326
+ *
327
+ * @returns Server capabilities or undefined if not initialized
328
+ */
329
+ getServerCapabilities() {
330
+ return this.mcpClient.getServerCapabilities();
331
+ }
332
+ /**
333
+ * Get server version information after initialization.
334
+ * Passthrough to the underlying MCP client.
335
+ *
336
+ * @returns Server version info or undefined if not initialized
337
+ */
338
+ getServerVersion() {
339
+ return this.mcpClient.getServerVersion();
340
+ }
341
+ /**
342
+ * Get server instructions after initialization.
343
+ * Passthrough to the underlying MCP client.
344
+ *
345
+ * @returns Server instructions or undefined if not initialized
346
+ */
347
+ getInstructions() {
348
+ return this.mcpClient.getInstructions();
349
+ }
350
+ /**
351
+ * Send notification that roots list has changed.
352
+ * Passthrough to the underlying MCP client.
353
+ *
354
+ * @returns Promise resolving when notification is sent
355
+ */
356
+ async sendRootsListChanged() {
357
+ return this.mcpClient.sendRootsListChanged();
358
+ }
359
+ /**
360
+ * Register a hook to run when a 402 payment required is received.
361
+ * Hooks run in order; first to return a result wins.
362
+ *
363
+ * This can be used to:
364
+ * - Provide pre-existing payment payloads (implementation-specific, not part of x402 spec)
365
+ * - Abort the payment flow for certain tools
366
+ * - Log or track payment required events
367
+ *
368
+ * Note: Payment caching is an implementation pattern and not defined in the x402 MCP
369
+ * transport specification. Implementations that cache payments should ensure cached
370
+ * payloads are still valid (not expired, correct nonce, etc.).
371
+ *
372
+ * @param hook - Hook function
373
+ * @returns This instance for chaining
374
+ *
375
+ * @example
376
+ * ```typescript
377
+ * // Example: Custom payment handling (implementation-specific)
378
+ * client.onPaymentRequired(async ({ toolName, paymentRequired }) => {
379
+ * // Custom logic to provide a payment or abort
380
+ * if (shouldAbort(toolName)) {
381
+ * return { abort: true };
382
+ * }
383
+ * // Return undefined to proceed with normal payment flow
384
+ * });
385
+ * ```
386
+ */
387
+ onPaymentRequired(hook) {
388
+ this.paymentRequiredHooks.push(hook);
389
+ return this;
390
+ }
391
+ /**
392
+ * Register a hook to run before payment is created.
393
+ *
394
+ * @param hook - Hook function
395
+ * @returns This instance for chaining
396
+ */
397
+ onBeforePayment(hook) {
398
+ this.beforePaymentHooks.push(hook);
399
+ return this;
400
+ }
401
+ /**
402
+ * Register a hook to run after payment is submitted.
403
+ *
404
+ * @param hook - Hook function
405
+ * @returns This instance for chaining
406
+ */
407
+ onAfterPayment(hook) {
408
+ this.afterPaymentHooks.push(hook);
409
+ return this;
410
+ }
411
+ /**
412
+ * Calls a tool, automatically handling 402 payment required errors.
413
+ *
414
+ * If the tool returns a 402 error and autoPayment is enabled, this method
415
+ * will automatically create a payment payload and retry the tool call.
416
+ *
417
+ * @param name - The name of the tool to call
418
+ * @param args - Arguments to pass to the tool
419
+ * @param options - Optional MCP request options (timeout, signal, etc.)
420
+ * @param options.timeout - Request timeout in milliseconds (default: 60000)
421
+ * @param options.signal - AbortSignal for cancellation
422
+ * @param options.resetTimeoutOnProgress - If true, progress notifications reset the timeout
423
+ * @returns The tool result with payment metadata
424
+ * @throws Error if payment is required but autoPayment is disabled and no payment provided
425
+ * @throws Error if payment approval is denied
426
+ * @throws Error if payment creation fails
427
+ */
428
+ async callTool(name, args = {}, options) {
429
+ const result = await this.mcpClient.callTool({ name, arguments: args }, void 0, options);
430
+ if (!isMCPCallToolResult(result)) {
431
+ throw new Error("Invalid MCP tool result: missing content array");
432
+ }
433
+ const paymentRequired = this.extractPaymentRequiredFromResult(result);
434
+ if (!paymentRequired) {
435
+ return {
436
+ content: result.content,
437
+ isError: result.isError,
438
+ paymentMade: false
439
+ };
440
+ }
441
+ const paymentRequiredContext = {
442
+ toolName: name,
443
+ arguments: args,
444
+ paymentRequired
445
+ };
446
+ for (const hook of this.paymentRequiredHooks) {
447
+ const hookResult = await hook(paymentRequiredContext);
448
+ if (hookResult) {
449
+ if (hookResult.abort) {
450
+ throw new Error("Payment aborted by hook");
451
+ }
452
+ if (hookResult.payment) {
453
+ return this.callToolWithPayment(name, args, hookResult.payment, options);
454
+ }
455
+ }
456
+ }
457
+ if (!this.options.autoPayment) {
458
+ const err = new Error("Payment required");
459
+ err.code = MCP_PAYMENT_REQUIRED_CODE;
460
+ err.paymentRequired = paymentRequired;
461
+ throw err;
462
+ }
463
+ const paymentRequestedContext = {
464
+ toolName: name,
465
+ arguments: args,
466
+ paymentRequired
467
+ };
468
+ const approved = await this.options.onPaymentRequested(paymentRequestedContext);
469
+ if (!approved) {
470
+ throw new Error("Payment request denied");
471
+ }
472
+ for (const hook of this.beforePaymentHooks) {
473
+ await hook(paymentRequestedContext);
474
+ }
475
+ const paymentPayload = await this._paymentClient.createPaymentPayload(paymentRequired);
476
+ return this.callToolWithPayment(name, args, paymentPayload, options);
477
+ }
478
+ /**
479
+ * Calls a tool with an explicit payment payload.
480
+ *
481
+ * Use this method when you want to provide payment upfront or when
482
+ * implementing custom payment handling.
483
+ *
484
+ * @param name - The name of the tool to call
485
+ * @param args - Arguments to pass to the tool
486
+ * @param paymentPayload - The payment payload to include
487
+ * @param options - Optional MCP request options (timeout, signal, etc.)
488
+ * @param options.timeout - Request timeout in milliseconds (default: 60000)
489
+ * @param options.signal - AbortSignal for cancellation
490
+ * @param options.resetTimeoutOnProgress - If true, progress notifications reset the timeout
491
+ * @returns The tool result with payment metadata
492
+ */
493
+ async callToolWithPayment(name, args, paymentPayload, options) {
494
+ const callParams = {
495
+ name,
496
+ arguments: args,
497
+ _meta: {
498
+ [MCP_PAYMENT_META_KEY]: paymentPayload
499
+ }
500
+ };
501
+ const result = await this.mcpClient.callTool(callParams, void 0, options);
502
+ if (!isMCPCallToolResult(result)) {
503
+ throw new Error("Invalid MCP tool result: missing content array");
504
+ }
505
+ const resultWithMeta = {
506
+ content: result.content,
507
+ isError: result.isError,
508
+ _meta: result._meta
509
+ };
510
+ const paymentResponse = extractPaymentResponseFromMeta(resultWithMeta);
511
+ for (const hook of this.afterPaymentHooks) {
512
+ await hook({
513
+ toolName: name,
514
+ paymentPayload,
515
+ result: resultWithMeta,
516
+ settleResponse: paymentResponse
517
+ });
518
+ }
519
+ return {
520
+ content: result.content,
521
+ isError: result.isError,
522
+ paymentResponse: paymentResponse ?? void 0,
523
+ paymentMade: true
524
+ };
525
+ }
526
+ /**
527
+ * Probes a tool to discover its payment requirements.
528
+ *
529
+ * **WARNING: Side Effects** - This method actually calls the tool to trigger a 402 response.
530
+ * If the tool is free (no payment required), it will execute and return null.
531
+ * Use with caution on tools that have side effects or are expensive to run.
532
+ *
533
+ * Useful for displaying pricing information to users before calling paid tools.
534
+ *
535
+ * @param name - The name of the tool to probe
536
+ * @param args - Arguments that may affect pricing (for dynamic pricing scenarios)
537
+ * @returns The payment requirements if the tool requires payment, null if the tool is free
538
+ *
539
+ * @example
540
+ * ```typescript
541
+ * // Check if a tool requires payment before calling
542
+ * const requirements = await client.getToolPaymentRequirements("expensive_analysis");
543
+ *
544
+ * if (requirements) {
545
+ * const price = requirements.accepts[0];
546
+ * console.log(`This tool costs ${price.amount} on ${price.network}`);
547
+ * // Optionally show user and get confirmation before calling
548
+ * } else {
549
+ * console.log("This tool is free");
550
+ * // Note: the tool has already executed!
551
+ * }
552
+ * ```
553
+ */
554
+ async getToolPaymentRequirements(name, args = {}) {
555
+ const result = await this.mcpClient.callTool({ name, arguments: args });
556
+ if (!isMCPCallToolResult(result)) {
557
+ return null;
558
+ }
559
+ return this.extractPaymentRequiredFromResult(result);
560
+ }
561
+ // ============================================================================
562
+ // Private Methods
563
+ // ============================================================================
564
+ /**
565
+ * Extracts PaymentRequired from a tool result (structured 402 response).
566
+ *
567
+ * Per MCP transport spec, supports:
568
+ * 1. structuredContent with direct PaymentRequired object (optional, preferred)
569
+ * 2. content[0].text with JSON-encoded PaymentRequired object (required)
570
+ *
571
+ * @param result - The tool call result
572
+ * @returns PaymentRequired if this is a 402 response, null otherwise
573
+ */
574
+ extractPaymentRequiredFromResult(result) {
575
+ if (!result.isError) {
576
+ return null;
577
+ }
578
+ if (result.structuredContent) {
579
+ const extracted = this.extractPaymentRequiredFromObject(result.structuredContent);
580
+ if (extracted) {
581
+ return extracted;
582
+ }
583
+ }
584
+ const content = result.content;
585
+ if (content.length === 0) {
586
+ return null;
587
+ }
588
+ const firstItem = content[0];
589
+ if (!isMCPTextContent(firstItem)) {
590
+ return null;
591
+ }
592
+ try {
593
+ const parsed = JSON.parse(firstItem.text);
594
+ if (typeof parsed === "object" && parsed !== null) {
595
+ const extracted = this.extractPaymentRequiredFromObject(
596
+ parsed
597
+ );
598
+ if (extracted) {
599
+ return extracted;
600
+ }
601
+ }
602
+ } catch {
603
+ }
604
+ return null;
605
+ }
606
+ /**
607
+ * Extracts PaymentRequired from an object.
608
+ * Expects direct PaymentRequired format (per MCP transport spec).
609
+ *
610
+ * @param obj - The object to extract from
611
+ * @returns PaymentRequired if found, null otherwise
612
+ */
613
+ extractPaymentRequiredFromObject(obj) {
614
+ if ((0, import_schemas.isPaymentRequired)(obj)) {
615
+ return obj;
616
+ }
617
+ return null;
618
+ }
619
+ };
620
+ function wrapMCPClientWithPayment(mcpClient, paymentClient, options) {
621
+ return new x402MCPClient(mcpClient, paymentClient, options);
622
+ }
623
+ function wrapMCPClientWithPaymentFromConfig(mcpClient, config, options) {
624
+ const paymentClient = import_client.x402Client.fromConfig(config);
625
+ return new x402MCPClient(mcpClient, paymentClient, options);
626
+ }
627
+ function createx402MCPClient(config) {
628
+ const mcpClient = new import_client2.Client(
629
+ {
630
+ name: config.name,
631
+ version: config.version
632
+ },
633
+ config.mcpClientOptions
634
+ );
635
+ const paymentClient = new import_client.x402Client();
636
+ for (const scheme of config.schemes) {
637
+ if (scheme.x402Version === 1) {
638
+ paymentClient.registerV1(scheme.network, scheme.client);
639
+ } else {
640
+ paymentClient.register(scheme.network, scheme.client);
641
+ }
642
+ }
643
+ return new x402MCPClient(mcpClient, paymentClient, {
644
+ autoPayment: config.autoPayment,
645
+ onPaymentRequested: config.onPaymentRequested
646
+ });
647
+ }
648
+
649
+ // src/server/paymentWrapper.ts
650
+ function createPaymentWrapper(resourceServer, config) {
651
+ if (!config.accepts || config.accepts.length === 0) {
652
+ throw new Error("PaymentWrapperConfig.accepts must have at least one payment requirement");
653
+ }
654
+ return (handler) => {
655
+ return async (args, extra) => {
656
+ var _a, _b, _c, _d, _e;
657
+ const _meta = extra == null ? void 0 : extra._meta;
658
+ const toolName = ((_b = (_a = config.resource) == null ? void 0 : _a.url) == null ? void 0 : _b.replace("mcp://tool/", "")) || "paid_tool";
659
+ const context = {
660
+ toolName,
661
+ arguments: args,
662
+ meta: _meta
663
+ };
664
+ const paymentPayload = extractPaymentFromMeta({
665
+ name: toolName,
666
+ arguments: args,
667
+ _meta
668
+ });
669
+ const paymentRequirements = config.accepts[0];
670
+ if (!paymentPayload) {
671
+ return createPaymentRequiredResult(
672
+ resourceServer,
673
+ toolName,
674
+ config,
675
+ "Payment required to access this tool"
676
+ );
677
+ }
678
+ const verifyResult = await resourceServer.verifyPayment(paymentPayload, paymentRequirements);
679
+ if (!verifyResult.isValid) {
680
+ return createPaymentRequiredResult(
681
+ resourceServer,
682
+ toolName,
683
+ config,
684
+ verifyResult.invalidReason || "Payment verification failed"
685
+ );
686
+ }
687
+ const hookContext = {
688
+ toolName,
689
+ arguments: args,
690
+ paymentRequirements,
691
+ paymentPayload
692
+ };
693
+ if ((_c = config.hooks) == null ? void 0 : _c.onBeforeExecution) {
694
+ const hookResult = await config.hooks.onBeforeExecution(hookContext);
695
+ if (hookResult === false) {
696
+ return createPaymentRequiredResult(
697
+ resourceServer,
698
+ toolName,
699
+ config,
700
+ "Execution blocked by hook"
701
+ );
702
+ }
703
+ }
704
+ const result = await handler(args, context);
705
+ const afterExecContext = {
706
+ ...hookContext,
707
+ result
708
+ };
709
+ if ((_d = config.hooks) == null ? void 0 : _d.onAfterExecution) {
710
+ await config.hooks.onAfterExecution(afterExecContext);
711
+ }
712
+ if (result.isError) {
713
+ return result;
714
+ }
715
+ try {
716
+ const settleResult = await resourceServer.settlePayment(
717
+ paymentPayload,
718
+ paymentRequirements
719
+ );
720
+ if ((_e = config.hooks) == null ? void 0 : _e.onAfterSettlement) {
721
+ const settlementContext = {
722
+ ...hookContext,
723
+ settlement: settleResult
724
+ };
725
+ await config.hooks.onAfterSettlement(settlementContext);
726
+ }
727
+ return {
728
+ content: result.content,
729
+ isError: result.isError,
730
+ _meta: {
731
+ [MCP_PAYMENT_RESPONSE_META_KEY]: settleResult
732
+ }
733
+ };
734
+ } catch (settleError) {
735
+ return createSettlementFailedResult(
736
+ resourceServer,
737
+ toolName,
738
+ config,
739
+ settleError instanceof Error ? settleError.message : "Settlement failed"
740
+ );
741
+ }
742
+ };
743
+ };
744
+ }
745
+ async function createPaymentRequiredResult(resourceServer, toolName, config, errorMessage) {
746
+ var _a, _b, _c;
747
+ const resourceInfo = {
748
+ url: createToolResourceUrl(toolName, (_a = config.resource) == null ? void 0 : _a.url),
749
+ description: ((_b = config.resource) == null ? void 0 : _b.description) || `Tool: ${toolName}`,
750
+ mimeType: ((_c = config.resource) == null ? void 0 : _c.mimeType) || "application/json"
751
+ };
752
+ const paymentRequired = await resourceServer.createPaymentRequiredResponse(
753
+ config.accepts,
754
+ resourceInfo,
755
+ errorMessage
756
+ );
757
+ return {
758
+ structuredContent: paymentRequired,
759
+ content: [
760
+ {
761
+ type: "text",
762
+ text: JSON.stringify(paymentRequired)
763
+ }
764
+ ],
765
+ isError: true
766
+ };
767
+ }
768
+ async function createSettlementFailedResult(resourceServer, toolName, config, errorMessage) {
769
+ var _a, _b, _c;
770
+ const resourceInfo = {
771
+ url: createToolResourceUrl(toolName, (_a = config.resource) == null ? void 0 : _a.url),
772
+ description: ((_b = config.resource) == null ? void 0 : _b.description) || `Tool: ${toolName}`,
773
+ mimeType: ((_c = config.resource) == null ? void 0 : _c.mimeType) || "application/json"
774
+ };
775
+ const paymentRequired = await resourceServer.createPaymentRequiredResponse(
776
+ config.accepts,
777
+ resourceInfo,
778
+ `Payment settlement failed: ${errorMessage}`
779
+ );
780
+ const settlementFailure = {
781
+ success: false,
782
+ errorReason: errorMessage,
783
+ transaction: "",
784
+ network: config.accepts[0].network
785
+ };
786
+ const errorData = {
787
+ ...paymentRequired,
788
+ [MCP_PAYMENT_RESPONSE_META_KEY]: settlementFailure
789
+ };
790
+ return {
791
+ structuredContent: errorData,
792
+ content: [
793
+ {
794
+ type: "text",
795
+ text: JSON.stringify(errorData)
796
+ }
797
+ ],
798
+ isError: true
799
+ };
800
+ }
801
+
802
+ // src/index.ts
803
+ var import_client4 = require("@x402/core/client");
804
+ var import_server2 = require("@x402/core/server");
805
+ // Annotate the CommonJS export names for ESM import in node:
806
+ 0 && (module.exports = {
807
+ MCP_PAYMENT_META_KEY,
808
+ MCP_PAYMENT_REQUIRED_CODE,
809
+ MCP_PAYMENT_RESPONSE_META_KEY,
810
+ attachPaymentResponseToMeta,
811
+ attachPaymentToMeta,
812
+ createPaymentRequiredError,
813
+ createPaymentWrapper,
814
+ createToolResourceUrl,
815
+ createx402MCPClient,
816
+ extractPaymentFromMeta,
817
+ extractPaymentRequiredFromError,
818
+ extractPaymentResponseFromMeta,
819
+ isPaymentRequiredError,
820
+ wrapMCPClientWithPayment,
821
+ wrapMCPClientWithPaymentFromConfig,
822
+ x402Client,
823
+ x402MCPClient,
824
+ x402ResourceServer
825
+ });
826
+ //# sourceMappingURL=index.js.map