@rhea-finance/cross-chain-aggregation-dex 2.0.3 → 2.0.5

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.js CHANGED
@@ -97,14 +97,33 @@ var ApiClient = class {
97
97
  retryableOperation: true,
98
98
  query: {
99
99
  sender: params.sender,
100
+ mode: params.mode,
100
101
  pageNumber: params.pageNumber,
101
102
  pageSize: params.pageSize
102
- }
103
+ },
104
+ ...params.mode === "confidential" && params.walletToken ? { authenticationToken: params.walletToken } : {}
105
+ });
106
+ }
107
+ createHistoryAuthChallenge(body, options = {}) {
108
+ return this.request("/api/swap/history/auth/challenge", "history", {
109
+ ...options,
110
+ method: "POST",
111
+ body
112
+ });
113
+ }
114
+ verifyHistoryAuthChallenge(body, options = {}) {
115
+ return this.request("/api/swap/history/auth/verify", "history", {
116
+ ...options,
117
+ method: "POST",
118
+ body
103
119
  });
104
120
  }
105
121
  async request(path, stage, options) {
106
122
  const url = this.buildUrl(path, options.query);
107
- const headers = await this.buildHeaders(options.idempotencyKey);
123
+ const headers = await this.buildHeaders(
124
+ options.idempotencyKey,
125
+ options.authenticationToken
126
+ );
108
127
  const retry = this.retryConfig();
109
128
  let attempt = 1;
110
129
  for (; ; ) {
@@ -256,12 +275,13 @@ var ApiClient = class {
256
275
  const suffix = search.toString();
257
276
  return suffix ? `${this.baseUrl}${path}?${suffix}` : `${this.baseUrl}${path}`;
258
277
  }
259
- async buildHeaders(idempotencyKey) {
278
+ async buildHeaders(idempotencyKey, authenticationToken) {
260
279
  const configured = typeof this.config.headers === "function" ? await this.config.headers() : this.config.headers ?? {};
261
280
  const token = this.config.getAccessToken ? await this.config.getAccessToken() : this.config.apiKey;
262
281
  return {
263
282
  "Content-Type": "application/json",
264
283
  ...token ? { Authorization: `Bearer ${token}` } : {},
284
+ ...authenticationToken ? { Authentication: `Bearer ${authenticationToken}` } : {},
265
285
  ...idempotencyKey ? { "Idempotency-Key": idempotencyKey } : {},
266
286
  ...configured
267
287
  };
@@ -943,6 +963,7 @@ function serializeQuoteRequest(request) {
943
963
  amountIn: request.amountIn,
944
964
  slippage: request.slippageBps,
945
965
  quoteWaitingTimeMs: request.quoteWaitingTimeMs ?? DEFAULT_QUOTE_WAITING_TIME_MS,
966
+ ...request.confidentiality ? { confidentiality: request.confidentiality } : {},
946
967
  sender: request.sender.trim(),
947
968
  ...request.recipient?.trim() ? { recipient: request.recipient.trim() } : {}
948
969
  };
@@ -977,7 +998,7 @@ function normalizeQuote(request, raw, receivedAt = Date.now()) {
977
998
  estimatedOut: bestRoute.amountOut,
978
999
  minAmountOut: bestRoute.minAmountOut,
979
1000
  route: bestRoute,
980
- alternatives: raw.allQuotes.flatMap((route) => {
1001
+ alternatives: readQuoteAlternatives(raw.allQuotes).flatMap((route) => {
981
1002
  try {
982
1003
  const normalized = normalizeRoute(route, false);
983
1004
  return normalized ? [normalized] : [];
@@ -991,6 +1012,13 @@ function normalizeQuote(request, raw, receivedAt = Date.now()) {
991
1012
  raw
992
1013
  };
993
1014
  }
1015
+ function readQuoteAlternatives(value) {
1016
+ if (!Array.isArray(value)) return [];
1017
+ return value.filter(isRecord);
1018
+ }
1019
+ function isRecord(value) {
1020
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1021
+ }
994
1022
  function validateQuoteRequest(request) {
995
1023
  assertBaseUnitAmount(request.amountIn);
996
1024
  if (!Number.isInteger(request.slippageBps) || request.slippageBps < 0) {
@@ -1208,6 +1236,112 @@ function normalizeTimestamp(value) {
1208
1236
  return Number.isNaN(date.getTime()) ? void 0 : date.toISOString();
1209
1237
  }
1210
1238
 
1239
+ // src/mca/collateral.ts
1240
+ function resolveMcaWithdrawPolicy(input) {
1241
+ const decreaseCollateral = resolveMcaRequiredCollateralDecrease({
1242
+ amountBurrow: input.amountBurrow,
1243
+ suppliedBalance: input.suppliedBalance
1244
+ });
1245
+ const available = parseDecimal(input.availableBalance, "availableBalance");
1246
+ const amount = parseDecimal(input.amountIn, "amountIn");
1247
+ return {
1248
+ ...decreaseCollateral,
1249
+ withdrawAll: input.isMax || available.digits > 0n && isAtLeastWithdrawAllThreshold(amount, available)
1250
+ };
1251
+ }
1252
+ function resolveMcaRequiredCollateralDecrease(input) {
1253
+ const amount = parseBurrowDecimal(input.amountBurrow, "amountBurrow");
1254
+ const supplied = parseBurrowDecimal(
1255
+ input.suppliedBalance,
1256
+ "suppliedBalance"
1257
+ );
1258
+ const [amountScaled, suppliedScaled] = alignScale(amount, supplied);
1259
+ const decreaseScaled = amountScaled > suppliedScaled ? amountScaled - suppliedScaled : 0n;
1260
+ return resolveParsedMcaDecreaseCollateral({
1261
+ digits: decreaseScaled,
1262
+ scale: Math.max(amount.scale, supplied.scale)
1263
+ });
1264
+ }
1265
+ function resolveMcaDecreaseCollateral(decreaseAmountBurrow, field = "decreaseAmountBurrow") {
1266
+ const parsed = parseBurrowDecimal(decreaseAmountBurrow, field);
1267
+ return resolveParsedMcaDecreaseCollateral(parsed);
1268
+ }
1269
+ function resolveParsedMcaDecreaseCollateral(parsed) {
1270
+ const needDecrease = parsed.digits > 0n;
1271
+ return {
1272
+ needDecrease,
1273
+ decreaseAmountBurrow: needDecrease ? formatDecimal(parsed) : "0"
1274
+ };
1275
+ }
1276
+ function isAtLeastWithdrawAllThreshold(amount, available) {
1277
+ const [amountScaled, availableScaled] = alignScale(amount, available);
1278
+ return amountScaled * 1000000n >= availableScaled * 999999n;
1279
+ }
1280
+ function alignScale(a, b) {
1281
+ const scale = Math.max(a.scale, b.scale);
1282
+ return [
1283
+ a.digits * pow10(scale - a.scale),
1284
+ b.digits * pow10(scale - b.scale)
1285
+ ];
1286
+ }
1287
+ function parseDecimal(value, field) {
1288
+ const trimmed = value.trim();
1289
+ if (!/^(?:0|[1-9]\d*)(?:\.\d+)?$/.test(trimmed)) {
1290
+ throw new SwapSdkError(
1291
+ "INVALID_REQUEST",
1292
+ "quote",
1293
+ `${field} must be a non-negative decimal string`
1294
+ );
1295
+ }
1296
+ const [integer = "0", fraction = ""] = trimmed.split(".");
1297
+ return {
1298
+ digits: BigInt(`${integer}${fraction}`),
1299
+ scale: fraction.length
1300
+ };
1301
+ }
1302
+ function parseBurrowDecimal(value, field) {
1303
+ const trimmed = value.trim();
1304
+ const match = /^(?:([0-9]+)(?:\.([0-9]*))?|\.([0-9]+))(?:[eE]([+-]?[0-9]+))?$/.exec(
1305
+ trimmed
1306
+ );
1307
+ if (!match) {
1308
+ throw new SwapSdkError(
1309
+ "INVALID_REQUEST",
1310
+ "quote",
1311
+ `${field} must be a non-negative decimal string`
1312
+ );
1313
+ }
1314
+ const integer = match[1] ?? "0";
1315
+ const fraction = match[2] ?? match[3] ?? "";
1316
+ const exponent = Number(match[4] ?? "0");
1317
+ if (!Number.isSafeInteger(exponent) || Math.abs(exponent) > 1e5) {
1318
+ throw new SwapSdkError(
1319
+ "INVALID_REQUEST",
1320
+ "quote",
1321
+ `${field} exponent is out of range`
1322
+ );
1323
+ }
1324
+ let digits = BigInt(`${integer}${fraction}` || "0");
1325
+ let scale = fraction.length - exponent;
1326
+ if (scale < 0) {
1327
+ digits *= pow10(-scale);
1328
+ scale = 0;
1329
+ }
1330
+ return { digits, scale };
1331
+ }
1332
+ function formatDecimal(value) {
1333
+ if (value.digits === 0n) return "0";
1334
+ if (value.scale === 0) return value.digits.toString();
1335
+ const padded = value.digits.toString().padStart(value.scale + 1, "0");
1336
+ const splitAt = padded.length - value.scale;
1337
+ const integer = padded.slice(0, splitAt);
1338
+ const fraction = padded.slice(splitAt).replace(/0+$/, "");
1339
+ return fraction ? `${integer}.${fraction}` : integer;
1340
+ }
1341
+ function pow10(exponent) {
1342
+ return 10n ** BigInt(exponent);
1343
+ }
1344
+
1211
1345
  // src/mca/quote.ts
1212
1346
  function serializeMcaQuoteRequest(request, signer) {
1213
1347
  const mcaAccountId = request.mcaAccountId.trim();
@@ -1223,13 +1357,10 @@ function serializeMcaQuoteRequest(request, signer) {
1223
1357
  if (!identityKey) {
1224
1358
  throw invalidRequest("signer identityKey is required");
1225
1359
  }
1226
- if (request.flow === "withdraw" && !/^(?:0|[1-9]\d*)(?:\.\d+)?$/.test(
1227
- request.collateral.decreaseAmountBurrow.trim()
1228
- )) {
1229
- throw invalidRequest(
1230
- "collateral.decreaseAmountBurrow must be a non-negative decimal string"
1231
- );
1232
- }
1360
+ const decreaseCollateral = request.flow === "withdraw" ? resolveMcaDecreaseCollateral(
1361
+ request.collateral.decreaseAmountBurrow,
1362
+ "collateral.decreaseAmountBurrow"
1363
+ ) : void 0;
1233
1364
  const mca = {
1234
1365
  flow: request.flow,
1235
1366
  mcaAccountId,
@@ -1238,8 +1369,8 @@ function serializeMcaQuoteRequest(request, signer) {
1238
1369
  identityKey
1239
1370
  },
1240
1371
  ...request.flow === "deposit" ? { useAsCollateral: request.collateral.useAsCollateral } : {
1241
- needDecreaseCollateral: request.collateral.needDecrease,
1242
- decreaseCollateralAmountBurrow: request.collateral.decreaseAmountBurrow,
1372
+ needDecreaseCollateral: decreaseCollateral.needDecrease,
1373
+ decreaseCollateralAmountBurrow: decreaseCollateral.decreaseAmountBurrow,
1243
1374
  ...request.collateral.withdrawAll ? { withdrawAll: true } : {}
1244
1375
  },
1245
1376
  ...request.recipientMsgSignatures ? { recipientMsgSignatures: [...request.recipientMsgSignatures] } : {},
@@ -1894,7 +2025,8 @@ var McaSwapService = class {
1894
2025
  is_cross_chain: true,
1895
2026
  tx_type: "mca-withdraw-relayer",
1896
2027
  multi_addr: input.quote.mcaAccountId,
1897
- swapId: orderId
2028
+ swapId: orderId,
2029
+ ...request.confidentiality ? { confidentiality: request.confidentiality } : {}
1898
2030
  };
1899
2031
  this.relayerReports.set(executionId, reportRequest);
1900
2032
  const result = {
@@ -2291,10 +2423,30 @@ var SwapClient = class {
2291
2423
  getHistoryRaw(params, options = {}) {
2292
2424
  return this.api.getHistory(params, options);
2293
2425
  }
2426
+ createHistoryAuthChallenge(request, options = {}) {
2427
+ return this.api.createHistoryAuthChallenge(request, options);
2428
+ }
2429
+ verifyHistoryAuthChallenge(request, options = {}) {
2430
+ return this.api.verifyHistoryAuthChallenge(request, options);
2431
+ }
2432
+ async authorizeConfidentialHistory(request, signChallenge, options = {}) {
2433
+ const challenge = await this.createHistoryAuthChallenge(request, options);
2434
+ assertHistoryChallengeMatchesRequest(challenge, request);
2435
+ const proof = await signChallenge(challenge);
2436
+ const verifyRequest = {
2437
+ challengeId: challenge.challengeId,
2438
+ proof
2439
+ };
2440
+ const token = await this.verifyHistoryAuthChallenge(verifyRequest, options);
2441
+ assertHistoryTokenMatchesChallenge(token, challenge);
2442
+ return token;
2443
+ }
2294
2444
  async getHistory(request, options = {}) {
2295
2445
  const raw = await this.api.getHistory(
2296
2446
  {
2297
2447
  sender: request.sender,
2448
+ ...request.mode ? { mode: request.mode } : {},
2449
+ ...request.walletToken ? { walletToken: request.walletToken } : {},
2298
2450
  ...request.page !== void 0 ? { pageNumber: request.page } : {},
2299
2451
  ...request.pageSize !== void 0 ? { pageSize: request.pageSize } : {}
2300
2452
  },
@@ -2345,10 +2497,39 @@ var SwapClient = class {
2345
2497
  router: build.router,
2346
2498
  tx_type: reportContext?.txType ?? (build.isCrossChain ? "cross-chain" : "same-chain"),
2347
2499
  ...reportContext?.multiAddr ? { multi_addr: reportContext.multiAddr } : {},
2348
- ...reportContext?.swapId ?? result.orderId ? { swapId: reportContext?.swapId ?? result.orderId } : {}
2500
+ ...reportContext?.swapId ?? result.orderId ? { swapId: reportContext?.swapId ?? result.orderId } : {},
2501
+ ...request.confidentiality ? { confidentiality: request.confidentiality } : {}
2349
2502
  };
2350
2503
  }
2351
2504
  };
2505
+ function assertHistoryChallengeMatchesRequest(challenge, request) {
2506
+ const expectedMca = request.mcaAccountId?.trim();
2507
+ const principalMatches = expectedMca ? challenge.principalType === "mca" && challenge.mcaAccountId?.toLowerCase() === expectedMca.toLowerCase() : challenge.principalType === "wallet" && !challenge.mcaAccountId;
2508
+ const identityMatches = request.identityKey ? normalizeHistoryIdentity(challenge.chainFamily, challenge.identityKey) === normalizeHistoryIdentity(challenge.chainFamily, request.identityKey) : true;
2509
+ if (challenge.chainFamily !== request.chainFamily || challenge.chainId !== request.chainId || normalizeHistoryAddress(challenge.chainFamily, challenge.walletAddress) !== normalizeHistoryAddress(request.chainFamily, request.walletAddress) || !identityMatches || !principalMatches || !challenge.queryAddress) {
2510
+ throw new SwapSdkError(
2511
+ "INVALID_API_RESPONSE",
2512
+ "history",
2513
+ "Confidential history challenge does not match the requested wallet or MCA"
2514
+ );
2515
+ }
2516
+ }
2517
+ function assertHistoryTokenMatchesChallenge(token, challenge) {
2518
+ const principalMatches = token.principalType === challenge.principalType && (challenge.principalType === "mca" ? token.mcaAccountId?.toLowerCase() === challenge.mcaAccountId?.toLowerCase() : !token.mcaAccountId);
2519
+ if (!principalMatches || token.queryAddress !== challenge.queryAddress) {
2520
+ throw new SwapSdkError(
2521
+ "INVALID_API_RESPONSE",
2522
+ "history",
2523
+ "Confidential history authorization returned a different principal"
2524
+ );
2525
+ }
2526
+ }
2527
+ function normalizeHistoryAddress(chain, value) {
2528
+ return chain === "evm" || chain === "aptos" || chain === "sui" ? value.toLowerCase() : value;
2529
+ }
2530
+ function normalizeHistoryIdentity(chain, value) {
2531
+ return chain === "evm" || chain === "aptos" || chain === "sui" || chain === "btc" || chain === "zcash" ? value.toLowerCase().replace(/^0x/, "") : value;
2532
+ }
2352
2533
  function isMcaQuoteRequest(request) {
2353
2534
  if (!("flow" in request) || !("mcaAccountId" in request)) return false;
2354
2535
  const flow = Reflect.get(request, "flow");
@@ -2395,48 +2576,6 @@ function delay(ms, signal) {
2395
2576
  });
2396
2577
  }
2397
2578
 
2398
- // src/mca/collateral.ts
2399
- function resolveMcaWithdrawPolicy(input) {
2400
- const collateral = parseDecimal(input.collateralBalance, "collateralBalance");
2401
- const available = parseDecimal(input.availableBalance, "availableBalance");
2402
- const amount = parseDecimal(input.amountIn, "amountIn");
2403
- const needDecrease = collateral.digits > 0n;
2404
- return {
2405
- needDecrease,
2406
- decreaseAmountBurrow: needDecrease ? input.collateralBalance.trim() : "0",
2407
- withdrawAll: input.isMax || available.digits > 0n && isAtLeastWithdrawAllThreshold(amount, available)
2408
- };
2409
- }
2410
- function isAtLeastWithdrawAllThreshold(amount, available) {
2411
- const [amountScaled, availableScaled] = alignScale(amount, available);
2412
- return amountScaled * 1000000n >= availableScaled * 999999n;
2413
- }
2414
- function alignScale(a, b) {
2415
- const scale = Math.max(a.scale, b.scale);
2416
- return [
2417
- a.digits * pow10(scale - a.scale),
2418
- b.digits * pow10(scale - b.scale)
2419
- ];
2420
- }
2421
- function parseDecimal(value, field) {
2422
- const trimmed = value.trim();
2423
- if (!/^(?:0|[1-9]\d*)(?:\.\d+)?$/.test(trimmed)) {
2424
- throw new SwapSdkError(
2425
- "INVALID_REQUEST",
2426
- "quote",
2427
- `${field} must be a non-negative decimal string`
2428
- );
2429
- }
2430
- const [integer = "0", fraction = ""] = trimmed.split(".");
2431
- return {
2432
- digits: BigInt(`${integer}${fraction}`),
2433
- scale: fraction.length
2434
- };
2435
- }
2436
- function pow10(exponent) {
2437
- return 10n ** BigInt(exponent);
2438
- }
2439
-
2440
2579
  exports.ApiClient = ApiClient;
2441
2580
  exports.DEFAULT_MCA_SIGNER_PRIORITY = DEFAULT_MCA_SIGNER_PRIORITY;
2442
2581
  exports.ExecutorRegistry = ExecutorRegistry;
@@ -2461,6 +2600,8 @@ exports.normalizeMcaQuote = normalizeMcaQuote;
2461
2600
  exports.normalizeOrderStatus = normalizeOrderStatus;
2462
2601
  exports.normalizeQuote = normalizeQuote;
2463
2602
  exports.parseUnits = parseUnits;
2603
+ exports.resolveMcaDecreaseCollateral = resolveMcaDecreaseCollateral;
2604
+ exports.resolveMcaRequiredCollateralDecrease = resolveMcaRequiredCollateralDecrease;
2464
2605
  exports.resolveMcaWithdrawPolicy = resolveMcaWithdrawPolicy;
2465
2606
  exports.selectMcaSigner = selectMcaSigner;
2466
2607
  exports.serializeMcaQuoteRequest = serializeMcaQuoteRequest;