@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.
- package/README.md +207 -77
- package/dist/executors/aptos.d.mts +1 -1
- package/dist/executors/aptos.d.ts +1 -1
- package/dist/executors/aptos.js.map +1 -1
- package/dist/executors/aptos.mjs.map +1 -1
- package/dist/executors/bitcoin.d.mts +1 -1
- package/dist/executors/bitcoin.d.ts +1 -1
- package/dist/executors/bitcoin.js.map +1 -1
- package/dist/executors/bitcoin.mjs.map +1 -1
- package/dist/executors/evm.d.mts +1 -1
- package/dist/executors/evm.d.ts +1 -1
- package/dist/executors/evm.js.map +1 -1
- package/dist/executors/evm.mjs.map +1 -1
- package/dist/executors/near.d.mts +1 -1
- package/dist/executors/near.d.ts +1 -1
- package/dist/executors/near.js.map +1 -1
- package/dist/executors/near.mjs.map +1 -1
- package/dist/executors/solana.d.mts +1 -1
- package/dist/executors/solana.d.ts +1 -1
- package/dist/executors/solana.js.map +1 -1
- package/dist/executors/solana.mjs.map +1 -1
- package/dist/executors/sui.d.mts +1 -1
- package/dist/executors/sui.d.ts +1 -1
- package/dist/executors/sui.js.map +1 -1
- package/dist/executors/sui.mjs.map +1 -1
- package/dist/executors/tron.d.mts +1 -1
- package/dist/executors/tron.d.ts +1 -1
- package/dist/executors/tron.js.map +1 -1
- package/dist/executors/tron.mjs.map +1 -1
- package/dist/executors/zcash.d.mts +1 -1
- package/dist/executors/zcash.d.ts +1 -1
- package/dist/executors/zcash.js.map +1 -1
- package/dist/executors/zcash.mjs.map +1 -1
- package/dist/index.d.mts +82 -6
- package/dist/index.d.ts +82 -6
- package/dist/index.js +454 -71
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +451 -72
- package/dist/index.mjs.map +1 -1
- package/dist/{shared-D0_DbMT2.d.mts → shared-COkGiqaz.d.mts} +84 -2
- package/dist/{shared-D0_DbMT2.d.ts → shared-COkGiqaz.d.ts} +84 -2
- 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(
|
|
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 =
|
|
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
|
-
|
|
1232
|
-
request.collateral.decreaseAmountBurrow
|
|
1233
|
-
|
|
1234
|
-
|
|
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:
|
|
1247
|
-
decreaseCollateralAmountBurrow:
|
|
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 (
|
|
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 (
|
|
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
|
|
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 =
|
|
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:
|
|
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 =
|
|
1878
|
-
const 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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|