@devlab.group/agent-commerce 1.4.1 → 1.5.0
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 +111 -128
- package/dist/ap2.d.ts +5 -5
- package/dist/ap2.js +19 -11
- package/dist/ap2.js.map +1 -1
- package/dist/{authorization-CPDcpJVa.d.ts → authorization-DA7mjy_O.d.ts} +4 -4
- package/dist/{chunk-ZEGFLRGV.js → chunk-5GEWKNIH.js} +5 -4
- package/dist/chunk-5GEWKNIH.js.map +1 -0
- package/dist/chunk-6D2EZ5ME.js +27 -0
- package/dist/chunk-6D2EZ5ME.js.map +1 -0
- package/dist/chunk-NKNXVDHN.js +701 -0
- package/dist/chunk-NKNXVDHN.js.map +1 -0
- package/dist/{chunk-NWIQLJNU.js → chunk-PBYN7EK2.js} +33 -31
- package/dist/chunk-PBYN7EK2.js.map +1 -0
- package/dist/{chunk-GF6KHHKL.js → chunk-US622BKF.js} +3 -3
- package/dist/{chunk-GF6KHHKL.js.map → chunk-US622BKF.js.map} +1 -1
- package/dist/cli/index.js +339 -107
- package/dist/cli/index.js.map +1 -1
- package/dist/constants-6mypC60h.d.ts +50 -0
- package/dist/index.d.ts +26 -11
- package/dist/index.js +189 -36
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts +3 -3
- package/dist/mcp.js +4 -1
- package/dist/mcp.js.map +1 -1
- package/dist/mpp.d.ts +50 -0
- package/dist/mpp.js +351 -0
- package/dist/mpp.js.map +1 -0
- package/dist/{protocol-adapter-Bebmggf_.d.ts → protocol-adapter-APRjs1E2.d.ts} +2 -2
- package/dist/{runtime-CKq3d_3K.d.ts → runtime-DC5XQ9Cc.d.ts} +24 -13
- package/dist/x402.d.ts +1 -1
- package/dist/x402.js +7 -688
- package/dist/x402.js.map +1 -1
- package/package.json +13 -2
- package/dist/chunk-NWIQLJNU.js.map +0 -1
- package/dist/chunk-ZEGFLRGV.js.map +0 -1
package/dist/mpp.js
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
import { MPP_PROFILE, MPP_NETWORKS, MPP_SUPPORTED_SPEC, MPP_DEFAULT_NETWORK, MPP_MIN_CHALLENGE_SECRET_LENGTH, isMppNetwork, MPP_SPEC_DRAFTS } from './chunk-6D2EZ5ME.js';
|
|
2
|
+
export { MPPX_VERSION, MPP_PROFILE, MPP_SPEC_COMMIT, MPP_SPEC_DRAFTS, MPP_SPEC_REPOSITORY, MPP_SUPPORTED_SPEC } from './chunk-6D2EZ5ME.js';
|
|
3
|
+
import { createX402PaymentProvider, parseCanonicalAmount, computeReplayKey } from './chunk-NKNXVDHN.js';
|
|
4
|
+
import './chunk-PBYN7EK2.js';
|
|
5
|
+
import { PACKAGE_VERSION, systemClock, CommerceError } from './chunk-5GEWKNIH.js';
|
|
6
|
+
import { Challenge, Credential, Method, Receipt, PaymentRequest, Errors } from 'mppx';
|
|
7
|
+
import { Methods } from 'mppx/evm';
|
|
8
|
+
import { charge } from 'mppx/evm/server';
|
|
9
|
+
import { getAddress, isAddress } from 'viem';
|
|
10
|
+
|
|
11
|
+
// src/payments/mpp/descriptor.ts
|
|
12
|
+
var MPP_DESCRIPTOR = {
|
|
13
|
+
name: "mpp",
|
|
14
|
+
kind: "payment",
|
|
15
|
+
implementationVersion: PACKAGE_VERSION,
|
|
16
|
+
supportedSpec: MPP_SUPPORTED_SPEC,
|
|
17
|
+
capabilities: [
|
|
18
|
+
`intent=${MPP_PROFILE.intent}`,
|
|
19
|
+
`method=${MPP_PROFILE.method}`,
|
|
20
|
+
`credential=${MPP_PROFILE.credentialType}`,
|
|
21
|
+
"eip-3009",
|
|
22
|
+
...MPP_NETWORKS.map((network) => `network=${network}`),
|
|
23
|
+
`asset=${MPP_PROFILE.assetSymbol}`,
|
|
24
|
+
"verify-before-settle",
|
|
25
|
+
"payment-receipt"
|
|
26
|
+
],
|
|
27
|
+
// The pinned specs are -00 drafts and mppx is pre-1.0, so the wire format can still change
|
|
28
|
+
status: "experimental",
|
|
29
|
+
unsupported: [
|
|
30
|
+
// Name other methods as a class instead of maintaining a second list
|
|
31
|
+
"methods other than evm",
|
|
32
|
+
// This profile supports only the EIP-3009 `authorization` credential
|
|
33
|
+
"credential=permit2",
|
|
34
|
+
"credential=transaction",
|
|
35
|
+
"credential=hash",
|
|
36
|
+
// The draft allows splits only with permit2 credentials
|
|
37
|
+
"splits",
|
|
38
|
+
"intent=subscription",
|
|
39
|
+
// A separate EVM draft, not an option of charge
|
|
40
|
+
"evm sessions",
|
|
41
|
+
"discovery extension"
|
|
42
|
+
]
|
|
43
|
+
};
|
|
44
|
+
var DEFAULT_IDS = {
|
|
45
|
+
next: (prefix) => `${prefix ? `${prefix}_` : ""}${crypto.randomUUID()}`
|
|
46
|
+
};
|
|
47
|
+
var DEFAULT_CHALLENGE_TTL_SECONDS = 300;
|
|
48
|
+
var VERIFICATION_REASONS = [
|
|
49
|
+
["EVM authorization challenge hash mismatch", "wrong_nonce"],
|
|
50
|
+
["EVM authorization signature mismatch", "invalid_signature"],
|
|
51
|
+
["EVM authorization is not valid yet", "authorization_not_yet_valid"],
|
|
52
|
+
["EVM authorization has expired", "authorization_expired"],
|
|
53
|
+
["EVM authorization source mismatch", "source_mismatch"],
|
|
54
|
+
["EVM authorization amount mismatch", "wrong_amount"],
|
|
55
|
+
["EVM authorization recipient mismatch", "wrong_recipient"]
|
|
56
|
+
];
|
|
57
|
+
function configInvalid(message) {
|
|
58
|
+
return new CommerceError("CONFIG_INVALID", message);
|
|
59
|
+
}
|
|
60
|
+
function validateOptions(options) {
|
|
61
|
+
if (!isAddress(options.recipient)) throw configInvalid("MPP recipient is not an EVM address");
|
|
62
|
+
if (!isAddress(options.asset)) throw configInvalid("MPP asset is not an EVM address");
|
|
63
|
+
if (options.assetName.length === 0 || options.assetVersion.length === 0) {
|
|
64
|
+
throw configInvalid("MPP asset needs its EIP-712 domain name and version");
|
|
65
|
+
}
|
|
66
|
+
if (options.realm.length === 0 || /[\r\n]/.test(options.realm)) {
|
|
67
|
+
throw configInvalid("MPP realm must be a non-empty single-line string");
|
|
68
|
+
}
|
|
69
|
+
if (options.challengeSecret.length < MPP_MIN_CHALLENGE_SECRET_LENGTH) {
|
|
70
|
+
throw configInvalid(
|
|
71
|
+
`MPP challenge secret must have length at least ${MPP_MIN_CHALLENGE_SECRET_LENGTH}`
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
const ttl = options.challengeTtlSeconds;
|
|
75
|
+
if (ttl !== void 0 && (!Number.isInteger(ttl) || ttl <= 0)) {
|
|
76
|
+
throw configInvalid("MPP challenge TTL must be a positive whole number of seconds");
|
|
77
|
+
}
|
|
78
|
+
if (options.network !== void 0 && !isMppNetwork(options.network)) {
|
|
79
|
+
throw configInvalid(`MPP network must be one of ${MPP_NETWORKS.join(", ")}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function verificationReason(error) {
|
|
83
|
+
if (error instanceof Errors.PaymentExpiredError) return "challenge_expired";
|
|
84
|
+
if (error instanceof Errors.InvalidPayloadError) return "invalid_payload";
|
|
85
|
+
if (error instanceof Errors.InvalidChallengeError) return "invalid_challenge";
|
|
86
|
+
if (error instanceof Errors.VerificationFailedError) {
|
|
87
|
+
const match = VERIFICATION_REASONS.find(([text]) => error.message.includes(text));
|
|
88
|
+
if (match) return match[1];
|
|
89
|
+
}
|
|
90
|
+
return "authorization_invalid";
|
|
91
|
+
}
|
|
92
|
+
function createMppPaymentProvider(options) {
|
|
93
|
+
const { rpcUrl, facilitator, allowMainnet, allowUnauthenticatedFacilitator, logger, ...rest } = options;
|
|
94
|
+
validateOptions(rest);
|
|
95
|
+
const settlement = createX402PaymentProvider({
|
|
96
|
+
network: options.network ?? MPP_DEFAULT_NETWORK,
|
|
97
|
+
rpcUrl,
|
|
98
|
+
asset: options.asset,
|
|
99
|
+
assetName: options.assetName,
|
|
100
|
+
assetVersion: options.assetVersion,
|
|
101
|
+
assetDecimals: MPP_PROFILE.assetDecimals,
|
|
102
|
+
payTo: options.recipient,
|
|
103
|
+
facilitator,
|
|
104
|
+
...allowMainnet !== void 0 ? { allowMainnet } : {},
|
|
105
|
+
...allowUnauthenticatedFacilitator !== void 0 ? { allowUnauthenticatedFacilitator } : {},
|
|
106
|
+
...logger !== void 0 ? { logger } : {},
|
|
107
|
+
...options.clock !== void 0 ? { clock: options.clock } : {}
|
|
108
|
+
});
|
|
109
|
+
return createMppProviderWithSettlement(rest, settlement);
|
|
110
|
+
}
|
|
111
|
+
function createMppProviderWithSettlement(options, settlement) {
|
|
112
|
+
validateOptions(options);
|
|
113
|
+
if (settlement.name !== "x402") {
|
|
114
|
+
throw configInvalid("MPP settlement must be an x402 payment provider");
|
|
115
|
+
}
|
|
116
|
+
const network = options.network ?? MPP_DEFAULT_NETWORK;
|
|
117
|
+
const chainId = Number(network.split(":")[1]);
|
|
118
|
+
const clock = options.clock ?? systemClock;
|
|
119
|
+
const ttlSeconds = options.challengeTtlSeconds ?? DEFAULT_CHALLENGE_TTL_SECONDS;
|
|
120
|
+
const recipient = getAddress(options.recipient);
|
|
121
|
+
const asset = getAddress(options.asset);
|
|
122
|
+
const ids = options.ids ?? DEFAULT_IDS;
|
|
123
|
+
const method = charge({
|
|
124
|
+
currency: asset,
|
|
125
|
+
recipient,
|
|
126
|
+
chainId,
|
|
127
|
+
decimals: MPP_PROFILE.assetDecimals,
|
|
128
|
+
authorization: { name: options.assetName, version: options.assetVersion },
|
|
129
|
+
settle: async () => {
|
|
130
|
+
throw new CommerceError("INTERNAL_ERROR", "MPP direct broadcast is disabled");
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
function rejected(requirement, reason) {
|
|
134
|
+
return {
|
|
135
|
+
status: "rejected",
|
|
136
|
+
provider: "mpp",
|
|
137
|
+
amount: requirement.amount,
|
|
138
|
+
currency: requirement.currency,
|
|
139
|
+
network,
|
|
140
|
+
asset,
|
|
141
|
+
rejectionReason: reason
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
async function createRequirement(context) {
|
|
145
|
+
if (context.currency !== MPP_PROFILE.assetSymbol) {
|
|
146
|
+
throw configInvalid(
|
|
147
|
+
`Resource "${context.resource.id}" is priced in ${context.currency}, but MPP charges ${MPP_PROFILE.assetSymbol}`
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
if (parseCanonicalAmount(context.amount, MPP_PROFILE.assetDecimals) <= 0n) {
|
|
151
|
+
throw new CommerceError("PAYMENT_INVALID", `Amount "${context.amount}" must be above zero`, {
|
|
152
|
+
details: { amount: context.amount }
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
await settlementRequirement(context);
|
|
156
|
+
const expires = new Date(clock.now().getTime() + ttlSeconds * 1e3);
|
|
157
|
+
const challenge = Challenge.fromMethod(Methods.charge, {
|
|
158
|
+
secretKey: options.challengeSecret,
|
|
159
|
+
realm: options.realm,
|
|
160
|
+
expires,
|
|
161
|
+
// Bound by the challenge HMAC, so a challenge for one resource cannot pay
|
|
162
|
+
// for another at the same price
|
|
163
|
+
meta: { resource: context.resource.id },
|
|
164
|
+
request: {
|
|
165
|
+
amount: context.amount,
|
|
166
|
+
currency: asset,
|
|
167
|
+
recipient,
|
|
168
|
+
chainId,
|
|
169
|
+
decimals: MPP_PROFILE.assetDecimals,
|
|
170
|
+
credentialTypes: [MPP_PROFILE.credentialType]
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
return {
|
|
174
|
+
id: ids.next("payreq"),
|
|
175
|
+
requestId: context.requestId,
|
|
176
|
+
resourceId: context.resource.id,
|
|
177
|
+
provider: "mpp",
|
|
178
|
+
amount: context.amount,
|
|
179
|
+
currency: context.currency,
|
|
180
|
+
destination: recipient,
|
|
181
|
+
network,
|
|
182
|
+
asset,
|
|
183
|
+
expiresAt: expires.toISOString(),
|
|
184
|
+
challenge: {
|
|
185
|
+
provider: "mpp",
|
|
186
|
+
version: MPP_SPEC_DRAFTS.core,
|
|
187
|
+
accepts: [challenge],
|
|
188
|
+
// Serialised here because the HTTP route, which sends it as
|
|
189
|
+
// `WWW-Authenticate`, is in the main entry and cannot import mppx
|
|
190
|
+
envelope: { wwwAuthenticate: Challenge.serialize(challenge) }
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
async function verify(context) {
|
|
195
|
+
const { requirement, resource, submission } = context;
|
|
196
|
+
if (requirement.provider !== "mpp" || requirement.challenge.provider !== "mpp") {
|
|
197
|
+
return rejected(requirement, "wrong_provider");
|
|
198
|
+
}
|
|
199
|
+
const issued = requirement.challenge.accepts[0];
|
|
200
|
+
if (!issued) return rejected(requirement, "missing_challenge");
|
|
201
|
+
let credential;
|
|
202
|
+
try {
|
|
203
|
+
credential = Credential.deserialize(submission.payload);
|
|
204
|
+
} catch {
|
|
205
|
+
return rejected(requirement, "malformed_credential");
|
|
206
|
+
}
|
|
207
|
+
const echoed = credential.challenge;
|
|
208
|
+
if (!Challenge.verify(echoed, { secretKey: options.challengeSecret })) {
|
|
209
|
+
return rejected(requirement, "challenge_not_issued");
|
|
210
|
+
}
|
|
211
|
+
const binding = bindingMismatch(echoed, issued, resource.id);
|
|
212
|
+
if (binding) return rejected(requirement, binding);
|
|
213
|
+
if (!echoed.expires || new Date(echoed.expires).getTime() <= clock.now().getTime()) {
|
|
214
|
+
return rejected(requirement, "challenge_expired");
|
|
215
|
+
}
|
|
216
|
+
if (credential.payload?.type !== MPP_PROFILE.credentialType) {
|
|
217
|
+
return rejected(requirement, "unsupported_credential");
|
|
218
|
+
}
|
|
219
|
+
let payer;
|
|
220
|
+
try {
|
|
221
|
+
const validation = await Method.validateCredential([method], credential);
|
|
222
|
+
payer = getAddress(validation.details.payer);
|
|
223
|
+
} catch (error) {
|
|
224
|
+
return rejected(requirement, verificationReason(error));
|
|
225
|
+
}
|
|
226
|
+
const replayKey = computeReplayKey({
|
|
227
|
+
chainId,
|
|
228
|
+
asset,
|
|
229
|
+
from: payer,
|
|
230
|
+
// validateCredential proved it equals the 32-byte challenge hash
|
|
231
|
+
nonce: credential.payload.nonce
|
|
232
|
+
});
|
|
233
|
+
const x402Verification = await settlement.verify(await toX402Context(context));
|
|
234
|
+
if (x402Verification.status !== "verified") {
|
|
235
|
+
return rejected(requirement, x402Verification.rejectionReason ?? "settlement_rejected");
|
|
236
|
+
}
|
|
237
|
+
if (x402Verification.replayKey !== replayKey) {
|
|
238
|
+
return rejected(requirement, "settlement_mismatch");
|
|
239
|
+
}
|
|
240
|
+
return {
|
|
241
|
+
status: "verified",
|
|
242
|
+
provider: "mpp",
|
|
243
|
+
payer,
|
|
244
|
+
payee: recipient,
|
|
245
|
+
amount: requirement.amount,
|
|
246
|
+
currency: requirement.currency,
|
|
247
|
+
network,
|
|
248
|
+
asset,
|
|
249
|
+
replayKey
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
async function toX402Context(context) {
|
|
253
|
+
const { requestId, requirement, resource, submission } = context;
|
|
254
|
+
const x402Requirement = await settlementRequirement({
|
|
255
|
+
requestId,
|
|
256
|
+
resource,
|
|
257
|
+
amount: requirement.amount,
|
|
258
|
+
currency: requirement.currency,
|
|
259
|
+
requestedAt: clock.nowIso()
|
|
260
|
+
});
|
|
261
|
+
return {
|
|
262
|
+
requestId,
|
|
263
|
+
resource,
|
|
264
|
+
requirement: x402Requirement,
|
|
265
|
+
submission: toX402Submission(x402Requirement, submission)
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
async function settlementRequirement(context) {
|
|
269
|
+
const x402 = await settlement.createRequirement(context);
|
|
270
|
+
const extra = x402.challenge.accepts[0]?.["extra"] ?? {};
|
|
271
|
+
if (x402.network !== network || !sameAddress(x402.asset, asset) || !sameAddress(x402.destination, recipient) || extra["name"] !== options.assetName || extra["version"] !== options.assetVersion) {
|
|
272
|
+
throw configInvalid(
|
|
273
|
+
"MPP settlement provider must use the same network, asset, EIP-712 domain and recipient"
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
return x402;
|
|
277
|
+
}
|
|
278
|
+
async function settle(context) {
|
|
279
|
+
const { requestId, requirement, resource, submission, verification } = context;
|
|
280
|
+
if (verification.status !== "verified" || verification.replayKey === void 0) {
|
|
281
|
+
throw new CommerceError(
|
|
282
|
+
"PAYMENT_INVALID",
|
|
283
|
+
"MPP settle() called without a successful verify()"
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
const settled = await settlement.settle({
|
|
287
|
+
...await toX402Context({ requestId, requirement, resource, submission }),
|
|
288
|
+
verification: { ...verification, provider: "x402" }
|
|
289
|
+
});
|
|
290
|
+
const result = {
|
|
291
|
+
...settled,
|
|
292
|
+
provider: "mpp",
|
|
293
|
+
amount: requirement.amount,
|
|
294
|
+
currency: requirement.currency,
|
|
295
|
+
replayKey: verification.replayKey
|
|
296
|
+
};
|
|
297
|
+
if (settled.status !== "settled" || settled.externalReference === void 0) return result;
|
|
298
|
+
const receipt = Receipt.from({
|
|
299
|
+
method: MPP_PROFILE.method,
|
|
300
|
+
reference: settled.externalReference,
|
|
301
|
+
status: "success",
|
|
302
|
+
timestamp: settled.settledAt ?? clock.nowIso()
|
|
303
|
+
});
|
|
304
|
+
return { ...result, metadata: { ...settled.metadata, receipt: Receipt.serialize(receipt) } };
|
|
305
|
+
}
|
|
306
|
+
function health() {
|
|
307
|
+
return settlement.health();
|
|
308
|
+
}
|
|
309
|
+
return { name: "mpp", descriptor: MPP_DESCRIPTOR, createRequirement, verify, settle, health };
|
|
310
|
+
}
|
|
311
|
+
function bindingMismatch(echoed, issued, resourceId) {
|
|
312
|
+
if (echoed.realm !== issued.realm) return "wrong_realm";
|
|
313
|
+
if (echoed.method !== issued.method || echoed.intent !== issued.intent) {
|
|
314
|
+
return "unsupported_method";
|
|
315
|
+
}
|
|
316
|
+
if (echoed.opaque !== PaymentRequest.serialize({ resource: resourceId })) {
|
|
317
|
+
return "wrong_resource";
|
|
318
|
+
}
|
|
319
|
+
const got = echoed.request;
|
|
320
|
+
const want = issued.request;
|
|
321
|
+
if (got.amount !== want.amount) return "wrong_amount";
|
|
322
|
+
if (!sameAddress(got.recipient, want.recipient)) return "wrong_recipient";
|
|
323
|
+
if (got.methodDetails?.chainId !== want.methodDetails?.chainId) return "wrong_network";
|
|
324
|
+
if (!sameAddress(got.currency, want.currency)) return "wrong_asset";
|
|
325
|
+
if (canonical(got.methodDetails) !== canonical(want.methodDetails)) {
|
|
326
|
+
return "unsupported_credential";
|
|
327
|
+
}
|
|
328
|
+
if (canonical(got) !== canonical(want)) return "wrong_terms";
|
|
329
|
+
return void 0;
|
|
330
|
+
}
|
|
331
|
+
function toX402Submission(x402Requirement, submission) {
|
|
332
|
+
const { signature, from, to, value, validAfter, validBefore, nonce } = Credential.deserialize(
|
|
333
|
+
submission.payload
|
|
334
|
+
).payload;
|
|
335
|
+
const payment = {
|
|
336
|
+
x402Version: 2,
|
|
337
|
+
accepted: x402Requirement.challenge.accepts[0],
|
|
338
|
+
payload: { signature, authorization: { from, to, value, validAfter, validBefore, nonce } }
|
|
339
|
+
};
|
|
340
|
+
return { method: "x402", payload: Buffer.from(JSON.stringify(payment)).toString("base64") };
|
|
341
|
+
}
|
|
342
|
+
function canonical(value) {
|
|
343
|
+
return value === void 0 ? "" : PaymentRequest.serialize(value);
|
|
344
|
+
}
|
|
345
|
+
function sameAddress(a, b) {
|
|
346
|
+
return a !== void 0 && b !== void 0 && isAddress(a) && isAddress(b) ? getAddress(a) === getAddress(b) : false;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
export { MPP_DESCRIPTOR, createMppPaymentProvider, createMppPaymentProvider as mpp };
|
|
350
|
+
//# sourceMappingURL=mpp.js.map
|
|
351
|
+
//# sourceMappingURL=mpp.js.map
|
package/dist/mpp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/payments/mpp/descriptor.ts","../src/payments/mpp/provider.ts"],"names":[],"mappings":"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","file":"mpp.js","sourcesContent":["/**\n * Describes the MPP profile and its unsupported variants.\n *\n * The protocol name alone cannot identify a compatible intent, method and\n * extension set, so the descriptor lists both the target and its gaps.\n *\n * Importing the descriptor does not load `mppx`.\n */\nimport type { AdapterDescriptor } from '../../core/public-types.js';\nimport { PACKAGE_VERSION } from '../../version.js';\nimport { MPP_NETWORKS, MPP_PROFILE, MPP_SUPPORTED_SPEC } from './constants.js';\n\nexport const MPP_DESCRIPTOR: AdapterDescriptor = {\n name: 'mpp',\n kind: 'payment',\n implementationVersion: PACKAGE_VERSION,\n supportedSpec: MPP_SUPPORTED_SPEC,\n capabilities: [\n `intent=${MPP_PROFILE.intent}`,\n `method=${MPP_PROFILE.method}`,\n `credential=${MPP_PROFILE.credentialType}`,\n 'eip-3009',\n ...MPP_NETWORKS.map((network) => `network=${network}`),\n `asset=${MPP_PROFILE.assetSymbol}`,\n 'verify-before-settle',\n 'payment-receipt',\n ],\n // The pinned specs are -00 drafts and mppx is pre-1.0, so the wire format can still change\n status: 'experimental',\n unsupported: [\n // Name other methods as a class instead of maintaining a second list\n 'methods other than evm',\n // This profile supports only the EIP-3009 `authorization` credential\n 'credential=permit2',\n 'credential=transaction',\n 'credential=hash',\n // The draft allows splits only with permit2 credentials\n 'splits',\n 'intent=subscription',\n // A separate EVM draft, not an option of charge\n 'evm sessions',\n 'discovery extension',\n ],\n};\n","/**\n * MPP payment provider for the `charge` intent, the `evm` method and the\n * EIP-3009 `authorization` credential.\n *\n * It issues challenges and verifies credentials without moving funds: local\n * checks first, then a read-only check by an x402 facilitator. Settlement hands\n * the same signed authorization to that facilitator through an internal x402\n * provider built from these options. The MPP layer adds no signing key.\n */\nimport { Challenge, Credential, Errors, Method, PaymentRequest, Receipt } from 'mppx';\nimport { Methods, type Types } from 'mppx/evm';\nimport { charge } from 'mppx/evm/server';\nimport { getAddress, isAddress } from 'viem';\nimport {\n type AdapterHealth,\n type Clock,\n CommerceError,\n type IdGenerator,\n type Logger,\n type PaymentContext,\n type PaymentProvider,\n type PaymentRequirement,\n type PaymentResult,\n type PaymentSettlementContext,\n type PaymentSubmission,\n type PaymentVerificationContext,\n systemClock,\n} from '../../core/index.js';\nimport { parseCanonicalAmount } from '../x402/amount.js';\nimport type { X402FacilitatorConfig } from '../x402/guardrails.js';\nimport { createX402PaymentProvider } from '../x402/provider.js';\nimport { computeReplayKey } from '../x402/replay-key.js';\nimport {\n isMppNetwork,\n MPP_DEFAULT_NETWORK,\n MPP_MIN_CHALLENGE_SECRET_LENGTH,\n MPP_NETWORKS,\n MPP_PROFILE,\n MPP_SPEC_DRAFTS,\n} from './constants.js';\nimport { MPP_DESCRIPTOR } from './descriptor.js';\n\nconst DEFAULT_IDS: IdGenerator = {\n next: (prefix?: string) => `${prefix ? `${prefix}_` : ''}${crypto.randomUUID()}`,\n};\nconst DEFAULT_CHALLENGE_TTL_SECONDS = 300;\n\nexport interface MppProviderOptions {\n /** Merchant-controlled settlement destination. Never gateway-owned */\n readonly recipient: `0x${string}`;\n /** EIP-3009 token the charge is paid in */\n readonly asset: `0x${string}`;\n /** EIP-712 domain name of the asset, e.g. 'USDC' or 'MockUSDC' */\n readonly assetName: string;\n /** EIP-712 domain version of the asset, e.g. '2' */\n readonly assetVersion: string;\n /** Value of each challenge's `realm`, such as the gateway's host */\n readonly realm: string;\n /** Key that binds each challenge to this gateway. Never logged or published */\n readonly challengeSecret: string;\n /** RPC endpoint of the settlement chain */\n readonly rpcUrl: string;\n /** The x402 facilitator that verifies and broadcasts the authorization */\n readonly facilitator: X402FacilitatorConfig;\n /** Must be `true` before anything settles on a mainnet. Never a default */\n readonly allowMainnet?: boolean;\n /** Must be `true` to settle on a mainnet through a facilitator that takes no credential */\n readonly allowUnauthenticatedFacilitator?: boolean;\n readonly logger?: Logger;\n /**\n * Seconds a challenge stays valid, 300 by default. The mppx client signs its\n * authorization to expire at the same moment.\n */\n readonly challengeTtlSeconds?: number;\n /** CAIP-2 network; accepts `eip155:84532` or `eip155:8453` and defaults to the former */\n readonly network?: string;\n readonly clock?: Clock;\n readonly ids?: IdGenerator;\n}\n\n// mppx reports a verification failure only as message text. The pinned\n// release's wording maps to stable reasons, and the tests cover every entry;\n// unmapped text becomes `authorization_invalid`.\nconst VERIFICATION_REASONS: readonly (readonly [string, string])[] = [\n ['EVM authorization challenge hash mismatch', 'wrong_nonce'],\n ['EVM authorization signature mismatch', 'invalid_signature'],\n ['EVM authorization is not valid yet', 'authorization_not_yet_valid'],\n ['EVM authorization has expired', 'authorization_expired'],\n ['EVM authorization source mismatch', 'source_mismatch'],\n ['EVM authorization amount mismatch', 'wrong_amount'],\n ['EVM authorization recipient mismatch', 'wrong_recipient'],\n];\n\nfunction configInvalid(message: string): CommerceError {\n return new CommerceError('CONFIG_INVALID', message);\n}\n\ntype MppChallengeOptions = Omit<\n MppProviderOptions,\n 'rpcUrl' | 'facilitator' | 'allowMainnet' | 'allowUnauthenticatedFacilitator' | 'logger'\n>;\n\nfunction validateOptions(options: MppChallengeOptions): void {\n if (!isAddress(options.recipient)) throw configInvalid('MPP recipient is not an EVM address');\n if (!isAddress(options.asset)) throw configInvalid('MPP asset is not an EVM address');\n if (options.assetName.length === 0 || options.assetVersion.length === 0) {\n throw configInvalid('MPP asset needs its EIP-712 domain name and version');\n }\n // mppx refuses CR or LF in the quoted realm parameter, so checking here fails\n // at construction instead of on every challenge\n if (options.realm.length === 0 || /[\\r\\n]/.test(options.realm)) {\n throw configInvalid('MPP realm must be a non-empty single-line string');\n }\n if (options.challengeSecret.length < MPP_MIN_CHALLENGE_SECRET_LENGTH) {\n throw configInvalid(\n `MPP challenge secret must have length at least ${MPP_MIN_CHALLENGE_SECRET_LENGTH}`,\n );\n }\n const ttl = options.challengeTtlSeconds;\n if (ttl !== undefined && (!Number.isInteger(ttl) || ttl <= 0)) {\n throw configInvalid('MPP challenge TTL must be a positive whole number of seconds');\n }\n if (options.network !== undefined && !isMppNetwork(options.network)) {\n throw configInvalid(`MPP network must be one of ${MPP_NETWORKS.join(', ')}`);\n }\n}\n\nfunction verificationReason(error: unknown): string {\n if (error instanceof Errors.PaymentExpiredError) return 'challenge_expired';\n if (error instanceof Errors.InvalidPayloadError) return 'invalid_payload';\n if (error instanceof Errors.InvalidChallengeError) return 'invalid_challenge';\n if (error instanceof Errors.VerificationFailedError) {\n const match = VERIFICATION_REASONS.find(([text]) => error.message.includes(text));\n if (match) return match[1];\n }\n return 'authorization_invalid';\n}\n\nexport function createMppPaymentProvider(options: MppProviderOptions): PaymentProvider {\n const { rpcUrl, facilitator, allowMainnet, allowUnauthenticatedFacilitator, logger, ...rest } =\n options;\n // Checked first so a bad MPP option is reported as one, not as an x402 error\n validateOptions(rest);\n // Built from the same terms, and never registered as a rail, so an MPP-only\n // deployment needs no x402 configuration\n const settlement = createX402PaymentProvider({\n network: options.network ?? MPP_DEFAULT_NETWORK,\n rpcUrl,\n asset: options.asset,\n assetName: options.assetName,\n assetVersion: options.assetVersion,\n assetDecimals: MPP_PROFILE.assetDecimals,\n payTo: options.recipient,\n facilitator,\n ...(allowMainnet !== undefined ? { allowMainnet } : {}),\n ...(allowUnauthenticatedFacilitator !== undefined ? { allowUnauthenticatedFacilitator } : {}),\n ...(logger !== undefined ? { logger } : {}),\n ...(options.clock !== undefined ? { clock: options.clock } : {}),\n });\n return createMppProviderWithSettlement(rest, settlement);\n}\n\n/** Internal seam: tests inject a settlement provider. Not exported from the `./mpp` entry */\nexport function createMppProviderWithSettlement(\n options: MppChallengeOptions,\n settlement: PaymentProvider,\n): PaymentProvider {\n validateOptions(options);\n if (settlement.name !== 'x402') {\n throw configInvalid('MPP settlement must be an x402 payment provider');\n }\n const network = options.network ?? MPP_DEFAULT_NETWORK;\n const chainId = Number(network.split(':')[1]);\n const clock = options.clock ?? systemClock;\n const ttlSeconds = options.challengeTtlSeconds ?? DEFAULT_CHALLENGE_TTL_SECONDS;\n const recipient = getAddress(options.recipient);\n const asset = getAddress(options.asset);\n const ids = options.ids ?? DEFAULT_IDS;\n\n // charge() requires a callback even though this provider never invokes the\n // mppx broadcast path. Settlement is delegated to the x402 provider.\n const method = charge({\n currency: asset,\n recipient,\n chainId,\n decimals: MPP_PROFILE.assetDecimals,\n authorization: { name: options.assetName, version: options.assetVersion },\n settle: async () => {\n throw new CommerceError('INTERNAL_ERROR', 'MPP direct broadcast is disabled');\n },\n });\n\n function rejected(requirement: PaymentRequirement, reason: string): PaymentResult {\n return {\n status: 'rejected',\n provider: 'mpp',\n amount: requirement.amount,\n currency: requirement.currency,\n network,\n asset,\n rejectionReason: reason,\n };\n }\n\n async function createRequirement(context: PaymentContext): Promise<PaymentRequirement> {\n if (context.currency !== MPP_PROFILE.assetSymbol) {\n throw configInvalid(\n `Resource \"${context.resource.id}\" is priced in ${context.currency}, but MPP charges ${MPP_PROFILE.assetSymbol}`,\n );\n }\n // Strict parse first: mppx converts with viem's parseUnits, which rounds\n // excess precision instead of refusing it\n if (parseCanonicalAmount(context.amount, MPP_PROFILE.assetDecimals) <= 0n) {\n throw new CommerceError('PAYMENT_INVALID', `Amount \"${context.amount}\" must be above zero`, {\n details: { amount: context.amount },\n });\n }\n // Reject a mismatched settlement requirement before the buyer signs\n await settlementRequirement(context);\n const expires = new Date(clock.now().getTime() + ttlSeconds * 1000);\n const challenge = Challenge.fromMethod(Methods.charge, {\n secretKey: options.challengeSecret,\n realm: options.realm,\n expires,\n // Bound by the challenge HMAC, so a challenge for one resource cannot pay\n // for another at the same price\n meta: { resource: context.resource.id },\n request: {\n amount: context.amount,\n currency: asset,\n recipient,\n chainId,\n decimals: MPP_PROFILE.assetDecimals,\n credentialTypes: [MPP_PROFILE.credentialType],\n },\n });\n return {\n id: ids.next('payreq'),\n requestId: context.requestId,\n resourceId: context.resource.id,\n provider: 'mpp',\n amount: context.amount,\n currency: context.currency,\n destination: recipient,\n network,\n asset,\n expiresAt: expires.toISOString(),\n challenge: {\n provider: 'mpp',\n version: MPP_SPEC_DRAFTS.core,\n accepts: [challenge],\n // Serialised here because the HTTP route, which sends it as\n // `WWW-Authenticate`, is in the main entry and cannot import mppx\n envelope: { wwwAuthenticate: Challenge.serialize(challenge) },\n },\n };\n }\n\n async function verify(context: PaymentVerificationContext): Promise<PaymentResult> {\n const { requirement, resource, submission } = context;\n if (requirement.provider !== 'mpp' || requirement.challenge.provider !== 'mpp') {\n return rejected(requirement, 'wrong_provider');\n }\n const issued = requirement.challenge.accepts[0] as Challenge.Challenge | undefined;\n if (!issued) return rejected(requirement, 'missing_challenge');\n\n let credential: Credential.Credential;\n try {\n credential = Credential.deserialize(submission.payload);\n } catch {\n return rejected(requirement, 'malformed_credential');\n }\n const echoed = credential.challenge;\n\n // A valid HMAC means this gateway issued the challenge, not that it was\n // issued for this resource and price. The binding checks below close that gap.\n if (!Challenge.verify(echoed, { secretKey: options.challengeSecret })) {\n return rejected(requirement, 'challenge_not_issued');\n }\n const binding = bindingMismatch(echoed, issued, resource.id);\n if (binding) return rejected(requirement, binding);\n if (!echoed.expires || new Date(echoed.expires).getTime() <= clock.now().getTime()) {\n return rejected(requirement, 'challenge_expired');\n }\n if ((credential.payload as { type?: unknown } | null)?.type !== MPP_PROFILE.credentialType) {\n return rejected(requirement, 'unsupported_credential');\n }\n\n // Local checks only: signature recovery, nonce == challenge hash, the\n // validity window and payload terms. With no network call involved, any\n // failure here is a verdict on the credential, not an outage.\n let payer: `0x${string}`;\n try {\n const validation = await Method.validateCredential([method], credential);\n payer = getAddress((validation.details as { payer: string }).payer);\n } catch (error) {\n return rejected(requirement, verificationReason(error));\n }\n\n // Match x402's key so the same authorization collides across both rails\n const replayKey = computeReplayKey({\n chainId,\n asset,\n from: payer,\n // validateCredential proved it equals the 32-byte challenge hash\n nonce: (credential.payload as Types.AuthorizationPayload).nonce as `0x${string}`,\n });\n\n // The facilitator check runs before the pipeline reserves the replay key,\n // so an outage throws the x402 provider's retryable error and uses up\n // nothing, and a refusal is an ordinary rejection\n const x402Verification = await settlement.verify(await toX402Context(context));\n if (x402Verification.status !== 'verified') {\n return rejected(requirement, x402Verification.rejectionReason ?? 'settlement_rejected');\n }\n // A different key would settle an authorization the pipeline did not reserve\n if (x402Verification.replayKey !== replayKey) {\n return rejected(requirement, 'settlement_mismatch');\n }\n\n return {\n status: 'verified',\n provider: 'mpp',\n payer,\n payee: recipient,\n amount: requirement.amount,\n currency: requirement.currency,\n network,\n asset,\n replayKey,\n };\n }\n\n // The same payment as an x402 requirement and `exact` submission\n async function toX402Context(\n context: PaymentVerificationContext,\n ): Promise<PaymentVerificationContext> {\n const { requestId, requirement, resource, submission } = context;\n const x402Requirement = await settlementRequirement({\n requestId,\n resource,\n amount: requirement.amount,\n currency: requirement.currency,\n requestedAt: clock.nowIso(),\n });\n return {\n requestId,\n resource,\n requirement: x402Requirement,\n submission: toX402Submission(x402Requirement, submission),\n };\n }\n\n async function settlementRequirement(context: PaymentContext): Promise<PaymentRequirement> {\n const x402 = await settlement.createRequirement(context);\n const extra = (x402.challenge.accepts[0]?.['extra'] ?? {}) as Record<string, unknown>;\n if (\n x402.network !== network ||\n !sameAddress(x402.asset, asset) ||\n !sameAddress(x402.destination, recipient) ||\n extra['name'] !== options.assetName ||\n extra['version'] !== options.assetVersion\n ) {\n throw configInvalid(\n 'MPP settlement provider must use the same network, asset, EIP-712 domain and recipient',\n );\n }\n return x402;\n }\n\n async function settle(context: PaymentSettlementContext): Promise<PaymentResult> {\n const { requestId, requirement, resource, submission, verification } = context;\n if (verification.status !== 'verified' || verification.replayKey === undefined) {\n throw new CommerceError(\n 'PAYMENT_INVALID',\n 'MPP settle() called without a successful verify()',\n );\n }\n\n // verify() already ran the facilitator check, and x402 settle checks again\n // before broadcasting. A throw may follow a broadcast, so it propagates and\n // the pipeline marks the payment uncertain.\n const settled = await settlement.settle({\n ...(await toX402Context({ requestId, requirement, resource, submission })),\n verification: { ...verification, provider: 'x402' },\n });\n const result: PaymentResult = {\n ...settled,\n provider: 'mpp',\n amount: requirement.amount,\n currency: requirement.currency,\n replayKey: verification.replayKey,\n };\n if (settled.status !== 'settled' || settled.externalReference === undefined) return result;\n // Serialised for the HTTP route's `Payment-Receipt` header\n const receipt = Receipt.from({\n method: MPP_PROFILE.method,\n reference: settled.externalReference,\n status: 'success',\n timestamp: settled.settledAt ?? clock.nowIso(),\n });\n return { ...result, metadata: { ...settled.metadata, receipt: Receipt.serialize(receipt) } };\n }\n\n function health(): Promise<AdapterHealth> {\n return settlement.health();\n }\n\n return { name: 'mpp', descriptor: MPP_DESCRIPTOR, createRequirement, verify, settle, health };\n}\n\n// Compares the echoed challenge with the one issued for this request. Both\n// carry a valid HMAC by now, so any difference means the credential answers a\n// challenge issued for other terms. The final comparison catches a difference\n// in any request field the named checks do not cover.\nfunction bindingMismatch(\n echoed: Challenge.Challenge,\n issued: Challenge.Challenge,\n resourceId: string,\n): string | undefined {\n if (echoed.realm !== issued.realm) return 'wrong_realm';\n if (echoed.method !== issued.method || echoed.intent !== issued.intent) {\n return 'unsupported_method';\n }\n // Only the encoded `opaque` survives the credential round trip, not `meta`,\n // so compare it with the encoding of this resource's binding\n if (echoed.opaque !== PaymentRequest.serialize({ resource: resourceId })) {\n return 'wrong_resource';\n }\n const got = echoed.request as ChargeRequest;\n const want = issued.request as ChargeRequest;\n if (got.amount !== want.amount) return 'wrong_amount';\n if (!sameAddress(got.recipient, want.recipient)) return 'wrong_recipient';\n if (got.methodDetails?.chainId !== want.methodDetails?.chainId) return 'wrong_network';\n if (!sameAddress(got.currency, want.currency)) return 'wrong_asset';\n if (canonical(got.methodDetails) !== canonical(want.methodDetails)) {\n return 'unsupported_credential';\n }\n if (canonical(got) !== canonical(want)) return 'wrong_terms';\n return undefined;\n}\n\n// Rewrap the MPP authorization as the x402 `exact` payload expected by settlement\nfunction toX402Submission(\n x402Requirement: PaymentRequirement,\n submission: PaymentSubmission,\n): PaymentSubmission {\n const { signature, from, to, value, validAfter, validBefore, nonce } = Credential.deserialize(\n submission.payload,\n ).payload as Types.AuthorizationPayload;\n const payment = {\n x402Version: 2,\n accepted: x402Requirement.challenge.accepts[0],\n payload: { signature, authorization: { from, to, value, validAfter, validBefore, nonce } },\n };\n return { method: 'x402', payload: Buffer.from(JSON.stringify(payment)).toString('base64') };\n}\n\ninterface ChargeRequest {\n readonly amount?: string;\n readonly currency?: string;\n readonly recipient?: string;\n readonly methodDetails?: { readonly chainId?: number };\n}\n\n// The encoding mppx binds into the challenge HMAC, so key order cannot\n// produce a false mismatch\nfunction canonical(value: object | undefined): string {\n return value === undefined ? '' : PaymentRequest.serialize(value as PaymentRequest.Request);\n}\n\nfunction sameAddress(a: string | undefined, b: string | undefined): boolean {\n return a !== undefined && b !== undefined && isAddress(a) && isAddress(b)\n ? getAddress(a) === getAddress(b)\n : false;\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
-
import { I as IsoTimestamp,
|
|
3
|
-
import { d as AuthorizationRecord, b as AuthorizationSubmission, a as AuthorizationRequirement } from './authorization-
|
|
2
|
+
import { I as IsoTimestamp, n as PaymentResult, r as ProtocolName, b as PaymentSubmission, m as PaymentRequirement, A as AdapterDescriptor, R as ResourceRegistry, L as Logger, C as Clock, e as IdGenerator, c as AdapterHealth } from './runtime-DC5XQ9Cc.js';
|
|
3
|
+
import { d as AuthorizationRecord, b as AuthorizationSubmission, a as AuthorizationRequirement } from './authorization-DA7mjy_O.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Canonical commerce events.
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
type JsonSchema = Record<string, unknown>;
|
|
15
15
|
/**
|
|
16
|
-
* Protocol surfaces a resource can be exposed through
|
|
16
|
+
* Protocol surfaces a resource can be exposed through.
|
|
17
17
|
*
|
|
18
18
|
* The runtime list is the definition and the type is derived from it, so a
|
|
19
19
|
* caller that has to *check* a name (config validation, the OpenAPI
|
|
@@ -28,10 +28,24 @@ type ProtocolName = 'http' | 'mcp' | 'a2a' | 'acp';
|
|
|
28
28
|
* is what keeps this from becoming a second definition that drifts.
|
|
29
29
|
*/
|
|
30
30
|
declare const PROTOCOL_NAMES: readonly ProtocolName[];
|
|
31
|
-
/** Payment methods a resource can accept in this release. */
|
|
32
|
-
type PaymentMethodName = 'x402';
|
|
33
31
|
/**
|
|
34
|
-
*
|
|
32
|
+
* Payment rails a resource can accept.
|
|
33
|
+
*
|
|
34
|
+
* This is an ordered candidate list, not a buyer-selected menu. The pipeline
|
|
35
|
+
* uses the first method with a configured provider; a rejection ends the
|
|
36
|
+
* request instead of trying another rail. Config requires at least one named
|
|
37
|
+
* rail to be enabled but permits additional unavailable candidates.
|
|
38
|
+
*/
|
|
39
|
+
type PaymentMethodName = 'x402' | 'mpp';
|
|
40
|
+
/**
|
|
41
|
+
* The same names as a value, for config validation, which checks a name at
|
|
42
|
+
* runtime. The annotation rejects an entry that is not a
|
|
43
|
+
* `PaymentMethodName`, but nothing makes the list exhaustive, so a new rail
|
|
44
|
+
* has to be added here as well as to the type.
|
|
45
|
+
*/
|
|
46
|
+
declare const PAYMENT_METHOD_NAMES: readonly PaymentMethodName[];
|
|
47
|
+
/**
|
|
48
|
+
* Authorization methods a resource can require.
|
|
35
49
|
*
|
|
36
50
|
* Deliberately not a `ProtocolName` and not a `PaymentMethodName`: an
|
|
37
51
|
* authorization method is neither a transport nor a payment rail. It proves
|
|
@@ -56,10 +70,7 @@ interface AdapterHealth {
|
|
|
56
70
|
readonly durationMs?: number;
|
|
57
71
|
}
|
|
58
72
|
/**
|
|
59
|
-
*
|
|
60
|
-
* what is supported instead of implying blanket protocol compatibility.
|
|
61
|
-
*
|
|
62
|
-
*
|
|
73
|
+
* Describes an adapter's supported surface for diagnostics
|
|
63
74
|
*/
|
|
64
75
|
interface AdapterDescriptor {
|
|
65
76
|
readonly name: string;
|
|
@@ -197,10 +208,10 @@ interface PaymentChallenge {
|
|
|
197
208
|
*
|
|
198
209
|
* `accepts` alone is not that document: v2 moves the resource description
|
|
199
210
|
* out of the individual requirements and up onto the envelope, and the
|
|
200
|
-
* protocol version rides there too. Protocol adapters
|
|
201
|
-
*
|
|
202
|
-
* rather than reassembling it, so every surface offers the same
|
|
203
|
-
* instead of each building its own from parts. Opaque to core.
|
|
211
|
+
* protocol version rides there too. Protocol adapters with a native channel
|
|
212
|
+
* for it (x402's `PAYMENT-REQUIRED` header, MPP's `WWW-Authenticate`) send
|
|
213
|
+
* it there rather than reassembling it, so every surface offers the same
|
|
214
|
+
* challenge instead of each building its own from parts. Opaque to core.
|
|
204
215
|
*/
|
|
205
216
|
readonly envelope?: Readonly<Record<string, unknown>>;
|
|
206
217
|
}
|
|
@@ -337,4 +348,4 @@ interface IdGenerator {
|
|
|
337
348
|
}
|
|
338
349
|
declare const systemClock: Clock;
|
|
339
350
|
|
|
340
|
-
export { type AdapterDescriptor as A, type BackendHandler as B, type Clock as C, type DecimalAmount as D, type IsoTimestamp as I, type JsonSchema as J, type Logger as L, NOOP_LOGGER as N, type PaymentMethodName as P, type ResourceRegistry as R, type CommerceResource as a, type PaymentSubmission as b, type AdapterHealth as c, type PaymentProvider as d, type IdGenerator as e, type AuthorizationMethodName as f, type BackendMethod as g, DEFAULT_BACKEND_TIMEOUT_MS as h,
|
|
351
|
+
export { type AdapterDescriptor as A, type BackendHandler as B, type Clock as C, type DecimalAmount as D, type IsoTimestamp as I, type JsonSchema as J, type Logger as L, NOOP_LOGGER as N, type PaymentMethodName as P, type ResourceRegistry as R, type CommerceResource as a, type PaymentSubmission as b, type AdapterHealth as c, type PaymentProvider as d, type IdGenerator as e, type AuthorizationMethodName as f, type BackendMethod as g, DEFAULT_BACKEND_TIMEOUT_MS as h, PAYMENT_METHOD_NAMES as i, PROTOCOL_NAMES as j, type PaymentChallenge as k, type PaymentContext as l, type PaymentRequirement as m, type PaymentResult as n, type PaymentSettlementContext as o, type PaymentVerificationContext as p, type Pricing as q, type ProtocolName as r, systemClock as s };
|
package/dist/x402.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { X as X402FacilitatorConfig } from './guardrails-Dmwi63KB.js';
|
|
2
2
|
export { F as FacilitatorAuth } from './guardrails-Dmwi63KB.js';
|
|
3
|
-
import { L as Logger, C as Clock, e as IdGenerator, d as PaymentProvider } from './runtime-
|
|
3
|
+
import { L as Logger, C as Clock, e as IdGenerator, d as PaymentProvider } from './runtime-DC5XQ9Cc.js';
|
|
4
4
|
|
|
5
5
|
interface NetworkProfile {
|
|
6
6
|
/** CAIP-2 identifier, e.g. `eip155:84532`. */
|