@t2000/sdk 10.13.1 → 10.13.3

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/dist/index.cjs CHANGED
@@ -1151,8 +1151,9 @@ async function payWithMpp(args) {
1151
1151
  if (probe.status !== 402) {
1152
1152
  return finalize(probe, { paid: false });
1153
1153
  }
1154
- const requirements = await pickSuiExactRequirements(probe, client.network);
1155
- if (requirements) {
1154
+ const pick = await pickSuiExactRequirements(probe, client.network);
1155
+ if (pick.kind === "payable") {
1156
+ const requirements = pick.requirements;
1156
1157
  const { isX402EscrowRequirements } = await import('@suimpp/mpp/x402');
1157
1158
  if (isX402EscrowRequirements(requirements)) {
1158
1159
  const escrow = requirements.extra.escrow;
@@ -1185,6 +1186,13 @@ async function payWithMpp(args) {
1185
1186
  await reportDirectPayment(result, options.url);
1186
1187
  return result;
1187
1188
  }
1189
+ if (pick.kind === "incomplete") {
1190
+ throw new exports.T2000Error(
1191
+ "FACILITATOR_REJECTION",
1192
+ "Seller's x402 challenge is incomplete (missing extra.suimpp) \u2014 nothing was paid. The 402 advertises an exact/sui entry but carries no settlement challenge to bind a payment to; the seller must emit the createX402Requirements shape to be x402-payable.",
1193
+ { reason: "incomplete-x402-accepts" }
1194
+ );
1195
+ }
1188
1196
  throw new exports.T2000Error(
1189
1197
  "FACILITATOR_REJECTION",
1190
1198
  `Endpoint returned 402 without an x402 'exact' / sui:${client.network} requirement in the body or an MPP 'sui' challenge in WWW-Authenticate. Nothing this SDK can pay.`
@@ -1223,17 +1231,34 @@ async function parseMppSuiChallenge(response) {
1223
1231
  return void 0;
1224
1232
  }
1225
1233
  }
1234
+ function hasCompleteSuimppChallenge(entry) {
1235
+ const s = entry.extra?.suimpp;
1236
+ return !!s && typeof s.challengeId === "string" && s.challengeId.length > 0 && typeof s.nonce === "number" && typeof s.chain === "string" && s.chain.length > 0 && typeof s.minEpoch === "string" && typeof s.maxEpoch === "string";
1237
+ }
1226
1238
  async function pickSuiExactRequirements(response, network) {
1227
1239
  try {
1228
1240
  const body2 = await response.clone().json();
1229
1241
  const want = `sui:${network === "testnet" ? "testnet" : "mainnet"}`;
1230
- return body2.accepts?.find((a) => a.scheme === "exact" && a.network === want);
1242
+ const entry = body2.accepts?.find((a) => a.scheme === "exact" && a.network === want);
1243
+ if (!entry) return { kind: "none" };
1244
+ const { isX402EscrowRequirements } = await import('@suimpp/mpp/x402');
1245
+ if (hasCompleteSuimppChallenge(entry) || isX402EscrowRequirements(entry)) {
1246
+ return { kind: "payable", requirements: entry };
1247
+ }
1248
+ return { kind: "incomplete" };
1231
1249
  } catch {
1232
- return void 0;
1250
+ return { kind: "none" };
1233
1251
  }
1234
1252
  }
1235
1253
  async function payViaX402(args) {
1236
1254
  const { signer, client, options, reqInit, requirements } = args;
1255
+ if (!hasCompleteSuimppChallenge(requirements)) {
1256
+ throw new exports.T2000Error(
1257
+ "FACILITATOR_REJECTION",
1258
+ "Seller's x402 challenge is incomplete (missing extra.suimpp) \u2014 nothing was paid.",
1259
+ { reason: "incomplete-x402-accepts" }
1260
+ );
1261
+ }
1237
1262
  const { buildX402SignedPayment, X402_PAYMENT_HEADER, X402_PAYMENT_RESPONSE_HEADER } = await import('@suimpp/mpp/x402');
1238
1263
  const amountRaw = BigInt(requirements.maxAmountRequired);
1239
1264
  assertWithinMaxPrice(atomicToHuman(amountRaw, await assetDecimals(requirements.asset)), options.maxPrice);
@@ -3439,7 +3464,12 @@ function requirementFieldMap(listing) {
3439
3464
  return listing;
3440
3465
  }
3441
3466
  function requirementHint(value) {
3442
- return typeof value === "string" ? value : JSON.stringify(value);
3467
+ if (typeof value === "string") return value;
3468
+ if (value && typeof value === "object" && !Array.isArray(value)) {
3469
+ const desc = value.description;
3470
+ if (typeof desc === "string" && desc.trim().length > 0) return desc;
3471
+ }
3472
+ return JSON.stringify(value);
3443
3473
  }
3444
3474
  function isPlainObject(value) {
3445
3475
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -3450,7 +3480,8 @@ function assertBuyerRequirements(listingRequirements, buyerPayload) {
3450
3480
  }
3451
3481
  if (isPlainObject(listingRequirements)) {
3452
3482
  const fields = requirementFieldMap(listingRequirements);
3453
- const keys = Object.keys(fields);
3483
+ const requiredRaw = listingRequirements.required;
3484
+ const keys = isPlainObject(listingRequirements.properties) && Array.isArray(requiredRaw) && requiredRaw.every((k) => typeof k === "string") ? requiredRaw : Object.keys(fields);
3454
3485
  if (keys.length === 0) {
3455
3486
  return;
3456
3487
  }