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