@rhea-finance/cross-chain-aggregation-dex 2.0.4 → 2.0.6

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.
Files changed (42) hide show
  1. package/README.md +207 -77
  2. package/dist/executors/aptos.d.mts +1 -1
  3. package/dist/executors/aptos.d.ts +1 -1
  4. package/dist/executors/aptos.js.map +1 -1
  5. package/dist/executors/aptos.mjs.map +1 -1
  6. package/dist/executors/bitcoin.d.mts +1 -1
  7. package/dist/executors/bitcoin.d.ts +1 -1
  8. package/dist/executors/bitcoin.js.map +1 -1
  9. package/dist/executors/bitcoin.mjs.map +1 -1
  10. package/dist/executors/evm.d.mts +1 -1
  11. package/dist/executors/evm.d.ts +1 -1
  12. package/dist/executors/evm.js.map +1 -1
  13. package/dist/executors/evm.mjs.map +1 -1
  14. package/dist/executors/near.d.mts +1 -1
  15. package/dist/executors/near.d.ts +1 -1
  16. package/dist/executors/near.js.map +1 -1
  17. package/dist/executors/near.mjs.map +1 -1
  18. package/dist/executors/solana.d.mts +1 -1
  19. package/dist/executors/solana.d.ts +1 -1
  20. package/dist/executors/solana.js.map +1 -1
  21. package/dist/executors/solana.mjs.map +1 -1
  22. package/dist/executors/sui.d.mts +1 -1
  23. package/dist/executors/sui.d.ts +1 -1
  24. package/dist/executors/sui.js.map +1 -1
  25. package/dist/executors/sui.mjs.map +1 -1
  26. package/dist/executors/tron.d.mts +1 -1
  27. package/dist/executors/tron.d.ts +1 -1
  28. package/dist/executors/tron.js.map +1 -1
  29. package/dist/executors/tron.mjs.map +1 -1
  30. package/dist/executors/zcash.d.mts +1 -1
  31. package/dist/executors/zcash.d.ts +1 -1
  32. package/dist/executors/zcash.js.map +1 -1
  33. package/dist/executors/zcash.mjs.map +1 -1
  34. package/dist/index.d.mts +82 -6
  35. package/dist/index.d.ts +82 -6
  36. package/dist/index.js +454 -71
  37. package/dist/index.js.map +1 -1
  38. package/dist/index.mjs +451 -72
  39. package/dist/index.mjs.map +1 -1
  40. package/dist/{shared-D0_DbMT2.d.mts → shared-COkGiqaz.d.mts} +84 -2
  41. package/dist/{shared-D0_DbMT2.d.ts → shared-COkGiqaz.d.ts} +84 -2
  42. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -95,14 +95,49 @@ var ApiClient = class {
95
95
  retryableOperation: true,
96
96
  query: {
97
97
  sender: params.sender,
98
+ mode: params.mode,
98
99
  pageNumber: params.pageNumber,
99
100
  pageSize: params.pageSize
100
- }
101
+ },
102
+ ...params.mode === "confidential" && params.walletToken ? { authenticationToken: params.walletToken } : {}
103
+ });
104
+ }
105
+ createHistoryAuthChallenge(body, options = {}) {
106
+ return this.request("/api/swap/history/auth/challenge", "history", {
107
+ ...options,
108
+ method: "POST",
109
+ body
110
+ });
111
+ }
112
+ verifyHistoryAuthChallenge(body, options = {}) {
113
+ return this.request("/api/swap/history/auth/verify", "history", {
114
+ ...options,
115
+ method: "POST",
116
+ body
117
+ });
118
+ }
119
+ getFromTokenRows(chainId, options = {}) {
120
+ return this.request("/get_chain_prices", "tokens", {
121
+ ...options,
122
+ method: "GET",
123
+ retryableOperation: true,
124
+ query: { chain: chainId }
125
+ });
126
+ }
127
+ getCrossChainToTokenRows(chainId, options = {}) {
128
+ return this.request("/api/swap/supported_to_tokens", "tokens", {
129
+ ...options,
130
+ method: "GET",
131
+ retryableOperation: true,
132
+ query: { chain: chainId }
101
133
  });
102
134
  }
103
135
  async request(path, stage, options) {
104
136
  const url = this.buildUrl(path, options.query);
105
- const headers = await this.buildHeaders(options.idempotencyKey);
137
+ const headers = await this.buildHeaders(
138
+ options.idempotencyKey,
139
+ options.authenticationToken
140
+ );
106
141
  const retry = this.retryConfig();
107
142
  let attempt = 1;
108
143
  for (; ; ) {
@@ -254,12 +289,13 @@ var ApiClient = class {
254
289
  const suffix = search.toString();
255
290
  return suffix ? `${this.baseUrl}${path}?${suffix}` : `${this.baseUrl}${path}`;
256
291
  }
257
- async buildHeaders(idempotencyKey) {
292
+ async buildHeaders(idempotencyKey, authenticationToken) {
258
293
  const configured = typeof this.config.headers === "function" ? await this.config.headers() : this.config.headers ?? {};
259
294
  const token = this.config.getAccessToken ? await this.config.getAccessToken() : this.config.apiKey;
260
295
  return {
261
296
  "Content-Type": "application/json",
262
297
  ...token ? { Authorization: `Bearer ${token}` } : {},
298
+ ...authenticationToken ? { Authentication: `Bearer ${authenticationToken}` } : {},
263
299
  ...idempotencyKey ? { "Idempotency-Key": idempotencyKey } : {},
264
300
  ...configured
265
301
  };
@@ -635,7 +671,7 @@ function normalizeBuild(raw, executionId = createExecutionId(), request) {
635
671
  const lane = laneFromChainType(common.chainType, fromChain);
636
672
  assertLaneMatchesChain(lane, fromChain);
637
673
  const execution = normalizeExecution(raw, lane, fromChain);
638
- const order = normalizeOrder(raw, execution);
674
+ const order = normalizeOrder(raw, execution, request);
639
675
  const deposit = normalizeDeposit(raw.deposit);
640
676
  return {
641
677
  executionId,
@@ -866,11 +902,12 @@ function assertKind(actual, allowed) {
866
902
  );
867
903
  }
868
904
  }
869
- function normalizeOrder(raw, execution) {
905
+ function normalizeOrder(raw, execution, request) {
870
906
  const depositOrderId = readRecordString(raw.deposit, "orderId");
871
- const orderId = raw.orderId ?? depositOrderId;
872
- if (!orderId) return void 0;
873
907
  const router = raw.statusRouter ?? (execution.kind === "evm-signature" ? execution.request.router : void 0) ?? raw.router;
908
+ const confidentialNearIntentsStatusKey = request?.confidentiality === "basic" && router.toLowerCase().includes("nearintents") ? readRecordString(raw.deposit, "depositAddress") : void 0;
909
+ const orderId = raw.orderId ?? depositOrderId ?? confidentialNearIntentsStatusKey;
910
+ if (!orderId) return void 0;
874
911
  const chainId = execution.kind === "evm-signature" ? String(execution.request.chainId) : execution.kind === "evm-transaction" ? String(execution.tx.chainId) : void 0;
875
912
  return { orderId, router, ...chainId ? { chainId } : {} };
876
913
  }
@@ -930,6 +967,8 @@ function assertBaseUnitAmount(value) {
930
967
 
931
968
  // src/normalizers/quote.ts
932
969
  var DEFAULT_QUOTE_WAITING_TIME_MS = 3e3;
970
+ var DEFAULT_SAME_CHAIN_TIMEOUT_MS = 500;
971
+ var DEFAULT_CROSS_CHAIN_TIMEOUT_MS = 3e3;
933
972
  function serializeQuoteRequest(request) {
934
973
  validateQuoteRequest(request);
935
974
  return {
@@ -941,6 +980,9 @@ function serializeQuoteRequest(request) {
941
980
  amountIn: request.amountIn,
942
981
  slippage: request.slippageBps,
943
982
  quoteWaitingTimeMs: request.quoteWaitingTimeMs ?? DEFAULT_QUOTE_WAITING_TIME_MS,
983
+ sameChainTimeoutMs: request.sameChainTimeoutMs ?? DEFAULT_SAME_CHAIN_TIMEOUT_MS,
984
+ crossChainTimeoutMs: request.crossChainTimeoutMs ?? DEFAULT_CROSS_CHAIN_TIMEOUT_MS,
985
+ ...request.confidentiality ? { confidentiality: request.confidentiality } : {},
944
986
  sender: request.sender.trim(),
945
987
  ...request.recipient?.trim() ? { recipient: request.recipient.trim() } : {}
946
988
  };
@@ -951,7 +993,11 @@ function normalizeQuote(request, raw, receivedAt = Date.now()) {
951
993
  throw invalidQuote("Quote response does not contain a valid best route");
952
994
  }
953
995
  const quoteId = readOptionalString(raw.bestQuote.quoteId);
954
- const apiRequest = Object.freeze({ ...serializeQuoteRequest(request) });
996
+ const apiRequest = { ...serializeQuoteRequest(request) };
997
+ delete apiRequest.quoteWaitingTimeMs;
998
+ delete apiRequest.sameChainTimeoutMs;
999
+ delete apiRequest.crossChainTimeoutMs;
1000
+ Object.freeze(apiRequest);
955
1001
  const buildContext = Object.freeze({
956
1002
  request: apiRequest,
957
1003
  router: bestRoute.router,
@@ -1019,6 +1065,14 @@ function validateQuoteRequest(request) {
1019
1065
  "quoteWaitingTimeMs must be a non-negative integer"
1020
1066
  );
1021
1067
  }
1068
+ validateQuoteTimingParameter(
1069
+ request.sameChainTimeoutMs,
1070
+ "sameChainTimeoutMs"
1071
+ );
1072
+ validateQuoteTimingParameter(
1073
+ request.crossChainTimeoutMs,
1074
+ "crossChainTimeoutMs"
1075
+ );
1022
1076
  if (!request.sender.trim()) {
1023
1077
  throw new SwapSdkError(
1024
1078
  "INVALID_REQUEST",
@@ -1041,6 +1095,15 @@ function validateQuoteRequest(request) {
1041
1095
  );
1042
1096
  }
1043
1097
  }
1098
+ function validateQuoteTimingParameter(value, field) {
1099
+ if (value !== void 0 && (!Number.isFinite(value) || !Number.isInteger(value) || value < 0)) {
1100
+ throw new SwapSdkError(
1101
+ "INVALID_REQUEST",
1102
+ "quote",
1103
+ `${field} must be a non-negative integer`
1104
+ );
1105
+ }
1106
+ }
1044
1107
  function normalizeRoute(raw, required) {
1045
1108
  const router = readOptionalString(raw.router);
1046
1109
  const amountOutValue = raw.amountOut ?? raw.estimatedOut;
@@ -1213,6 +1276,243 @@ function normalizeTimestamp(value) {
1213
1276
  return Number.isNaN(date.getTime()) ? void 0 : date.toISOString();
1214
1277
  }
1215
1278
 
1279
+ // src/normalizers/tokens.ts
1280
+ var TOKEN_LIST_CHAIN_METADATA = /* @__PURE__ */ new Map([
1281
+ [1, { chain: "1", blockchain: "eth" }],
1282
+ [10, { chain: "10", blockchain: "op" }],
1283
+ [43114, { chain: "43114", blockchain: "avax" }],
1284
+ [4663, { chain: "4663", blockchain: "robinhood" }],
1285
+ [747474, { chain: "747474", blockchain: "katana" }],
1286
+ [146, { chain: "146", blockchain: "sonic" }],
1287
+ [130, { chain: "130", blockchain: "unichain" }],
1288
+ [1672, { chain: "1672", blockchain: "pharos" }],
1289
+ [4217, { chain: "4217", blockchain: "tempo" }],
1290
+ [56, { chain: "56", blockchain: "bsc" }],
1291
+ [100, { chain: "100", blockchain: "gnosis" }],
1292
+ [137, { chain: "137", blockchain: "pol" }],
1293
+ [143, { chain: "143", blockchain: "monad" }],
1294
+ [196, { chain: "196", blockchain: "xlayer" }],
1295
+ [8453, { chain: "8453", blockchain: "base" }],
1296
+ [9745, { chain: "9745", blockchain: "plasma" }],
1297
+ [42161, { chain: "42161", blockchain: "arb" }],
1298
+ [80094, { chain: "80094", blockchain: "bera" }],
1299
+ [195, { chain: "tron", blockchain: "tron" }],
1300
+ [501, { chain: "solana", blockchain: "sol" }],
1301
+ [784, { chain: "sui", blockchain: "sui" }],
1302
+ [900001, { chain: "near", blockchain: "near" }],
1303
+ [900002, { chain: "btc", blockchain: "btc" }],
1304
+ [900010, { chain: "zcash", blockchain: "zec" }],
1305
+ [900012, { chain: "aptos", blockchain: "aptos" }]
1306
+ ]);
1307
+ function normalizeFromTokenList(raw, chainId) {
1308
+ if (!isRecord2(raw) || Array.isArray(raw)) {
1309
+ throw invalidTokenList("From-token response data must be an object");
1310
+ }
1311
+ return normalizeRows(Object.values(raw), chainId);
1312
+ }
1313
+ function normalizeCrossChainToTokenList(raw, chainId) {
1314
+ if (!isRecord2(raw) || !Array.isArray(raw.tokens)) {
1315
+ throw invalidTokenList(
1316
+ "Cross-chain to-token response data must contain a tokens array"
1317
+ );
1318
+ }
1319
+ return normalizeRows(raw.tokens, chainId);
1320
+ }
1321
+ function normalizeRows(rows, chainId) {
1322
+ const tokens = rows.map((row) => normalizeRow(row, chainId)).filter((token) => token !== void 0);
1323
+ if (rows.length > 0 && tokens.length === 0) {
1324
+ throw invalidTokenList("Token-list response contains no valid token rows");
1325
+ }
1326
+ return tokens;
1327
+ }
1328
+ function normalizeRow(value, chainId) {
1329
+ if (!isRecord2(value)) return void 0;
1330
+ const row = value;
1331
+ const assetId = readString(row.assetId) ?? readString(row.address) ?? readString(row.contractAddress) ?? readString(row.coinType);
1332
+ const symbol = readString(row.symbol);
1333
+ const decimals = readDecimals(row.decimals);
1334
+ if (!assetId || !symbol || decimals === void 0) return void 0;
1335
+ const metadata = TOKEN_LIST_CHAIN_METADATA.get(chainId);
1336
+ const chain = metadata?.chain ?? String(chainId);
1337
+ const blockchain = readString(row.blockchain)?.toLowerCase() ?? metadata?.blockchain ?? String(chainId);
1338
+ const rawAddress = readString(row.contractAddress) ?? readString(row.address) ?? readString(row.coinType);
1339
+ const isNative = isNativeToken({
1340
+ row,
1341
+ chain,
1342
+ blockchain,
1343
+ assetId,
1344
+ rawAddress,
1345
+ symbol
1346
+ });
1347
+ const sources = Array.isArray(row.sources) ? row.sources.filter(
1348
+ (source) => typeof source === "string" && source.trim().length > 0
1349
+ ) : readString(row.platform) ? [readString(row.platform)] : [];
1350
+ const price = typeof row.price === "string" || typeof row.price === "number" ? row.price : null;
1351
+ const priceUpdatedAt = typeof row.updated_at === "number" && Number.isFinite(row.updated_at) ? row.updated_at : null;
1352
+ return {
1353
+ chain,
1354
+ address: assetId,
1355
+ symbol,
1356
+ decimals,
1357
+ isNative,
1358
+ tokenListChainId: chainId,
1359
+ blockchain,
1360
+ assetId,
1361
+ contractAddress: isNative ? null : rawAddress ?? null,
1362
+ coinType: readString(row.coinType) ?? null,
1363
+ name: readString(row.name) ?? null,
1364
+ logoURI: readString(row.logoURI) ?? null,
1365
+ price,
1366
+ priceUpdatedAt,
1367
+ sources,
1368
+ raw: { ...row }
1369
+ };
1370
+ }
1371
+ function isNativeToken(input) {
1372
+ if (input.row.isNative === true) return true;
1373
+ const address = (input.rawAddress ?? "").toLowerCase();
1374
+ const assetId = input.assetId.toLowerCase();
1375
+ const coinType = readString(input.row.coinType)?.toLowerCase() ?? "";
1376
+ if (/^[1-9]\d*$/.test(input.chain)) {
1377
+ return address === "0x0000000000000000000000000000000000000000" || address === "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" || (input.blockchain === "pol" || input.blockchain === "polygon") && address === "0x0000000000000000000000000000000000001010";
1378
+ }
1379
+ if (input.chain === "solana") {
1380
+ return address === "11111111111111111111111111111111" || assetId === "nep141:sol.omft.near";
1381
+ }
1382
+ if (input.chain === "tron") {
1383
+ return input.symbol.toUpperCase() === "TRX";
1384
+ }
1385
+ if (input.chain === "sui") {
1386
+ return address.endsWith("::sui::sui");
1387
+ }
1388
+ if (input.chain === "aptos") {
1389
+ if (coinType === "0x1::aptos_coin::aptoscoin") return true;
1390
+ if (!/^0x[0-9a-f]+$/.test(address)) return false;
1391
+ const compactAddress = address.slice(2).replace(/^0+/, "") || "0";
1392
+ return compactAddress === "a";
1393
+ }
1394
+ return false;
1395
+ }
1396
+ function readString(value) {
1397
+ return typeof value === "string" && value.trim() ? value.trim() : void 0;
1398
+ }
1399
+ function readDecimals(value) {
1400
+ const decimals = typeof value === "number" ? value : typeof value === "string" && value.trim() ? Number(value) : Number.NaN;
1401
+ return Number.isInteger(decimals) && decimals >= 0 ? decimals : void 0;
1402
+ }
1403
+ function isRecord2(value) {
1404
+ return typeof value === "object" && value !== null;
1405
+ }
1406
+ function invalidTokenList(message) {
1407
+ return new SwapSdkError("INVALID_API_RESPONSE", "tokens", message);
1408
+ }
1409
+
1410
+ // src/mca/collateral.ts
1411
+ function resolveMcaWithdrawPolicy(input) {
1412
+ const decreaseCollateral = resolveMcaRequiredCollateralDecrease({
1413
+ amountBurrow: input.amountBurrow,
1414
+ suppliedBalance: input.suppliedBalance
1415
+ });
1416
+ const available = parseDecimal(input.availableBalance, "availableBalance");
1417
+ const amount = parseDecimal(input.amountIn, "amountIn");
1418
+ return {
1419
+ ...decreaseCollateral,
1420
+ withdrawAll: input.isMax || available.digits > 0n && isAtLeastWithdrawAllThreshold(amount, available)
1421
+ };
1422
+ }
1423
+ function resolveMcaRequiredCollateralDecrease(input) {
1424
+ const amount = parseBurrowDecimal(input.amountBurrow, "amountBurrow");
1425
+ const supplied = parseBurrowDecimal(
1426
+ input.suppliedBalance,
1427
+ "suppliedBalance"
1428
+ );
1429
+ const [amountScaled, suppliedScaled] = alignScale(amount, supplied);
1430
+ const decreaseScaled = amountScaled > suppliedScaled ? amountScaled - suppliedScaled : 0n;
1431
+ return resolveParsedMcaDecreaseCollateral({
1432
+ digits: decreaseScaled,
1433
+ scale: Math.max(amount.scale, supplied.scale)
1434
+ });
1435
+ }
1436
+ function resolveMcaDecreaseCollateral(decreaseAmountBurrow, field = "decreaseAmountBurrow") {
1437
+ const parsed = parseBurrowDecimal(decreaseAmountBurrow, field);
1438
+ return resolveParsedMcaDecreaseCollateral(parsed);
1439
+ }
1440
+ function resolveParsedMcaDecreaseCollateral(parsed) {
1441
+ const needDecrease = parsed.digits > 0n;
1442
+ return {
1443
+ needDecrease,
1444
+ decreaseAmountBurrow: needDecrease ? formatDecimal(parsed) : "0"
1445
+ };
1446
+ }
1447
+ function isAtLeastWithdrawAllThreshold(amount, available) {
1448
+ const [amountScaled, availableScaled] = alignScale(amount, available);
1449
+ return amountScaled * 1000000n >= availableScaled * 999999n;
1450
+ }
1451
+ function alignScale(a, b) {
1452
+ const scale = Math.max(a.scale, b.scale);
1453
+ return [
1454
+ a.digits * pow10(scale - a.scale),
1455
+ b.digits * pow10(scale - b.scale)
1456
+ ];
1457
+ }
1458
+ function parseDecimal(value, field) {
1459
+ const trimmed = value.trim();
1460
+ if (!/^(?:0|[1-9]\d*)(?:\.\d+)?$/.test(trimmed)) {
1461
+ throw new SwapSdkError(
1462
+ "INVALID_REQUEST",
1463
+ "quote",
1464
+ `${field} must be a non-negative decimal string`
1465
+ );
1466
+ }
1467
+ const [integer = "0", fraction = ""] = trimmed.split(".");
1468
+ return {
1469
+ digits: BigInt(`${integer}${fraction}`),
1470
+ scale: fraction.length
1471
+ };
1472
+ }
1473
+ function parseBurrowDecimal(value, field) {
1474
+ const trimmed = value.trim();
1475
+ const match = /^(?:([0-9]+)(?:\.([0-9]*))?|\.([0-9]+))(?:[eE]([+-]?[0-9]+))?$/.exec(
1476
+ trimmed
1477
+ );
1478
+ if (!match) {
1479
+ throw new SwapSdkError(
1480
+ "INVALID_REQUEST",
1481
+ "quote",
1482
+ `${field} must be a non-negative decimal string`
1483
+ );
1484
+ }
1485
+ const integer = match[1] ?? "0";
1486
+ const fraction = match[2] ?? match[3] ?? "";
1487
+ const exponent = Number(match[4] ?? "0");
1488
+ if (!Number.isSafeInteger(exponent) || Math.abs(exponent) > 1e5) {
1489
+ throw new SwapSdkError(
1490
+ "INVALID_REQUEST",
1491
+ "quote",
1492
+ `${field} exponent is out of range`
1493
+ );
1494
+ }
1495
+ let digits = BigInt(`${integer}${fraction}` || "0");
1496
+ let scale = fraction.length - exponent;
1497
+ if (scale < 0) {
1498
+ digits *= pow10(-scale);
1499
+ scale = 0;
1500
+ }
1501
+ return { digits, scale };
1502
+ }
1503
+ function formatDecimal(value) {
1504
+ if (value.digits === 0n) return "0";
1505
+ if (value.scale === 0) return value.digits.toString();
1506
+ const padded = value.digits.toString().padStart(value.scale + 1, "0");
1507
+ const splitAt = padded.length - value.scale;
1508
+ const integer = padded.slice(0, splitAt);
1509
+ const fraction = padded.slice(splitAt).replace(/0+$/, "");
1510
+ return fraction ? `${integer}.${fraction}` : integer;
1511
+ }
1512
+ function pow10(exponent) {
1513
+ return 10n ** BigInt(exponent);
1514
+ }
1515
+
1216
1516
  // src/mca/quote.ts
1217
1517
  function serializeMcaQuoteRequest(request, signer) {
1218
1518
  const mcaAccountId = request.mcaAccountId.trim();
@@ -1228,13 +1528,10 @@ function serializeMcaQuoteRequest(request, signer) {
1228
1528
  if (!identityKey) {
1229
1529
  throw invalidRequest("signer identityKey is required");
1230
1530
  }
1231
- if (request.flow === "withdraw" && !/^(?:0|[1-9]\d*)(?:\.\d+)?$/.test(
1232
- request.collateral.decreaseAmountBurrow.trim()
1233
- )) {
1234
- throw invalidRequest(
1235
- "collateral.decreaseAmountBurrow must be a non-negative decimal string"
1236
- );
1237
- }
1531
+ const decreaseCollateral = request.flow === "withdraw" ? resolveMcaDecreaseCollateral(
1532
+ request.collateral.decreaseAmountBurrow,
1533
+ "collateral.decreaseAmountBurrow"
1534
+ ) : void 0;
1238
1535
  const mca = {
1239
1536
  flow: request.flow,
1240
1537
  mcaAccountId,
@@ -1243,8 +1540,8 @@ function serializeMcaQuoteRequest(request, signer) {
1243
1540
  identityKey
1244
1541
  },
1245
1542
  ...request.flow === "deposit" ? { useAsCollateral: request.collateral.useAsCollateral } : {
1246
- needDecreaseCollateral: request.collateral.needDecrease,
1247
- decreaseCollateralAmountBurrow: request.collateral.decreaseAmountBurrow,
1543
+ needDecreaseCollateral: decreaseCollateral.needDecrease,
1544
+ decreaseCollateralAmountBurrow: decreaseCollateral.decreaseAmountBurrow,
1248
1545
  ...request.collateral.withdrawAll ? { withdrawAll: true } : {}
1249
1546
  },
1250
1547
  ...request.recipientMsgSignatures ? { recipientMsgSignatures: [...request.recipientMsgSignatures] } : {},
@@ -1273,7 +1570,7 @@ function normalizeMcaQuote(request, signer, quote) {
1273
1570
  mca: Object.freeze({ ...mca })
1274
1571
  };
1275
1572
  if (request.flow === "deposit") {
1276
- if (readString(quote.raw.nearDepositTxError)) {
1573
+ if (readString2(quote.raw.nearDepositTxError)) {
1277
1574
  throw invalidResponse(String(quote.raw.nearDepositTxError));
1278
1575
  }
1279
1576
  return {
@@ -1284,7 +1581,7 @@ function normalizeMcaQuote(request, signer, quote) {
1284
1581
  ...quote.raw.nearDepositTx === void 0 ? {} : { nearDepositTx: quote.raw.nearDepositTx }
1285
1582
  };
1286
1583
  }
1287
- if (readString(quote.raw.nearMcaWithdrawTxError)) {
1584
+ if (readString2(quote.raw.nearMcaWithdrawTxError)) {
1288
1585
  throw invalidResponse(String(quote.raw.nearMcaWithdrawTxError));
1289
1586
  }
1290
1587
  const mode = resolveWithdrawMode(request);
@@ -1312,7 +1609,7 @@ function resolveWithdrawMode(request) {
1312
1609
  function isPlainObject(value) {
1313
1610
  return typeof value === "object" && value !== null && !Array.isArray(value);
1314
1611
  }
1315
- function readString(value) {
1612
+ function readString2(value) {
1316
1613
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
1317
1614
  }
1318
1615
  function invalidRequest(message) {
@@ -1800,7 +2097,7 @@ var McaSwapService = class {
1800
2097
  "MCA relayer preview is missing business"
1801
2098
  );
1802
2099
  }
1803
- const message = readString2(input.quote.preview.messageToSign);
2100
+ const message = readString3(input.quote.preview.messageToSign);
1804
2101
  if (!message) {
1805
2102
  throw new SwapSdkError(
1806
2103
  "INVALID_API_RESPONSE",
@@ -1809,7 +2106,7 @@ var McaSwapService = class {
1809
2106
  );
1810
2107
  }
1811
2108
  const depositAddress = extractMcaWithdrawDepositAddress({
1812
- snapshotDepositAddress: readString2(input.quote.raw.depositAddress),
2109
+ snapshotDepositAddress: readString3(input.quote.raw.depositAddress),
1813
2110
  preview: input.quote.preview,
1814
2111
  bestQuote: input.quote.raw.bestQuote
1815
2112
  });
@@ -1874,8 +2171,8 @@ var McaSwapService = class {
1874
2171
  signal: input.signal,
1875
2172
  idempotencyKey: input.idempotencyKey
1876
2173
  });
1877
- const orderId = readString2(raw.orderId) ?? readRecordString2(raw.deposit, "orderId");
1878
- const router = readString2(raw.router) ?? input.quote.route.router;
2174
+ const orderId = readString3(raw.orderId) ?? readRecordString2(raw.deposit, "orderId");
2175
+ const router = readString3(raw.router) ?? input.quote.route.router;
1879
2176
  const submittedDepositAddress = readRecordString2(raw.deposit, "depositAddress") ?? depositAddress;
1880
2177
  if (!orderId || !router) {
1881
2178
  throw new SwapSdkError(
@@ -1899,7 +2196,8 @@ var McaSwapService = class {
1899
2196
  is_cross_chain: true,
1900
2197
  tx_type: "mca-withdraw-relayer",
1901
2198
  multi_addr: input.quote.mcaAccountId,
1902
- swapId: orderId
2199
+ swapId: orderId,
2200
+ ...request.confidentiality ? { confidentiality: request.confidentiality } : {}
1903
2201
  };
1904
2202
  this.relayerReports.set(executionId, reportRequest);
1905
2203
  const result = {
@@ -2007,14 +2305,14 @@ function assertSignerMatchesQuote(signer, expected) {
2007
2305
  );
2008
2306
  }
2009
2307
  }
2010
- function readString2(value) {
2308
+ function readString3(value) {
2011
2309
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
2012
2310
  }
2013
2311
  function readRecordString2(value, field) {
2014
2312
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
2015
2313
  return void 0;
2016
2314
  }
2017
- return readString2(value[field]);
2315
+ return readString3(value[field]);
2018
2316
  }
2019
2317
 
2020
2318
  // src/client/SwapClient.ts
@@ -2022,6 +2320,8 @@ var SwapClient = class {
2022
2320
  constructor(config) {
2023
2321
  this.inFlight = /* @__PURE__ */ new Set();
2024
2322
  this.reportRequests = /* @__PURE__ */ new Map();
2323
+ this.tokenListCache = /* @__PURE__ */ new Map();
2324
+ this.tokenListInflight = /* @__PURE__ */ new Map();
2025
2325
  this.config = config;
2026
2326
  this.api = new ApiClient(config);
2027
2327
  this.registry = new ExecutorRegistry(config.executors ?? []);
@@ -2054,6 +2354,55 @@ var SwapClient = class {
2054
2354
  buildRaw(request, options = {}) {
2055
2355
  return this.api.build(request, options);
2056
2356
  }
2357
+ async getFromTokens(request, options = {}) {
2358
+ return this.loadTokenList("from", request, options, async () => {
2359
+ const raw = await this.api.getFromTokenRows(request.chainId, options);
2360
+ return normalizeFromTokenList(raw, request.chainId);
2361
+ });
2362
+ }
2363
+ async getCrossChainToTokens(request, options = {}) {
2364
+ return this.loadTokenList("cross-chain-to", request, options, async () => {
2365
+ const raw = await this.api.getCrossChainToTokenRows(
2366
+ request.chainId,
2367
+ options
2368
+ );
2369
+ return normalizeCrossChainToTokenList(raw, request.chainId);
2370
+ });
2371
+ }
2372
+ async loadTokenList(direction, request, options, load) {
2373
+ if (!Number.isSafeInteger(request.chainId) || request.chainId <= 0) {
2374
+ throw new SwapSdkError(
2375
+ "INVALID_REQUEST",
2376
+ "tokens",
2377
+ `Token-list chainId must be a positive safe integer: ${String(
2378
+ request.chainId
2379
+ )}`
2380
+ );
2381
+ }
2382
+ const ttlMs = Math.max(0, this.config.tokenListCacheTtlMs ?? 6e5);
2383
+ const key = `${direction}:${request.chainId}`;
2384
+ const cached = this.tokenListCache.get(key);
2385
+ if (ttlMs > 0 && cached && cached.expiresAt > this.now()) {
2386
+ return cloneTokenList(cached.tokens);
2387
+ }
2388
+ const existing = options.signal ? void 0 : this.tokenListInflight.get(key);
2389
+ if (existing) return cloneTokenList(await existing);
2390
+ const pending = load().then((tokens) => {
2391
+ if (ttlMs > 0) {
2392
+ this.tokenListCache.set(key, {
2393
+ expiresAt: this.now() + ttlMs,
2394
+ tokens: cloneTokenList(tokens)
2395
+ });
2396
+ }
2397
+ return tokens;
2398
+ }).finally(() => {
2399
+ if (this.tokenListInflight.get(key) === pending) {
2400
+ this.tokenListInflight.delete(key);
2401
+ }
2402
+ });
2403
+ if (!options.signal) this.tokenListInflight.set(key, pending);
2404
+ return cloneTokenList(await pending);
2405
+ }
2057
2406
  async buildSwap(input) {
2058
2407
  if (isMcaQuote(input.quote)) {
2059
2408
  return this.managedSwapFlow.build({
@@ -2184,7 +2533,23 @@ var SwapClient = class {
2184
2533
  emit({ type: "warning", executionId: build.executionId, warning });
2185
2534
  }
2186
2535
  }
2187
- if ((input.waitFor ?? "submitted") === "completed" && orderId) {
2536
+ const waitsForCompletion = (input.waitFor ?? "submitted") === "completed";
2537
+ const requiresOrderStatus = build.isCrossChain || build.request?.confidentiality === "basic";
2538
+ if (waitsForCompletion && requiresOrderStatus && !orderId) {
2539
+ throw new SwapSdkError(
2540
+ "INVALID_API_RESPONSE",
2541
+ "status",
2542
+ "Swap submitted, but the API did not provide a status key",
2543
+ {
2544
+ details: {
2545
+ executionId: build.executionId,
2546
+ ...result.txHash ? { txHash: result.txHash } : {},
2547
+ router: orderRouter ?? build.router
2548
+ }
2549
+ }
2550
+ );
2551
+ }
2552
+ if (waitsForCompletion && orderId) {
2188
2553
  const status = await this.waitForOrder({
2189
2554
  orderId,
2190
2555
  router: orderRouter ?? build.router,
@@ -2296,10 +2661,30 @@ var SwapClient = class {
2296
2661
  getHistoryRaw(params, options = {}) {
2297
2662
  return this.api.getHistory(params, options);
2298
2663
  }
2664
+ createHistoryAuthChallenge(request, options = {}) {
2665
+ return this.api.createHistoryAuthChallenge(request, options);
2666
+ }
2667
+ verifyHistoryAuthChallenge(request, options = {}) {
2668
+ return this.api.verifyHistoryAuthChallenge(request, options);
2669
+ }
2670
+ async authorizeConfidentialHistory(request, signChallenge, options = {}) {
2671
+ const challenge = await this.createHistoryAuthChallenge(request, options);
2672
+ assertHistoryChallengeMatchesRequest(challenge, request);
2673
+ const proof = await signChallenge(challenge);
2674
+ const verifyRequest = {
2675
+ challengeId: challenge.challengeId,
2676
+ proof
2677
+ };
2678
+ const token = await this.verifyHistoryAuthChallenge(verifyRequest, options);
2679
+ assertHistoryTokenMatchesChallenge(token, challenge);
2680
+ return token;
2681
+ }
2299
2682
  async getHistory(request, options = {}) {
2300
2683
  const raw = await this.api.getHistory(
2301
2684
  {
2302
2685
  sender: request.sender,
2686
+ ...request.mode ? { mode: request.mode } : {},
2687
+ ...request.walletToken ? { walletToken: request.walletToken } : {},
2303
2688
  ...request.page !== void 0 ? { pageNumber: request.page } : {},
2304
2689
  ...request.pageSize !== void 0 ? { pageSize: request.pageSize } : {}
2305
2690
  },
@@ -2350,10 +2735,39 @@ var SwapClient = class {
2350
2735
  router: build.router,
2351
2736
  tx_type: reportContext?.txType ?? (build.isCrossChain ? "cross-chain" : "same-chain"),
2352
2737
  ...reportContext?.multiAddr ? { multi_addr: reportContext.multiAddr } : {},
2353
- ...reportContext?.swapId ?? result.orderId ? { swapId: reportContext?.swapId ?? result.orderId } : {}
2738
+ ...reportContext?.swapId ?? result.orderId ? { swapId: reportContext?.swapId ?? result.orderId } : {},
2739
+ ...request.confidentiality ? { confidentiality: request.confidentiality } : {}
2354
2740
  };
2355
2741
  }
2356
2742
  };
2743
+ function assertHistoryChallengeMatchesRequest(challenge, request) {
2744
+ const expectedMca = request.mcaAccountId?.trim();
2745
+ const principalMatches = expectedMca ? challenge.principalType === "mca" && challenge.mcaAccountId?.toLowerCase() === expectedMca.toLowerCase() : challenge.principalType === "wallet" && !challenge.mcaAccountId;
2746
+ const identityMatches = request.identityKey ? normalizeHistoryIdentity(challenge.chainFamily, challenge.identityKey) === normalizeHistoryIdentity(challenge.chainFamily, request.identityKey) : true;
2747
+ if (challenge.chainFamily !== request.chainFamily || challenge.chainId !== request.chainId || normalizeHistoryAddress(challenge.chainFamily, challenge.walletAddress) !== normalizeHistoryAddress(request.chainFamily, request.walletAddress) || !identityMatches || !principalMatches || !challenge.queryAddress) {
2748
+ throw new SwapSdkError(
2749
+ "INVALID_API_RESPONSE",
2750
+ "history",
2751
+ "Confidential history challenge does not match the requested wallet or MCA"
2752
+ );
2753
+ }
2754
+ }
2755
+ function assertHistoryTokenMatchesChallenge(token, challenge) {
2756
+ const principalMatches = token.principalType === challenge.principalType && (challenge.principalType === "mca" ? token.mcaAccountId?.toLowerCase() === challenge.mcaAccountId?.toLowerCase() : !token.mcaAccountId);
2757
+ if (!principalMatches || token.queryAddress !== challenge.queryAddress) {
2758
+ throw new SwapSdkError(
2759
+ "INVALID_API_RESPONSE",
2760
+ "history",
2761
+ "Confidential history authorization returned a different principal"
2762
+ );
2763
+ }
2764
+ }
2765
+ function normalizeHistoryAddress(chain, value) {
2766
+ return chain === "evm" || chain === "aptos" || chain === "sui" ? value.toLowerCase() : value;
2767
+ }
2768
+ function normalizeHistoryIdentity(chain, value) {
2769
+ return chain === "evm" || chain === "aptos" || chain === "sui" || chain === "btc" || chain === "zcash" ? value.toLowerCase().replace(/^0x/, "") : value;
2770
+ }
2357
2771
  function isMcaQuoteRequest(request) {
2358
2772
  if (!("flow" in request) || !("mcaAccountId" in request)) return false;
2359
2773
  const flow = Reflect.get(request, "flow");
@@ -2370,6 +2784,13 @@ function isMcaQuote(quote) {
2370
2784
  function readNonEmptyString(value) {
2371
2785
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
2372
2786
  }
2787
+ function cloneTokenList(tokens) {
2788
+ return tokens.map((token) => ({
2789
+ ...token,
2790
+ sources: [...token.sources],
2791
+ raw: { ...token.raw }
2792
+ }));
2793
+ }
2373
2794
  function delay(ms, signal) {
2374
2795
  return new Promise((resolve, reject) => {
2375
2796
  if (signal?.aborted) {
@@ -2400,48 +2821,6 @@ function delay(ms, signal) {
2400
2821
  });
2401
2822
  }
2402
2823
 
2403
- // src/mca/collateral.ts
2404
- function resolveMcaWithdrawPolicy(input) {
2405
- const collateral = parseDecimal(input.collateralBalance, "collateralBalance");
2406
- const available = parseDecimal(input.availableBalance, "availableBalance");
2407
- const amount = parseDecimal(input.amountIn, "amountIn");
2408
- const needDecrease = collateral.digits > 0n;
2409
- return {
2410
- needDecrease,
2411
- decreaseAmountBurrow: needDecrease ? input.collateralBalance.trim() : "0",
2412
- withdrawAll: input.isMax || available.digits > 0n && isAtLeastWithdrawAllThreshold(amount, available)
2413
- };
2414
- }
2415
- function isAtLeastWithdrawAllThreshold(amount, available) {
2416
- const [amountScaled, availableScaled] = alignScale(amount, available);
2417
- return amountScaled * 1000000n >= availableScaled * 999999n;
2418
- }
2419
- function alignScale(a, b) {
2420
- const scale = Math.max(a.scale, b.scale);
2421
- return [
2422
- a.digits * pow10(scale - a.scale),
2423
- b.digits * pow10(scale - b.scale)
2424
- ];
2425
- }
2426
- function parseDecimal(value, field) {
2427
- const trimmed = value.trim();
2428
- if (!/^(?:0|[1-9]\d*)(?:\.\d+)?$/.test(trimmed)) {
2429
- throw new SwapSdkError(
2430
- "INVALID_REQUEST",
2431
- "quote",
2432
- `${field} must be a non-negative decimal string`
2433
- );
2434
- }
2435
- const [integer = "0", fraction = ""] = trimmed.split(".");
2436
- return {
2437
- digits: BigInt(`${integer}${fraction}`),
2438
- scale: fraction.length
2439
- };
2440
- }
2441
- function pow10(exponent) {
2442
- return 10n ** BigInt(exponent);
2443
- }
2444
-
2445
- export { ApiClient, DEFAULT_MCA_SIGNER_PRIORITY, ExecutorRegistry, SwapClient, SwapSdkError, asSwapSdkError, assertBaseUnitAmount, buildMcaWithdrawRelayerRequest, buildNearMcaWithdrawTransactions, createExecutionId, extractMcaWithdrawBusiness, extractMcaWithdrawDepositAddress, extractMcaWithdrawSignerWallet, formatMcaWallet, formatUnits, fromApiChain, isSameMcaSignerIdentity, normalizeBuild, normalizeHistory, normalizeHistoryStatus, normalizeMcaQuote, normalizeOrderStatus, normalizeQuote, parseUnits, resolveMcaWithdrawPolicy, selectMcaSigner, serializeMcaQuoteRequest, serializeQuoteRequest, toApiAssetAddress, toApiChain };
2824
+ export { ApiClient, DEFAULT_MCA_SIGNER_PRIORITY, ExecutorRegistry, SwapClient, SwapSdkError, asSwapSdkError, assertBaseUnitAmount, buildMcaWithdrawRelayerRequest, buildNearMcaWithdrawTransactions, createExecutionId, extractMcaWithdrawBusiness, extractMcaWithdrawDepositAddress, extractMcaWithdrawSignerWallet, formatMcaWallet, formatUnits, fromApiChain, isSameMcaSignerIdentity, normalizeBuild, normalizeCrossChainToTokenList, normalizeFromTokenList, normalizeHistory, normalizeHistoryStatus, normalizeMcaQuote, normalizeOrderStatus, normalizeQuote, parseUnits, resolveMcaDecreaseCollateral, resolveMcaRequiredCollateralDecrease, resolveMcaWithdrawPolicy, selectMcaSigner, serializeMcaQuoteRequest, serializeQuoteRequest, toApiAssetAddress, toApiChain };
2446
2825
  //# sourceMappingURL=index.mjs.map
2447
2826
  //# sourceMappingURL=index.mjs.map