x402-surface-check 0.2.11 → 0.2.12

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 CHANGED
@@ -15,6 +15,7 @@ npx --yes x402-surface-check --endpoint --method POST https://x402.rpc.ankr.com/
15
15
  ## What It Checks
16
16
 
17
17
  - Manifest endpoint discovery from `items[]`, `endpoints[]`, `x402Endpoints`, category arrays, resource strings, and OpenAPI paths
18
+ - Linked discovery documents via `discovery_url`, `discoveryUrl`, `resources_url`, or `resourcesUrl`
18
19
  - No-payment HTTP 402 challenge shape
19
20
  - x402 v1 and v2 price fields, including `accepts[]` and `schemes[]` challenge arrays
20
21
  - MPP `WWW-Authenticate: Payment` and x402 V2 `WWW-Authenticate: X402 requirements=...` challenges
@@ -39,6 +40,7 @@ Recent public no-payment checks have found and verified real launch fixes:
39
40
  - Spraay: resource echo and browser payment-header behavior verified clean. https://github.com/solana-foundation/pay-skills/pull/60#issuecomment-4455519760
40
41
  - UZPROOF: schemes-style Solana x402 challenge and browser payment-header behavior verified clean. https://github.com/solana-foundation/pay-skills/pull/28#issuecomment-4455613892
41
42
  - HYRE Agent: OpenAPI-declared prices found 10x below live 402 challenge prices. https://github.com/solana-foundation/pay-skills/pull/19#issuecomment-4455641258
43
+ - anchor-x402: multi-rail x402 challenges verified, with browser preflight blockers isolated before merge. https://github.com/solana-foundation/pay-skills/pull/47#issuecomment-4455678163
42
44
  - Agent Trust Bench: live discovery URL and browser-compatibility notes for adversarial agent-payment resources. https://github.com/solana-foundation/pay-skills/pull/23#issuecomment-4455484414
43
45
 
44
46
  Field notes and browser version: https://tateprograms.com/x402-surface-check.html
@@ -132,6 +132,15 @@ function endpointUrl(rawPath, baseUrl, sourceUrl) {
132
132
  return new URL(value, base).toString()
133
133
  }
134
134
 
135
+ function linkedDiscoveryUrl(document, sourceUrl) {
136
+ const rawUrl = document?.discovery_url
137
+ ?? document?.discoveryUrl
138
+ ?? document?.resources_url
139
+ ?? document?.resourcesUrl
140
+ if (typeof rawUrl !== 'string' || !rawUrl.trim()) return ''
141
+ return endpointUrl(rawUrl, documentBaseUrl(document, sourceUrl), sourceUrl)
142
+ }
143
+
135
144
  function operationExpectedPrice(operation) {
136
145
  const price = operation?.['x-payment-info']?.price
137
146
  ?? operation?.['x-payment']?.price
@@ -620,6 +629,7 @@ function formatMarkdown(report) {
620
629
  return [
621
630
  '# x402 Public Surface Check',
622
631
  '',
632
+ ...(report.sourceDocument ? [`Source: ${report.sourceDocument.url}`] : []),
623
633
  `Document: ${report.document.url}`,
624
634
  `Checked: ${report.checkedAt}`,
625
635
  'Scope: manifest/OpenAPI parsing, no-payment endpoint probes, and browser-style CORS preflight. No payment headers or paid calls.',
@@ -656,7 +666,8 @@ function formatMarkdown(report) {
656
666
  }
657
667
 
658
668
  async function runCheck(options) {
659
- const document = options.endpoint
669
+ let sourceDocument = null
670
+ let document = options.endpoint
660
671
  ? {
661
672
  status: 200,
662
673
  ok: true,
@@ -665,9 +676,25 @@ async function runCheck(options) {
665
676
  body: { text: '{}', json: {} },
666
677
  }
667
678
  : await fetchDocument(options.url)
668
- const entries = options.endpoint
679
+ let entries = options.endpoint
669
680
  ? [{ name: new URL(options.url).pathname.split('/').filter(Boolean).at(-1) ?? options.url, url: options.url, method: options.method || 'POST' }]
670
681
  : (document.body.json ? endpointEntries(document.body.json, document.url, options.limit) : [])
682
+
683
+ if (!options.endpoint && entries.length === 0 && document.body.json) {
684
+ const discoveryUrl = linkedDiscoveryUrl(document.body.json, document.url)
685
+ if (discoveryUrl) {
686
+ const followedDocument = await fetchDocument(discoveryUrl)
687
+ const followedEntries = followedDocument.body.json
688
+ ? endpointEntries(followedDocument.body.json, followedDocument.url, options.limit)
689
+ : []
690
+ if (followedEntries.length > 0) {
691
+ sourceDocument = document
692
+ document = followedDocument
693
+ entries = followedEntries
694
+ }
695
+ }
696
+ }
697
+
671
698
  const origin = options.origin ?? new URL(document.url).origin
672
699
  const challenges = []
673
700
  const preflights = []
@@ -686,6 +713,7 @@ async function runCheck(options) {
686
713
  origin,
687
714
  challenges,
688
715
  preflights,
716
+ sourceDocument,
689
717
  }
690
718
  report.findings = findingList(document, challenges, preflights, entries)
691
719
  return report
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "x402-surface-check",
3
- "version": "0.2.11",
3
+ "version": "0.2.12",
4
4
  "description": "No-payment x402 public-surface checker for manifests, OpenAPI specs, and HTTP 402 challenges.",
5
5
  "type": "module",
6
6
  "bin": {