x402scan-mcp 0.0.1 → 0.0.2
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.
- package/dist/index.js +85 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -438,6 +438,73 @@ import { randomBytes as randomBytes2 } from "crypto";
|
|
|
438
438
|
import { x402Client } from "@x402/core/client";
|
|
439
439
|
import { x402HTTPClient } from "@x402/core/http";
|
|
440
440
|
import { registerExactEvmScheme } from "@x402/evm/exact/client";
|
|
441
|
+
|
|
442
|
+
// src/x402/normalize.ts
|
|
443
|
+
function isV1Response(pr) {
|
|
444
|
+
if (!pr || typeof pr !== "object") return false;
|
|
445
|
+
const obj = pr;
|
|
446
|
+
if (obj.x402Version === 1) return true;
|
|
447
|
+
const accepts = obj.accepts;
|
|
448
|
+
if (Array.isArray(accepts) && accepts.length > 0) {
|
|
449
|
+
return "maxAmountRequired" in accepts[0];
|
|
450
|
+
}
|
|
451
|
+
return false;
|
|
452
|
+
}
|
|
453
|
+
function normalizeV1Requirement(req) {
|
|
454
|
+
if (!req.maxAmountRequired) {
|
|
455
|
+
throw new Error("v1 requirement missing maxAmountRequired field");
|
|
456
|
+
}
|
|
457
|
+
return {
|
|
458
|
+
scheme: req.scheme,
|
|
459
|
+
network: req.network,
|
|
460
|
+
amount: req.maxAmountRequired,
|
|
461
|
+
// Map to unified 'amount' field
|
|
462
|
+
asset: req.asset,
|
|
463
|
+
payTo: req.payTo,
|
|
464
|
+
maxTimeoutSeconds: req.maxTimeoutSeconds,
|
|
465
|
+
extra: req.extra,
|
|
466
|
+
// Preserve v1-specific embedded resource fields
|
|
467
|
+
resource: req.resource,
|
|
468
|
+
description: req.description,
|
|
469
|
+
mimeType: req.mimeType
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
function normalizeV2Requirement(req) {
|
|
473
|
+
if (!req.amount) {
|
|
474
|
+
throw new Error("v2 requirement missing amount field");
|
|
475
|
+
}
|
|
476
|
+
return {
|
|
477
|
+
scheme: req.scheme,
|
|
478
|
+
network: req.network,
|
|
479
|
+
amount: req.amount,
|
|
480
|
+
asset: req.asset,
|
|
481
|
+
payTo: req.payTo,
|
|
482
|
+
maxTimeoutSeconds: req.maxTimeoutSeconds,
|
|
483
|
+
extra: req.extra
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
function normalizePaymentRequired(pr) {
|
|
487
|
+
const version = pr.x402Version ?? 1;
|
|
488
|
+
if (isV1Response(pr)) {
|
|
489
|
+
const v1Pr = pr;
|
|
490
|
+
return {
|
|
491
|
+
x402Version: 1,
|
|
492
|
+
error: v1Pr.error,
|
|
493
|
+
accepts: v1Pr.accepts.map(normalizeV1Requirement)
|
|
494
|
+
};
|
|
495
|
+
} else {
|
|
496
|
+
const v2Pr = pr;
|
|
497
|
+
return {
|
|
498
|
+
x402Version: version,
|
|
499
|
+
error: v2Pr.error,
|
|
500
|
+
accepts: v2Pr.accepts.map(normalizeV2Requirement),
|
|
501
|
+
resource: v2Pr.resource,
|
|
502
|
+
extensions: v2Pr.extensions
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// src/x402/client.ts
|
|
441
508
|
function createX402Client(config) {
|
|
442
509
|
const { account, preferredNetwork } = config;
|
|
443
510
|
const coreClient = new x402Client(
|
|
@@ -502,6 +569,7 @@ async function makeX402Request(httpClient, url, options = {}) {
|
|
|
502
569
|
}
|
|
503
570
|
}
|
|
504
571
|
log.debug("Got 402 Payment Required, parsing requirements...");
|
|
572
|
+
let rawPaymentRequired;
|
|
505
573
|
let paymentRequired;
|
|
506
574
|
let responseBody;
|
|
507
575
|
try {
|
|
@@ -510,11 +578,12 @@ async function makeX402Request(httpClient, url, options = {}) {
|
|
|
510
578
|
} catch {
|
|
511
579
|
responseBody = void 0;
|
|
512
580
|
}
|
|
513
|
-
|
|
581
|
+
rawPaymentRequired = httpClient.getPaymentRequiredResponse(
|
|
514
582
|
(name) => firstResponse.headers.get(name),
|
|
515
583
|
responseBody
|
|
516
584
|
);
|
|
517
|
-
|
|
585
|
+
paymentRequired = normalizePaymentRequired(rawPaymentRequired);
|
|
586
|
+
logPaymentRequired(rawPaymentRequired);
|
|
518
587
|
} catch (err) {
|
|
519
588
|
return {
|
|
520
589
|
success: false,
|
|
@@ -532,7 +601,7 @@ async function makeX402Request(httpClient, url, options = {}) {
|
|
|
532
601
|
log.debug("Creating payment payload...");
|
|
533
602
|
let paymentPayload;
|
|
534
603
|
try {
|
|
535
|
-
paymentPayload = await httpClient.createPaymentPayload(
|
|
604
|
+
paymentPayload = await httpClient.createPaymentPayload(rawPaymentRequired);
|
|
536
605
|
log.debug(`Payment created for network: ${paymentPayload.accepted?.network}`);
|
|
537
606
|
} catch (err) {
|
|
538
607
|
return {
|
|
@@ -647,10 +716,11 @@ async function queryEndpoint(url, httpClient, options = {}) {
|
|
|
647
716
|
rawBody = void 0;
|
|
648
717
|
}
|
|
649
718
|
try {
|
|
650
|
-
const
|
|
719
|
+
const rawPaymentRequired = httpClient.getPaymentRequiredResponse(
|
|
651
720
|
(name) => response.headers.get(name),
|
|
652
721
|
rawBody
|
|
653
722
|
);
|
|
723
|
+
const paymentRequired = normalizePaymentRequired(rawPaymentRequired);
|
|
654
724
|
return {
|
|
655
725
|
success: true,
|
|
656
726
|
statusCode: 402,
|
|
@@ -757,12 +827,21 @@ import { z as z2 } from "zod";
|
|
|
757
827
|
var PaymentRequirementsSchema = z2.object({
|
|
758
828
|
scheme: z2.string(),
|
|
759
829
|
network: z2.string(),
|
|
760
|
-
amount: z2.string(),
|
|
830
|
+
amount: z2.string().optional(),
|
|
831
|
+
// v2 field name
|
|
832
|
+
maxAmountRequired: z2.string().optional(),
|
|
833
|
+
// v1 field name
|
|
761
834
|
asset: z2.string(),
|
|
762
835
|
payTo: z2.string(),
|
|
763
836
|
maxTimeoutSeconds: z2.number(),
|
|
764
837
|
extra: z2.record(z2.unknown()).optional()
|
|
765
|
-
})
|
|
838
|
+
}).refine((data) => data.amount || data.maxAmountRequired, {
|
|
839
|
+
message: "Either amount (v2) or maxAmountRequired (v1) must be provided"
|
|
840
|
+
}).transform((data) => ({
|
|
841
|
+
...data,
|
|
842
|
+
// Normalize to 'amount' internally
|
|
843
|
+
amount: data.amount ?? data.maxAmountRequired
|
|
844
|
+
}));
|
|
766
845
|
function registerValidatePaymentTool(server) {
|
|
767
846
|
server.tool(
|
|
768
847
|
"validate_payment",
|