@agent-score/commerce 2.1.0 → 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 +1 -1
- package/dist/challenge/index.js.map +1 -1
- package/dist/challenge/index.mjs.map +1 -1
- package/dist/{checkout-Bd_4aQ6c.d.mts → checkout-BRw_caGr.d.mts} +1 -22
- package/dist/{checkout-BH-I_Ns8.d.ts → checkout-CuSNUJFX.d.ts} +1 -22
- 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-BxBzcCA1.d.ts → default_rails-C5gKZJMI.d.ts} +11 -1
- package/dist/{default_rails-BWAquZeu.d.mts → default_rails-XFCuRddA.d.mts} +11 -1
- package/dist/discovery/index.d.mts +1 -1
- package/dist/discovery/index.d.ts +1 -1
- package/dist/identity/express.js +1 -1
- package/dist/identity/express.js.map +1 -1
- package/dist/identity/express.mjs +1 -1
- package/dist/identity/express.mjs.map +1 -1
- package/dist/identity/fastify.js +1 -1
- package/dist/identity/fastify.js.map +1 -1
- package/dist/identity/fastify.mjs +1 -1
- package/dist/identity/fastify.mjs.map +1 -1
- package/dist/identity/hono.js +1 -1
- package/dist/identity/hono.js.map +1 -1
- package/dist/identity/hono.mjs +1 -1
- package/dist/identity/hono.mjs.map +1 -1
- package/dist/identity/nextjs.js +1 -1
- package/dist/identity/nextjs.js.map +1 -1
- package/dist/identity/nextjs.mjs +1 -1
- package/dist/identity/nextjs.mjs.map +1 -1
- package/dist/identity/policy.js +22 -23363
- package/dist/identity/policy.js.map +1 -1
- package/dist/identity/policy.mjs +1 -23366
- package/dist/identity/policy.mjs.map +1 -1
- package/dist/identity/web.js +1 -1
- package/dist/identity/web.js.map +1 -1
- package/dist/identity/web.mjs +1 -1
- package/dist/identity/web.mjs.map +1 -1
- package/dist/index.d.mts +72 -5
- package/dist/index.d.ts +72 -5
- package/dist/index.js +256 -136
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +253 -134
- package/dist/index.mjs.map +1 -1
- package/dist/middleware/express.js.map +1 -1
- package/dist/middleware/express.mjs.map +1 -1
- package/dist/middleware/fastify.js.map +1 -1
- package/dist/middleware/fastify.mjs.map +1 -1
- package/dist/middleware/hono.js.map +1 -1
- package/dist/middleware/hono.mjs.map +1 -1
- package/dist/middleware/nextjs.js.map +1 -1
- package/dist/middleware/nextjs.mjs.map +1 -1
- package/dist/middleware/web.js.map +1 -1
- package/dist/middleware/web.mjs.map +1 -1
- package/dist/payment/index.d.mts +13 -17
- package/dist/payment/index.d.ts +13 -17
- package/dist/payment/index.js +80 -4
- package/dist/payment/index.js.map +1 -1
- package/dist/payment/index.mjs +79 -4
- package/dist/payment/index.mjs.map +1 -1
- package/dist/stripe-multichain/index.js +53 -4
- package/dist/stripe-multichain/index.js.map +1 -1
- package/dist/stripe-multichain/index.mjs +53 -4
- package/dist/stripe-multichain/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.mjs
CHANGED
|
@@ -20990,6 +20990,20 @@ var RESERVED_FIELDS = /* @__PURE__ */ new Set([
|
|
|
20990
20990
|
"actual_signer",
|
|
20991
20991
|
"linked_wallets"
|
|
20992
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
|
+
}
|
|
20993
21007
|
function denialReasonToBody(reason) {
|
|
20994
21008
|
const message = reason.message ?? DEFAULT_MESSAGES[reason.code];
|
|
20995
21009
|
const body = { error: { code: reason.code, message } };
|
|
@@ -21147,7 +21161,7 @@ function createAgentScoreCore(options) {
|
|
|
21147
21161
|
} = options;
|
|
21148
21162
|
const baseUrl = stripTrailingSlashes(rawBaseUrl);
|
|
21149
21163
|
const agentMemoryHint = buildAgentMemoryHint();
|
|
21150
|
-
const defaultUa = `@agent-score/commerce@${"2.1.
|
|
21164
|
+
const defaultUa = `@agent-score/commerce@${"2.1.1"}`;
|
|
21151
21165
|
const userAgentHeader = userAgent ? `${userAgent} (${defaultUa})` : defaultUa;
|
|
21152
21166
|
const sdk = new AgentScore({ apiKey, baseUrl, userAgent: userAgentHeader });
|
|
21153
21167
|
const sessionSdkCache = /* @__PURE__ */ new Map();
|
|
@@ -21605,6 +21619,137 @@ var A2A_DEFAULT_TRANSPORT = DEFAULT_TRANSPORT;
|
|
|
21605
21619
|
init_ucp();
|
|
21606
21620
|
init_ucp_jwks();
|
|
21607
21621
|
|
|
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;
|
|
21635
|
+
}
|
|
21636
|
+
};
|
|
21637
|
+
|
|
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
|
+
};
|
|
21665
|
+
}
|
|
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
|
+
|
|
21608
21753
|
// src/checkout.ts
|
|
21609
21754
|
import { randomUUID } from "crypto";
|
|
21610
21755
|
|
|
@@ -22014,6 +22159,12 @@ function buildValidationError({
|
|
|
22014
22159
|
return body;
|
|
22015
22160
|
}
|
|
22016
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
|
+
|
|
22017
22168
|
// src/stripe-multichain/mppx_stripe.ts
|
|
22018
22169
|
async function createMppxStripe({
|
|
22019
22170
|
profileId,
|
|
@@ -22194,6 +22345,31 @@ function wrapSolanaChargeWithFinalizedBlockhash(baseMethod, rpcUrl) {
|
|
|
22194
22345
|
}
|
|
22195
22346
|
};
|
|
22196
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
|
+
}
|
|
22197
22373
|
|
|
22198
22374
|
// src/payment/x402_server.ts
|
|
22199
22375
|
init_networks();
|
|
@@ -22335,40 +22511,28 @@ function lazyMppxServer(opts) {
|
|
|
22335
22511
|
};
|
|
22336
22512
|
}
|
|
22337
22513
|
|
|
22338
|
-
// src/
|
|
22339
|
-
|
|
22340
|
-
|
|
22341
|
-
|
|
22342
|
-
|
|
22343
|
-
|
|
22344
|
-
|
|
22345
|
-
|
|
22346
|
-
|
|
22347
|
-
|
|
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;
|
|
22348
22530
|
}
|
|
22349
|
-
const rec = headers;
|
|
22350
|
-
const v = rec[name] ?? rec[name.toLowerCase()] ?? rec[toTitleCase(name)];
|
|
22351
|
-
if (typeof v === "string") return v;
|
|
22352
|
-
if (Array.isArray(v) && typeof v[0] === "string") return v[0];
|
|
22353
22531
|
return null;
|
|
22354
22532
|
}
|
|
22355
|
-
|
|
22356
|
-
|
|
22357
|
-
|
|
22358
|
-
function hasPaymentHeader(input) {
|
|
22359
|
-
const headers = asHeaders(input);
|
|
22360
|
-
return Boolean(
|
|
22361
|
-
readHeader(headers, "payment-signature") || readHeader(headers, "x-payment") || readHeader(headers, "authorization")?.startsWith("Payment ")
|
|
22362
|
-
);
|
|
22363
|
-
}
|
|
22364
|
-
function hasX402Header(input) {
|
|
22365
|
-
const headers = asHeaders(input);
|
|
22366
|
-
return Boolean(readHeader(headers, "payment-signature") || readHeader(headers, "x-payment"));
|
|
22367
|
-
}
|
|
22368
|
-
function hasMppxHeader(input) {
|
|
22369
|
-
const headers = asHeaders(input);
|
|
22370
|
-
return Boolean(readHeader(headers, "authorization")?.startsWith("Payment "));
|
|
22371
|
-
}
|
|
22533
|
+
|
|
22534
|
+
// src/checkout.ts
|
|
22535
|
+
init_network_kind();
|
|
22372
22536
|
|
|
22373
22537
|
// src/payment/x402_settle.ts
|
|
22374
22538
|
function classifyX402SettleResult(result) {
|
|
@@ -22691,20 +22855,6 @@ function getIdentityStatus(ctx) {
|
|
|
22691
22855
|
if (decision === "allow") return "verified";
|
|
22692
22856
|
return "unverified";
|
|
22693
22857
|
}
|
|
22694
|
-
var CheckoutValidationError = class extends Error {
|
|
22695
|
-
code;
|
|
22696
|
-
action;
|
|
22697
|
-
status;
|
|
22698
|
-
extra;
|
|
22699
|
-
constructor(opts) {
|
|
22700
|
-
super(opts.message);
|
|
22701
|
-
this.name = "CheckoutValidationError";
|
|
22702
|
-
this.code = opts.code;
|
|
22703
|
-
this.action = opts.action ?? "fix_request";
|
|
22704
|
-
this.status = opts.status ?? 400;
|
|
22705
|
-
this.extra = opts.extra;
|
|
22706
|
-
}
|
|
22707
|
-
};
|
|
22708
22858
|
function resolveIdentityMetadata(ctx) {
|
|
22709
22859
|
const h = normalizeHeadersToLowercase(ctx.request.headers);
|
|
22710
22860
|
const wallet = h["x-wallet-address"];
|
|
@@ -23041,7 +23191,14 @@ var Checkout = class {
|
|
|
23041
23191
|
}
|
|
23042
23192
|
}
|
|
23043
23193
|
ctx.pricing = await this.computePricing(ctx);
|
|
23044
|
-
|
|
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
|
+
}
|
|
23045
23202
|
const x402ServerOk = this.x402ServerAvailable() && this.x402BaseNetwork !== null;
|
|
23046
23203
|
if (hasX402Header(request.headers) && x402ServerOk) {
|
|
23047
23204
|
const zero = await this.handleZeroSettle(ctx, "x402-base");
|
|
@@ -23112,8 +23269,16 @@ var Checkout = class {
|
|
|
23112
23269
|
...gate.failOpen !== void 0 && { failOpen: gate.failOpen },
|
|
23113
23270
|
...gate.cacheSeconds !== void 0 && { cacheSeconds: gate.cacheSeconds },
|
|
23114
23271
|
...gate.chain !== void 0 && { chain: gate.chain },
|
|
23115
|
-
|
|
23116
|
-
|
|
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 }
|
|
23117
23282
|
},
|
|
23118
23283
|
...policyOverride ?? {}
|
|
23119
23284
|
};
|
|
@@ -23313,7 +23478,9 @@ var Checkout = class {
|
|
|
23313
23478
|
if (this.composeMppx === void 0) {
|
|
23314
23479
|
throw new Error("Checkout.handleMppx: composeMppx hook not configured");
|
|
23315
23480
|
}
|
|
23316
|
-
const composed = await
|
|
23481
|
+
const { result: composed, failureReason } = await runWithMppxFailureCapture(
|
|
23482
|
+
async () => this.composeMppx(ctx)
|
|
23483
|
+
);
|
|
23317
23484
|
if (composed.status === 200) {
|
|
23318
23485
|
const paymentReceiptHeader = composed.paymentReceiptHeader ?? extractMppxReceiptHeaderFromRaw(composed.raw);
|
|
23319
23486
|
const directMethod = composed.raw?.receipt?.method;
|
|
@@ -23332,6 +23499,22 @@ var Checkout = class {
|
|
|
23332
23499
|
};
|
|
23333
23500
|
return await this.buildSuccess(ctx, outcome);
|
|
23334
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
|
+
}
|
|
23335
23518
|
return {
|
|
23336
23519
|
status: 400,
|
|
23337
23520
|
body: buildValidationError({
|
|
@@ -23350,7 +23533,11 @@ var Checkout = class {
|
|
|
23350
23533
|
throw new Error("Checkout.emit402: pricing not computed");
|
|
23351
23534
|
}
|
|
23352
23535
|
await this.resolveRecipientsForCtx(ctx);
|
|
23353
|
-
|
|
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
|
+
}
|
|
23354
23541
|
const accepted = await buildAcceptedMethods({
|
|
23355
23542
|
tempo: pickRail(emitRails, "tempo"),
|
|
23356
23543
|
x402_base: pickRail(emitRails, "x402_base"),
|
|
@@ -23753,87 +23940,6 @@ Checkout.prototype.mountUcpRoutesFastify = function(app, opts) {
|
|
|
23753
23940
|
app.options(jwksPath, preflight);
|
|
23754
23941
|
};
|
|
23755
23942
|
|
|
23756
|
-
// src/identity/policy.ts
|
|
23757
|
-
function buildGateFromPolicy(policy, base) {
|
|
23758
|
-
if (!policy || !policy.enforcement) return null;
|
|
23759
|
-
return {
|
|
23760
|
-
apiKey: base.apiKey,
|
|
23761
|
-
...base.baseUrl !== void 0 && { baseUrl: base.baseUrl },
|
|
23762
|
-
...policy.requireKyc !== void 0 && { requireKyc: policy.requireKyc },
|
|
23763
|
-
...policy.requireSanctionsClear !== void 0 && {
|
|
23764
|
-
requireSanctionsClear: policy.requireSanctionsClear
|
|
23765
|
-
},
|
|
23766
|
-
...policy.minAge !== void 0 && { minAge: policy.minAge },
|
|
23767
|
-
...policy.allowedJurisdictions !== void 0 && {
|
|
23768
|
-
allowedJurisdictions: [...policy.allowedJurisdictions]
|
|
23769
|
-
}
|
|
23770
|
-
};
|
|
23771
|
-
}
|
|
23772
|
-
async function runGateWithEnforcement(enforcement, runGate) {
|
|
23773
|
-
if (!runGate || !enforcement) return { status: "anonymous" };
|
|
23774
|
-
const outcome = await runGate();
|
|
23775
|
-
if (outcome.ok) return { status: "verified" };
|
|
23776
|
-
if (enforcement === "hard") {
|
|
23777
|
-
return {
|
|
23778
|
-
status: "denied",
|
|
23779
|
-
denialStatus: outcome.status,
|
|
23780
|
-
denialBody: outcome.body,
|
|
23781
|
-
...outcome.reason !== void 0 && { denialReason: outcome.reason }
|
|
23782
|
-
};
|
|
23783
|
-
}
|
|
23784
|
-
return {
|
|
23785
|
-
status: "unverified",
|
|
23786
|
-
denialStatus: outcome.status,
|
|
23787
|
-
denialBody: outcome.body,
|
|
23788
|
-
...outcome.reason !== void 0 && { denialReason: outcome.reason }
|
|
23789
|
-
};
|
|
23790
|
-
}
|
|
23791
|
-
function shippingCountryAllowed(country, policy) {
|
|
23792
|
-
if (!policy?.allowedShippingCountries || policy.allowedShippingCountries.length === 0) return true;
|
|
23793
|
-
const allowed = new Set(policy.allowedShippingCountries.map((c) => c.toUpperCase()));
|
|
23794
|
-
return allowed.has(country.toUpperCase());
|
|
23795
|
-
}
|
|
23796
|
-
function shippingStateAllowed(state, country, policy) {
|
|
23797
|
-
if (!policy?.allowedShippingStates || policy.allowedShippingStates.length === 0) return true;
|
|
23798
|
-
if (country.toUpperCase() !== "US") return true;
|
|
23799
|
-
const allowed = new Set(policy.allowedShippingStates.map((s) => s.toUpperCase()));
|
|
23800
|
-
return allowed.has(state.toUpperCase());
|
|
23801
|
-
}
|
|
23802
|
-
function validateShippingAgainstPolicy(opts) {
|
|
23803
|
-
const code = opts.errorCode ?? "unsupported_jurisdiction";
|
|
23804
|
-
const action = opts.errorAction ?? "change_shipping_state";
|
|
23805
|
-
const item = opts.productName ? `'${opts.productName}'` : "this item";
|
|
23806
|
-
if (!shippingCountryAllowed(opts.country, opts.policy)) {
|
|
23807
|
-
throw new CheckoutValidationError({
|
|
23808
|
-
code,
|
|
23809
|
-
message: opts.countryMessage ?? `We can't ship ${item} to ${opts.country.toUpperCase() || "<unset>"}.`,
|
|
23810
|
-
action
|
|
23811
|
-
});
|
|
23812
|
-
}
|
|
23813
|
-
if (!shippingStateAllowed(opts.state, opts.country, opts.policy)) {
|
|
23814
|
-
throw new CheckoutValidationError({
|
|
23815
|
-
code,
|
|
23816
|
-
message: opts.stateMessage ?? `We can't ship ${item} to ${opts.state.toUpperCase() || "<unset>"}.`,
|
|
23817
|
-
action
|
|
23818
|
-
});
|
|
23819
|
-
}
|
|
23820
|
-
}
|
|
23821
|
-
|
|
23822
|
-
// src/identity/tokens.ts
|
|
23823
|
-
import { createHash } from "crypto";
|
|
23824
|
-
function hashOperatorToken(plaintext) {
|
|
23825
|
-
return createHash("sha256").update(plaintext, "utf8").digest("hex");
|
|
23826
|
-
}
|
|
23827
|
-
function extractOwnerScope(input) {
|
|
23828
|
-
const headers = asHeaders(input);
|
|
23829
|
-
const walletAddress = readHeader(headers, "x-wallet-address");
|
|
23830
|
-
const operatorToken = readHeader(headers, "x-operator-token");
|
|
23831
|
-
return {
|
|
23832
|
-
...walletAddress ? { walletAddress } : {},
|
|
23833
|
-
...operatorToken ? { operatorTokenHash: hashOperatorToken(operatorToken) } : {}
|
|
23834
|
-
};
|
|
23835
|
-
}
|
|
23836
|
-
|
|
23837
23943
|
// src/payment/index.ts
|
|
23838
23944
|
init_directive();
|
|
23839
23945
|
init_networks();
|
|
@@ -23910,6 +24016,7 @@ async function loadSolanaFeePayer(opts) {
|
|
|
23910
24016
|
|
|
23911
24017
|
// src/payment/compose_rails.ts
|
|
23912
24018
|
init_usdc();
|
|
24019
|
+
var warnedStripeBelowMinimum = false;
|
|
23913
24020
|
function buildMppxComposeRails(opts) {
|
|
23914
24021
|
const rails2 = [];
|
|
23915
24022
|
if (opts.tempoRecipient) {
|
|
@@ -23931,7 +24038,17 @@ function buildMppxComposeRails(opts) {
|
|
|
23931
24038
|
}]);
|
|
23932
24039
|
}
|
|
23933
24040
|
if (opts.includeStripe !== false) {
|
|
23934
|
-
|
|
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
|
+
}
|
|
23935
24052
|
}
|
|
23936
24053
|
return rails2;
|
|
23937
24054
|
}
|
|
@@ -24122,10 +24239,11 @@ function computeFirstCheckout(opts) {
|
|
|
24122
24239
|
const tempoRecipient = recipients.tempo;
|
|
24123
24240
|
const x402BaseRecipient = recipients.x402_base;
|
|
24124
24241
|
const solanaRecipient = recipients.solana_mpp;
|
|
24242
|
+
const includeStripeInDiscovery = opts.rails.stripe !== void 0 && Number(totalUsd) >= STRIPE_MIN_CHARGE_USD;
|
|
24125
24243
|
const accepted = await buildAcceptedMethods({
|
|
24126
24244
|
...tempoRecipient && opts.rails.tempo && { tempo: { ...opts.rails.tempo, recipient: tempoRecipient } },
|
|
24127
24245
|
...solanaRecipient && opts.rails.solana_mpp && { solana_mpp: { ...opts.rails.solana_mpp, recipient: solanaRecipient } },
|
|
24128
|
-
...
|
|
24246
|
+
...includeStripeInDiscovery && { stripe: opts.rails.stripe }
|
|
24129
24247
|
});
|
|
24130
24248
|
if (x402BaseRecipient && opts.rails.x402_base) {
|
|
24131
24249
|
try {
|
|
@@ -24548,6 +24666,7 @@ export {
|
|
|
24548
24666
|
buildMppxComposeRails,
|
|
24549
24667
|
buildSignerMismatchBody,
|
|
24550
24668
|
buildUCPProfile,
|
|
24669
|
+
buildVerificationRequiredBody,
|
|
24551
24670
|
computeFirstCheckout,
|
|
24552
24671
|
createDefaultOnDenied,
|
|
24553
24672
|
createQuoteCache,
|