mppx 0.8.6 → 0.8.7
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/CHANGELOG.md +13 -0
- package/dist/cli/internal.js +2 -2
- package/dist/cli/internal.js.map +1 -1
- package/dist/cli/plugins/evm.d.ts +2 -0
- package/dist/cli/plugins/evm.d.ts.map +1 -0
- package/dist/cli/plugins/evm.js +51 -0
- package/dist/cli/plugins/evm.js.map +1 -0
- package/dist/cli/plugins/index.d.ts +1 -0
- package/dist/cli/plugins/index.d.ts.map +1 -1
- package/dist/cli/plugins/index.js +1 -0
- package/dist/cli/plugins/index.js.map +1 -1
- package/dist/cli/validate/challenge.d.ts +2 -0
- package/dist/cli/validate/challenge.d.ts.map +1 -1
- package/dist/cli/validate/challenge.js +184 -78
- package/dist/cli/validate/challenge.js.map +1 -1
- package/dist/cli/validate/discovery.d.ts +1 -0
- package/dist/cli/validate/discovery.d.ts.map +1 -1
- package/dist/cli/validate/discovery.js +99 -35
- package/dist/cli/validate/discovery.js.map +1 -1
- package/dist/cli/validate/helpers.d.ts +14 -1
- package/dist/cli/validate/helpers.d.ts.map +1 -1
- package/dist/cli/validate/helpers.js +0 -13
- package/dist/cli/validate/helpers.js.map +1 -1
- package/dist/cli/validate/index.d.ts +1 -0
- package/dist/cli/validate/index.d.ts.map +1 -1
- package/dist/cli/validate/index.js +98 -151
- package/dist/cli/validate/index.js.map +1 -1
- package/dist/cli/validate/payment.d.ts +1 -0
- package/dist/cli/validate/payment.d.ts.map +1 -1
- package/dist/cli/validate/payment.js +215 -144
- package/dist/cli/validate/payment.js.map +1 -1
- package/dist/evm/Chains.d.ts +4 -0
- package/dist/evm/Chains.d.ts.map +1 -1
- package/dist/evm/Chains.js +4 -0
- package/dist/evm/Chains.js.map +1 -1
- package/dist/internal/AcceptPayment.d.ts.map +1 -1
- package/dist/internal/AcceptPayment.js +7 -1
- package/dist/internal/AcceptPayment.js.map +1 -1
- package/dist/stripe/server/internal/html.gen.d.ts +1 -1
- package/dist/stripe/server/internal/html.gen.d.ts.map +1 -1
- package/dist/stripe/server/internal/html.gen.js +1 -1
- package/dist/stripe/server/internal/html.gen.js.map +1 -1
- package/dist/tempo/server/internal/html.gen.d.ts +1 -1
- package/dist/tempo/server/internal/html.gen.d.ts.map +1 -1
- package/dist/tempo/server/internal/html.gen.js +1 -1
- package/dist/tempo/server/internal/html.gen.js.map +1 -1
- package/dist/tempo/server/internal/request-body.d.ts.map +1 -1
- package/dist/tempo/server/internal/request-body.js +2 -0
- package/dist/tempo/server/internal/request-body.js.map +1 -1
- package/dist/tempo/session/server/ChannelStore.js +4 -4
- package/dist/tempo/session/server/ChannelStore.js.map +1 -1
- package/dist/tempo/session/server/CredentialVerification.d.ts +8 -0
- package/dist/tempo/session/server/CredentialVerification.d.ts.map +1 -1
- package/dist/tempo/session/server/CredentialVerification.js +21 -1
- package/dist/tempo/session/server/CredentialVerification.js.map +1 -1
- package/dist/tempo/session/server/Session.d.ts.map +1 -1
- package/dist/tempo/session/server/Session.js +1 -0
- package/dist/tempo/session/server/Session.js.map +1 -1
- package/dist/validation/core.d.ts +79 -0
- package/dist/validation/core.d.ts.map +1 -0
- package/dist/validation/core.js +256 -0
- package/dist/validation/core.js.map +1 -0
- package/dist/validation/index.d.ts +3 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +2 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/x402/Assets.d.ts +9 -0
- package/dist/x402/Assets.d.ts.map +1 -1
- package/dist/x402/Assets.js +38 -0
- package/dist/x402/Assets.js.map +1 -1
- package/package.json +9 -4
- package/src/cli/internal.ts +2 -2
- package/src/cli/plugins/evm.ts +55 -0
- package/src/cli/plugins/index.ts +1 -0
- package/src/cli/validate/challenge.ts +334 -121
- package/src/cli/validate/discovery.test.ts +307 -0
- package/src/cli/validate/discovery.ts +104 -38
- package/src/cli/validate/helpers.ts +15 -13
- package/src/cli/validate/index.ts +117 -240
- package/src/cli/validate/payment.ts +261 -178
- package/src/cli/validate.test.ts +143 -3
- package/src/client/internal/Fetch.test.ts +142 -2
- package/src/evm/Chains.ts +6 -0
- package/src/evm/PublicInterface.test-d.ts +7 -0
- package/src/internal/AcceptPayment.test.ts +45 -0
- package/src/internal/AcceptPayment.ts +11 -1
- package/src/stripe/server/internal/html/package.json +1 -1
- package/src/stripe/server/internal/html.gen.ts +1 -1
- package/src/tempo/server/internal/html/package.json +1 -1
- package/src/tempo/server/internal/html.gen.ts +1 -1
- package/src/tempo/server/internal/request-body.test.ts +9 -0
- package/src/tempo/server/internal/request-body.ts +2 -0
- package/src/tempo/session/server/ChannelStore.test.ts +17 -0
- package/src/tempo/session/server/ChannelStore.ts +4 -4
- package/src/tempo/session/server/CredentialVerification.test.ts +118 -1
- package/src/tempo/session/server/CredentialVerification.ts +30 -0
- package/src/tempo/session/server/Session.integration.test.ts +5 -0
- package/src/tempo/session/server/Session.test.ts +119 -53
- package/src/tempo/session/server/Session.ts +1 -0
- package/src/validation/core.ts +348 -0
- package/src/validation/index.ts +11 -0
- package/src/x402/Assets.test.ts +42 -0
- package/src/x402/Assets.ts +40 -0
- package/src/x402/Exact.localnet.test.ts +475 -0
|
@@ -1,25 +1,9 @@
|
|
|
1
1
|
import { Cli, z } from 'incur'
|
|
2
2
|
|
|
3
|
-
import { validate as
|
|
3
|
+
import { validate as validateCore, validateStream } from '../../validation/core.js'
|
|
4
4
|
import { pc } from '../utils.js'
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
extractEndpointsFromDiscovery,
|
|
8
|
-
extractRequestBodyFromDiscovery,
|
|
9
|
-
fetchDiscoveryDoc,
|
|
10
|
-
} from './discovery.js'
|
|
11
|
-
import {
|
|
12
|
-
check,
|
|
13
|
-
fail,
|
|
14
|
-
parseEndpointArg,
|
|
15
|
-
printCheck,
|
|
16
|
-
printResults,
|
|
17
|
-
printSection,
|
|
18
|
-
resolveBodyForEndpoint,
|
|
19
|
-
warn,
|
|
20
|
-
} from './helpers.js'
|
|
21
|
-
import type { Counts, EndpointSpec } from './helpers.js'
|
|
22
|
-
import { validatePaymentFlow } from './payment.js'
|
|
5
|
+
import type { Counts } from './helpers.js'
|
|
6
|
+
import { printResults, printSection } from './helpers.js'
|
|
23
7
|
|
|
24
8
|
const validate = Cli.create('validate', {
|
|
25
9
|
description: 'Validate an MPP server implementation end-to-end',
|
|
@@ -37,260 +21,155 @@ const validate = Cli.create('validate', {
|
|
|
37
21
|
query: z.array(z.string()).optional().describe('Query parameter (key=value, repeatable)'),
|
|
38
22
|
verbose: z.number().default(0).meta({ count: true }).describe('Verbosity level'),
|
|
39
23
|
yes: z.boolean().default(false).describe('Auto-approve mainnet payments'),
|
|
24
|
+
outputJson: z.boolean().default(false).describe('Output results as JSON'),
|
|
40
25
|
}),
|
|
41
26
|
alias: {
|
|
42
27
|
endpoint: 'e',
|
|
43
28
|
verbose: 'v',
|
|
44
29
|
yes: 'y',
|
|
30
|
+
outputJson: 'j',
|
|
45
31
|
},
|
|
46
32
|
async run(c) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
33
|
+
// JSON mode: batch everything
|
|
34
|
+
if (c.options.outputJson) {
|
|
35
|
+
const result = await validateCore({
|
|
36
|
+
url: c.args.url,
|
|
37
|
+
endpoint: c.options.endpoint,
|
|
38
|
+
body: c.options.body,
|
|
39
|
+
query: c.options.query,
|
|
40
|
+
verbose: c.options.verbose > 0,
|
|
41
|
+
yes: c.options.yes,
|
|
42
|
+
})
|
|
43
|
+
console.log(JSON.stringify(result, null, 2))
|
|
44
|
+
const noEndpoints = result.endpoints.length === 0 && !c.options.endpoint
|
|
45
|
+
if (result.summary.failed > 0 || !result.discovery.found || noEndpoints) process.exit(1)
|
|
46
|
+
return
|
|
47
|
+
}
|
|
50
48
|
|
|
49
|
+
// Streaming human-readable output
|
|
50
|
+
const baseUrl = c.args.url.replace(/\/$/, '').replace(/\/openapi\.json$/i, '')
|
|
51
51
|
console.log(`\n${pc.bold('mppx validate')} ${pc.dim(baseUrl)}\n`)
|
|
52
52
|
|
|
53
|
-
const {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
53
|
+
const counts: Counts = { passed: 0, failed: 0, warnings: 0, skipped: 0 }
|
|
54
|
+
let sawMppEndpoint = false
|
|
55
|
+
let sawNonMppPaymentEndpoint = false
|
|
56
|
+
let sawMalformedChallenge = false
|
|
57
|
+
let sawTestnet = false
|
|
58
|
+
let sawMainnet = false
|
|
59
|
+
let paymentSucceeded = false
|
|
60
|
+
let discoveryFound = false
|
|
61
|
+
let endpointCount = 0
|
|
62
|
+
|
|
63
|
+
for await (const event of validateStream({
|
|
64
|
+
url: c.args.url,
|
|
61
65
|
endpoint: c.options.endpoint,
|
|
62
66
|
body: c.options.body,
|
|
63
67
|
query: c.options.query,
|
|
68
|
+
verbose: c.options.verbose > 0,
|
|
64
69
|
yes: c.options.yes,
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
return { endpoints, discoveryDoc, shouldExit: true }
|
|
117
|
-
}
|
|
118
|
-
} else {
|
|
119
|
-
printCheck(check('Document found and parseable'))
|
|
120
|
-
counts.passed++
|
|
121
|
-
|
|
122
|
-
const issues = validateDiscovery(discoveryResult.doc)
|
|
123
|
-
const errors = issues.filter((i) => i.severity === 'error')
|
|
124
|
-
const warnings = issues.filter((i) => i.severity === 'warning')
|
|
125
|
-
|
|
126
|
-
if (errors.length > 0) {
|
|
127
|
-
printCheck(fail('Valid OpenAPI structure', `${errors.length} error(s)`))
|
|
128
|
-
counts.failed++
|
|
129
|
-
for (const issue of errors) {
|
|
130
|
-
console.log(pc.dim(` ${issue.path}: ${issue.message}`))
|
|
70
|
+
onPaymentResults: (results) => printResults(results, counts),
|
|
71
|
+
})) {
|
|
72
|
+
switch (event.phase) {
|
|
73
|
+
case 'discovery':
|
|
74
|
+
printSection('Discovery (/openapi.json)')
|
|
75
|
+
printResults(event.results, counts)
|
|
76
|
+
discoveryFound = event.discovery.found
|
|
77
|
+
if (!discoveryFound && !c.options.endpoint) {
|
|
78
|
+
console.log('')
|
|
79
|
+
console.log(pc.yellow(' No discovery document found.'))
|
|
80
|
+
console.log(
|
|
81
|
+
pc.dim(
|
|
82
|
+
' MPP servers must serve an OpenAPI document at /openapi.json with x-payment-info extensions.',
|
|
83
|
+
),
|
|
84
|
+
)
|
|
85
|
+
console.log(
|
|
86
|
+
pc.dim(
|
|
87
|
+
' To test a specific endpoint: mppx validate <url> --endpoint POST:/your/path',
|
|
88
|
+
),
|
|
89
|
+
)
|
|
90
|
+
console.log('')
|
|
91
|
+
process.exit(1)
|
|
92
|
+
}
|
|
93
|
+
if (event.discovery.endpoints.length === 0 && !c.options.endpoint && discoveryFound) {
|
|
94
|
+
console.log(pc.dim(' Use --endpoint to specify endpoints manually.'))
|
|
95
|
+
console.log('')
|
|
96
|
+
process.exit(1)
|
|
97
|
+
}
|
|
98
|
+
break
|
|
99
|
+
case 'endpoint':
|
|
100
|
+
endpointCount++
|
|
101
|
+
printSection(`${event.endpoint.method} ${event.endpoint.path}`)
|
|
102
|
+
break
|
|
103
|
+
case 'challenge':
|
|
104
|
+
console.log(pc.dim(' Challenge'))
|
|
105
|
+
printResults(event.results, counts)
|
|
106
|
+
if (event.isMpp) {
|
|
107
|
+
sawMppEndpoint = true
|
|
108
|
+
if (event.isTestnet) sawTestnet = true
|
|
109
|
+
else sawMainnet = true
|
|
110
|
+
}
|
|
111
|
+
if (event.isNonMppPayment) sawNonMppPaymentEndpoint = true
|
|
112
|
+
if (event.isMalformedChallenge) sawMalformedChallenge = true
|
|
113
|
+
break
|
|
114
|
+
case 'errorHandling':
|
|
115
|
+
console.log(pc.dim(' Error Handling'))
|
|
116
|
+
printResults(event.results, counts)
|
|
117
|
+
break
|
|
118
|
+
case 'payment':
|
|
119
|
+
if (event.succeeded) paymentSucceeded = true
|
|
120
|
+
break
|
|
131
121
|
}
|
|
132
|
-
} else {
|
|
133
|
-
printCheck(check('Valid OpenAPI structure'))
|
|
134
|
-
counts.passed++
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
for (const w of warnings) {
|
|
138
|
-
printCheck(warn(w.message, w.path))
|
|
139
|
-
counts.warnings++
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
discoveryDoc = discoveryResult.doc as Record<string, unknown>
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// Resolve endpoints: --endpoint overrides discovery
|
|
146
|
-
if (options.endpoint) {
|
|
147
|
-
const parsed = parseEndpointArg(options.endpoint)
|
|
148
|
-
if (!parsed) {
|
|
149
|
-
console.log(
|
|
150
|
-
pc.red(
|
|
151
|
-
`Invalid endpoint format: "${options.endpoint}". Use METHOD:path (e.g. GET:/api/data)`,
|
|
152
|
-
),
|
|
153
|
-
)
|
|
154
|
-
return { endpoints, discoveryDoc, shouldExit: true }
|
|
155
122
|
}
|
|
156
|
-
endpoints.push(parsed)
|
|
157
|
-
} else if (discoveryDoc) {
|
|
158
|
-
endpoints = extractEndpointsFromDiscovery(discoveryDoc)
|
|
159
123
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
const bAmt = b.amount ? BigInt(b.amount) : NO_AMOUNT
|
|
164
|
-
return aAmt < bAmt ? -1 : aAmt > bAmt ? 1 : 0
|
|
165
|
-
})
|
|
166
|
-
|
|
167
|
-
if (endpoints.length === 0) {
|
|
168
|
-
printCheck(warn('Paid endpoints found', 'No endpoints with x-payment-info'))
|
|
169
|
-
counts.warnings++
|
|
170
|
-
console.log(pc.dim(' Use --endpoint to specify endpoints manually.'))
|
|
171
|
-
return { endpoints, discoveryDoc, shouldExit: true }
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
printCheck(check('Paid endpoints found', `${endpoints.length} endpoint(s)`))
|
|
175
|
-
counts.passed++
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
return { endpoints, discoveryDoc }
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
async function validateEndpoints(
|
|
182
|
-
baseUrl: string,
|
|
183
|
-
endpoints: EndpointSpec[],
|
|
184
|
-
discoveryDoc: Record<string, unknown> | null,
|
|
185
|
-
counts: Counts,
|
|
186
|
-
options: {
|
|
187
|
-
verbose: boolean
|
|
188
|
-
endpoint?: string | undefined
|
|
189
|
-
body?: string | undefined
|
|
190
|
-
query?: string[] | undefined
|
|
191
|
-
yes: boolean
|
|
192
|
-
},
|
|
193
|
-
): Promise<{
|
|
194
|
-
sawMppEndpoint: boolean
|
|
195
|
-
sawNonMppPaymentEndpoint: boolean
|
|
196
|
-
sawTestnet: boolean
|
|
197
|
-
sawMainnet: boolean
|
|
198
|
-
paymentSucceeded: boolean
|
|
199
|
-
}> {
|
|
200
|
-
let sawTestnet = false
|
|
201
|
-
let sawMainnet = false
|
|
202
|
-
let paymentSucceeded = false
|
|
203
|
-
let sawMppEndpoint = false
|
|
204
|
-
let sawNonMppPaymentEndpoint = false
|
|
205
|
-
|
|
206
|
-
for (const endpoint of endpoints) {
|
|
207
|
-
printSection(`${endpoint.method} ${endpoint.path}`)
|
|
208
|
-
|
|
209
|
-
// With --endpoint, --body is used directly. In discovery mode, resolve per-path or auto-generate.
|
|
210
|
-
let body: string | undefined
|
|
211
|
-
if (options.endpoint) {
|
|
212
|
-
body = options.body
|
|
213
|
-
} else {
|
|
214
|
-
body = resolveBodyForEndpoint(options.body, endpoint.path)
|
|
215
|
-
if (!body && discoveryDoc) {
|
|
216
|
-
body = extractRequestBodyFromDiscovery(discoveryDoc, endpoint)
|
|
217
|
-
if (body && options.verbose) {
|
|
218
|
-
console.log(pc.dim(` Auto-generated body: ${body}`))
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// Challenge
|
|
224
|
-
console.log(pc.dim(' Challenge'))
|
|
225
|
-
const { results: challengeResults, resolvedBody } = await validateChallenge(
|
|
226
|
-
baseUrl,
|
|
227
|
-
endpoint,
|
|
228
|
-
options.verbose,
|
|
124
|
+
// Summary
|
|
125
|
+
printSummary(
|
|
126
|
+
counts,
|
|
229
127
|
{
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
128
|
+
sawMppEndpoint,
|
|
129
|
+
sawNonMppPaymentEndpoint,
|
|
130
|
+
sawMalformedChallenge,
|
|
131
|
+
sawTestnet,
|
|
132
|
+
sawMainnet,
|
|
133
|
+
paymentSucceeded,
|
|
233
134
|
},
|
|
135
|
+
endpointCount,
|
|
234
136
|
)
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
const isMppEndpoint = challengeResults.some(
|
|
239
|
-
(r) => r.severity === 'pass' && r.label === 'Challenge parseable',
|
|
240
|
-
)
|
|
241
|
-
if (!isMppEndpoint) {
|
|
242
|
-
if (challengeResults.some((r) => r.label === 'Not an MPP endpoint'))
|
|
243
|
-
sawNonMppPaymentEndpoint = true
|
|
244
|
-
continue
|
|
245
|
-
}
|
|
246
|
-
sawMppEndpoint = true
|
|
247
|
-
|
|
248
|
-
const isTestnetEndpoint = challengeResults.some(
|
|
249
|
-
(r) =>
|
|
250
|
-
r.severity === 'pass' && r.label === 'Valid currency address' && r.detail === 'testnet',
|
|
251
|
-
)
|
|
252
|
-
if (isTestnetEndpoint) sawTestnet = true
|
|
253
|
-
else sawMainnet = true
|
|
254
|
-
|
|
255
|
-
// Error Handling
|
|
256
|
-
console.log(pc.dim(' Error Handling'))
|
|
257
|
-
const errorResults = await validateErrorHandling(baseUrl, endpoint, {
|
|
258
|
-
body: effectiveBody,
|
|
259
|
-
query: options.query,
|
|
260
|
-
})
|
|
261
|
-
printResults(errorResults, counts)
|
|
262
|
-
|
|
263
|
-
// Payment
|
|
264
|
-
console.log(pc.dim(' Payment'))
|
|
265
|
-
const paymentResults = await validatePaymentFlow(baseUrl, endpoint, options.verbose, {
|
|
266
|
-
body: effectiveBody,
|
|
267
|
-
query: options.query,
|
|
268
|
-
yes: options.yes,
|
|
269
|
-
})
|
|
270
|
-
printResults(paymentResults, counts)
|
|
271
|
-
if (paymentResults.some((r) => r.severity === 'pass' && r.label === 'Payment: successful')) {
|
|
272
|
-
paymentSucceeded = true
|
|
273
|
-
}
|
|
274
|
-
}
|
|
137
|
+
},
|
|
138
|
+
})
|
|
275
139
|
|
|
276
|
-
|
|
277
|
-
}
|
|
140
|
+
export default validate
|
|
278
141
|
|
|
279
142
|
function printSummary(
|
|
280
143
|
counts: Counts,
|
|
281
144
|
flags: {
|
|
282
145
|
sawMppEndpoint: boolean
|
|
283
146
|
sawNonMppPaymentEndpoint: boolean
|
|
147
|
+
sawMalformedChallenge: boolean
|
|
284
148
|
sawTestnet: boolean
|
|
285
149
|
sawMainnet: boolean
|
|
286
150
|
paymentSucceeded: boolean
|
|
287
151
|
},
|
|
288
152
|
endpointsLength: number,
|
|
289
153
|
): void {
|
|
290
|
-
// No MPP endpoints found
|
|
291
154
|
if (!flags.sawMppEndpoint && endpointsLength > 0) {
|
|
292
155
|
console.log('')
|
|
293
|
-
if (flags.
|
|
156
|
+
if (flags.sawMalformedChallenge) {
|
|
157
|
+
console.log(
|
|
158
|
+
pc.yellow(
|
|
159
|
+
` Payment scheme detected but challenge format is invalid on ${endpointsLength} endpoint(s).`,
|
|
160
|
+
),
|
|
161
|
+
)
|
|
162
|
+
console.log(
|
|
163
|
+
pc.dim(
|
|
164
|
+
' The server uses WWW-Authenticate: Payment but the challenge parameters do not conform to MPP.',
|
|
165
|
+
),
|
|
166
|
+
)
|
|
167
|
+
console.log(
|
|
168
|
+
pc.dim(
|
|
169
|
+
' Fix: encode payment details as base64url JSON in a request="..." parameter. See errors above.',
|
|
170
|
+
),
|
|
171
|
+
)
|
|
172
|
+
} else if (flags.sawNonMppPaymentEndpoint) {
|
|
294
173
|
console.log(
|
|
295
174
|
pc.yellow(
|
|
296
175
|
` No MPP endpoints found. Tested ${endpointsLength} endpoint(s) but none use WWW-Authenticate: Payment.`,
|
|
@@ -318,7 +197,6 @@ function printSummary(
|
|
|
318
197
|
process.exit(1)
|
|
319
198
|
}
|
|
320
199
|
|
|
321
|
-
// Summary
|
|
322
200
|
console.log('')
|
|
323
201
|
const parts: string[] = []
|
|
324
202
|
if (counts.passed > 0) parts.push(pc.green(`${counts.passed} passed`))
|
|
@@ -327,7 +205,6 @@ function printSummary(
|
|
|
327
205
|
if (counts.skipped > 0) parts.push(pc.yellow(`${counts.skipped} skipped`))
|
|
328
206
|
console.log(`${pc.bold('Summary:')} ${parts.join(', ')}`)
|
|
329
207
|
|
|
330
|
-
// Cross-promotion
|
|
331
208
|
if (flags.paymentSucceeded && flags.sawTestnet && !flags.sawMainnet) {
|
|
332
209
|
console.log('')
|
|
333
210
|
console.log(
|