x402-surface-check 0.2.36 → 0.2.37
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/README.md +1 -0
- package/bin/x402-surface-check.mjs +28 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -30,6 +30,7 @@ npx --yes x402-surface-check --strict-proof https://api.example.com/openapi.json
|
|
|
30
30
|
- No-payment HTTP 402 challenge shape
|
|
31
31
|
- x402 v1 and v2 price fields, including `accepts[]` and `schemes[]` challenge arrays
|
|
32
32
|
- MPP `WWW-Authenticate: Payment` and x402 V2 `WWW-Authenticate: X402 requirements=...` challenges
|
|
33
|
+
- x402 challenges nested inside framework error wrappers such as FastAPI-style `{"detail": {...}}`
|
|
33
34
|
- MPP descriptor-only 402s that advertise discovery headers but do not return a machine-readable payment retry challenge
|
|
34
35
|
- Atomic-unit `amount` / `maxAmountRequired` fields, plus legacy decimal `amount` + `token` x402 v1 challenges
|
|
35
36
|
- `asset` or token metadata, `network`, and `payTo`
|
|
@@ -648,6 +648,29 @@ function parseX402Authenticate(value) {
|
|
|
648
648
|
}
|
|
649
649
|
}
|
|
650
650
|
|
|
651
|
+
function bodyChallengeJson(value) {
|
|
652
|
+
if (!value || typeof value !== 'object') return null
|
|
653
|
+
if (Array.isArray(value.accepts) || Array.isArray(value.schemes)) return value
|
|
654
|
+
|
|
655
|
+
const candidates = [
|
|
656
|
+
value.detail,
|
|
657
|
+
value.error,
|
|
658
|
+
value.payment,
|
|
659
|
+
value.paymentRequired,
|
|
660
|
+
value.payment_required,
|
|
661
|
+
value.challenge,
|
|
662
|
+
value.x402,
|
|
663
|
+
]
|
|
664
|
+
|
|
665
|
+
for (const candidate of candidates) {
|
|
666
|
+
if (!candidate || typeof candidate !== 'object') continue
|
|
667
|
+
const nested = bodyChallengeJson(candidate)
|
|
668
|
+
if (nested) return nested
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
return null
|
|
672
|
+
}
|
|
673
|
+
|
|
651
674
|
async function fetchDocument(url) {
|
|
652
675
|
const response = await fetch(url, {
|
|
653
676
|
headers: {
|
|
@@ -750,7 +773,11 @@ async function probeEndpoint(entry, origin) {
|
|
|
750
773
|
const authenticateChallenge = parsePaymentAuthenticate(response.headers.get('www-authenticate'))
|
|
751
774
|
?? parseX402Authenticate(response.headers.get('www-authenticate'))
|
|
752
775
|
|
|
753
|
-
const
|
|
776
|
+
const bodyChallenge = bodyChallengeJson(body.json)
|
|
777
|
+
const bodyHasChallenge = Boolean(bodyChallenge)
|
|
778
|
+
if (bodyChallenge && body.json !== bodyChallenge) {
|
|
779
|
+
body.json = bodyChallenge
|
|
780
|
+
}
|
|
754
781
|
if (!bodyHasChallenge) {
|
|
755
782
|
if (headerChallenge && typeof headerChallenge === 'object') {
|
|
756
783
|
body.json = headerChallenge
|