@agent-score/commerce 2.0.2 → 2.1.1
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 +26 -11
- package/dist/_core-kI7FRAiZ.d.mts +10 -0
- package/dist/_core-kI7FRAiZ.d.ts +10 -0
- package/dist/challenge/index.d.mts +3 -3
- package/dist/challenge/index.d.ts +3 -3
- package/dist/challenge/index.js +21 -14
- package/dist/challenge/index.js.map +1 -1
- package/dist/challenge/index.mjs +21 -14
- package/dist/challenge/index.mjs.map +1 -1
- package/dist/{checkout-jNUIql6D.d.mts → checkout-BRw_caGr.d.mts} +13 -33
- package/dist/{checkout-DhSj_h94.d.ts → checkout-CuSNUJFX.d.ts} +13 -33
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/core.mjs +1 -1
- package/dist/core.mjs.map +1 -1
- package/dist/default_rails-C5gKZJMI.d.ts +198 -0
- package/dist/default_rails-XFCuRddA.d.mts +198 -0
- package/dist/discovery/index.d.mts +5 -5
- package/dist/discovery/index.d.ts +5 -5
- package/dist/discovery/index.js +14 -1
- package/dist/discovery/index.js.map +1 -1
- package/dist/discovery/index.mjs +14 -1
- package/dist/discovery/index.mjs.map +1 -1
- package/dist/identity/express.d.mts +7 -3
- package/dist/identity/express.d.ts +7 -3
- package/dist/identity/express.js +39 -96
- package/dist/identity/express.js.map +1 -1
- package/dist/identity/express.mjs +37 -87
- package/dist/identity/express.mjs.map +1 -1
- package/dist/identity/fastify.d.mts +4 -4
- package/dist/identity/fastify.d.ts +4 -4
- package/dist/identity/fastify.js +60 -96
- package/dist/identity/fastify.js.map +1 -1
- package/dist/identity/fastify.mjs +58 -87
- package/dist/identity/fastify.mjs.map +1 -1
- package/dist/identity/hono.d.mts +11 -3
- package/dist/identity/hono.d.ts +11 -3
- package/dist/identity/hono.js +39 -93
- package/dist/identity/hono.js.map +1 -1
- package/dist/identity/hono.mjs +37 -84
- package/dist/identity/hono.mjs.map +1 -1
- package/dist/identity/nextjs.d.mts +10 -3
- package/dist/identity/nextjs.d.ts +10 -3
- package/dist/identity/nextjs.js +49 -93
- package/dist/identity/nextjs.js.map +1 -1
- package/dist/identity/nextjs.mjs +46 -84
- package/dist/identity/nextjs.mjs.map +1 -1
- package/dist/identity/policy.js +22 -23317
- package/dist/identity/policy.js.map +1 -1
- package/dist/identity/policy.mjs +1 -23320
- package/dist/identity/policy.mjs.map +1 -1
- package/dist/identity/web.d.mts +9 -3
- package/dist/identity/web.d.ts +9 -3
- package/dist/identity/web.js +45 -93
- package/dist/identity/web.js.map +1 -1
- package/dist/identity/web.mjs +42 -84
- package/dist/identity/web.mjs.map +1 -1
- package/dist/index.d.mts +621 -90
- package/dist/index.d.ts +621 -90
- package/dist/index.js +1202 -328
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1188 -327
- package/dist/index.mjs.map +1 -1
- package/dist/middleware/express.d.mts +10 -0
- package/dist/middleware/express.d.ts +10 -0
- package/dist/middleware/express.js +128 -0
- package/dist/middleware/express.js.map +1 -0
- package/dist/middleware/express.mjs +91 -0
- package/dist/middleware/express.mjs.map +1 -0
- package/dist/middleware/fastify.d.mts +10 -0
- package/dist/middleware/fastify.d.ts +10 -0
- package/dist/middleware/fastify.js +127 -0
- package/dist/middleware/fastify.js.map +1 -0
- package/dist/middleware/fastify.mjs +90 -0
- package/dist/middleware/fastify.mjs.map +1 -0
- package/dist/middleware/hono.d.mts +10 -0
- package/dist/middleware/hono.d.ts +10 -0
- package/dist/middleware/hono.js +122 -0
- package/dist/middleware/hono.js.map +1 -0
- package/dist/middleware/hono.mjs +85 -0
- package/dist/middleware/hono.mjs.map +1 -0
- package/dist/middleware/nextjs.d.mts +22 -0
- package/dist/middleware/nextjs.d.ts +22 -0
- package/dist/middleware/nextjs.js +143 -0
- package/dist/middleware/nextjs.js.map +1 -0
- package/dist/middleware/nextjs.mjs +105 -0
- package/dist/middleware/nextjs.mjs.map +1 -0
- package/dist/middleware/web.d.mts +25 -0
- package/dist/middleware/web.d.ts +25 -0
- package/dist/middleware/web.js +128 -0
- package/dist/middleware/web.js.map +1 -0
- package/dist/middleware/web.mjs +91 -0
- package/dist/middleware/web.mjs.map +1 -0
- package/dist/payment/index.d.mts +32 -21
- package/dist/payment/index.d.ts +32 -21
- package/dist/payment/index.js +215 -12
- package/dist/payment/index.js.map +1 -1
- package/dist/payment/index.mjs +205 -12
- package/dist/payment/index.mjs.map +1 -1
- package/dist/{pricing-CxzwyiO6.d.mts → pricing-4n5Ota0D.d.mts} +14 -4
- package/dist/{pricing-CQ9DIFaw.d.ts → pricing-DHfH3ogG.d.ts} +14 -4
- package/dist/{rail_spec-XP0wKgJV.d.mts → rail_spec-D6qzh3J0.d.mts} +1 -1
- package/dist/{rail_spec-XP0wKgJV.d.ts → rail_spec-D6qzh3J0.d.ts} +1 -1
- package/dist/stripe-multichain/index.d.mts +150 -47
- package/dist/stripe-multichain/index.d.ts +150 -47
- package/dist/stripe-multichain/index.js +19799 -43
- package/dist/stripe-multichain/index.js.map +1 -1
- package/dist/stripe-multichain/index.mjs +19808 -28
- package/dist/stripe-multichain/index.mjs.map +1 -1
- package/dist/{x402_server-hgQzWQwB.d.mts → x402_server-Ciz2mls2.d.mts} +1 -1
- package/dist/{x402_server-hgQzWQwB.d.ts → x402_server-Ciz2mls2.d.ts} +1 -1
- package/package.json +43 -5
- package/dist/_response-BFYN3b6i.d.mts +0 -142
- package/dist/_response-_iPD5AIj.d.ts +0 -142
- package/dist/solana-Cds87OTu.d.mts +0 -67
- package/dist/solana-Cds87OTu.d.ts +0 -67
package/dist/index.mjs
CHANGED
|
@@ -31,6 +31,27 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
31
31
|
mod
|
|
32
32
|
));
|
|
33
33
|
|
|
34
|
+
// src/payment/network_kind.ts
|
|
35
|
+
function readNetwork(input) {
|
|
36
|
+
if (typeof input === "string") return input;
|
|
37
|
+
if (input && typeof input === "object") {
|
|
38
|
+
const network = input.network;
|
|
39
|
+
return typeof network === "string" ? network : "";
|
|
40
|
+
}
|
|
41
|
+
return "";
|
|
42
|
+
}
|
|
43
|
+
function isEvmNetwork(input) {
|
|
44
|
+
return readNetwork(input).startsWith("eip155:");
|
|
45
|
+
}
|
|
46
|
+
function isSolanaNetwork(input) {
|
|
47
|
+
return readNetwork(input).startsWith("solana:");
|
|
48
|
+
}
|
|
49
|
+
var init_network_kind = __esm({
|
|
50
|
+
"src/payment/network_kind.ts"() {
|
|
51
|
+
"use strict";
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
34
55
|
// src/identity/ucp.ts
|
|
35
56
|
function ucpSigningKeyFromJWKImpl(jwk) {
|
|
36
57
|
if (!jwk || typeof jwk !== "object") {
|
|
@@ -160,7 +181,7 @@ function isTempoSessionRailSpec(s) {
|
|
|
160
181
|
}
|
|
161
182
|
function mppRailToNetworkEntry(spec) {
|
|
162
183
|
if (isTempoSessionRailSpec(spec)) return tempoSessionToNetworkEntry(spec);
|
|
163
|
-
if ("rpcUrl" in spec || "tokenProgram" in spec || (spec
|
|
184
|
+
if ("rpcUrl" in spec || "tokenProgram" in spec || isSolanaNetwork(spec)) {
|
|
164
185
|
return solanaMppToNetworkEntry(spec);
|
|
165
186
|
}
|
|
166
187
|
if (isTempoRailSpec(spec)) return tempoToNetworkEntry(spec);
|
|
@@ -217,6 +238,7 @@ var UCPSigningKey, DEFAULT_VERSION, AGENTSCORE_CAPABILITY_NAME, AGENTSCORE_CAPAB
|
|
|
217
238
|
var init_ucp = __esm({
|
|
218
239
|
"src/identity/ucp.ts"() {
|
|
219
240
|
"use strict";
|
|
241
|
+
init_network_kind();
|
|
220
242
|
UCPSigningKey = {
|
|
221
243
|
fromJWK: ucpSigningKeyFromJWKImpl
|
|
222
244
|
};
|
|
@@ -636,64 +658,6 @@ var init_ucp_jwks = __esm({
|
|
|
636
658
|
}
|
|
637
659
|
});
|
|
638
660
|
|
|
639
|
-
// src/payment/usdc.ts
|
|
640
|
-
var USDC;
|
|
641
|
-
var init_usdc = __esm({
|
|
642
|
-
"src/payment/usdc.ts"() {
|
|
643
|
-
"use strict";
|
|
644
|
-
USDC = {
|
|
645
|
-
base: {
|
|
646
|
-
mainnet: { address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", decimals: 6 },
|
|
647
|
-
sepolia: { address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", decimals: 6 }
|
|
648
|
-
},
|
|
649
|
-
solana: {
|
|
650
|
-
mainnet: { mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", decimals: 6 },
|
|
651
|
-
devnet: { mint: "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", decimals: 6 }
|
|
652
|
-
},
|
|
653
|
-
tempo: {
|
|
654
|
-
mainnet: { address: "0x20C000000000000000000000b9537d11c60E8b50", decimals: 6 },
|
|
655
|
-
testnet: { address: "0x20c0000000000000000000000000000000000000", decimals: 6 }
|
|
656
|
-
}
|
|
657
|
-
};
|
|
658
|
-
}
|
|
659
|
-
});
|
|
660
|
-
|
|
661
|
-
// src/payment/wwwauthenticate.ts
|
|
662
|
-
function paymentRequiredHeader({
|
|
663
|
-
x402Version,
|
|
664
|
-
accepts,
|
|
665
|
-
resource
|
|
666
|
-
}) {
|
|
667
|
-
return Buffer.from(JSON.stringify({ x402Version, accepts, ...resource ? { resource } : {} })).toString("base64");
|
|
668
|
-
}
|
|
669
|
-
var init_wwwauthenticate = __esm({
|
|
670
|
-
"src/payment/wwwauthenticate.ts"() {
|
|
671
|
-
"use strict";
|
|
672
|
-
}
|
|
673
|
-
});
|
|
674
|
-
|
|
675
|
-
// src/payment/networks.ts
|
|
676
|
-
var networks;
|
|
677
|
-
var init_networks = __esm({
|
|
678
|
-
"src/payment/networks.ts"() {
|
|
679
|
-
"use strict";
|
|
680
|
-
networks = {
|
|
681
|
-
base: {
|
|
682
|
-
mainnet: { caip2: "eip155:8453", chainId: 8453 },
|
|
683
|
-
sepolia: { caip2: "eip155:84532", chainId: 84532 }
|
|
684
|
-
},
|
|
685
|
-
solana: {
|
|
686
|
-
mainnet: { caip2: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp" },
|
|
687
|
-
devnet: { caip2: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1" }
|
|
688
|
-
},
|
|
689
|
-
tempo: {
|
|
690
|
-
mainnet: { caip2: "eip155:4217", chainId: 4217 },
|
|
691
|
-
testnet: { caip2: "eip155:42431", chainId: 42431 }
|
|
692
|
-
}
|
|
693
|
-
};
|
|
694
|
-
}
|
|
695
|
-
});
|
|
696
|
-
|
|
697
661
|
// node_modules/ox/_esm/core/Abi.js
|
|
698
662
|
var init_Abi = __esm({
|
|
699
663
|
"node_modules/ox/_esm/core/Abi.js"() {
|
|
@@ -20305,6 +20269,64 @@ var init_dist2 = __esm({
|
|
|
20305
20269
|
}
|
|
20306
20270
|
});
|
|
20307
20271
|
|
|
20272
|
+
// src/payment/usdc.ts
|
|
20273
|
+
var USDC;
|
|
20274
|
+
var init_usdc = __esm({
|
|
20275
|
+
"src/payment/usdc.ts"() {
|
|
20276
|
+
"use strict";
|
|
20277
|
+
USDC = {
|
|
20278
|
+
base: {
|
|
20279
|
+
mainnet: { address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", decimals: 6 },
|
|
20280
|
+
sepolia: { address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", decimals: 6 }
|
|
20281
|
+
},
|
|
20282
|
+
solana: {
|
|
20283
|
+
mainnet: { mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", decimals: 6 },
|
|
20284
|
+
devnet: { mint: "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", decimals: 6 }
|
|
20285
|
+
},
|
|
20286
|
+
tempo: {
|
|
20287
|
+
mainnet: { address: "0x20C000000000000000000000b9537d11c60E8b50", decimals: 6 },
|
|
20288
|
+
testnet: { address: "0x20c0000000000000000000000000000000000000", decimals: 6 }
|
|
20289
|
+
}
|
|
20290
|
+
};
|
|
20291
|
+
}
|
|
20292
|
+
});
|
|
20293
|
+
|
|
20294
|
+
// src/payment/wwwauthenticate.ts
|
|
20295
|
+
function paymentRequiredHeader({
|
|
20296
|
+
x402Version,
|
|
20297
|
+
accepts,
|
|
20298
|
+
resource
|
|
20299
|
+
}) {
|
|
20300
|
+
return Buffer.from(JSON.stringify({ x402Version, accepts, ...resource ? { resource } : {} })).toString("base64");
|
|
20301
|
+
}
|
|
20302
|
+
var init_wwwauthenticate = __esm({
|
|
20303
|
+
"src/payment/wwwauthenticate.ts"() {
|
|
20304
|
+
"use strict";
|
|
20305
|
+
}
|
|
20306
|
+
});
|
|
20307
|
+
|
|
20308
|
+
// src/payment/networks.ts
|
|
20309
|
+
var networks;
|
|
20310
|
+
var init_networks = __esm({
|
|
20311
|
+
"src/payment/networks.ts"() {
|
|
20312
|
+
"use strict";
|
|
20313
|
+
networks = {
|
|
20314
|
+
base: {
|
|
20315
|
+
mainnet: { caip2: "eip155:8453", chainId: 8453 },
|
|
20316
|
+
sepolia: { caip2: "eip155:84532", chainId: 84532 }
|
|
20317
|
+
},
|
|
20318
|
+
solana: {
|
|
20319
|
+
mainnet: { caip2: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp" },
|
|
20320
|
+
devnet: { caip2: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1" }
|
|
20321
|
+
},
|
|
20322
|
+
tempo: {
|
|
20323
|
+
mainnet: { caip2: "eip155:4217", chainId: 4217 },
|
|
20324
|
+
testnet: { caip2: "eip155:42431", chainId: 42431 }
|
|
20325
|
+
}
|
|
20326
|
+
};
|
|
20327
|
+
}
|
|
20328
|
+
});
|
|
20329
|
+
|
|
20308
20330
|
// src/payment/rails.ts
|
|
20309
20331
|
function lookupRail(name) {
|
|
20310
20332
|
return rails[name];
|
|
@@ -20968,6 +20990,20 @@ var RESERVED_FIELDS = /* @__PURE__ */ new Set([
|
|
|
20968
20990
|
"actual_signer",
|
|
20969
20991
|
"linked_wallets"
|
|
20970
20992
|
]);
|
|
20993
|
+
function buildVerificationRequiredBody(reason, opts = {}) {
|
|
20994
|
+
const body = denialReasonToBody(reason);
|
|
20995
|
+
body.error = {
|
|
20996
|
+
code: "operator_verification_required",
|
|
20997
|
+
message: opts.message ?? "Identity verification is required."
|
|
20998
|
+
};
|
|
20999
|
+
if (opts.agentInstructions !== void 0) {
|
|
21000
|
+
body.agent_instructions = opts.agentInstructions;
|
|
21001
|
+
}
|
|
21002
|
+
if (opts.extra) {
|
|
21003
|
+
for (const [k, v] of Object.entries(opts.extra)) body[k] = v;
|
|
21004
|
+
}
|
|
21005
|
+
return body;
|
|
21006
|
+
}
|
|
20971
21007
|
function denialReasonToBody(reason) {
|
|
20972
21008
|
const message = reason.message ?? DEFAULT_MESSAGES[reason.code];
|
|
20973
21009
|
const body = { error: { code: reason.code, message } };
|
|
@@ -21125,7 +21161,7 @@ function createAgentScoreCore(options) {
|
|
|
21125
21161
|
} = options;
|
|
21126
21162
|
const baseUrl = stripTrailingSlashes(rawBaseUrl);
|
|
21127
21163
|
const agentMemoryHint = buildAgentMemoryHint();
|
|
21128
|
-
const defaultUa = `@agent-score/commerce@${"2.
|
|
21164
|
+
const defaultUa = `@agent-score/commerce@${"2.1.1"}`;
|
|
21129
21165
|
const userAgentHeader = userAgent ? `${userAgent} (${defaultUa})` : defaultUa;
|
|
21130
21166
|
const sdk = new AgentScore({ apiKey, baseUrl, userAgent: userAgentHeader });
|
|
21131
21167
|
const sessionSdkCache = /* @__PURE__ */ new Map();
|
|
@@ -21417,6 +21453,13 @@ function createAgentScoreCore(options) {
|
|
|
21417
21453
|
return { evaluate, captureWallet, getSignerVerdict };
|
|
21418
21454
|
}
|
|
21419
21455
|
|
|
21456
|
+
// src/_headers.ts
|
|
21457
|
+
function normalizeHeadersToLowercase(headers) {
|
|
21458
|
+
const out = {};
|
|
21459
|
+
for (const [k, v] of Object.entries(headers)) out[k.toLowerCase()] = v;
|
|
21460
|
+
return out;
|
|
21461
|
+
}
|
|
21462
|
+
|
|
21420
21463
|
// src/signer.ts
|
|
21421
21464
|
var TOKEN_PROGRAM = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
|
|
21422
21465
|
var TOKEN_2022_PROGRAM = "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb";
|
|
@@ -21499,13 +21542,8 @@ async function extractPaymentSignerFromAuth(authHeader, x402PaymentHeader) {
|
|
|
21499
21542
|
function readX402PaymentHeader(request) {
|
|
21500
21543
|
return request.headers.get("payment-signature") ?? request.headers.get("x-payment") ?? void 0;
|
|
21501
21544
|
}
|
|
21502
|
-
function lowerHeaders(headers) {
|
|
21503
|
-
const out = {};
|
|
21504
|
-
for (const [k, v] of Object.entries(headers)) out[k.toLowerCase()] = v;
|
|
21505
|
-
return out;
|
|
21506
|
-
}
|
|
21507
21545
|
async function extractSignerForPrecheck(headers) {
|
|
21508
|
-
const lower =
|
|
21546
|
+
const lower = normalizeHeadersToLowercase(headers);
|
|
21509
21547
|
const x402 = lower["payment-signature"] ?? lower["x-payment"];
|
|
21510
21548
|
if (x402) {
|
|
21511
21549
|
const signer = await extractPaymentSignerFromAuth(void 0, x402);
|
|
@@ -21520,7 +21558,7 @@ async function extractSignerForPrecheck(headers) {
|
|
|
21520
21558
|
|
|
21521
21559
|
// src/identity/a2a.ts
|
|
21522
21560
|
var PROTOCOL_VERSION = "1.0";
|
|
21523
|
-
var
|
|
21561
|
+
var DEFAULT_TRANSPORT = "JSONRPC";
|
|
21524
21562
|
var DEFAULT_INPUT_MODE = "application/json";
|
|
21525
21563
|
var DEFAULT_OUTPUT_MODE = "application/json";
|
|
21526
21564
|
var UCP_A2A_EXTENSION_URI = "https://ucp.dev/2026-04-08/specification/reference";
|
|
@@ -21540,30 +21578,33 @@ function buildA2AAgentCard(input) {
|
|
|
21540
21578
|
}
|
|
21541
21579
|
const capabilities = {};
|
|
21542
21580
|
if (input.streaming !== void 0) capabilities.streaming = input.streaming;
|
|
21543
|
-
if (input.
|
|
21581
|
+
if (input.pushNotifications !== void 0) capabilities.pushNotifications = input.pushNotifications;
|
|
21582
|
+
if (input.stateTransitionHistory !== void 0) capabilities.stateTransitionHistory = input.stateTransitionHistory;
|
|
21544
21583
|
if (input.extensions && input.extensions.length > 0) capabilities.extensions = input.extensions;
|
|
21545
|
-
if (input.extended_agent_card !== void 0) capabilities.extended_agent_card = input.extended_agent_card;
|
|
21546
|
-
const primaryInterface = {
|
|
21547
|
-
url: input.url,
|
|
21548
|
-
protocol_binding: input.protocol_binding ?? DEFAULT_PROTOCOL_BINDING,
|
|
21549
|
-
protocol_version: input.a2a_protocol_version ?? PROTOCOL_VERSION
|
|
21550
|
-
};
|
|
21551
21584
|
const card = {
|
|
21552
21585
|
name: input.name,
|
|
21553
21586
|
description: input.description,
|
|
21554
|
-
|
|
21587
|
+
url: input.url,
|
|
21588
|
+
preferredTransport: input.preferredTransport ?? "HTTP+JSON",
|
|
21589
|
+
protocolVersion: input.protocolVersion ?? PROTOCOL_VERSION,
|
|
21555
21590
|
version: input.version ?? "1.0.0",
|
|
21556
21591
|
capabilities,
|
|
21557
|
-
|
|
21558
|
-
|
|
21592
|
+
defaultInputModes: input.defaultInputModes ?? [DEFAULT_INPUT_MODE],
|
|
21593
|
+
defaultOutputModes: input.defaultOutputModes ?? [DEFAULT_OUTPUT_MODE],
|
|
21559
21594
|
skills: input.skills
|
|
21560
21595
|
};
|
|
21596
|
+
if (input.additionalInterfaces !== void 0 && input.additionalInterfaces.length > 0) {
|
|
21597
|
+
card.additionalInterfaces = input.additionalInterfaces;
|
|
21598
|
+
}
|
|
21561
21599
|
if (input.provider !== void 0) card.provider = input.provider;
|
|
21562
|
-
if (input.
|
|
21563
|
-
if (input.
|
|
21600
|
+
if (input.documentationUrl !== void 0) card.documentationUrl = input.documentationUrl;
|
|
21601
|
+
if (input.iconUrl !== void 0) card.iconUrl = input.iconUrl;
|
|
21602
|
+
if (input.supportsAuthenticatedExtendedCard !== void 0) {
|
|
21603
|
+
card.supportsAuthenticatedExtendedCard = input.supportsAuthenticatedExtendedCard;
|
|
21604
|
+
}
|
|
21564
21605
|
if (input.signatures !== void 0 && input.signatures.length > 0) card.signatures = input.signatures;
|
|
21565
|
-
if (input.
|
|
21566
|
-
if (input.
|
|
21606
|
+
if (input.security !== void 0) card.security = input.security;
|
|
21607
|
+
if (input.securitySchemes !== void 0) card.securitySchemes = input.securitySchemes;
|
|
21567
21608
|
if (input.extras) {
|
|
21568
21609
|
for (const [k, v] of Object.entries(input.extras)) {
|
|
21569
21610
|
card[k] = v;
|
|
@@ -21571,89 +21612,250 @@ function buildA2AAgentCard(input) {
|
|
|
21571
21612
|
}
|
|
21572
21613
|
return card;
|
|
21573
21614
|
}
|
|
21615
|
+
var A2A_PROTOCOL_VERSION = PROTOCOL_VERSION;
|
|
21616
|
+
var A2A_DEFAULT_TRANSPORT = DEFAULT_TRANSPORT;
|
|
21574
21617
|
|
|
21575
21618
|
// src/index.ts
|
|
21576
21619
|
init_ucp();
|
|
21577
21620
|
init_ucp_jwks();
|
|
21578
21621
|
|
|
21579
|
-
// src/
|
|
21580
|
-
|
|
21581
|
-
|
|
21582
|
-
|
|
21583
|
-
|
|
21584
|
-
|
|
21585
|
-
|
|
21586
|
-
|
|
21587
|
-
|
|
21588
|
-
|
|
21589
|
-
|
|
21590
|
-
|
|
21591
|
-
|
|
21592
|
-
token: USDC.tempo.mainnet.address,
|
|
21593
|
-
symbol: "USDC.e",
|
|
21594
|
-
decimals: 6,
|
|
21595
|
-
testnet: false,
|
|
21596
|
-
recommend: "both"
|
|
21597
|
-
},
|
|
21598
|
-
x402Base: {
|
|
21599
|
-
network: "eip155:8453",
|
|
21600
|
-
chainId: 8453,
|
|
21601
|
-
token: USDC.base.mainnet.address,
|
|
21602
|
-
symbol: "USDC",
|
|
21603
|
-
decimals: 6,
|
|
21604
|
-
mode: "exact"
|
|
21605
|
-
},
|
|
21606
|
-
solanaMpp: {
|
|
21607
|
-
network: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
|
|
21608
|
-
token: USDC.solana.mainnet.mint,
|
|
21609
|
-
symbol: "USDC",
|
|
21610
|
-
decimals: 6
|
|
21611
|
-
},
|
|
21612
|
-
stripe: {
|
|
21613
|
-
rails: ["card", "link", "shared_payment_token"]
|
|
21614
|
-
},
|
|
21615
|
-
tempoSession: {
|
|
21616
|
-
currency: USDC.tempo.mainnet.address,
|
|
21617
|
-
testnet: false
|
|
21622
|
+
// src/errors.ts
|
|
21623
|
+
var CheckoutValidationError = class extends Error {
|
|
21624
|
+
code;
|
|
21625
|
+
action;
|
|
21626
|
+
status;
|
|
21627
|
+
extra;
|
|
21628
|
+
constructor(opts) {
|
|
21629
|
+
super(opts.message);
|
|
21630
|
+
this.name = "CheckoutValidationError";
|
|
21631
|
+
this.code = opts.code;
|
|
21632
|
+
this.action = opts.action ?? "fix_request";
|
|
21633
|
+
this.status = opts.status ?? 400;
|
|
21634
|
+
this.extra = opts.extra;
|
|
21618
21635
|
}
|
|
21619
21636
|
};
|
|
21620
21637
|
|
|
21621
|
-
// src/
|
|
21622
|
-
|
|
21623
|
-
|
|
21624
|
-
|
|
21625
|
-
|
|
21626
|
-
|
|
21627
|
-
|
|
21628
|
-
|
|
21629
|
-
|
|
21630
|
-
|
|
21631
|
-
|
|
21632
|
-
|
|
21633
|
-
|
|
21634
|
-
|
|
21635
|
-
|
|
21636
|
-
|
|
21637
|
-
|
|
21638
|
-
|
|
21639
|
-
|
|
21640
|
-
if (
|
|
21641
|
-
|
|
21642
|
-
|
|
21643
|
-
|
|
21644
|
-
|
|
21645
|
-
|
|
21646
|
-
|
|
21647
|
-
|
|
21648
|
-
pay_to: await resolveRecipient(x402_base.recipient)
|
|
21649
|
-
});
|
|
21638
|
+
// src/identity/policy.ts
|
|
21639
|
+
function buildGateFromPolicy(policy, base) {
|
|
21640
|
+
if (!policy || !policy.enforcement) return null;
|
|
21641
|
+
return {
|
|
21642
|
+
apiKey: base.apiKey,
|
|
21643
|
+
...base.baseUrl !== void 0 && { baseUrl: base.baseUrl },
|
|
21644
|
+
...policy.requireKyc !== void 0 && { requireKyc: policy.requireKyc },
|
|
21645
|
+
...policy.requireSanctionsClear !== void 0 && {
|
|
21646
|
+
requireSanctionsClear: policy.requireSanctionsClear
|
|
21647
|
+
},
|
|
21648
|
+
...policy.minAge !== void 0 && { minAge: policy.minAge },
|
|
21649
|
+
...policy.allowedJurisdictions !== void 0 && {
|
|
21650
|
+
allowedJurisdictions: [...policy.allowedJurisdictions]
|
|
21651
|
+
}
|
|
21652
|
+
};
|
|
21653
|
+
}
|
|
21654
|
+
async function runGateWithEnforcement(enforcement, runGate) {
|
|
21655
|
+
if (!runGate || !enforcement) return { status: "anonymous" };
|
|
21656
|
+
const outcome = await runGate();
|
|
21657
|
+
if (outcome.ok) return { status: "verified" };
|
|
21658
|
+
if (enforcement === "hard") {
|
|
21659
|
+
return {
|
|
21660
|
+
status: "denied",
|
|
21661
|
+
denialStatus: outcome.status,
|
|
21662
|
+
denialBody: outcome.body,
|
|
21663
|
+
...outcome.reason !== void 0 && { denialReason: outcome.reason }
|
|
21664
|
+
};
|
|
21650
21665
|
}
|
|
21651
|
-
|
|
21652
|
-
|
|
21653
|
-
|
|
21654
|
-
|
|
21655
|
-
|
|
21656
|
-
|
|
21666
|
+
return {
|
|
21667
|
+
status: "unverified",
|
|
21668
|
+
denialStatus: outcome.status,
|
|
21669
|
+
denialBody: outcome.body,
|
|
21670
|
+
...outcome.reason !== void 0 && { denialReason: outcome.reason }
|
|
21671
|
+
};
|
|
21672
|
+
}
|
|
21673
|
+
function shippingCountryAllowed(country, policy) {
|
|
21674
|
+
if (!policy?.allowedShippingCountries || policy.allowedShippingCountries.length === 0) return true;
|
|
21675
|
+
const allowed = new Set(policy.allowedShippingCountries.map((c) => c.toUpperCase()));
|
|
21676
|
+
return allowed.has(country.toUpperCase());
|
|
21677
|
+
}
|
|
21678
|
+
function shippingStateAllowed(state, country, policy) {
|
|
21679
|
+
if (!policy?.allowedShippingStates || policy.allowedShippingStates.length === 0) return true;
|
|
21680
|
+
if (country.toUpperCase() !== "US") return true;
|
|
21681
|
+
const allowed = new Set(policy.allowedShippingStates.map((s) => s.toUpperCase()));
|
|
21682
|
+
return allowed.has(state.toUpperCase());
|
|
21683
|
+
}
|
|
21684
|
+
function validateShippingAgainstPolicy(opts) {
|
|
21685
|
+
const code = opts.errorCode ?? "unsupported_jurisdiction";
|
|
21686
|
+
const action = opts.errorAction ?? "change_shipping_state";
|
|
21687
|
+
const item = opts.productName ? `'${opts.productName}'` : "this item";
|
|
21688
|
+
if (!shippingCountryAllowed(opts.country, opts.policy)) {
|
|
21689
|
+
throw new CheckoutValidationError({
|
|
21690
|
+
code,
|
|
21691
|
+
message: opts.countryMessage ?? `We can't ship ${item} to ${opts.country.toUpperCase() || "<unset>"}.`,
|
|
21692
|
+
action
|
|
21693
|
+
});
|
|
21694
|
+
}
|
|
21695
|
+
if (!shippingStateAllowed(opts.state, opts.country, opts.policy)) {
|
|
21696
|
+
throw new CheckoutValidationError({
|
|
21697
|
+
code,
|
|
21698
|
+
message: opts.stateMessage ?? `We can't ship ${item} to ${opts.state.toUpperCase() || "<unset>"}.`,
|
|
21699
|
+
action
|
|
21700
|
+
});
|
|
21701
|
+
}
|
|
21702
|
+
}
|
|
21703
|
+
|
|
21704
|
+
// src/identity/tokens.ts
|
|
21705
|
+
import { createHash } from "crypto";
|
|
21706
|
+
|
|
21707
|
+
// src/payment/payment_header.ts
|
|
21708
|
+
function toTitleCase(name) {
|
|
21709
|
+
return name.replace(/(^|-)([a-z])/g, (_m, sep, c) => sep + c.toUpperCase());
|
|
21710
|
+
}
|
|
21711
|
+
function readHeader(headers, name) {
|
|
21712
|
+
if (typeof headers.get === "function") {
|
|
21713
|
+
return headers.get(name);
|
|
21714
|
+
}
|
|
21715
|
+
const rec = headers;
|
|
21716
|
+
const v = rec[name] ?? rec[name.toLowerCase()] ?? rec[toTitleCase(name)];
|
|
21717
|
+
if (typeof v === "string") return v;
|
|
21718
|
+
if (Array.isArray(v) && typeof v[0] === "string") return v[0];
|
|
21719
|
+
return null;
|
|
21720
|
+
}
|
|
21721
|
+
function asHeaders(input) {
|
|
21722
|
+
return typeof input.headers === "object" && input instanceof Request ? input.headers : input;
|
|
21723
|
+
}
|
|
21724
|
+
function hasPaymentHeader(input) {
|
|
21725
|
+
const headers = asHeaders(input);
|
|
21726
|
+
return Boolean(
|
|
21727
|
+
readHeader(headers, "payment-signature") || readHeader(headers, "x-payment") || readHeader(headers, "authorization")?.startsWith("Payment ")
|
|
21728
|
+
);
|
|
21729
|
+
}
|
|
21730
|
+
function hasX402Header(input) {
|
|
21731
|
+
const headers = asHeaders(input);
|
|
21732
|
+
return Boolean(readHeader(headers, "payment-signature") || readHeader(headers, "x-payment"));
|
|
21733
|
+
}
|
|
21734
|
+
function hasMppxHeader(input) {
|
|
21735
|
+
const headers = asHeaders(input);
|
|
21736
|
+
return Boolean(readHeader(headers, "authorization")?.startsWith("Payment "));
|
|
21737
|
+
}
|
|
21738
|
+
|
|
21739
|
+
// src/identity/tokens.ts
|
|
21740
|
+
function hashOperatorToken(plaintext) {
|
|
21741
|
+
return createHash("sha256").update(plaintext, "utf8").digest("hex");
|
|
21742
|
+
}
|
|
21743
|
+
function extractOwnerScope(input) {
|
|
21744
|
+
const headers = asHeaders(input);
|
|
21745
|
+
const walletAddress = readHeader(headers, "x-wallet-address");
|
|
21746
|
+
const operatorToken = readHeader(headers, "x-operator-token");
|
|
21747
|
+
return {
|
|
21748
|
+
...walletAddress ? { walletAddress } : {},
|
|
21749
|
+
...operatorToken ? { operatorTokenHash: hashOperatorToken(operatorToken) } : {}
|
|
21750
|
+
};
|
|
21751
|
+
}
|
|
21752
|
+
|
|
21753
|
+
// src/checkout.ts
|
|
21754
|
+
import { randomUUID } from "crypto";
|
|
21755
|
+
|
|
21756
|
+
// src/_mppx_receipt.ts
|
|
21757
|
+
function extractMppxReceiptHeaderFromRaw(raw) {
|
|
21758
|
+
if (!raw || typeof raw !== "object" || !("withReceipt" in raw)) return null;
|
|
21759
|
+
const fn = raw.withReceipt;
|
|
21760
|
+
if (typeof fn !== "function") return null;
|
|
21761
|
+
try {
|
|
21762
|
+
const wrapped = fn.call(raw, new Response());
|
|
21763
|
+
return wrapped.headers.get("Payment-Receipt");
|
|
21764
|
+
} catch {
|
|
21765
|
+
return null;
|
|
21766
|
+
}
|
|
21767
|
+
}
|
|
21768
|
+
async function extractMppxReceiptMethod(header) {
|
|
21769
|
+
try {
|
|
21770
|
+
const { Receipt } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
|
|
21771
|
+
return Receipt.deserialize(header).method;
|
|
21772
|
+
} catch {
|
|
21773
|
+
return void 0;
|
|
21774
|
+
}
|
|
21775
|
+
}
|
|
21776
|
+
async function deriveMppxReceiptMethod(raw) {
|
|
21777
|
+
const direct = raw?.receipt?.method;
|
|
21778
|
+
if (direct) return direct;
|
|
21779
|
+
const header = extractMppxReceiptHeaderFromRaw(raw);
|
|
21780
|
+
if (!header) return void 0;
|
|
21781
|
+
return extractMppxReceiptMethod(header);
|
|
21782
|
+
}
|
|
21783
|
+
|
|
21784
|
+
// src/payment/rail_spec.ts
|
|
21785
|
+
init_usdc();
|
|
21786
|
+
async function resolveRecipient(r) {
|
|
21787
|
+
if (typeof r === "string") return r;
|
|
21788
|
+
return Promise.resolve(r());
|
|
21789
|
+
}
|
|
21790
|
+
var RAIL_SPEC_DEFAULTS = {
|
|
21791
|
+
tempo: {
|
|
21792
|
+
network: "tempo-mainnet",
|
|
21793
|
+
chainId: 4217,
|
|
21794
|
+
token: USDC.tempo.mainnet.address,
|
|
21795
|
+
symbol: "USDC.e",
|
|
21796
|
+
decimals: 6,
|
|
21797
|
+
testnet: false,
|
|
21798
|
+
recommend: "both"
|
|
21799
|
+
},
|
|
21800
|
+
x402Base: {
|
|
21801
|
+
network: "eip155:8453",
|
|
21802
|
+
chainId: 8453,
|
|
21803
|
+
token: USDC.base.mainnet.address,
|
|
21804
|
+
symbol: "USDC",
|
|
21805
|
+
decimals: 6,
|
|
21806
|
+
mode: "exact"
|
|
21807
|
+
},
|
|
21808
|
+
solanaMpp: {
|
|
21809
|
+
network: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
|
|
21810
|
+
token: USDC.solana.mainnet.mint,
|
|
21811
|
+
symbol: "USDC",
|
|
21812
|
+
decimals: 6
|
|
21813
|
+
},
|
|
21814
|
+
stripe: {
|
|
21815
|
+
rails: ["card", "link", "shared_payment_token"]
|
|
21816
|
+
},
|
|
21817
|
+
tempoSession: {
|
|
21818
|
+
currency: USDC.tempo.mainnet.address,
|
|
21819
|
+
testnet: false
|
|
21820
|
+
}
|
|
21821
|
+
};
|
|
21822
|
+
|
|
21823
|
+
// src/challenge/accepted_methods.ts
|
|
21824
|
+
async function buildAcceptedMethods({
|
|
21825
|
+
tempo,
|
|
21826
|
+
x402_base,
|
|
21827
|
+
solana_mpp,
|
|
21828
|
+
stripe
|
|
21829
|
+
}) {
|
|
21830
|
+
const out = [];
|
|
21831
|
+
if (tempo) {
|
|
21832
|
+
out.push({
|
|
21833
|
+
method: "tempo/charge",
|
|
21834
|
+
network: tempo.network ?? RAIL_SPEC_DEFAULTS.tempo.network,
|
|
21835
|
+
chain_id: tempo.chainId ?? RAIL_SPEC_DEFAULTS.tempo.chainId,
|
|
21836
|
+
token: tempo.token ?? RAIL_SPEC_DEFAULTS.tempo.token,
|
|
21837
|
+
symbol: tempo.symbol ?? RAIL_SPEC_DEFAULTS.tempo.symbol,
|
|
21838
|
+
decimals: tempo.decimals ?? RAIL_SPEC_DEFAULTS.tempo.decimals,
|
|
21839
|
+
pay_to: await resolveRecipient(tempo.recipient)
|
|
21840
|
+
});
|
|
21841
|
+
}
|
|
21842
|
+
if (x402_base) {
|
|
21843
|
+
out.push({
|
|
21844
|
+
method: "x402/exact",
|
|
21845
|
+
network: x402_base.network ?? RAIL_SPEC_DEFAULTS.x402Base.network,
|
|
21846
|
+
chain_id: x402_base.chainId ?? RAIL_SPEC_DEFAULTS.x402Base.chainId,
|
|
21847
|
+
token: x402_base.token ?? RAIL_SPEC_DEFAULTS.x402Base.token,
|
|
21848
|
+
symbol: x402_base.symbol ?? RAIL_SPEC_DEFAULTS.x402Base.symbol,
|
|
21849
|
+
decimals: x402_base.decimals ?? RAIL_SPEC_DEFAULTS.x402Base.decimals,
|
|
21850
|
+
pay_to: await resolveRecipient(x402_base.recipient)
|
|
21851
|
+
});
|
|
21852
|
+
}
|
|
21853
|
+
if (solana_mpp) {
|
|
21854
|
+
out.push({
|
|
21855
|
+
method: "solana/charge",
|
|
21856
|
+
network: solana_mpp.network ?? RAIL_SPEC_DEFAULTS.solanaMpp.network,
|
|
21857
|
+
token: solana_mpp.token ?? RAIL_SPEC_DEFAULTS.solanaMpp.token,
|
|
21858
|
+
symbol: solana_mpp.symbol ?? RAIL_SPEC_DEFAULTS.solanaMpp.symbol,
|
|
21657
21859
|
decimals: solana_mpp.decimals ?? RAIL_SPEC_DEFAULTS.solanaMpp.decimals,
|
|
21658
21860
|
pay_to: await resolveRecipient(solana_mpp.recipient)
|
|
21659
21861
|
});
|
|
@@ -21803,10 +22005,13 @@ function buildHowToPay({
|
|
|
21803
22005
|
totalUsd,
|
|
21804
22006
|
rails: rails2,
|
|
21805
22007
|
opTokenPlaceholder,
|
|
21806
|
-
maxSpend
|
|
22008
|
+
maxSpend,
|
|
22009
|
+
decimals
|
|
21807
22010
|
}) {
|
|
21808
22011
|
const totalNum = typeof totalUsd === "string" ? Number(totalUsd) : totalUsd;
|
|
21809
|
-
const
|
|
22012
|
+
const d = decimals ?? 2;
|
|
22013
|
+
const defaultMaxSpend = totalNum >= 1 ? (Math.ceil(totalNum) + 1).toFixed(d) : totalNum.toFixed(d);
|
|
22014
|
+
const maxSpendStr = String(maxSpend ?? defaultMaxSpend);
|
|
21810
22015
|
const opToken = opTokenPlaceholder ?? "<your_opc_token>";
|
|
21811
22016
|
const block = {};
|
|
21812
22017
|
if (rails2.tempo) {
|
|
@@ -21899,26 +22104,26 @@ function buildPricingBlock({
|
|
|
21899
22104
|
totalCents,
|
|
21900
22105
|
taxRate,
|
|
21901
22106
|
taxState,
|
|
21902
|
-
currency
|
|
22107
|
+
currency,
|
|
22108
|
+
decimals
|
|
21903
22109
|
}) {
|
|
21904
22110
|
const shipping = shippingCents ?? 0;
|
|
21905
22111
|
const discount = discountCents ?? 0;
|
|
21906
22112
|
const total = totalCents ?? Math.max(0, subtotalCents + taxCents + shipping - discount);
|
|
22113
|
+
const d = decimals ?? 2;
|
|
22114
|
+
const fmt = (cents) => (cents / 100).toFixed(d);
|
|
21907
22115
|
const block = {
|
|
21908
|
-
subtotal:
|
|
21909
|
-
tax:
|
|
21910
|
-
total:
|
|
22116
|
+
subtotal: fmt(subtotalCents),
|
|
22117
|
+
tax: fmt(taxCents),
|
|
22118
|
+
total: fmt(total)
|
|
21911
22119
|
};
|
|
21912
|
-
if (shippingCents !== void 0) block.shipping =
|
|
21913
|
-
if (discountCents !== void 0) block.discount =
|
|
22120
|
+
if (shippingCents !== void 0) block.shipping = fmt(shipping);
|
|
22121
|
+
if (discountCents !== void 0) block.discount = fmt(discount);
|
|
21914
22122
|
if (taxRate !== void 0) block.tax_rate = taxRate;
|
|
21915
22123
|
if (taxState !== void 0) block.tax_state = taxState;
|
|
21916
22124
|
if (currency !== void 0) block.currency = currency;
|
|
21917
22125
|
return block;
|
|
21918
22126
|
}
|
|
21919
|
-
function formatCents(cents) {
|
|
21920
|
-
return (cents / 100).toFixed(2);
|
|
21921
|
-
}
|
|
21922
22127
|
|
|
21923
22128
|
// src/challenge/respond_402.ts
|
|
21924
22129
|
init_wwwauthenticate();
|
|
@@ -21927,10 +22132,7 @@ function respond402({
|
|
|
21927
22132
|
body,
|
|
21928
22133
|
x402
|
|
21929
22134
|
}) {
|
|
21930
|
-
const headers =
|
|
21931
|
-
for (const [k, v] of Object.entries(mppxChallengeHeaders)) {
|
|
21932
|
-
headers[k.toLowerCase()] = v;
|
|
21933
|
-
}
|
|
22135
|
+
const headers = normalizeHeadersToLowercase(mppxChallengeHeaders);
|
|
21934
22136
|
headers["content-type"] = "application/json";
|
|
21935
22137
|
if (x402) {
|
|
21936
22138
|
headers["payment-required"] = paymentRequiredHeader(x402);
|
|
@@ -21957,6 +22159,12 @@ function buildValidationError({
|
|
|
21957
22159
|
return body;
|
|
21958
22160
|
}
|
|
21959
22161
|
|
|
22162
|
+
// src/payment/constants.ts
|
|
22163
|
+
var STRIPE_MIN_CHARGE_USD = 0.5;
|
|
22164
|
+
|
|
22165
|
+
// src/payment/mppx_server.ts
|
|
22166
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
22167
|
+
|
|
21960
22168
|
// src/stripe-multichain/mppx_stripe.ts
|
|
21961
22169
|
async function createMppxStripe({
|
|
21962
22170
|
profileId,
|
|
@@ -21993,7 +22201,8 @@ function isSolanaMppRailSpec(s) {
|
|
|
21993
22201
|
return s.network?.startsWith("solana:") ?? false;
|
|
21994
22202
|
}
|
|
21995
22203
|
function solanaNetworkFromCAIP2(caip2) {
|
|
21996
|
-
if (caip2 === networks.solana.devnet.caip2) return "devnet";
|
|
22204
|
+
if (caip2 === "devnet" || caip2 === networks.solana.devnet.caip2) return "devnet";
|
|
22205
|
+
if (caip2 === "localnet") return "localnet";
|
|
21997
22206
|
return "mainnet-beta";
|
|
21998
22207
|
}
|
|
21999
22208
|
function solanaDefaultRpcUrl(network) {
|
|
@@ -22136,6 +22345,31 @@ function wrapSolanaChargeWithFinalizedBlockhash(baseMethod, rpcUrl) {
|
|
|
22136
22345
|
}
|
|
22137
22346
|
};
|
|
22138
22347
|
}
|
|
22348
|
+
var mppxCapture = new AsyncLocalStorage();
|
|
22349
|
+
var consoleErrorPatched = false;
|
|
22350
|
+
function ensureConsoleErrorPatch() {
|
|
22351
|
+
if (consoleErrorPatched) return;
|
|
22352
|
+
consoleErrorPatched = true;
|
|
22353
|
+
const original = console.error.bind(console);
|
|
22354
|
+
console.error = function captureMppxInternal(...args) {
|
|
22355
|
+
if (args[0] === "mppx: internal verification error" && args[1] !== void 0) {
|
|
22356
|
+
const ctx = mppxCapture.getStore();
|
|
22357
|
+
if (ctx) {
|
|
22358
|
+
const e = args[1];
|
|
22359
|
+
const reason = typeof e?.shortMessage === "string" ? e.shortMessage : typeof e?.message === "string" ? e.message : String(args[1]);
|
|
22360
|
+
const details = e?.details;
|
|
22361
|
+
ctx.reason = typeof details === "string" && details.length > 0 ? `${reason} (${details})` : reason;
|
|
22362
|
+
}
|
|
22363
|
+
}
|
|
22364
|
+
return original(...args);
|
|
22365
|
+
};
|
|
22366
|
+
}
|
|
22367
|
+
async function runWithMppxFailureCapture(fn) {
|
|
22368
|
+
ensureConsoleErrorPatch();
|
|
22369
|
+
const ctx = { reason: null };
|
|
22370
|
+
const result = await mppxCapture.run(ctx, fn);
|
|
22371
|
+
return { result, failureReason: ctx.reason };
|
|
22372
|
+
}
|
|
22139
22373
|
|
|
22140
22374
|
// src/payment/x402_server.ts
|
|
22141
22375
|
init_networks();
|
|
@@ -22277,6 +22511,29 @@ function lazyMppxServer(opts) {
|
|
|
22277
22511
|
};
|
|
22278
22512
|
}
|
|
22279
22513
|
|
|
22514
|
+
// src/payment/mppx_failures.ts
|
|
22515
|
+
var TEMPO_KEY_NOT_REGISTERED = {
|
|
22516
|
+
code: "tempo_key_not_registered",
|
|
22517
|
+
status: 401,
|
|
22518
|
+
message: "Tempo rejected the transaction: signer wallet is not registered with Tempo's keychain.",
|
|
22519
|
+
nextSteps: {
|
|
22520
|
+
action: "register_tempo_key",
|
|
22521
|
+
user_message: "Your wallet is not enrolled with Tempo. Run `tempo wallet login` to complete the one-time WebAuthn enrollment (or use `tempo request` directly), then retry. To skip enrollment, switch to the Base or Solana rail on this 402."
|
|
22522
|
+
},
|
|
22523
|
+
extra: { upstream_error: "KeyNotFound", chain: "tempo" }
|
|
22524
|
+
};
|
|
22525
|
+
function classifyMppxFailure(reason) {
|
|
22526
|
+
if (!reason) return null;
|
|
22527
|
+
const lower = reason.toLowerCase();
|
|
22528
|
+
if (lower.includes("keychain validation failed") || lower.includes("keynotfound")) {
|
|
22529
|
+
return TEMPO_KEY_NOT_REGISTERED;
|
|
22530
|
+
}
|
|
22531
|
+
return null;
|
|
22532
|
+
}
|
|
22533
|
+
|
|
22534
|
+
// src/checkout.ts
|
|
22535
|
+
init_network_kind();
|
|
22536
|
+
|
|
22280
22537
|
// src/payment/x402_settle.ts
|
|
22281
22538
|
function classifyX402SettleResult(result) {
|
|
22282
22539
|
if (result.success) return null;
|
|
@@ -22568,12 +22825,14 @@ function pricingResult(opts) {
|
|
|
22568
22825
|
...opts.discountCents !== void 0 && { discountCents: opts.discountCents },
|
|
22569
22826
|
...opts.taxRate !== void 0 && { taxRate: opts.taxRate },
|
|
22570
22827
|
...opts.taxState !== void 0 && { taxState: opts.taxState },
|
|
22571
|
-
currency
|
|
22828
|
+
currency,
|
|
22829
|
+
...opts.decimals !== void 0 && { decimals: opts.decimals }
|
|
22572
22830
|
});
|
|
22573
22831
|
return {
|
|
22574
22832
|
amountUsd: derivedAmount,
|
|
22575
22833
|
currency,
|
|
22576
22834
|
block,
|
|
22835
|
+
...opts.decimals !== void 0 && { decimals: opts.decimals },
|
|
22577
22836
|
...opts.product !== void 0 && { product: opts.product },
|
|
22578
22837
|
...opts.bodyExtras !== void 0 && { bodyExtras: opts.bodyExtras }
|
|
22579
22838
|
};
|
|
@@ -22584,6 +22843,7 @@ function pricingResult(opts) {
|
|
|
22584
22843
|
return {
|
|
22585
22844
|
amountUsd: opts.amountUsd,
|
|
22586
22845
|
currency,
|
|
22846
|
+
...opts.decimals !== void 0 && { decimals: opts.decimals },
|
|
22587
22847
|
...opts.product !== void 0 && { product: opts.product },
|
|
22588
22848
|
...opts.bodyExtras !== void 0 && { bodyExtras: opts.bodyExtras }
|
|
22589
22849
|
};
|
|
@@ -22595,35 +22855,8 @@ function getIdentityStatus(ctx) {
|
|
|
22595
22855
|
if (decision === "allow") return "verified";
|
|
22596
22856
|
return "unverified";
|
|
22597
22857
|
}
|
|
22598
|
-
var CheckoutValidationError = class extends Error {
|
|
22599
|
-
code;
|
|
22600
|
-
action;
|
|
22601
|
-
status;
|
|
22602
|
-
extra;
|
|
22603
|
-
constructor(opts) {
|
|
22604
|
-
super(opts.message);
|
|
22605
|
-
this.name = "CheckoutValidationError";
|
|
22606
|
-
this.code = opts.code;
|
|
22607
|
-
this.action = opts.action ?? "fix_request";
|
|
22608
|
-
this.status = opts.status ?? 400;
|
|
22609
|
-
this.extra = opts.extra;
|
|
22610
|
-
}
|
|
22611
|
-
};
|
|
22612
|
-
function lowerHeaders2(headers) {
|
|
22613
|
-
const out = {};
|
|
22614
|
-
for (const [k, v] of Object.entries(headers)) out[k.toLowerCase()] = v;
|
|
22615
|
-
return out;
|
|
22616
|
-
}
|
|
22617
|
-
function hasX402Header(headers) {
|
|
22618
|
-
const h = lowerHeaders2(headers);
|
|
22619
|
-
return Boolean(h["payment-signature"] ?? h["x-payment"]);
|
|
22620
|
-
}
|
|
22621
|
-
function hasMppxHeader(headers) {
|
|
22622
|
-
const h = lowerHeaders2(headers);
|
|
22623
|
-
return (h["authorization"] ?? "").startsWith("Payment ");
|
|
22624
|
-
}
|
|
22625
22858
|
function resolveIdentityMetadata(ctx) {
|
|
22626
|
-
const h =
|
|
22859
|
+
const h = normalizeHeadersToLowercase(ctx.request.headers);
|
|
22627
22860
|
const wallet = h["x-wallet-address"];
|
|
22628
22861
|
if (!wallet) return void 0;
|
|
22629
22862
|
let linkedWallets;
|
|
@@ -22652,26 +22885,24 @@ function isTempoSessionRailSpec3(s) {
|
|
|
22652
22885
|
function specRailKey(spec) {
|
|
22653
22886
|
if (isStripeRailSpec2(spec)) return "stripe";
|
|
22654
22887
|
if (isTempoSessionRailSpec3(spec)) return "tempo_mpp";
|
|
22655
|
-
|
|
22656
|
-
if (
|
|
22657
|
-
if (network.startsWith("solana:") || "rpcUrl" in spec) return "solana_mpp";
|
|
22888
|
+
if (isEvmNetwork(spec)) return "x402_base";
|
|
22889
|
+
if (isSolanaNetwork(spec) || "rpcUrl" in spec) return "solana_mpp";
|
|
22658
22890
|
return "tempo_mpp";
|
|
22659
22891
|
}
|
|
22660
22892
|
function specMethodName(spec) {
|
|
22661
22893
|
if (isStripeRailSpec2(spec)) return "stripe/spt";
|
|
22662
22894
|
if (isTempoSessionRailSpec3(spec)) return "tempo/charge";
|
|
22663
|
-
|
|
22664
|
-
if (
|
|
22665
|
-
if (network.startsWith("solana:") || "rpcUrl" in spec) return "solana/charge";
|
|
22895
|
+
if (isEvmNetwork(spec)) return "x402/exact (base)";
|
|
22896
|
+
if (isSolanaNetwork(spec) || "rpcUrl" in spec) return "solana/charge";
|
|
22666
22897
|
return "tempo/charge";
|
|
22667
22898
|
}
|
|
22668
22899
|
function makeMppxComposeHook(opts) {
|
|
22669
22900
|
return async (ctx) => {
|
|
22670
22901
|
if (ctx.pricing === null) return { status: 402 };
|
|
22671
22902
|
const mpp = await opts.serverGetter();
|
|
22672
|
-
const lower =
|
|
22903
|
+
const lower = normalizeHeadersToLowercase(ctx.request.headers);
|
|
22673
22904
|
const authorization = lower["authorization"];
|
|
22674
|
-
const amountStr = ctx.pricing.amountUsd.toFixed(2);
|
|
22905
|
+
const amountStr = ctx.pricing.amountUsd.toFixed(ctx.pricing.decimals ?? 2);
|
|
22675
22906
|
let result;
|
|
22676
22907
|
try {
|
|
22677
22908
|
result = await mpp.charge({ authorization, amount: amountStr });
|
|
@@ -22755,7 +22986,7 @@ var Checkout = class {
|
|
|
22755
22986
|
let x402ServerGetter;
|
|
22756
22987
|
if (x402Server === void 0) {
|
|
22757
22988
|
const baseSpec = Object.values(opts.rails).find(
|
|
22758
|
-
(s) => !isTempoSessionRailSpec3(s) && !isStripeRailSpec2(s) && "recipient" in s && (s
|
|
22989
|
+
(s) => !isTempoSessionRailSpec3(s) && !isStripeRailSpec2(s) && "recipient" in s && isEvmNetwork(s)
|
|
22759
22990
|
);
|
|
22760
22991
|
if (baseSpec !== void 0) {
|
|
22761
22992
|
x402ServerGetter = lazyX402Server({
|
|
@@ -22845,7 +23076,7 @@ var Checkout = class {
|
|
|
22845
23076
|
* `"x402_base"` when no match found. */
|
|
22846
23077
|
x402RailKey() {
|
|
22847
23078
|
for (const [k, v] of Object.entries(this.rails)) {
|
|
22848
|
-
if (!isStripeRailSpec2(v) && !isTempoSessionRailSpec3(v) && (v
|
|
23079
|
+
if (!isStripeRailSpec2(v) && !isTempoSessionRailSpec3(v) && isEvmNetwork(v)) {
|
|
22849
23080
|
return k;
|
|
22850
23081
|
}
|
|
22851
23082
|
}
|
|
@@ -22854,8 +23085,7 @@ var Checkout = class {
|
|
|
22854
23085
|
/** Return the rails-dict key for the primary MPP rail. */
|
|
22855
23086
|
mppRailKey() {
|
|
22856
23087
|
for (const [k, v] of Object.entries(this.rails)) {
|
|
22857
|
-
|
|
22858
|
-
if (!isStripeRailSpec2(v) && !network.startsWith("eip155:")) return k;
|
|
23088
|
+
if (!isStripeRailSpec2(v) && !isEvmNetwork(v)) return k;
|
|
22859
23089
|
}
|
|
22860
23090
|
return "tempo";
|
|
22861
23091
|
}
|
|
@@ -22874,17 +23104,15 @@ var Checkout = class {
|
|
|
22874
23104
|
if (method === "solana") {
|
|
22875
23105
|
for (const [k, v] of Object.entries(this.rails)) {
|
|
22876
23106
|
if (isStripeRailSpec2(v) || isTempoSessionRailSpec3(v)) continue;
|
|
22877
|
-
|
|
22878
|
-
if (network.startsWith("solana:") || "rpcUrl" in v || "tokenProgram" in v) return k;
|
|
23107
|
+
if (isSolanaNetwork(v) || "rpcUrl" in v || "tokenProgram" in v) return k;
|
|
22879
23108
|
}
|
|
22880
23109
|
return void 0;
|
|
22881
23110
|
}
|
|
22882
23111
|
if (method === "tempo") {
|
|
22883
23112
|
for (const [k, v] of Object.entries(this.rails)) {
|
|
22884
23113
|
if (isStripeRailSpec2(v)) continue;
|
|
22885
|
-
|
|
22886
|
-
if (
|
|
22887
|
-
if (network.startsWith("eip155:")) continue;
|
|
23114
|
+
if (isSolanaNetwork(v) || "rpcUrl" in v || "tokenProgram" in v) continue;
|
|
23115
|
+
if (isEvmNetwork(v)) continue;
|
|
22888
23116
|
return k;
|
|
22889
23117
|
}
|
|
22890
23118
|
return void 0;
|
|
@@ -22897,7 +23125,7 @@ var Checkout = class {
|
|
|
22897
23125
|
get x402BaseNetwork() {
|
|
22898
23126
|
if (!this.x402ServerAvailable()) return null;
|
|
22899
23127
|
for (const spec of Object.values(this.rails)) {
|
|
22900
|
-
if (!isStripeRailSpec2(spec) && !isTempoSessionRailSpec3(spec) && (spec
|
|
23128
|
+
if (!isStripeRailSpec2(spec) && !isTempoSessionRailSpec3(spec) && isEvmNetwork(spec)) {
|
|
22901
23129
|
return spec.network ?? "eip155:8453";
|
|
22902
23130
|
}
|
|
22903
23131
|
}
|
|
@@ -22949,8 +23177,8 @@ var Checkout = class {
|
|
|
22949
23177
|
throw err;
|
|
22950
23178
|
}
|
|
22951
23179
|
}
|
|
22952
|
-
const
|
|
22953
|
-
if (this.gate !== void 0 &&
|
|
23180
|
+
const hasPaymentHeader2 = hasX402Header(request.headers) || hasMppxHeader(request.headers);
|
|
23181
|
+
if (this.gate !== void 0 && hasPaymentHeader2) {
|
|
22954
23182
|
const denial = await this.runGate(ctx);
|
|
22955
23183
|
if (denial !== null) {
|
|
22956
23184
|
return {
|
|
@@ -22963,7 +23191,14 @@ var Checkout = class {
|
|
|
22963
23191
|
}
|
|
22964
23192
|
}
|
|
22965
23193
|
ctx.pricing = await this.computePricing(ctx);
|
|
22966
|
-
|
|
23194
|
+
try {
|
|
23195
|
+
await this.resolveRecipientsForCtx(ctx);
|
|
23196
|
+
} catch (err) {
|
|
23197
|
+
if (err instanceof Error && err.name === "CheckoutValidationError") {
|
|
23198
|
+
return this.validationErrorResult(ctx, err);
|
|
23199
|
+
}
|
|
23200
|
+
throw err;
|
|
23201
|
+
}
|
|
22967
23202
|
const x402ServerOk = this.x402ServerAvailable() && this.x402BaseNetwork !== null;
|
|
22968
23203
|
if (hasX402Header(request.headers) && x402ServerOk) {
|
|
22969
23204
|
const zero = await this.handleZeroSettle(ctx, "x402-base");
|
|
@@ -23034,13 +23269,21 @@ var Checkout = class {
|
|
|
23034
23269
|
...gate.failOpen !== void 0 && { failOpen: gate.failOpen },
|
|
23035
23270
|
...gate.cacheSeconds !== void 0 && { cacheSeconds: gate.cacheSeconds },
|
|
23036
23271
|
...gate.chain !== void 0 && { chain: gate.chain },
|
|
23037
|
-
|
|
23038
|
-
|
|
23272
|
+
// Auto-default `createSessionOnMissing` from gate config when the merchant
|
|
23273
|
+
// didn't supply one. Matches python-commerce's behavior — every gated route
|
|
23274
|
+
// gets the bootstrap session-mint UX out of the box. Merchants who need
|
|
23275
|
+
// custom session context or onBeforeSession side effects (goods merchants
|
|
23276
|
+
// pre-minting an order_id) supply their own config instead.
|
|
23277
|
+
createSessionOnMissing: gate.createSessionOnMissing ?? {
|
|
23278
|
+
apiKey: gate.apiKey,
|
|
23279
|
+
...gate.baseUrl !== void 0 && { baseUrl: gate.baseUrl },
|
|
23280
|
+
...gate.context !== void 0 && { context: gate.context },
|
|
23281
|
+
...gate.merchantName !== void 0 && { productName: gate.merchantName }
|
|
23039
23282
|
},
|
|
23040
23283
|
...policyOverride ?? {}
|
|
23041
23284
|
};
|
|
23042
23285
|
const core = createAgentScoreCore(coreOpts);
|
|
23043
|
-
const headers =
|
|
23286
|
+
const headers = normalizeHeadersToLowercase(ctx.request.headers);
|
|
23044
23287
|
const walletAddress = headers["x-wallet-address"];
|
|
23045
23288
|
const operatorToken = headers["x-operator-token"];
|
|
23046
23289
|
const identity = walletAddress !== void 0 || operatorToken !== void 0 ? {
|
|
@@ -23102,7 +23345,7 @@ var Checkout = class {
|
|
|
23102
23345
|
if (!this.zeroSettleCarveOut || ctx.pricing === null) return null;
|
|
23103
23346
|
const cents = Math.round(ctx.pricing.amountUsd * 100);
|
|
23104
23347
|
if (cents !== 0) return null;
|
|
23105
|
-
const headers =
|
|
23348
|
+
const headers = normalizeHeadersToLowercase(ctx.request.headers);
|
|
23106
23349
|
let zero;
|
|
23107
23350
|
if (rail === "x402-base") {
|
|
23108
23351
|
const x402Header = headers["payment-signature"] ?? headers["x-payment"];
|
|
@@ -23176,7 +23419,7 @@ var Checkout = class {
|
|
|
23176
23419
|
resourceConfig: {
|
|
23177
23420
|
scheme: "exact",
|
|
23178
23421
|
network: verified.signedNetwork,
|
|
23179
|
-
price: `$${ctx.pricing.amountUsd.toFixed(2)}`,
|
|
23422
|
+
price: `$${ctx.pricing.amountUsd.toFixed(ctx.pricing.decimals ?? 2)}`,
|
|
23180
23423
|
payTo: verified.signedPayTo,
|
|
23181
23424
|
maxTimeoutSeconds: 300
|
|
23182
23425
|
},
|
|
@@ -23235,7 +23478,9 @@ var Checkout = class {
|
|
|
23235
23478
|
if (this.composeMppx === void 0) {
|
|
23236
23479
|
throw new Error("Checkout.handleMppx: composeMppx hook not configured");
|
|
23237
23480
|
}
|
|
23238
|
-
const composed = await
|
|
23481
|
+
const { result: composed, failureReason } = await runWithMppxFailureCapture(
|
|
23482
|
+
async () => this.composeMppx(ctx)
|
|
23483
|
+
);
|
|
23239
23484
|
if (composed.status === 200) {
|
|
23240
23485
|
const paymentReceiptHeader = composed.paymentReceiptHeader ?? extractMppxReceiptHeaderFromRaw(composed.raw);
|
|
23241
23486
|
const directMethod = composed.raw?.receipt?.method;
|
|
@@ -23254,6 +23499,22 @@ var Checkout = class {
|
|
|
23254
23499
|
};
|
|
23255
23500
|
return await this.buildSuccess(ctx, outcome);
|
|
23256
23501
|
}
|
|
23502
|
+
const classified = classifyMppxFailure(failureReason);
|
|
23503
|
+
if (classified !== null) {
|
|
23504
|
+
return {
|
|
23505
|
+
status: classified.status,
|
|
23506
|
+
body: buildValidationError({
|
|
23507
|
+
code: classified.code,
|
|
23508
|
+
message: classified.message,
|
|
23509
|
+
nextSteps: classified.nextSteps,
|
|
23510
|
+
...classified.extra && { extra: classified.extra }
|
|
23511
|
+
}),
|
|
23512
|
+
headers: { ...composed.headers ?? {} },
|
|
23513
|
+
referenceId: ctx.referenceId,
|
|
23514
|
+
settled: false,
|
|
23515
|
+
settlePhase: "verify_failed"
|
|
23516
|
+
};
|
|
23517
|
+
}
|
|
23257
23518
|
return {
|
|
23258
23519
|
status: 400,
|
|
23259
23520
|
body: buildValidationError({
|
|
@@ -23272,7 +23533,11 @@ var Checkout = class {
|
|
|
23272
23533
|
throw new Error("Checkout.emit402: pricing not computed");
|
|
23273
23534
|
}
|
|
23274
23535
|
await this.resolveRecipientsForCtx(ctx);
|
|
23275
|
-
|
|
23536
|
+
let emitRails = applyRecipientOverrides(this.rails, ctx.recipients);
|
|
23537
|
+
if (ctx.pricing.amountUsd < STRIPE_MIN_CHARGE_USD && emitRails.stripe !== void 0) {
|
|
23538
|
+
const { stripe: _stripe, ...rest } = emitRails;
|
|
23539
|
+
emitRails = rest;
|
|
23540
|
+
}
|
|
23276
23541
|
const accepted = await buildAcceptedMethods({
|
|
23277
23542
|
tempo: pickRail(emitRails, "tempo"),
|
|
23278
23543
|
x402_base: pickRail(emitRails, "x402_base"),
|
|
@@ -23285,15 +23550,18 @@ var Checkout = class {
|
|
|
23285
23550
|
howToPayRails[k] = v;
|
|
23286
23551
|
}
|
|
23287
23552
|
}
|
|
23553
|
+
const pricingDecimals = ctx.pricing.decimals ?? 2;
|
|
23288
23554
|
const howToPay = buildHowToPay({
|
|
23289
23555
|
url: this.url,
|
|
23290
23556
|
retryBodyJson: JSON.stringify(ctx.request.body),
|
|
23291
|
-
totalUsd: ctx.pricing.amountUsd.toFixed(
|
|
23292
|
-
rails: howToPayRails
|
|
23557
|
+
totalUsd: ctx.pricing.amountUsd.toFixed(pricingDecimals),
|
|
23558
|
+
rails: howToPayRails,
|
|
23559
|
+
...ctx.pricing.decimals !== void 0 && { decimals: ctx.pricing.decimals }
|
|
23293
23560
|
});
|
|
23294
23561
|
const pricingBlock = ctx.pricing.block ?? buildPricingBlock({
|
|
23295
|
-
subtotalCents:
|
|
23296
|
-
currency: ctx.pricing.currency ?? "USD"
|
|
23562
|
+
subtotalCents: ctx.pricing.amountUsd * 100,
|
|
23563
|
+
currency: ctx.pricing.currency ?? "USD",
|
|
23564
|
+
...ctx.pricing.decimals !== void 0 && { decimals: ctx.pricing.decimals }
|
|
23297
23565
|
});
|
|
23298
23566
|
let x402Accepts = [];
|
|
23299
23567
|
let x402Resource;
|
|
@@ -23306,7 +23574,7 @@ var Checkout = class {
|
|
|
23306
23574
|
try {
|
|
23307
23575
|
x402Accepts = await buildX402AcceptsFor402(x402Server, {
|
|
23308
23576
|
network: baseNetwork,
|
|
23309
|
-
price: `$${ctx.pricing.amountUsd.toFixed(
|
|
23577
|
+
price: `$${ctx.pricing.amountUsd.toFixed(pricingDecimals)}`,
|
|
23310
23578
|
payTo: recipient,
|
|
23311
23579
|
maxTimeoutSeconds: 300
|
|
23312
23580
|
});
|
|
@@ -23322,7 +23590,7 @@ var Checkout = class {
|
|
|
23322
23590
|
agentInstructions: buildAgentInstructions({ howToPay }),
|
|
23323
23591
|
...identityMetadata !== void 0 ? { identityMetadata } : {},
|
|
23324
23592
|
pricing: pricingBlock,
|
|
23325
|
-
amountUsd: ctx.pricing.amountUsd.toFixed(
|
|
23593
|
+
amountUsd: ctx.pricing.amountUsd.toFixed(pricingDecimals),
|
|
23326
23594
|
retryBody: ctx.request.body,
|
|
23327
23595
|
agentMemory: firstEncounterAgentMemory({ firstEncounter: true }),
|
|
23328
23596
|
...ctx.pricing.product ? { product: ctx.pricing.product } : {},
|
|
@@ -23430,25 +23698,6 @@ function stripContentType(headers) {
|
|
|
23430
23698
|
}
|
|
23431
23699
|
return out;
|
|
23432
23700
|
}
|
|
23433
|
-
function extractMppxReceiptHeaderFromRaw(raw) {
|
|
23434
|
-
if (!raw || typeof raw !== "object" || !("withReceipt" in raw)) return null;
|
|
23435
|
-
const fn = raw.withReceipt;
|
|
23436
|
-
if (typeof fn !== "function") return null;
|
|
23437
|
-
try {
|
|
23438
|
-
const wrapped = fn.call(raw, new Response());
|
|
23439
|
-
return wrapped.headers.get("Payment-Receipt");
|
|
23440
|
-
} catch {
|
|
23441
|
-
return null;
|
|
23442
|
-
}
|
|
23443
|
-
}
|
|
23444
|
-
async function extractMppxReceiptMethod(header) {
|
|
23445
|
-
try {
|
|
23446
|
-
const { Receipt } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
|
|
23447
|
-
return Receipt.deserialize(header).method;
|
|
23448
|
-
} catch {
|
|
23449
|
-
return void 0;
|
|
23450
|
-
}
|
|
23451
|
-
}
|
|
23452
23701
|
function headersToRecord(h) {
|
|
23453
23702
|
if (h === void 0) return {};
|
|
23454
23703
|
if (h instanceof Headers) {
|
|
@@ -23691,78 +23940,6 @@ Checkout.prototype.mountUcpRoutesFastify = function(app, opts) {
|
|
|
23691
23940
|
app.options(jwksPath, preflight);
|
|
23692
23941
|
};
|
|
23693
23942
|
|
|
23694
|
-
// src/identity/policy.ts
|
|
23695
|
-
function buildGateFromPolicy(policy, base) {
|
|
23696
|
-
if (!policy || !policy.enforcement) return null;
|
|
23697
|
-
return {
|
|
23698
|
-
apiKey: base.apiKey,
|
|
23699
|
-
...base.baseUrl !== void 0 && { baseUrl: base.baseUrl },
|
|
23700
|
-
...policy.requireKyc !== void 0 && { requireKyc: policy.requireKyc },
|
|
23701
|
-
...policy.requireSanctionsClear !== void 0 && {
|
|
23702
|
-
requireSanctionsClear: policy.requireSanctionsClear
|
|
23703
|
-
},
|
|
23704
|
-
...policy.minAge !== void 0 && { minAge: policy.minAge },
|
|
23705
|
-
...policy.allowedJurisdictions !== void 0 && {
|
|
23706
|
-
allowedJurisdictions: [...policy.allowedJurisdictions]
|
|
23707
|
-
}
|
|
23708
|
-
};
|
|
23709
|
-
}
|
|
23710
|
-
async function runGateWithEnforcement(enforcement, runGate) {
|
|
23711
|
-
if (!runGate || !enforcement) return { status: "anonymous" };
|
|
23712
|
-
const outcome = await runGate();
|
|
23713
|
-
if (outcome.ok) return { status: "verified" };
|
|
23714
|
-
if (enforcement === "hard") {
|
|
23715
|
-
return {
|
|
23716
|
-
status: "denied",
|
|
23717
|
-
denialStatus: outcome.status,
|
|
23718
|
-
denialBody: outcome.body,
|
|
23719
|
-
...outcome.reason !== void 0 && { denialReason: outcome.reason }
|
|
23720
|
-
};
|
|
23721
|
-
}
|
|
23722
|
-
return {
|
|
23723
|
-
status: "unverified",
|
|
23724
|
-
denialStatus: outcome.status,
|
|
23725
|
-
denialBody: outcome.body,
|
|
23726
|
-
...outcome.reason !== void 0 && { denialReason: outcome.reason }
|
|
23727
|
-
};
|
|
23728
|
-
}
|
|
23729
|
-
function shippingCountryAllowed(country, policy) {
|
|
23730
|
-
if (!policy?.allowedShippingCountries || policy.allowedShippingCountries.length === 0) return true;
|
|
23731
|
-
const allowed = new Set(policy.allowedShippingCountries.map((c) => c.toUpperCase()));
|
|
23732
|
-
return allowed.has(country.toUpperCase());
|
|
23733
|
-
}
|
|
23734
|
-
function shippingStateAllowed(state, country, policy) {
|
|
23735
|
-
if (!policy?.allowedShippingStates || policy.allowedShippingStates.length === 0) return true;
|
|
23736
|
-
if (country.toUpperCase() !== "US") return true;
|
|
23737
|
-
const allowed = new Set(policy.allowedShippingStates.map((s) => s.toUpperCase()));
|
|
23738
|
-
return allowed.has(state.toUpperCase());
|
|
23739
|
-
}
|
|
23740
|
-
function validateShippingAgainstPolicy(opts) {
|
|
23741
|
-
const code = opts.errorCode ?? "unsupported_jurisdiction";
|
|
23742
|
-
const action = opts.errorAction ?? "change_shipping_state";
|
|
23743
|
-
const item = opts.productName ? `'${opts.productName}'` : "this item";
|
|
23744
|
-
if (!shippingCountryAllowed(opts.country, opts.policy)) {
|
|
23745
|
-
throw new CheckoutValidationError({
|
|
23746
|
-
code,
|
|
23747
|
-
message: opts.countryMessage ?? `We can't ship ${item} to ${opts.country.toUpperCase() || "<unset>"}.`,
|
|
23748
|
-
action
|
|
23749
|
-
});
|
|
23750
|
-
}
|
|
23751
|
-
if (!shippingStateAllowed(opts.state, opts.country, opts.policy)) {
|
|
23752
|
-
throw new CheckoutValidationError({
|
|
23753
|
-
code,
|
|
23754
|
-
message: opts.stateMessage ?? `We can't ship ${item} to ${opts.state.toUpperCase() || "<unset>"}.`,
|
|
23755
|
-
action
|
|
23756
|
-
});
|
|
23757
|
-
}
|
|
23758
|
-
}
|
|
23759
|
-
|
|
23760
|
-
// src/identity/tokens.ts
|
|
23761
|
-
import { createHash } from "crypto";
|
|
23762
|
-
function hashOperatorToken(plaintext) {
|
|
23763
|
-
return createHash("sha256").update(plaintext, "utf8").digest("hex");
|
|
23764
|
-
}
|
|
23765
|
-
|
|
23766
23943
|
// src/payment/index.ts
|
|
23767
23944
|
init_directive();
|
|
23768
23945
|
init_networks();
|
|
@@ -23775,8 +23952,45 @@ init_directive();
|
|
|
23775
23952
|
init_wwwauthenticate();
|
|
23776
23953
|
|
|
23777
23954
|
// src/payment/amounts.ts
|
|
23778
|
-
function
|
|
23779
|
-
|
|
23955
|
+
function usdToAtomic(usd, opts) {
|
|
23956
|
+
const { decimals } = opts;
|
|
23957
|
+
if (!Number.isInteger(decimals) || decimals < 0) {
|
|
23958
|
+
throw new RangeError(`decimals must be a non-negative integer, got ${decimals}`);
|
|
23959
|
+
}
|
|
23960
|
+
if (typeof usd === "number") {
|
|
23961
|
+
if (!Number.isFinite(usd)) {
|
|
23962
|
+
throw new RangeError(`usd must be finite, got ${usd}`);
|
|
23963
|
+
}
|
|
23964
|
+
if (usd < 0) {
|
|
23965
|
+
throw new RangeError(`usd must be non-negative, got ${usd}`);
|
|
23966
|
+
}
|
|
23967
|
+
}
|
|
23968
|
+
const s = (typeof usd === "number" ? usd.toString() : usd).trim();
|
|
23969
|
+
if (s.startsWith("-")) {
|
|
23970
|
+
throw new RangeError(`usd must be non-negative, got ${s}`);
|
|
23971
|
+
}
|
|
23972
|
+
if (s === "NaN" || s === "Infinity") {
|
|
23973
|
+
throw new RangeError(`usd must be finite, got ${s}`);
|
|
23974
|
+
}
|
|
23975
|
+
const match = /^(\d*)(?:\.(\d*))?$/.exec(s);
|
|
23976
|
+
if (!match || match[1] === "" && (match[2] === void 0 || match[2] === "")) {
|
|
23977
|
+
throw new SyntaxError(`invalid usd value: ${JSON.stringify(usd)}`);
|
|
23978
|
+
}
|
|
23979
|
+
const intPart = match[1] || "0";
|
|
23980
|
+
const fracPart = match[2] ?? "";
|
|
23981
|
+
if (fracPart.length <= decimals) {
|
|
23982
|
+
return BigInt(intPart + fracPart.padEnd(decimals, "0"));
|
|
23983
|
+
}
|
|
23984
|
+
const kept = fracPart.slice(0, decimals);
|
|
23985
|
+
const roundDigit = fracPart[decimals];
|
|
23986
|
+
let result = BigInt(intPart + kept);
|
|
23987
|
+
if (roundDigit >= "5") {
|
|
23988
|
+
result += 1n;
|
|
23989
|
+
}
|
|
23990
|
+
return result;
|
|
23991
|
+
}
|
|
23992
|
+
function formatUsdCents(cents, decimals = 2) {
|
|
23993
|
+
return (cents / 100).toFixed(decimals);
|
|
23780
23994
|
}
|
|
23781
23995
|
|
|
23782
23996
|
// src/payment/solana.ts
|
|
@@ -23799,7 +24013,643 @@ async function loadSolanaFeePayer(opts) {
|
|
|
23799
24013
|
}
|
|
23800
24014
|
return kit.createKeyPairSignerFromPrivateKeyBytes(bytes);
|
|
23801
24015
|
}
|
|
24016
|
+
|
|
24017
|
+
// src/payment/compose_rails.ts
|
|
24018
|
+
init_usdc();
|
|
24019
|
+
var warnedStripeBelowMinimum = false;
|
|
24020
|
+
function buildMppxComposeRails(opts) {
|
|
24021
|
+
const rails2 = [];
|
|
24022
|
+
if (opts.tempoRecipient) {
|
|
24023
|
+
rails2.push(["tempo/charge", {
|
|
24024
|
+
amount: opts.amountUsd,
|
|
24025
|
+
currency: opts.tempoTokenAddress ?? USDC.tempo.mainnet.address,
|
|
24026
|
+
decimals: 6,
|
|
24027
|
+
recipient: opts.tempoRecipient
|
|
24028
|
+
}]);
|
|
24029
|
+
}
|
|
24030
|
+
if (opts.solanaRecipient) {
|
|
24031
|
+
const atomic = usdToAtomic(opts.amountUsd, { decimals: 6 });
|
|
24032
|
+
rails2.push(["solana/charge", {
|
|
24033
|
+
amount: atomic.toString(),
|
|
24034
|
+
currency: opts.solanaTokenMint ?? USDC.solana.mainnet.mint,
|
|
24035
|
+
decimals: 6,
|
|
24036
|
+
recipient: opts.solanaRecipient,
|
|
24037
|
+
network: opts.solanaNetwork ?? "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
|
|
24038
|
+
}]);
|
|
24039
|
+
}
|
|
24040
|
+
if (opts.includeStripe !== false) {
|
|
24041
|
+
const amountUsdNumeric = Number(opts.amountUsd);
|
|
24042
|
+
if (Number.isFinite(amountUsdNumeric) && amountUsdNumeric < STRIPE_MIN_CHARGE_USD) {
|
|
24043
|
+
if (!warnedStripeBelowMinimum) {
|
|
24044
|
+
warnedStripeBelowMinimum = true;
|
|
24045
|
+
console.warn(
|
|
24046
|
+
`[buildMppxComposeRails] Dropping stripe/charge rail: amountUsd=${opts.amountUsd} is below Stripe's $${STRIPE_MIN_CHARGE_USD.toFixed(2)} USD minimum. Stripe's fixed ~$0.30 fee makes sub-50-cent charges unprofitable (and many accounts reject PI creation with amount_too_small below this floor). Pass includeStripe: false to suppress this warning.`
|
|
24047
|
+
);
|
|
24048
|
+
}
|
|
24049
|
+
} else {
|
|
24050
|
+
rails2.push(["stripe/charge", { amount: opts.amountUsd, currency: "usd", decimals: 2 }]);
|
|
24051
|
+
}
|
|
24052
|
+
}
|
|
24053
|
+
return rails2;
|
|
24054
|
+
}
|
|
24055
|
+
|
|
24056
|
+
// src/payment/default_rails.ts
|
|
24057
|
+
init_networks();
|
|
24058
|
+
init_usdc();
|
|
24059
|
+
function buildDefaultCheckoutRails(opts) {
|
|
24060
|
+
const out = {};
|
|
24061
|
+
if (opts.tempo) {
|
|
24062
|
+
out.tempo = { recipient: "", ...RAIL_SPEC_DEFAULTS.tempo, ...opts.tempo };
|
|
24063
|
+
}
|
|
24064
|
+
if (opts.x402Base) {
|
|
24065
|
+
const merged = { recipient: "", ...RAIL_SPEC_DEFAULTS.x402Base, ...opts.x402Base };
|
|
24066
|
+
if (merged.network === networks.base.sepolia.caip2) {
|
|
24067
|
+
if (opts.x402Base.chainId === void 0) merged.chainId = networks.base.sepolia.chainId;
|
|
24068
|
+
if (opts.x402Base.token === void 0) merged.token = USDC.base.sepolia.address;
|
|
24069
|
+
} else if (merged.network === networks.base.mainnet.caip2) {
|
|
24070
|
+
if (opts.x402Base.chainId === void 0) merged.chainId = networks.base.mainnet.chainId;
|
|
24071
|
+
if (opts.x402Base.token === void 0) merged.token = USDC.base.mainnet.address;
|
|
24072
|
+
}
|
|
24073
|
+
out.x402_base = merged;
|
|
24074
|
+
}
|
|
24075
|
+
if (opts.solanaMpp) {
|
|
24076
|
+
const merged = { recipient: "", ...RAIL_SPEC_DEFAULTS.solanaMpp, ...opts.solanaMpp };
|
|
24077
|
+
const isDevnet = merged.network === "devnet" || merged.network === networks.solana.devnet.caip2;
|
|
24078
|
+
if (isDevnet && opts.solanaMpp.token === void 0) {
|
|
24079
|
+
merged.token = USDC.solana.devnet.mint;
|
|
24080
|
+
}
|
|
24081
|
+
out.solana_mpp = merged;
|
|
24082
|
+
}
|
|
24083
|
+
if (opts.stripe) {
|
|
24084
|
+
out.stripe = { ...RAIL_SPEC_DEFAULTS.stripe, ...opts.stripe };
|
|
24085
|
+
}
|
|
24086
|
+
return out;
|
|
24087
|
+
}
|
|
24088
|
+
|
|
24089
|
+
// src/payment/index.ts
|
|
24090
|
+
init_network_kind();
|
|
24091
|
+
|
|
24092
|
+
// src/checkout_compute_first.ts
|
|
24093
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
24094
|
+
|
|
24095
|
+
// src/discovery/index.ts
|
|
24096
|
+
init_probe();
|
|
24097
|
+
|
|
24098
|
+
// src/discovery/agentscore_content.ts
|
|
24099
|
+
var PURCHASE_MODE_NOTES = Object.freeze({
|
|
24100
|
+
redemption_only: "Requires a single-use redemption code (printed on a mailer or other out-of-band delivery). Submit the code in the request body as `redemption_code`. Without a valid code the order is rejected.",
|
|
24101
|
+
coupon_applicable: "Codes are optional. Without one, settle at list price. With a valid code the discount is applied automatically (percent_off, fixed_off, or fixed_settle).",
|
|
24102
|
+
paid_only: "Codes are NOT accepted. Settle at the listed price. Submitting a `redemption_code` field returns 400 codes_not_accepted."
|
|
24103
|
+
});
|
|
24104
|
+
function buildSuccessNextSteps(opts) {
|
|
24105
|
+
const out = {
|
|
24106
|
+
action: "done",
|
|
24107
|
+
user_message: opts.userMessage ?? "Payment complete. Your AgentScore Passport is now active across every AgentScore-gated merchant."
|
|
24108
|
+
};
|
|
24109
|
+
if (opts.orderStatusUrl) out.order_status_url = opts.orderStatusUrl;
|
|
24110
|
+
if (opts.fulfillmentEta !== void 0) out.fulfillment_eta = opts.fulfillmentEta;
|
|
24111
|
+
return out;
|
|
24112
|
+
}
|
|
24113
|
+
|
|
24114
|
+
// src/discovery/index.ts
|
|
24115
|
+
init_well_known();
|
|
24116
|
+
|
|
24117
|
+
// src/quote_cache.ts
|
|
24118
|
+
import { createHash as createHash2 } from "crypto";
|
|
24119
|
+
|
|
24120
|
+
// src/_redis.ts
|
|
24121
|
+
async function tryCreateRedis(opts) {
|
|
24122
|
+
const url2 = opts.url ?? process.env.REDIS_URL;
|
|
24123
|
+
if (!url2) return null;
|
|
24124
|
+
try {
|
|
24125
|
+
const mod = await import("ioredis");
|
|
24126
|
+
const client = new mod.default(url2, {
|
|
24127
|
+
connectTimeout: opts.connectTimeout ?? 3e3,
|
|
24128
|
+
maxRetriesPerRequest: opts.maxRetriesPerRequest ?? 1,
|
|
24129
|
+
tls: url2.startsWith("rediss://") ? {} : void 0
|
|
24130
|
+
});
|
|
24131
|
+
client.on("error", (err) => console.error(`[${opts.label}] Redis error:`, err.message));
|
|
24132
|
+
return client;
|
|
24133
|
+
} catch {
|
|
24134
|
+
return null;
|
|
24135
|
+
}
|
|
24136
|
+
}
|
|
24137
|
+
function memoizedRedis(opts) {
|
|
24138
|
+
let promise2 = null;
|
|
24139
|
+
return () => {
|
|
24140
|
+
if (!promise2) promise2 = tryCreateRedis(opts);
|
|
24141
|
+
return promise2;
|
|
24142
|
+
};
|
|
24143
|
+
}
|
|
24144
|
+
|
|
24145
|
+
// src/quote_cache.ts
|
|
24146
|
+
function canonicalize2(value) {
|
|
24147
|
+
if (Array.isArray(value)) return value.map(canonicalize2);
|
|
24148
|
+
if (value && typeof value === "object") {
|
|
24149
|
+
const sorted = {};
|
|
24150
|
+
for (const key of Object.keys(value).sort()) {
|
|
24151
|
+
sorted[key] = canonicalize2(value[key]);
|
|
24152
|
+
}
|
|
24153
|
+
return sorted;
|
|
24154
|
+
}
|
|
24155
|
+
return value;
|
|
24156
|
+
}
|
|
24157
|
+
function createQuoteCache(opts = {}) {
|
|
24158
|
+
const ttlMs = opts.ttlMs ?? 5 * 6e4;
|
|
24159
|
+
const keyPrefix = opts.keyPrefix ?? "quote:";
|
|
24160
|
+
const memMap = /* @__PURE__ */ new Map();
|
|
24161
|
+
const getRedis = memoizedRedis({ url: opts.redisUrl, label: "quote-cache" });
|
|
24162
|
+
const evictExpired = () => {
|
|
24163
|
+
const now = Date.now();
|
|
24164
|
+
for (const [k, v] of memMap.entries()) {
|
|
24165
|
+
if (v.expiresAt <= now) memMap.delete(k);
|
|
24166
|
+
}
|
|
24167
|
+
};
|
|
24168
|
+
return {
|
|
24169
|
+
bodyHashKey(prefix, body) {
|
|
24170
|
+
const canonical = JSON.stringify(canonicalize2(body));
|
|
24171
|
+
const hash3 = createHash2("sha256").update(`${prefix}::${canonical}`).digest("hex").slice(0, 24);
|
|
24172
|
+
return `${prefix}::${hash3}`;
|
|
24173
|
+
},
|
|
24174
|
+
async read(key) {
|
|
24175
|
+
const r = await getRedis();
|
|
24176
|
+
if (r) {
|
|
24177
|
+
try {
|
|
24178
|
+
const raw = await r.get(`${keyPrefix}${key}`);
|
|
24179
|
+
if (!raw) return null;
|
|
24180
|
+
return JSON.parse(raw);
|
|
24181
|
+
} catch {
|
|
24182
|
+
}
|
|
24183
|
+
}
|
|
24184
|
+
evictExpired();
|
|
24185
|
+
const entry = memMap.get(key);
|
|
24186
|
+
return entry ? entry.entry : null;
|
|
24187
|
+
},
|
|
24188
|
+
async write(key, body, priceCents, recipients = {}) {
|
|
24189
|
+
const cached2 = { body, priceCents, recipients };
|
|
24190
|
+
const r = await getRedis();
|
|
24191
|
+
if (r) {
|
|
24192
|
+
try {
|
|
24193
|
+
await r.set(`${keyPrefix}${key}`, JSON.stringify(cached2), "PX", ttlMs);
|
|
24194
|
+
return;
|
|
24195
|
+
} catch {
|
|
24196
|
+
}
|
|
24197
|
+
}
|
|
24198
|
+
memMap.set(key, { entry: cached2, expiresAt: Date.now() + ttlMs });
|
|
24199
|
+
},
|
|
24200
|
+
async clear() {
|
|
24201
|
+
memMap.clear();
|
|
24202
|
+
const r = await getRedis();
|
|
24203
|
+
if (r) {
|
|
24204
|
+
try {
|
|
24205
|
+
await r.flushdb();
|
|
24206
|
+
} catch {
|
|
24207
|
+
}
|
|
24208
|
+
}
|
|
24209
|
+
}
|
|
24210
|
+
};
|
|
24211
|
+
}
|
|
24212
|
+
|
|
24213
|
+
// src/checkout_compute_first.ts
|
|
24214
|
+
var DEFAULT_TTL_MS = 5 * 6e4;
|
|
24215
|
+
function decimalsForUnit(unitPriceCents) {
|
|
24216
|
+
if (Number.isInteger(unitPriceCents)) return 2;
|
|
24217
|
+
const str = unitPriceCents.toString();
|
|
24218
|
+
const dotIdx = str.indexOf(".");
|
|
24219
|
+
const frac = dotIdx === -1 ? 0 : str.length - dotIdx - 1;
|
|
24220
|
+
return 2 + frac;
|
|
24221
|
+
}
|
|
24222
|
+
function computeFirstCheckout(opts) {
|
|
24223
|
+
const cache = opts.cache ?? createQuoteCache({ ttlMs: opts.cacheTtlMs ?? DEFAULT_TTL_MS });
|
|
24224
|
+
const decimals = opts.decimals ?? decimalsForUnit(opts.unitPriceCents);
|
|
24225
|
+
const appUrl = opts.appUrl ?? new URL(opts.url).origin;
|
|
24226
|
+
async function mintAndResolveRecipients(req, body, priceCents) {
|
|
24227
|
+
const minted = opts.mintRecipients ? await opts.mintRecipients({ request: req, body, priceCents }) : {};
|
|
24228
|
+
const out = {};
|
|
24229
|
+
const tempo = minted.tempo ?? (opts.rails.tempo ? await resolveRecipient(opts.rails.tempo.recipient) : void 0);
|
|
24230
|
+
const x402Base = minted.x402_base ?? (opts.rails.x402_base ? await resolveRecipient(opts.rails.x402_base.recipient) : void 0);
|
|
24231
|
+
const solana = minted.solana_mpp ?? (opts.rails.solana_mpp ? await resolveRecipient(opts.rails.solana_mpp.recipient) : void 0);
|
|
24232
|
+
if (tempo) out.tempo = tempo;
|
|
24233
|
+
if (x402Base) out.x402_base = x402Base;
|
|
24234
|
+
if (solana) out.solana_mpp = solana;
|
|
24235
|
+
return out;
|
|
24236
|
+
}
|
|
24237
|
+
async function emit402(req, body, priceCents, recipients) {
|
|
24238
|
+
const totalUsd = formatUsdCents(priceCents, decimals);
|
|
24239
|
+
const tempoRecipient = recipients.tempo;
|
|
24240
|
+
const x402BaseRecipient = recipients.x402_base;
|
|
24241
|
+
const solanaRecipient = recipients.solana_mpp;
|
|
24242
|
+
const includeStripeInDiscovery = opts.rails.stripe !== void 0 && Number(totalUsd) >= STRIPE_MIN_CHARGE_USD;
|
|
24243
|
+
const accepted = await buildAcceptedMethods({
|
|
24244
|
+
...tempoRecipient && opts.rails.tempo && { tempo: { ...opts.rails.tempo, recipient: tempoRecipient } },
|
|
24245
|
+
...solanaRecipient && opts.rails.solana_mpp && { solana_mpp: { ...opts.rails.solana_mpp, recipient: solanaRecipient } },
|
|
24246
|
+
...includeStripeInDiscovery && { stripe: opts.rails.stripe }
|
|
24247
|
+
});
|
|
24248
|
+
if (x402BaseRecipient && opts.rails.x402_base) {
|
|
24249
|
+
try {
|
|
24250
|
+
const resolvedX402PayTo = await resolveRecipient(x402BaseRecipient);
|
|
24251
|
+
const x402Entries = await buildX402AcceptsFor402(opts.x402Server, {
|
|
24252
|
+
network: opts.rails.x402_base.network ?? "eip155:8453",
|
|
24253
|
+
price: `$${totalUsd}`,
|
|
24254
|
+
payTo: resolvedX402PayTo,
|
|
24255
|
+
maxTimeoutSeconds: 300
|
|
24256
|
+
});
|
|
24257
|
+
accepted.push(...x402Entries);
|
|
24258
|
+
} catch (err) {
|
|
24259
|
+
console.warn(
|
|
24260
|
+
`[${opts.name}.computeFirst] buildX402AcceptsFor402 failed; dropping x402 from accepts:`,
|
|
24261
|
+
err instanceof Error ? err.message : err
|
|
24262
|
+
);
|
|
24263
|
+
}
|
|
24264
|
+
}
|
|
24265
|
+
const howToPay = buildHowToPay({
|
|
24266
|
+
url: opts.url,
|
|
24267
|
+
retryBodyJson: JSON.stringify(body),
|
|
24268
|
+
totalUsd,
|
|
24269
|
+
decimals,
|
|
24270
|
+
rails: {
|
|
24271
|
+
...tempoRecipient && opts.rails.tempo && { tempo: { ...opts.rails.tempo, recipient: tempoRecipient } },
|
|
24272
|
+
...x402BaseRecipient && opts.rails.x402_base && { x402_base: { ...opts.rails.x402_base, recipient: x402BaseRecipient } },
|
|
24273
|
+
...solanaRecipient && opts.rails.solana_mpp && { solana_mpp: { ...opts.rails.solana_mpp, recipient: solanaRecipient } },
|
|
24274
|
+
...opts.rails.stripe && { stripe: opts.rails.stripe }
|
|
24275
|
+
}
|
|
24276
|
+
});
|
|
24277
|
+
const pricing = buildPricingBlock({ subtotalCents: priceCents, currency: "USD", decimals });
|
|
24278
|
+
const agentInstructions = buildAgentInstructions({
|
|
24279
|
+
howToPay,
|
|
24280
|
+
warnings: [
|
|
24281
|
+
"The quoted price is exact: it was derived from the actual number of results returned by the work on the probe leg.",
|
|
24282
|
+
"The merchant cached the result against a hash of this request body. Retry with the same body within the quote TTL (default 5 min) to settle and receive the cached results; if the quote expires, re-probe."
|
|
24283
|
+
]
|
|
24284
|
+
});
|
|
24285
|
+
let mppChallengeHeaders = {};
|
|
24286
|
+
if (opts.composeMppx) {
|
|
24287
|
+
try {
|
|
24288
|
+
const mppResult = await opts.composeMppx({
|
|
24289
|
+
request: req,
|
|
24290
|
+
cachedBody: body,
|
|
24291
|
+
priceCents,
|
|
24292
|
+
priceUsd: totalUsd,
|
|
24293
|
+
recipients
|
|
24294
|
+
});
|
|
24295
|
+
if (mppResult.status === 402 && mppResult.headers) {
|
|
24296
|
+
mppChallengeHeaders = mppResult.headers;
|
|
24297
|
+
}
|
|
24298
|
+
} catch (err) {
|
|
24299
|
+
console.warn(
|
|
24300
|
+
`[${opts.name}.computeFirst] composeMppx probe-leg failed; dropping MPP rails from 402 challenge:`,
|
|
24301
|
+
err instanceof Error ? err.message : err
|
|
24302
|
+
);
|
|
24303
|
+
}
|
|
24304
|
+
}
|
|
24305
|
+
const body402 = build402Body({
|
|
24306
|
+
product: { id: opts.name, name: opts.name },
|
|
24307
|
+
acceptedMethods: accepted,
|
|
24308
|
+
pricing,
|
|
24309
|
+
agentInstructions,
|
|
24310
|
+
amountUsd: totalUsd,
|
|
24311
|
+
currency: "USD",
|
|
24312
|
+
orderId: null,
|
|
24313
|
+
retryBody: body
|
|
24314
|
+
});
|
|
24315
|
+
const headers = new Headers({ "Content-Type": "application/json" });
|
|
24316
|
+
for (const [k, v] of Object.entries(mppChallengeHeaders)) headers.set(k, v);
|
|
24317
|
+
headers.set(
|
|
24318
|
+
"PAYMENT-REQUIRED",
|
|
24319
|
+
paymentRequiredHeader({ x402Version: 2, accepts: accepted, resource: { url: opts.url } })
|
|
24320
|
+
);
|
|
24321
|
+
return new Response(JSON.stringify(body402), { status: 402, headers });
|
|
24322
|
+
}
|
|
24323
|
+
async function handleX402Settle(req, referenceId, cachedBody, priceCents, recipients) {
|
|
24324
|
+
const verified = await verifyX402Request({
|
|
24325
|
+
request: req,
|
|
24326
|
+
isCachedAddress: async () => true,
|
|
24327
|
+
acceptedNetwork: opts.rails.x402_base?.network ?? "eip155:8453"
|
|
24328
|
+
});
|
|
24329
|
+
if (!verified.ok) {
|
|
24330
|
+
return new Response(JSON.stringify(verified.body), {
|
|
24331
|
+
status: verified.status,
|
|
24332
|
+
headers: { "Content-Type": "application/json" }
|
|
24333
|
+
});
|
|
24334
|
+
}
|
|
24335
|
+
const actualUsd = formatUsdCents(priceCents, decimals);
|
|
24336
|
+
const settle = await processX402Settle({
|
|
24337
|
+
x402Server: opts.x402Server,
|
|
24338
|
+
payload: verified.payload,
|
|
24339
|
+
resourceConfig: {
|
|
24340
|
+
scheme: "exact",
|
|
24341
|
+
network: verified.signedNetwork,
|
|
24342
|
+
price: `$${actualUsd}`,
|
|
24343
|
+
payTo: verified.signedPayTo,
|
|
24344
|
+
maxTimeoutSeconds: 300
|
|
24345
|
+
},
|
|
24346
|
+
resourceMeta: {
|
|
24347
|
+
url: req.url,
|
|
24348
|
+
description: `Agent purchase via x402-exact (${opts.name})`,
|
|
24349
|
+
mimeType: "application/json"
|
|
24350
|
+
}
|
|
24351
|
+
});
|
|
24352
|
+
if (!settle.success) {
|
|
24353
|
+
const detail = settle.error?.message ?? "unknown";
|
|
24354
|
+
return new Response(
|
|
24355
|
+
JSON.stringify({
|
|
24356
|
+
id: referenceId,
|
|
24357
|
+
endpoint: opts.name,
|
|
24358
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24359
|
+
payment_status: "failed",
|
|
24360
|
+
charged_usd: "0.00",
|
|
24361
|
+
rail: `x402-base (${verified.signedNetwork})`,
|
|
24362
|
+
error: {
|
|
24363
|
+
code: "settle_failed",
|
|
24364
|
+
message: "Facilitator rejected the exact settle; no on-chain capture occurred.",
|
|
24365
|
+
detail
|
|
24366
|
+
}
|
|
24367
|
+
}),
|
|
24368
|
+
{ status: 502, headers: { "Content-Type": "application/json" } }
|
|
24369
|
+
);
|
|
24370
|
+
}
|
|
24371
|
+
const signer = await extractPaymentSigner(req, readX402PaymentHeader(req));
|
|
24372
|
+
const signerInfo = signer ? { address: signer.address, network: signer.network } : void 0;
|
|
24373
|
+
const railLabel = `Base (${verified.signedNetwork})`;
|
|
24374
|
+
if (opts.onSettled) {
|
|
24375
|
+
try {
|
|
24376
|
+
await opts.onSettled({
|
|
24377
|
+
request: req,
|
|
24378
|
+
rail: "x402",
|
|
24379
|
+
cachedBody,
|
|
24380
|
+
priceCents,
|
|
24381
|
+
priceUsd: actualUsd,
|
|
24382
|
+
recipients,
|
|
24383
|
+
...signerInfo ? { signer: signerInfo } : {}
|
|
24384
|
+
});
|
|
24385
|
+
} catch (err) {
|
|
24386
|
+
console.warn(`[${opts.name}.computeFirst.onSettled] x402 side-effect failed:`, err instanceof Error ? err.message : err);
|
|
24387
|
+
}
|
|
24388
|
+
}
|
|
24389
|
+
const buildBody = opts.buildSuccessBody ?? defaultSuccessBody(appUrl);
|
|
24390
|
+
const body = buildBody({
|
|
24391
|
+
referenceId,
|
|
24392
|
+
endpoint: opts.name,
|
|
24393
|
+
chargedUsd: actualUsd,
|
|
24394
|
+
rail: railLabel,
|
|
24395
|
+
...signerInfo ? { signer: signerInfo } : {},
|
|
24396
|
+
cachedBody
|
|
24397
|
+
});
|
|
24398
|
+
return new Response(JSON.stringify(body), { status: 200, headers: { "Content-Type": "application/json" } });
|
|
24399
|
+
}
|
|
24400
|
+
function mppRailLabel(method) {
|
|
24401
|
+
const scheme = method?.split("/")[0];
|
|
24402
|
+
if (scheme === "tempo") {
|
|
24403
|
+
const networkName = opts.rails.tempo?.testnet ? "tempo-testnet" : opts.rails.tempo?.network ?? "tempo-mainnet";
|
|
24404
|
+
return `Tempo (${networkName})`;
|
|
24405
|
+
}
|
|
24406
|
+
if (scheme === "solana") {
|
|
24407
|
+
const networkName = opts.rails.solana_mpp?.network ?? "solana";
|
|
24408
|
+
return `Solana (${networkName})`;
|
|
24409
|
+
}
|
|
24410
|
+
if (scheme === "stripe") return "Stripe (card+link)";
|
|
24411
|
+
return "MPP";
|
|
24412
|
+
}
|
|
24413
|
+
async function handleMppSettle(req, referenceId, cachedBody, priceCents, recipients) {
|
|
24414
|
+
if (!opts.composeMppx) {
|
|
24415
|
+
return new Response(
|
|
24416
|
+
JSON.stringify({
|
|
24417
|
+
id: referenceId,
|
|
24418
|
+
endpoint: opts.name,
|
|
24419
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24420
|
+
payment_status: "failed",
|
|
24421
|
+
charged_usd: "0.00",
|
|
24422
|
+
error: { code: "mpp_unavailable", message: "MPP settle hook not configured on this endpoint." }
|
|
24423
|
+
}),
|
|
24424
|
+
{ status: 503, headers: { "Content-Type": "application/json" } }
|
|
24425
|
+
);
|
|
24426
|
+
}
|
|
24427
|
+
const priceUsd = formatUsdCents(priceCents, decimals);
|
|
24428
|
+
const result = await opts.composeMppx({ request: req, cachedBody, priceCents, priceUsd, recipients });
|
|
24429
|
+
if (result.status !== 200) {
|
|
24430
|
+
const headers = result.headers ?? {};
|
|
24431
|
+
return new Response(
|
|
24432
|
+
JSON.stringify({
|
|
24433
|
+
id: referenceId,
|
|
24434
|
+
endpoint: opts.name,
|
|
24435
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24436
|
+
payment_status: "failed",
|
|
24437
|
+
charged_usd: "0.00",
|
|
24438
|
+
error: { code: "mpp_settle_failed", message: "MPP compose did not return 200; credential rejected." }
|
|
24439
|
+
}),
|
|
24440
|
+
{ status: 400, headers: { "Content-Type": "application/json", ...headers } }
|
|
24441
|
+
);
|
|
24442
|
+
}
|
|
24443
|
+
const signer = result.signerAddress ? { address: result.signerAddress, network: result.signerNetwork ?? "evm" } : await extractPaymentSigner(req, readX402PaymentHeader(req)).then((s) => s ? { address: s.address, network: s.network } : void 0);
|
|
24444
|
+
const method = await deriveMppxReceiptMethod(result.raw);
|
|
24445
|
+
const railLabel = mppRailLabel(method);
|
|
24446
|
+
if (opts.onSettled) {
|
|
24447
|
+
try {
|
|
24448
|
+
await opts.onSettled({
|
|
24449
|
+
request: req,
|
|
24450
|
+
rail: "mpp",
|
|
24451
|
+
mppMethod: method,
|
|
24452
|
+
cachedBody,
|
|
24453
|
+
priceCents,
|
|
24454
|
+
priceUsd,
|
|
24455
|
+
recipients,
|
|
24456
|
+
...signer ? { signer } : {},
|
|
24457
|
+
...result.txHash ? { paymentIntentId: result.txHash } : {}
|
|
24458
|
+
});
|
|
24459
|
+
} catch (err) {
|
|
24460
|
+
console.warn(`[${opts.name}.computeFirst.onSettled] MPP side-effect failed:`, err instanceof Error ? err.message : err);
|
|
24461
|
+
}
|
|
24462
|
+
}
|
|
24463
|
+
const buildBody = opts.buildSuccessBody ?? defaultSuccessBody(appUrl);
|
|
24464
|
+
const body = buildBody({
|
|
24465
|
+
referenceId,
|
|
24466
|
+
endpoint: opts.name,
|
|
24467
|
+
chargedUsd: priceUsd,
|
|
24468
|
+
rail: railLabel,
|
|
24469
|
+
...result.txHash ? { paymentIntentId: result.txHash } : {},
|
|
24470
|
+
...signer ? { signer } : {},
|
|
24471
|
+
cachedBody
|
|
24472
|
+
});
|
|
24473
|
+
return new Response(JSON.stringify(body), { status: 200, headers: { "Content-Type": "application/json" } });
|
|
24474
|
+
}
|
|
24475
|
+
async function handle(req) {
|
|
24476
|
+
const referenceId = `${opts.name}_${randomUUID2()}`;
|
|
24477
|
+
let body;
|
|
24478
|
+
try {
|
|
24479
|
+
body = await req.clone().json();
|
|
24480
|
+
} catch {
|
|
24481
|
+
body = {};
|
|
24482
|
+
}
|
|
24483
|
+
try {
|
|
24484
|
+
opts.validateInput?.(body);
|
|
24485
|
+
} catch (err) {
|
|
24486
|
+
if (err instanceof CheckoutValidationError) {
|
|
24487
|
+
return new Response(
|
|
24488
|
+
JSON.stringify({
|
|
24489
|
+
error: { code: err.code, message: err.message },
|
|
24490
|
+
...err.action ? { next_steps: { action: err.action, user_message: err.message } } : {},
|
|
24491
|
+
...err.extra
|
|
24492
|
+
}),
|
|
24493
|
+
{ status: err.status, headers: { "Content-Type": "application/json" } }
|
|
24494
|
+
);
|
|
24495
|
+
}
|
|
24496
|
+
throw err;
|
|
24497
|
+
}
|
|
24498
|
+
const cacheKey2 = cache.bodyHashKey(opts.name, body);
|
|
24499
|
+
if (hasX402Header(req.headers) || hasMppxHeader(req.headers)) {
|
|
24500
|
+
const quote2 = await cache.read(cacheKey2);
|
|
24501
|
+
if (!quote2) {
|
|
24502
|
+
return new Response(
|
|
24503
|
+
JSON.stringify({
|
|
24504
|
+
id: referenceId,
|
|
24505
|
+
endpoint: opts.name,
|
|
24506
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24507
|
+
payment_status: "failed",
|
|
24508
|
+
charged_usd: "0.00",
|
|
24509
|
+
error: {
|
|
24510
|
+
code: "stale_quote",
|
|
24511
|
+
message: "No active quote for this request body. The quote may have expired or the body changed since the probe."
|
|
24512
|
+
},
|
|
24513
|
+
next_steps: {
|
|
24514
|
+
action: "re_probe",
|
|
24515
|
+
suggestion: "Send the same body without a payment header to get a fresh 402 quote, then retry with the payment credential."
|
|
24516
|
+
}
|
|
24517
|
+
}),
|
|
24518
|
+
{ status: 400, headers: { "Content-Type": "application/json" } }
|
|
24519
|
+
);
|
|
24520
|
+
}
|
|
24521
|
+
if (hasX402Header(req.headers)) return handleX402Settle(req, referenceId, quote2.body, quote2.priceCents, quote2.recipients);
|
|
24522
|
+
return handleMppSettle(req, referenceId, quote2.body, quote2.priceCents, quote2.recipients);
|
|
24523
|
+
}
|
|
24524
|
+
let quote = await cache.read(cacheKey2);
|
|
24525
|
+
if (!quote) {
|
|
24526
|
+
let outcome;
|
|
24527
|
+
try {
|
|
24528
|
+
outcome = await opts.runWork(body, { request: req });
|
|
24529
|
+
} catch {
|
|
24530
|
+
return new Response(
|
|
24531
|
+
JSON.stringify({
|
|
24532
|
+
id: referenceId,
|
|
24533
|
+
endpoint: opts.name,
|
|
24534
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24535
|
+
payment_status: "no_charge",
|
|
24536
|
+
charged_usd: "0.00",
|
|
24537
|
+
result: { matches: [], total: 0 },
|
|
24538
|
+
error: {
|
|
24539
|
+
code: "upstream_failed",
|
|
24540
|
+
message: "The wrapped endpoint failed; no charge was applied."
|
|
24541
|
+
}
|
|
24542
|
+
}),
|
|
24543
|
+
{ status: 200, headers: { "Content-Type": "application/json" } }
|
|
24544
|
+
);
|
|
24545
|
+
}
|
|
24546
|
+
if (outcome.resultCount === 0) {
|
|
24547
|
+
return new Response(
|
|
24548
|
+
JSON.stringify({
|
|
24549
|
+
id: referenceId,
|
|
24550
|
+
endpoint: opts.name,
|
|
24551
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24552
|
+
payment_status: "no_charge",
|
|
24553
|
+
charged_usd: "0.00",
|
|
24554
|
+
result: outcome.body
|
|
24555
|
+
}),
|
|
24556
|
+
{ status: 200, headers: { "Content-Type": "application/json" } }
|
|
24557
|
+
);
|
|
24558
|
+
}
|
|
24559
|
+
const priceCents = opts.unitPriceCents * outcome.resultCount;
|
|
24560
|
+
const recipients = await mintAndResolveRecipients(req, body, priceCents);
|
|
24561
|
+
await cache.write(cacheKey2, outcome.body, priceCents, recipients);
|
|
24562
|
+
quote = { body: outcome.body, priceCents, recipients };
|
|
24563
|
+
}
|
|
24564
|
+
return emit402(req, body, quote.priceCents, quote.recipients);
|
|
24565
|
+
}
|
|
24566
|
+
return {
|
|
24567
|
+
handleWeb: handle,
|
|
24568
|
+
async handleHono(c) {
|
|
24569
|
+
return handle(c.req.raw);
|
|
24570
|
+
}
|
|
24571
|
+
};
|
|
24572
|
+
}
|
|
24573
|
+
function defaultSuccessBody(appUrl) {
|
|
24574
|
+
return ({ referenceId, endpoint, chargedUsd, rail, paymentIntentId, signer, cachedBody }) => ({
|
|
24575
|
+
id: referenceId,
|
|
24576
|
+
endpoint,
|
|
24577
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24578
|
+
payment_status: "completed",
|
|
24579
|
+
charged_usd: chargedUsd,
|
|
24580
|
+
rail,
|
|
24581
|
+
...paymentIntentId ? { payment_intent_id: paymentIntentId } : {},
|
|
24582
|
+
...signer ? { signer } : {},
|
|
24583
|
+
result: cachedBody,
|
|
24584
|
+
next_steps: buildSuccessNextSteps({ orderStatusUrl: `${appUrl}/health` }),
|
|
24585
|
+
agent_memory: firstEncounterAgentMemory({ firstEncounter: true })
|
|
24586
|
+
});
|
|
24587
|
+
}
|
|
24588
|
+
|
|
24589
|
+
// src/identity/default_denied.ts
|
|
24590
|
+
function createDefaultOnDenied(opts) {
|
|
24591
|
+
const supportContext = opts.supportContext ?? "Contact support if you believe this denial is in error.";
|
|
24592
|
+
const paymentRequiredMessage = opts.paymentRequiredMessage ?? "AgentScore tier does not support assess. Contact support.";
|
|
24593
|
+
const walletNotTrustedMessage = opts.walletNotTrustedMessage ?? `Identity check did not satisfy policy for ${opts.merchantName}.`;
|
|
24594
|
+
return function defaultOnDenied(reason) {
|
|
24595
|
+
if (reason.code === "wallet_signer_mismatch" || reason.code === "wallet_auth_requires_wallet_signing") {
|
|
24596
|
+
const body = buildSignerMismatchBody({
|
|
24597
|
+
result: {
|
|
24598
|
+
kind: reason.code,
|
|
24599
|
+
claimedOperator: reason.claimed_operator ?? null,
|
|
24600
|
+
actualSignerOperator: reason.actual_signer_operator ?? null,
|
|
24601
|
+
expectedSigner: reason.expected_signer ?? "",
|
|
24602
|
+
actualSigner: reason.actual_signer ?? "",
|
|
24603
|
+
linkedWallets: reason.linked_wallets ?? [],
|
|
24604
|
+
agentInstructions: reason.agent_instructions ?? "",
|
|
24605
|
+
claimedWallet: reason.expected_signer ?? ""
|
|
24606
|
+
}
|
|
24607
|
+
});
|
|
24608
|
+
return { status: 403, body: body ?? denialReasonToBody(reason) };
|
|
24609
|
+
}
|
|
24610
|
+
if (reason.code === "wallet_not_trusted") {
|
|
24611
|
+
return {
|
|
24612
|
+
status: 403,
|
|
24613
|
+
body: {
|
|
24614
|
+
error: { code: "compliance_denied", message: walletNotTrustedMessage },
|
|
24615
|
+
reasons: reason.reasons ?? [],
|
|
24616
|
+
policy_result: reason.data?.policy_result,
|
|
24617
|
+
verify_url: reason.verify_url,
|
|
24618
|
+
next_steps: buildContactSupportNextSteps(opts.supportEmail, supportContext)
|
|
24619
|
+
}
|
|
24620
|
+
};
|
|
24621
|
+
}
|
|
24622
|
+
if (reason.code === "payment_required") {
|
|
24623
|
+
return {
|
|
24624
|
+
status: 403,
|
|
24625
|
+
body: {
|
|
24626
|
+
...denialReasonToBody(reason),
|
|
24627
|
+
error: { code: "compliance_error", message: paymentRequiredMessage }
|
|
24628
|
+
}
|
|
24629
|
+
};
|
|
24630
|
+
}
|
|
24631
|
+
const status = reason.code === "token_expired" || reason.code === "invalid_credential" ? 401 : reason.code === "api_error" ? 503 : 403;
|
|
24632
|
+
return {
|
|
24633
|
+
status,
|
|
24634
|
+
body: denialReasonToBody(reason),
|
|
24635
|
+
...status >= 500 && { headers: { "Cache-Control": "no-store" } }
|
|
24636
|
+
};
|
|
24637
|
+
};
|
|
24638
|
+
}
|
|
24639
|
+
function defaultReadOnlyOnDenied(reason) {
|
|
24640
|
+
const message = reason.code === "missing_identity" ? "X-Wallet-Address or X-Operator-Token header required" : "Invalid identity";
|
|
24641
|
+
return {
|
|
24642
|
+
status: 401,
|
|
24643
|
+
body: {
|
|
24644
|
+
...denialReasonToBody(reason),
|
|
24645
|
+
error: { code: "unauthorized", message }
|
|
24646
|
+
},
|
|
24647
|
+
headers: { "Cache-Control": "no-store" }
|
|
24648
|
+
};
|
|
24649
|
+
}
|
|
23802
24650
|
export {
|
|
24651
|
+
A2A_DEFAULT_TRANSPORT,
|
|
24652
|
+
A2A_PROTOCOL_VERSION,
|
|
23803
24653
|
AGENTSCORE_UCP_CAPABILITY,
|
|
23804
24654
|
Checkout,
|
|
23805
24655
|
CheckoutValidationError,
|
|
@@ -23810,18 +24660,29 @@ export {
|
|
|
23810
24660
|
buildA2AAgentCard,
|
|
23811
24661
|
buildAgentMemoryHint,
|
|
23812
24662
|
buildContactSupportNextSteps,
|
|
24663
|
+
buildDefaultCheckoutRails,
|
|
23813
24664
|
buildGateFromPolicy,
|
|
23814
24665
|
buildJWKSResponse,
|
|
24666
|
+
buildMppxComposeRails,
|
|
23815
24667
|
buildSignerMismatchBody,
|
|
23816
24668
|
buildUCPProfile,
|
|
24669
|
+
buildVerificationRequiredBody,
|
|
24670
|
+
computeFirstCheckout,
|
|
24671
|
+
createDefaultOnDenied,
|
|
24672
|
+
createQuoteCache,
|
|
24673
|
+
defaultReadOnlyOnDenied,
|
|
23817
24674
|
denialReasonStatus,
|
|
23818
24675
|
denialReasonToBody,
|
|
24676
|
+
extractOwnerScope,
|
|
23819
24677
|
extractPaymentSigner,
|
|
23820
24678
|
extractPaymentSignerFromAuth,
|
|
23821
24679
|
extractSignerForPrecheck,
|
|
23822
24680
|
formatUsdCents,
|
|
23823
24681
|
generateUCPSigningKey,
|
|
23824
24682
|
getIdentityStatus,
|
|
24683
|
+
hasMppxHeader,
|
|
24684
|
+
hasPaymentHeader,
|
|
24685
|
+
hasX402Header,
|
|
23825
24686
|
hashOperatorToken,
|
|
23826
24687
|
isFixableDenial,
|
|
23827
24688
|
loadSolanaFeePayer,
|