lampamazaza-new-internal-utils 0.24.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/_virtual/rolldown_runtime.cjs +43 -0
- package/dist/_virtual/rolldown_runtime.js +18 -0
- package/dist/config.cjs +82 -0
- package/dist/config.d.cts +42 -0
- package/dist/config.d.ts +42 -0
- package/dist/config.js +72 -0
- package/dist/errors/assert.cjs +11 -0
- package/dist/errors/assert.d.cts +11 -0
- package/dist/errors/assert.d.ts +11 -0
- package/dist/errors/assert.js +11 -0
- package/dist/errors/base.cjs +34 -0
- package/dist/errors/base.d.cts +21 -0
- package/dist/errors/base.d.ts +21 -0
- package/dist/errors/base.js +33 -0
- package/dist/errors/index.cjs +23 -0
- package/dist/errors/index.d.cts +11 -0
- package/dist/errors/index.d.ts +11 -0
- package/dist/errors/index.js +18 -0
- package/dist/errors/request.cjs +48 -0
- package/dist/errors/request.d.cts +61 -0
- package/dist/errors/request.d.ts +61 -0
- package/dist/errors/request.js +46 -0
- package/dist/errors/utils/isNetworkError.cjs +23 -0
- package/dist/errors/utils/isNetworkError.js +22 -0
- package/dist/errors/utils/toError.cjs +8 -0
- package/dist/errors/utils/toError.d.cts +4 -0
- package/dist/errors/utils/toError.d.ts +4 -0
- package/dist/errors/utils/toError.js +7 -0
- package/dist/index.cjs +125 -0
- package/dist/index.d.cts +30 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +30 -0
- package/dist/logger.d.cts +11 -0
- package/dist/logger.d.ts +11 -0
- package/dist/nearClient.cjs +18 -0
- package/dist/nearClient.d.cts +8 -0
- package/dist/nearClient.d.ts +8 -0
- package/dist/nearClient.js +18 -0
- package/dist/poaBridge/constants/blockchains.cjs +57 -0
- package/dist/poaBridge/constants/blockchains.d.cts +86 -0
- package/dist/poaBridge/constants/blockchains.d.ts +86 -0
- package/dist/poaBridge/constants/blockchains.js +54 -0
- package/dist/poaBridge/errors/withdrawal.cjs +52 -0
- package/dist/poaBridge/errors/withdrawal.d.cts +34 -0
- package/dist/poaBridge/errors/withdrawal.d.ts +34 -0
- package/dist/poaBridge/errors/withdrawal.js +50 -0
- package/dist/poaBridge/getPendingDeposits.cjs +9 -0
- package/dist/poaBridge/getPendingDeposits.d.cts +12 -0
- package/dist/poaBridge/getPendingDeposits.d.ts +13 -0
- package/dist/poaBridge/getPendingDeposits.js +9 -0
- package/dist/poaBridge/index.cjs +23 -0
- package/dist/poaBridge/index.d.cts +11 -0
- package/dist/poaBridge/index.d.ts +11 -0
- package/dist/poaBridge/index.js +18 -0
- package/dist/poaBridge/poaBridgeHttpClient/apis.cjs +38 -0
- package/dist/poaBridge/poaBridgeHttpClient/apis.d.cts +12 -0
- package/dist/poaBridge/poaBridgeHttpClient/apis.d.ts +12 -0
- package/dist/poaBridge/poaBridgeHttpClient/apis.js +32 -0
- package/dist/poaBridge/poaBridgeHttpClient/index.cjs +21 -0
- package/dist/poaBridge/poaBridgeHttpClient/index.d.cts +9 -0
- package/dist/poaBridge/poaBridgeHttpClient/index.d.ts +9 -0
- package/dist/poaBridge/poaBridgeHttpClient/index.js +16 -0
- package/dist/poaBridge/poaBridgeHttpClient/runtime.cjs +49 -0
- package/dist/poaBridge/poaBridgeHttpClient/runtime.js +47 -0
- package/dist/poaBridge/poaBridgeHttpClient/types.d.cts +161 -0
- package/dist/poaBridge/poaBridgeHttpClient/types.d.ts +161 -0
- package/dist/poaBridge/waitForWithdrawalCompletion.cjs +57 -0
- package/dist/poaBridge/waitForWithdrawalCompletion.d.cts +31 -0
- package/dist/poaBridge/waitForWithdrawalCompletion.d.ts +31 -0
- package/dist/poaBridge/waitForWithdrawalCompletion.js +56 -0
- package/dist/services/blockchainBalanceService.cjs +40 -0
- package/dist/services/blockchainBalanceService.d.cts +21 -0
- package/dist/services/blockchainBalanceService.d.ts +21 -0
- package/dist/services/blockchainBalanceService.js +37 -0
- package/dist/solverRelay/errors/intentSettlement.cjs +20 -0
- package/dist/solverRelay/errors/intentSettlement.d.cts +13 -0
- package/dist/solverRelay/errors/intentSettlement.d.ts +13 -0
- package/dist/solverRelay/errors/intentSettlement.js +20 -0
- package/dist/solverRelay/errors/quote.cjs +18 -0
- package/dist/solverRelay/errors/quote.d.cts +21 -0
- package/dist/solverRelay/errors/quote.d.ts +22 -0
- package/dist/solverRelay/errors/quote.js +18 -0
- package/dist/solverRelay/getQuote.cjs +49 -0
- package/dist/solverRelay/getQuote.d.cts +14 -0
- package/dist/solverRelay/getQuote.d.ts +14 -0
- package/dist/solverRelay/getQuote.js +49 -0
- package/dist/solverRelay/getStatus.cjs +26 -0
- package/dist/solverRelay/getStatus.d.cts +17 -0
- package/dist/solverRelay/getStatus.d.ts +18 -0
- package/dist/solverRelay/getStatus.js +26 -0
- package/dist/solverRelay/index.cjs +27 -0
- package/dist/solverRelay/index.d.cts +16 -0
- package/dist/solverRelay/index.d.ts +16 -0
- package/dist/solverRelay/index.js +22 -0
- package/dist/solverRelay/publishIntent.cjs +20 -0
- package/dist/solverRelay/publishIntent.d.cts +15 -0
- package/dist/solverRelay/publishIntent.d.ts +16 -0
- package/dist/solverRelay/publishIntent.js +20 -0
- package/dist/solverRelay/publishIntents.cjs +43 -0
- package/dist/solverRelay/publishIntents.d.cts +10 -0
- package/dist/solverRelay/publishIntents.d.ts +11 -0
- package/dist/solverRelay/publishIntents.js +42 -0
- package/dist/solverRelay/solverRelayHttpClient/apis.cjs +21 -0
- package/dist/solverRelay/solverRelayHttpClient/apis.d.cts +9 -0
- package/dist/solverRelay/solverRelayHttpClient/apis.d.ts +9 -0
- package/dist/solverRelay/solverRelayHttpClient/apis.js +18 -0
- package/dist/solverRelay/solverRelayHttpClient/index.cjs +18 -0
- package/dist/solverRelay/solverRelayHttpClient/index.d.cts +9 -0
- package/dist/solverRelay/solverRelayHttpClient/index.d.ts +9 -0
- package/dist/solverRelay/solverRelayHttpClient/index.js +13 -0
- package/dist/solverRelay/solverRelayHttpClient/runtime.cjs +60 -0
- package/dist/solverRelay/solverRelayHttpClient/runtime.js +58 -0
- package/dist/solverRelay/solverRelayHttpClient/types.d.cts +109 -0
- package/dist/solverRelay/solverRelayHttpClient/types.d.ts +109 -0
- package/dist/solverRelay/utils/parseFailedPublishError.cjs +40 -0
- package/dist/solverRelay/utils/parseFailedPublishError.d.cts +25 -0
- package/dist/solverRelay/utils/parseFailedPublishError.d.ts +26 -0
- package/dist/solverRelay/utils/parseFailedPublishError.js +39 -0
- package/dist/solverRelay/utils/quoteWithLog.cjs +21 -0
- package/dist/solverRelay/utils/quoteWithLog.d.cts +12 -0
- package/dist/solverRelay/utils/quoteWithLog.d.ts +14 -0
- package/dist/solverRelay/utils/quoteWithLog.js +21 -0
- package/dist/solverRelay/waitForIntentSettlement.cjs +52 -0
- package/dist/solverRelay/waitForIntentSettlement.d.cts +30 -0
- package/dist/solverRelay/waitForIntentSettlement.d.ts +30 -0
- package/dist/solverRelay/waitForIntentSettlement.js +52 -0
- package/dist/types/authHandle.cjs +22 -0
- package/dist/types/authHandle.d.cts +25 -0
- package/dist/types/authHandle.d.ts +25 -0
- package/dist/types/authHandle.js +16 -0
- package/dist/types/base.d.cts +45 -0
- package/dist/types/base.d.ts +45 -0
- package/dist/types/intentsUserId.d.cts +10 -0
- package/dist/types/intentsUserId.d.ts +10 -0
- package/dist/types/walletMessage.cjs +11 -0
- package/dist/types/walletMessage.d.cts +106 -0
- package/dist/types/walletMessage.d.ts +106 -0
- package/dist/types/walletMessage.js +5 -0
- package/dist/utils/abortSignal.cjs +19 -0
- package/dist/utils/abortSignal.js +18 -0
- package/dist/utils/appFee.cjs +20 -0
- package/dist/utils/appFee.d.cts +9 -0
- package/dist/utils/appFee.d.ts +9 -0
- package/dist/utils/appFee.js +15 -0
- package/dist/utils/assert.cjs +9 -0
- package/dist/utils/assert.d.cts +7 -0
- package/dist/utils/assert.d.ts +7 -0
- package/dist/utils/assert.js +9 -0
- package/dist/utils/authIdentity.cjs +56 -0
- package/dist/utils/authIdentity.d.cts +34 -0
- package/dist/utils/authIdentity.d.ts +34 -0
- package/dist/utils/authIdentity.js +50 -0
- package/dist/utils/failover.cjs +22 -0
- package/dist/utils/failover.d.cts +16 -0
- package/dist/utils/failover.d.ts +16 -0
- package/dist/utils/failover.js +20 -0
- package/dist/utils/handleRPCResponse.cjs +30 -0
- package/dist/utils/handleRPCResponse.js +28 -0
- package/dist/utils/index.cjs +55 -0
- package/dist/utils/index.d.cts +13 -0
- package/dist/utils/index.d.ts +13 -0
- package/dist/utils/index.js +50 -0
- package/dist/utils/messageFactory.cjs +137 -0
- package/dist/utils/messageFactory.d.cts +70 -0
- package/dist/utils/messageFactory.d.ts +70 -0
- package/dist/utils/messageFactory.js +132 -0
- package/dist/utils/multiPayload/webauthn.cjs +27 -0
- package/dist/utils/multiPayload/webauthn.js +26 -0
- package/dist/utils/near.cjs +58 -0
- package/dist/utils/near.d.cts +35 -0
- package/dist/utils/near.d.ts +35 -0
- package/dist/utils/near.js +53 -0
- package/dist/utils/poll.cjs +87 -0
- package/dist/utils/poll.d.cts +54 -0
- package/dist/utils/poll.d.ts +54 -0
- package/dist/utils/poll.js +85 -0
- package/dist/utils/prepareBroadcastRequest.cjs +98 -0
- package/dist/utils/prepareBroadcastRequest.d.cts +16 -0
- package/dist/utils/prepareBroadcastRequest.d.ts +16 -0
- package/dist/utils/prepareBroadcastRequest.js +90 -0
- package/dist/utils/promise/withTimeout.cjs +34 -0
- package/dist/utils/promise/withTimeout.d.cts +16 -0
- package/dist/utils/promise/withTimeout.d.ts +16 -0
- package/dist/utils/promise/withTimeout.js +34 -0
- package/dist/utils/request.cjs +100 -0
- package/dist/utils/request.d.cts +27 -0
- package/dist/utils/request.d.ts +27 -0
- package/dist/utils/request.js +99 -0
- package/dist/utils/requestShouldRetry.cjs +20 -0
- package/dist/utils/requestShouldRetry.js +20 -0
- package/dist/utils/retry.cjs +66 -0
- package/dist/utils/retry.d.cts +56 -0
- package/dist/utils/retry.d.ts +56 -0
- package/dist/utils/retry.js +64 -0
- package/dist/utils/serialize.cjs +82 -0
- package/dist/utils/serialize.d.cts +17 -0
- package/dist/utils/serialize.d.ts +17 -0
- package/dist/utils/serialize.js +81 -0
- package/dist/utils/stellarAddressToBytes.cjs +295 -0
- package/dist/utils/stellarAddressToBytes.js +294 -0
- package/dist/utils/token.cjs +8 -0
- package/dist/utils/token.js +7 -0
- package/dist/utils/tokenUtils.cjs +263 -0
- package/dist/utils/tokenUtils.d.cts +88 -0
- package/dist/utils/tokenUtils.d.ts +88 -0
- package/dist/utils/tokenUtils.js +238 -0
- package/dist/utils/tronAddressToHex.cjs +18 -0
- package/dist/utils/tronAddressToHex.js +17 -0
- package/dist/utils/uint8Array.cjs +15 -0
- package/dist/utils/uint8Array.d.cts +4 -0
- package/dist/utils/uint8Array.d.ts +4 -0
- package/dist/utils/uint8Array.js +14 -0
- package/dist/utils/webAuthn.cjs +91 -0
- package/dist/utils/webAuthn.js +89 -0
- package/package.json +56 -0
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
const require_assert = require('./assert.cjs');
|
|
2
|
+
const require_near = require('./near.cjs');
|
|
3
|
+
const require_token = require('./token.cjs');
|
|
4
|
+
|
|
5
|
+
//#region src/utils/tokenUtils.ts
|
|
6
|
+
function computeTotalBalance(token, balances) {
|
|
7
|
+
if (Array.isArray(token)) {
|
|
8
|
+
const uniqueTokens = new Set(token);
|
|
9
|
+
let total = 0n;
|
|
10
|
+
for (const tokenId of uniqueTokens) {
|
|
11
|
+
const balance = balances[tokenId];
|
|
12
|
+
if (balance == null) return;
|
|
13
|
+
total += balance;
|
|
14
|
+
}
|
|
15
|
+
return total;
|
|
16
|
+
}
|
|
17
|
+
if (require_token.isBaseToken(token)) return balances[token.defuseAssetId];
|
|
18
|
+
return computeTotalBalance(token.groupedTokens.map((t) => t.defuseAssetId), balances);
|
|
19
|
+
}
|
|
20
|
+
var DuplicateTokenError = class extends Error {
|
|
21
|
+
constructor(tokenId, decimals1, decimals2) {
|
|
22
|
+
super(`Duplicate token ${tokenId} found with different decimals: ${decimals1} and ${decimals2}`);
|
|
23
|
+
this.name = "DuplicateTokenError";
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
function adjustDecimals(amount, fromDecimals, toDecimals) {
|
|
27
|
+
if (fromDecimals === toDecimals) return amount;
|
|
28
|
+
if (fromDecimals > toDecimals) return amount / BigInt(10 ** (fromDecimals - toDecimals));
|
|
29
|
+
return amount * BigInt(10 ** (toDecimals - fromDecimals));
|
|
30
|
+
}
|
|
31
|
+
function deduplicateTokens(tokens) {
|
|
32
|
+
const tokenMap = /* @__PURE__ */ new Map();
|
|
33
|
+
for (const token of tokens) {
|
|
34
|
+
const existing = tokenMap.get(token.defuseAssetId);
|
|
35
|
+
if (existing) {
|
|
36
|
+
if (existing.decimals !== token.decimals) throw new DuplicateTokenError(token.defuseAssetId, existing.decimals, token.decimals);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
tokenMap.set(token.defuseAssetId, token);
|
|
40
|
+
}
|
|
41
|
+
return Array.from(tokenMap.values());
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* @param token - The token or array of tokens to compute the balance for.
|
|
45
|
+
* @param balances - The mapping of token balances.
|
|
46
|
+
* @param config - Configuration options.
|
|
47
|
+
* @param config.strict - Ensures all tokens have a balance if `true`, otherwise returns `undefined`.
|
|
48
|
+
*/
|
|
49
|
+
function computeTotalBalanceDifferentDecimals(token, balances, config = { strict: true }) {
|
|
50
|
+
if (!Array.isArray(token) && require_token.isBaseToken(token)) token = [token];
|
|
51
|
+
const uniqueTokens = deduplicateTokens(Array.isArray(token) ? token : token.groupedTokens);
|
|
52
|
+
if (uniqueTokens.length === 0) return {
|
|
53
|
+
amount: 0n,
|
|
54
|
+
decimals: 0
|
|
55
|
+
};
|
|
56
|
+
const maxDecimals = Math.max(...uniqueTokens.map((t) => t.decimals));
|
|
57
|
+
let total = null;
|
|
58
|
+
for (const t of uniqueTokens) {
|
|
59
|
+
const balance = balances[t.defuseAssetId];
|
|
60
|
+
if (balance == null) {
|
|
61
|
+
if (config.strict) return;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
total ??= 0n;
|
|
65
|
+
total += adjustDecimals(balance, t.decimals, maxDecimals);
|
|
66
|
+
}
|
|
67
|
+
if (total == null) return;
|
|
68
|
+
return {
|
|
69
|
+
amount: total,
|
|
70
|
+
decimals: maxDecimals
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function computeTotalDeltaDifferentDecimals(tokens, tokenDeltas) {
|
|
74
|
+
const mapping = {};
|
|
75
|
+
for (const [token, amount] of tokenDeltas) {
|
|
76
|
+
mapping[token] ??= 0n;
|
|
77
|
+
mapping[token] += amount;
|
|
78
|
+
}
|
|
79
|
+
return computeTotalBalanceDifferentDecimals(tokens, mapping, { strict: false }) ?? {
|
|
80
|
+
amount: 0n,
|
|
81
|
+
decimals: 0
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Convert a unified token to a base token, by getting the first token in the group.
|
|
86
|
+
* It should be used when you need to get *ANY* single token from a unified token.
|
|
87
|
+
*/
|
|
88
|
+
function getAnyBaseTokenInfo(token) {
|
|
89
|
+
const t = getUnderlyingBaseTokenInfos(token)[0];
|
|
90
|
+
require_assert.assert(t != null, "Token is undefined");
|
|
91
|
+
return t;
|
|
92
|
+
}
|
|
93
|
+
function getUnderlyingBaseTokenInfos(token) {
|
|
94
|
+
let tokens;
|
|
95
|
+
if (Array.isArray(token)) tokens = token;
|
|
96
|
+
else tokens = require_token.isBaseToken(token) ? [token] : token.groupedTokens;
|
|
97
|
+
return deduplicateTokens(tokens);
|
|
98
|
+
}
|
|
99
|
+
function getDerivedToken(tokenIn, chainName) {
|
|
100
|
+
if (require_token.isBaseToken(tokenIn)) return chainName === tokenIn.chainName ? tokenIn : null;
|
|
101
|
+
if (chainName != null) {
|
|
102
|
+
const tokenOut = tokenIn.groupedTokens.find((token) => token.chainName === chainName);
|
|
103
|
+
if (tokenOut != null) return tokenOut;
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
function getTokenMaxDecimals(token) {
|
|
108
|
+
const tokens = getUnderlyingBaseTokenInfos(token);
|
|
109
|
+
return Math.max(...tokens.map((t) => t.decimals));
|
|
110
|
+
}
|
|
111
|
+
function compareAmounts(value1, value2) {
|
|
112
|
+
const maxDecimals = Math.max(value1.decimals, value2.decimals);
|
|
113
|
+
const normalizedAmount1 = adjustDecimals(value1.amount, value1.decimals, maxDecimals);
|
|
114
|
+
const normalizedAmount2 = adjustDecimals(value2.amount, value2.decimals, maxDecimals);
|
|
115
|
+
if (normalizedAmount1 < normalizedAmount2) return -1;
|
|
116
|
+
if (normalizedAmount1 > normalizedAmount2) return 1;
|
|
117
|
+
return 0;
|
|
118
|
+
}
|
|
119
|
+
function minAmounts(value1, value2) {
|
|
120
|
+
return compareAmounts(value1, value2) <= 0 ? value1 : value2;
|
|
121
|
+
}
|
|
122
|
+
function addAmounts(...values) {
|
|
123
|
+
const maxDecimals = Math.max(...values.map((v) => v.decimals));
|
|
124
|
+
let sum = 0n;
|
|
125
|
+
for (const v of values) sum += adjustDecimals(v.amount, v.decimals, maxDecimals);
|
|
126
|
+
return {
|
|
127
|
+
amount: sum,
|
|
128
|
+
decimals: maxDecimals
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function subtractAmounts(value1, token2) {
|
|
132
|
+
return addAmounts(value1, {
|
|
133
|
+
amount: -token2.amount,
|
|
134
|
+
decimals: token2.decimals
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
function adjustDecimalsTokenValue(value, toDecimals) {
|
|
138
|
+
return {
|
|
139
|
+
amount: adjustDecimals(value.amount, value.decimals, toDecimals),
|
|
140
|
+
decimals: toDecimals
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function truncateTokenValue(value, decimals) {
|
|
144
|
+
return adjustDecimalsTokenValue(adjustDecimalsTokenValue(value, decimals), value.decimals);
|
|
145
|
+
}
|
|
146
|
+
function negateTokenValue(value) {
|
|
147
|
+
return {
|
|
148
|
+
amount: -value.amount,
|
|
149
|
+
decimals: value.decimals
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* 1 bip = 0.0001% = 0.000001
|
|
154
|
+
* 3000 bips = 0.3% = 0.003
|
|
155
|
+
* 1000000 bips = 100% = 1
|
|
156
|
+
*/
|
|
157
|
+
const BASIS_POINTS_DENOMINATOR = 1000000n;
|
|
158
|
+
/**
|
|
159
|
+
* Calculates net amount by deducting fee from gross amount.
|
|
160
|
+
* @example
|
|
161
|
+
* // If gross amount is 100000n with 0.3% fee, net amount is 99700n
|
|
162
|
+
* netDownAmount(100000n, 3000) == 99700n
|
|
163
|
+
*/
|
|
164
|
+
function netDownAmount(amount, feeBip) {
|
|
165
|
+
if (feeBip < 0 || feeBip > Number(BASIS_POINTS_DENOMINATOR)) throw new Error(`Invalid feeBip value. It must be between 0 and ${BASIS_POINTS_DENOMINATOR}.`);
|
|
166
|
+
if (amount < 0n) throw new Error("Amount must be non-negative.");
|
|
167
|
+
if (amount === 0n || feeBip === 0) return amount;
|
|
168
|
+
return amount - (amount * BigInt(feeBip) + (BASIS_POINTS_DENOMINATOR - 1n)) / BASIS_POINTS_DENOMINATOR;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Calculates gross amount needed to achieve desired net amount after fee.
|
|
172
|
+
* @example
|
|
173
|
+
* // To receive net 100000n after 0.3% fee, gross amount needed is 100300n
|
|
174
|
+
* grossUpAmount(100000n, 3000) == 100300n
|
|
175
|
+
*/
|
|
176
|
+
function grossUpAmount(amount, feeBip) {
|
|
177
|
+
if (feeBip < 0 || feeBip > Number(BASIS_POINTS_DENOMINATOR)) throw new Error(`Invalid feeBip value. It must be between 0 and ${BASIS_POINTS_DENOMINATOR}.`);
|
|
178
|
+
if (amount < 0n) throw new Error("Amount must be non-negative.");
|
|
179
|
+
if (amount === 0n || feeBip === 0) return amount;
|
|
180
|
+
const feeMultiplier = BASIS_POINTS_DENOMINATOR - BigInt(feeBip);
|
|
181
|
+
return (amount * BASIS_POINTS_DENOMINATOR + (feeMultiplier - 1n)) / feeMultiplier;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Slippage can affect only positive numbers, because positive delta mean
|
|
185
|
+
* that much will receive, and user can receive a bit less than that
|
|
186
|
+
* depending on market conditions.
|
|
187
|
+
*/
|
|
188
|
+
function accountSlippageExactIn(delta, slippageBasisPoints) {
|
|
189
|
+
return delta.map(([token, amount]) => {
|
|
190
|
+
if (amount > 0n) return [token, netDownAmount(amount, slippageBasisPoints)];
|
|
191
|
+
return [token, amount];
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
function filterOutPoaBridgeTokens(token) {
|
|
195
|
+
if (require_token.isBaseToken(token)) return token.bridge === "poa" ? [token] : [];
|
|
196
|
+
return token.groupedTokens.filter((t) => t.bridge === "poa");
|
|
197
|
+
}
|
|
198
|
+
function getTokenAccountIds(tokens) {
|
|
199
|
+
return tokens.map((t) => getTokenAccountId(t.defuseAssetId));
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Converts Defuse asset ID to token contract ID.
|
|
203
|
+
* nep141:wrap.near → wrap.near
|
|
204
|
+
* nep245:v2_1.omni.hot.tg:56_11111111111111111111 → v2_1.omni.hot.tg
|
|
205
|
+
*/
|
|
206
|
+
function getTokenAccountId(assetId) {
|
|
207
|
+
const { contractId } = parseDefuseAssetId(assetId);
|
|
208
|
+
return contractId;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Parses Defuse asset ID into its components based on the token standard.
|
|
212
|
+
* nep141:wrap.near → { standard: nep141, contractId: wrap.near }
|
|
213
|
+
* nep245:v2_1.omni.hot.tg:56_11111111111111111111 -> { standard: nep245, contractId: v2_1.omni.hot.tg, tokenId: 56_11111111111111111111 }
|
|
214
|
+
*/
|
|
215
|
+
function parseDefuseAssetId(assetId) {
|
|
216
|
+
const [tokenStandard, tokenContractId, multiTokenId] = assetId.split(":");
|
|
217
|
+
require_assert.assert(tokenContractId != null && require_near.validateNearAddress(tokenContractId), "Incorrect format of assetId");
|
|
218
|
+
switch (tokenStandard) {
|
|
219
|
+
case "nep141": return {
|
|
220
|
+
standard: "nep141",
|
|
221
|
+
contractId: tokenContractId
|
|
222
|
+
};
|
|
223
|
+
case "nep245":
|
|
224
|
+
require_assert.assert(multiTokenId != null, "Incorrect NEP-245 token format");
|
|
225
|
+
return {
|
|
226
|
+
standard: "nep245",
|
|
227
|
+
contractId: tokenContractId,
|
|
228
|
+
tokenId: multiTokenId
|
|
229
|
+
};
|
|
230
|
+
default: require_assert.assert(false, `Unsupported token standard: ${tokenStandard}`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
function tokenAccountIdToDefuseAssetId(address) {
|
|
234
|
+
return `nep141:${address}`;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
//#endregion
|
|
238
|
+
exports.BASIS_POINTS_DENOMINATOR = BASIS_POINTS_DENOMINATOR;
|
|
239
|
+
exports.DuplicateTokenError = DuplicateTokenError;
|
|
240
|
+
exports.accountSlippageExactIn = accountSlippageExactIn;
|
|
241
|
+
exports.addAmounts = addAmounts;
|
|
242
|
+
exports.adjustDecimals = adjustDecimals;
|
|
243
|
+
exports.adjustDecimalsTokenValue = adjustDecimalsTokenValue;
|
|
244
|
+
exports.compareAmounts = compareAmounts;
|
|
245
|
+
exports.computeTotalBalance = computeTotalBalance;
|
|
246
|
+
exports.computeTotalBalanceDifferentDecimals = computeTotalBalanceDifferentDecimals;
|
|
247
|
+
exports.computeTotalDeltaDifferentDecimals = computeTotalDeltaDifferentDecimals;
|
|
248
|
+
exports.deduplicateTokens = deduplicateTokens;
|
|
249
|
+
exports.filterOutPoaBridgeTokens = filterOutPoaBridgeTokens;
|
|
250
|
+
exports.getAnyBaseTokenInfo = getAnyBaseTokenInfo;
|
|
251
|
+
exports.getDerivedToken = getDerivedToken;
|
|
252
|
+
exports.getTokenAccountId = getTokenAccountId;
|
|
253
|
+
exports.getTokenAccountIds = getTokenAccountIds;
|
|
254
|
+
exports.getTokenMaxDecimals = getTokenMaxDecimals;
|
|
255
|
+
exports.getUnderlyingBaseTokenInfos = getUnderlyingBaseTokenInfos;
|
|
256
|
+
exports.grossUpAmount = grossUpAmount;
|
|
257
|
+
exports.minAmounts = minAmounts;
|
|
258
|
+
exports.negateTokenValue = negateTokenValue;
|
|
259
|
+
exports.netDownAmount = netDownAmount;
|
|
260
|
+
exports.parseDefuseAssetId = parseDefuseAssetId;
|
|
261
|
+
exports.subtractAmounts = subtractAmounts;
|
|
262
|
+
exports.tokenAccountIdToDefuseAssetId = tokenAccountIdToDefuseAssetId;
|
|
263
|
+
exports.truncateTokenValue = truncateTokenValue;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { BaseTokenInfo, TokenValue, UnifiedTokenInfo } from "../types/base.cjs";
|
|
2
|
+
import { AssertErrorType } from "./assert.cjs";
|
|
3
|
+
|
|
4
|
+
//#region src/utils/tokenUtils.d.ts
|
|
5
|
+
type BalanceMapping = Record<string, bigint>;
|
|
6
|
+
declare function computeTotalBalance(token: BaseTokenInfo["defuseAssetId"][] | BaseTokenInfo | UnifiedTokenInfo, balances: BalanceMapping): bigint | undefined;
|
|
7
|
+
declare class DuplicateTokenError extends Error {
|
|
8
|
+
constructor(tokenId: string, decimals1: number, decimals2: number);
|
|
9
|
+
}
|
|
10
|
+
declare function adjustDecimals(amount: bigint, fromDecimals: number, toDecimals: number): bigint;
|
|
11
|
+
declare function deduplicateTokens(tokens: BaseTokenInfo[]): BaseTokenInfo[];
|
|
12
|
+
/**
|
|
13
|
+
* @param token - The token or array of tokens to compute the balance for.
|
|
14
|
+
* @param balances - The mapping of token balances.
|
|
15
|
+
* @param config - Configuration options.
|
|
16
|
+
* @param config.strict - Ensures all tokens have a balance if `true`, otherwise returns `undefined`.
|
|
17
|
+
*/
|
|
18
|
+
declare function computeTotalBalanceDifferentDecimals(token: BaseTokenInfo[] | BaseTokenInfo | UnifiedTokenInfo, balances: BalanceMapping, config?: {
|
|
19
|
+
strict: boolean;
|
|
20
|
+
}): TokenValue | undefined;
|
|
21
|
+
declare function computeTotalDeltaDifferentDecimals(tokens: BaseTokenInfo[], tokenDeltas: [string, bigint][]): TokenValue;
|
|
22
|
+
/**
|
|
23
|
+
* Convert a unified token to a base token, by getting the first token in the group.
|
|
24
|
+
* It should be used when you need to get *ANY* single token from a unified token.
|
|
25
|
+
*/
|
|
26
|
+
declare function getAnyBaseTokenInfo(token: BaseTokenInfo | UnifiedTokenInfo): BaseTokenInfo;
|
|
27
|
+
declare function getUnderlyingBaseTokenInfos(token: BaseTokenInfo | UnifiedTokenInfo | BaseTokenInfo[]): BaseTokenInfo[];
|
|
28
|
+
declare function getDerivedToken(tokenIn: BaseTokenInfo | UnifiedTokenInfo, chainName: string | null): BaseTokenInfo | null;
|
|
29
|
+
declare function getTokenMaxDecimals(token: BaseTokenInfo | UnifiedTokenInfo): number;
|
|
30
|
+
declare function compareAmounts(value1: TokenValue, value2: TokenValue): -1 | 0 | 1;
|
|
31
|
+
declare function minAmounts(value1: TokenValue, value2: TokenValue): TokenValue;
|
|
32
|
+
declare function addAmounts(...values: [TokenValue, TokenValue, ...TokenValue[]]): TokenValue;
|
|
33
|
+
declare function subtractAmounts(value1: TokenValue, token2: TokenValue): TokenValue;
|
|
34
|
+
declare function adjustDecimalsTokenValue(value: TokenValue, toDecimals: number): TokenValue;
|
|
35
|
+
declare function truncateTokenValue(value: TokenValue, decimals: number): TokenValue;
|
|
36
|
+
declare function negateTokenValue(value: TokenValue): TokenValue;
|
|
37
|
+
/**
|
|
38
|
+
* 1 bip = 0.0001% = 0.000001
|
|
39
|
+
* 3000 bips = 0.3% = 0.003
|
|
40
|
+
* 1000000 bips = 100% = 1
|
|
41
|
+
*/
|
|
42
|
+
declare const BASIS_POINTS_DENOMINATOR = 1000000n;
|
|
43
|
+
/**
|
|
44
|
+
* Calculates net amount by deducting fee from gross amount.
|
|
45
|
+
* @example
|
|
46
|
+
* // If gross amount is 100000n with 0.3% fee, net amount is 99700n
|
|
47
|
+
* netDownAmount(100000n, 3000) == 99700n
|
|
48
|
+
*/
|
|
49
|
+
declare function netDownAmount(amount: bigint, feeBip: number): bigint;
|
|
50
|
+
/**
|
|
51
|
+
* Calculates gross amount needed to achieve desired net amount after fee.
|
|
52
|
+
* @example
|
|
53
|
+
* // To receive net 100000n after 0.3% fee, gross amount needed is 100300n
|
|
54
|
+
* grossUpAmount(100000n, 3000) == 100300n
|
|
55
|
+
*/
|
|
56
|
+
declare function grossUpAmount(amount: bigint, feeBip: number): bigint;
|
|
57
|
+
/**
|
|
58
|
+
* Slippage can affect only positive numbers, because positive delta mean
|
|
59
|
+
* that much will receive, and user can receive a bit less than that
|
|
60
|
+
* depending on market conditions.
|
|
61
|
+
*/
|
|
62
|
+
declare function accountSlippageExactIn(delta: [string, bigint][], slippageBasisPoints: number): [string, bigint][];
|
|
63
|
+
declare function filterOutPoaBridgeTokens(token: BaseTokenInfo | UnifiedTokenInfo): BaseTokenInfo[];
|
|
64
|
+
declare function getTokenAccountIds(tokens: BaseTokenInfo[]): string[];
|
|
65
|
+
/**
|
|
66
|
+
* Converts Defuse asset ID to token contract ID.
|
|
67
|
+
* nep141:wrap.near → wrap.near
|
|
68
|
+
* nep245:v2_1.omni.hot.tg:56_11111111111111111111 → v2_1.omni.hot.tg
|
|
69
|
+
*/
|
|
70
|
+
declare function getTokenAccountId(assetId: string): string;
|
|
71
|
+
type ParseDefuseAssetIdReturnType = {
|
|
72
|
+
standard: "nep141";
|
|
73
|
+
contractId: string;
|
|
74
|
+
} | {
|
|
75
|
+
standard: "nep245";
|
|
76
|
+
contractId: string;
|
|
77
|
+
tokenId: string;
|
|
78
|
+
};
|
|
79
|
+
type ParseDefuseAssetIdErrorType = AssertErrorType;
|
|
80
|
+
/**
|
|
81
|
+
* Parses Defuse asset ID into its components based on the token standard.
|
|
82
|
+
* nep141:wrap.near → { standard: nep141, contractId: wrap.near }
|
|
83
|
+
* nep245:v2_1.omni.hot.tg:56_11111111111111111111 -> { standard: nep245, contractId: v2_1.omni.hot.tg, tokenId: 56_11111111111111111111 }
|
|
84
|
+
*/
|
|
85
|
+
declare function parseDefuseAssetId(assetId: string): ParseDefuseAssetIdReturnType;
|
|
86
|
+
declare function tokenAccountIdToDefuseAssetId(address: string): string;
|
|
87
|
+
//#endregion
|
|
88
|
+
export { BASIS_POINTS_DENOMINATOR, DuplicateTokenError, ParseDefuseAssetIdErrorType, ParseDefuseAssetIdReturnType, accountSlippageExactIn, addAmounts, adjustDecimals, adjustDecimalsTokenValue, compareAmounts, computeTotalBalance, computeTotalBalanceDifferentDecimals, computeTotalDeltaDifferentDecimals, deduplicateTokens, filterOutPoaBridgeTokens, getAnyBaseTokenInfo, getDerivedToken, getTokenAccountId, getTokenAccountIds, getTokenMaxDecimals, getUnderlyingBaseTokenInfos, grossUpAmount, minAmounts, negateTokenValue, netDownAmount, parseDefuseAssetId, subtractAmounts, tokenAccountIdToDefuseAssetId, truncateTokenValue };
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { BaseTokenInfo, TokenValue, UnifiedTokenInfo } from "../types/base.js";
|
|
2
|
+
import { AssertErrorType } from "./assert.js";
|
|
3
|
+
|
|
4
|
+
//#region src/utils/tokenUtils.d.ts
|
|
5
|
+
type BalanceMapping = Record<string, bigint>;
|
|
6
|
+
declare function computeTotalBalance(token: BaseTokenInfo["defuseAssetId"][] | BaseTokenInfo | UnifiedTokenInfo, balances: BalanceMapping): bigint | undefined;
|
|
7
|
+
declare class DuplicateTokenError extends Error {
|
|
8
|
+
constructor(tokenId: string, decimals1: number, decimals2: number);
|
|
9
|
+
}
|
|
10
|
+
declare function adjustDecimals(amount: bigint, fromDecimals: number, toDecimals: number): bigint;
|
|
11
|
+
declare function deduplicateTokens(tokens: BaseTokenInfo[]): BaseTokenInfo[];
|
|
12
|
+
/**
|
|
13
|
+
* @param token - The token or array of tokens to compute the balance for.
|
|
14
|
+
* @param balances - The mapping of token balances.
|
|
15
|
+
* @param config - Configuration options.
|
|
16
|
+
* @param config.strict - Ensures all tokens have a balance if `true`, otherwise returns `undefined`.
|
|
17
|
+
*/
|
|
18
|
+
declare function computeTotalBalanceDifferentDecimals(token: BaseTokenInfo[] | BaseTokenInfo | UnifiedTokenInfo, balances: BalanceMapping, config?: {
|
|
19
|
+
strict: boolean;
|
|
20
|
+
}): TokenValue | undefined;
|
|
21
|
+
declare function computeTotalDeltaDifferentDecimals(tokens: BaseTokenInfo[], tokenDeltas: [string, bigint][]): TokenValue;
|
|
22
|
+
/**
|
|
23
|
+
* Convert a unified token to a base token, by getting the first token in the group.
|
|
24
|
+
* It should be used when you need to get *ANY* single token from a unified token.
|
|
25
|
+
*/
|
|
26
|
+
declare function getAnyBaseTokenInfo(token: BaseTokenInfo | UnifiedTokenInfo): BaseTokenInfo;
|
|
27
|
+
declare function getUnderlyingBaseTokenInfos(token: BaseTokenInfo | UnifiedTokenInfo | BaseTokenInfo[]): BaseTokenInfo[];
|
|
28
|
+
declare function getDerivedToken(tokenIn: BaseTokenInfo | UnifiedTokenInfo, chainName: string | null): BaseTokenInfo | null;
|
|
29
|
+
declare function getTokenMaxDecimals(token: BaseTokenInfo | UnifiedTokenInfo): number;
|
|
30
|
+
declare function compareAmounts(value1: TokenValue, value2: TokenValue): -1 | 0 | 1;
|
|
31
|
+
declare function minAmounts(value1: TokenValue, value2: TokenValue): TokenValue;
|
|
32
|
+
declare function addAmounts(...values: [TokenValue, TokenValue, ...TokenValue[]]): TokenValue;
|
|
33
|
+
declare function subtractAmounts(value1: TokenValue, token2: TokenValue): TokenValue;
|
|
34
|
+
declare function adjustDecimalsTokenValue(value: TokenValue, toDecimals: number): TokenValue;
|
|
35
|
+
declare function truncateTokenValue(value: TokenValue, decimals: number): TokenValue;
|
|
36
|
+
declare function negateTokenValue(value: TokenValue): TokenValue;
|
|
37
|
+
/**
|
|
38
|
+
* 1 bip = 0.0001% = 0.000001
|
|
39
|
+
* 3000 bips = 0.3% = 0.003
|
|
40
|
+
* 1000000 bips = 100% = 1
|
|
41
|
+
*/
|
|
42
|
+
declare const BASIS_POINTS_DENOMINATOR = 1000000n;
|
|
43
|
+
/**
|
|
44
|
+
* Calculates net amount by deducting fee from gross amount.
|
|
45
|
+
* @example
|
|
46
|
+
* // If gross amount is 100000n with 0.3% fee, net amount is 99700n
|
|
47
|
+
* netDownAmount(100000n, 3000) == 99700n
|
|
48
|
+
*/
|
|
49
|
+
declare function netDownAmount(amount: bigint, feeBip: number): bigint;
|
|
50
|
+
/**
|
|
51
|
+
* Calculates gross amount needed to achieve desired net amount after fee.
|
|
52
|
+
* @example
|
|
53
|
+
* // To receive net 100000n after 0.3% fee, gross amount needed is 100300n
|
|
54
|
+
* grossUpAmount(100000n, 3000) == 100300n
|
|
55
|
+
*/
|
|
56
|
+
declare function grossUpAmount(amount: bigint, feeBip: number): bigint;
|
|
57
|
+
/**
|
|
58
|
+
* Slippage can affect only positive numbers, because positive delta mean
|
|
59
|
+
* that much will receive, and user can receive a bit less than that
|
|
60
|
+
* depending on market conditions.
|
|
61
|
+
*/
|
|
62
|
+
declare function accountSlippageExactIn(delta: [string, bigint][], slippageBasisPoints: number): [string, bigint][];
|
|
63
|
+
declare function filterOutPoaBridgeTokens(token: BaseTokenInfo | UnifiedTokenInfo): BaseTokenInfo[];
|
|
64
|
+
declare function getTokenAccountIds(tokens: BaseTokenInfo[]): string[];
|
|
65
|
+
/**
|
|
66
|
+
* Converts Defuse asset ID to token contract ID.
|
|
67
|
+
* nep141:wrap.near → wrap.near
|
|
68
|
+
* nep245:v2_1.omni.hot.tg:56_11111111111111111111 → v2_1.omni.hot.tg
|
|
69
|
+
*/
|
|
70
|
+
declare function getTokenAccountId(assetId: string): string;
|
|
71
|
+
type ParseDefuseAssetIdReturnType = {
|
|
72
|
+
standard: "nep141";
|
|
73
|
+
contractId: string;
|
|
74
|
+
} | {
|
|
75
|
+
standard: "nep245";
|
|
76
|
+
contractId: string;
|
|
77
|
+
tokenId: string;
|
|
78
|
+
};
|
|
79
|
+
type ParseDefuseAssetIdErrorType = AssertErrorType;
|
|
80
|
+
/**
|
|
81
|
+
* Parses Defuse asset ID into its components based on the token standard.
|
|
82
|
+
* nep141:wrap.near → { standard: nep141, contractId: wrap.near }
|
|
83
|
+
* nep245:v2_1.omni.hot.tg:56_11111111111111111111 -> { standard: nep245, contractId: v2_1.omni.hot.tg, tokenId: 56_11111111111111111111 }
|
|
84
|
+
*/
|
|
85
|
+
declare function parseDefuseAssetId(assetId: string): ParseDefuseAssetIdReturnType;
|
|
86
|
+
declare function tokenAccountIdToDefuseAssetId(address: string): string;
|
|
87
|
+
//#endregion
|
|
88
|
+
export { BASIS_POINTS_DENOMINATOR, DuplicateTokenError, ParseDefuseAssetIdErrorType, ParseDefuseAssetIdReturnType, accountSlippageExactIn, addAmounts, adjustDecimals, adjustDecimalsTokenValue, compareAmounts, computeTotalBalance, computeTotalBalanceDifferentDecimals, computeTotalDeltaDifferentDecimals, deduplicateTokens, filterOutPoaBridgeTokens, getAnyBaseTokenInfo, getDerivedToken, getTokenAccountId, getTokenAccountIds, getTokenMaxDecimals, getUnderlyingBaseTokenInfos, grossUpAmount, minAmounts, negateTokenValue, netDownAmount, parseDefuseAssetId, subtractAmounts, tokenAccountIdToDefuseAssetId, truncateTokenValue };
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { assert } from "./assert.js";
|
|
2
|
+
import { validateNearAddress } from "./near.js";
|
|
3
|
+
import { isBaseToken } from "./token.js";
|
|
4
|
+
|
|
5
|
+
//#region src/utils/tokenUtils.ts
|
|
6
|
+
function computeTotalBalance(token, balances) {
|
|
7
|
+
if (Array.isArray(token)) {
|
|
8
|
+
const uniqueTokens = new Set(token);
|
|
9
|
+
let total = 0n;
|
|
10
|
+
for (const tokenId of uniqueTokens) {
|
|
11
|
+
const balance = balances[tokenId];
|
|
12
|
+
if (balance == null) return;
|
|
13
|
+
total += balance;
|
|
14
|
+
}
|
|
15
|
+
return total;
|
|
16
|
+
}
|
|
17
|
+
if (isBaseToken(token)) return balances[token.defuseAssetId];
|
|
18
|
+
return computeTotalBalance(token.groupedTokens.map((t) => t.defuseAssetId), balances);
|
|
19
|
+
}
|
|
20
|
+
var DuplicateTokenError = class extends Error {
|
|
21
|
+
constructor(tokenId, decimals1, decimals2) {
|
|
22
|
+
super(`Duplicate token ${tokenId} found with different decimals: ${decimals1} and ${decimals2}`);
|
|
23
|
+
this.name = "DuplicateTokenError";
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
function adjustDecimals(amount, fromDecimals, toDecimals) {
|
|
27
|
+
if (fromDecimals === toDecimals) return amount;
|
|
28
|
+
if (fromDecimals > toDecimals) return amount / BigInt(10 ** (fromDecimals - toDecimals));
|
|
29
|
+
return amount * BigInt(10 ** (toDecimals - fromDecimals));
|
|
30
|
+
}
|
|
31
|
+
function deduplicateTokens(tokens) {
|
|
32
|
+
const tokenMap = /* @__PURE__ */ new Map();
|
|
33
|
+
for (const token of tokens) {
|
|
34
|
+
const existing = tokenMap.get(token.defuseAssetId);
|
|
35
|
+
if (existing) {
|
|
36
|
+
if (existing.decimals !== token.decimals) throw new DuplicateTokenError(token.defuseAssetId, existing.decimals, token.decimals);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
tokenMap.set(token.defuseAssetId, token);
|
|
40
|
+
}
|
|
41
|
+
return Array.from(tokenMap.values());
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* @param token - The token or array of tokens to compute the balance for.
|
|
45
|
+
* @param balances - The mapping of token balances.
|
|
46
|
+
* @param config - Configuration options.
|
|
47
|
+
* @param config.strict - Ensures all tokens have a balance if `true`, otherwise returns `undefined`.
|
|
48
|
+
*/
|
|
49
|
+
function computeTotalBalanceDifferentDecimals(token, balances, config = { strict: true }) {
|
|
50
|
+
if (!Array.isArray(token) && isBaseToken(token)) token = [token];
|
|
51
|
+
const uniqueTokens = deduplicateTokens(Array.isArray(token) ? token : token.groupedTokens);
|
|
52
|
+
if (uniqueTokens.length === 0) return {
|
|
53
|
+
amount: 0n,
|
|
54
|
+
decimals: 0
|
|
55
|
+
};
|
|
56
|
+
const maxDecimals = Math.max(...uniqueTokens.map((t) => t.decimals));
|
|
57
|
+
let total = null;
|
|
58
|
+
for (const t of uniqueTokens) {
|
|
59
|
+
const balance = balances[t.defuseAssetId];
|
|
60
|
+
if (balance == null) {
|
|
61
|
+
if (config.strict) return;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
total ??= 0n;
|
|
65
|
+
total += adjustDecimals(balance, t.decimals, maxDecimals);
|
|
66
|
+
}
|
|
67
|
+
if (total == null) return;
|
|
68
|
+
return {
|
|
69
|
+
amount: total,
|
|
70
|
+
decimals: maxDecimals
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function computeTotalDeltaDifferentDecimals(tokens, tokenDeltas) {
|
|
74
|
+
const mapping = {};
|
|
75
|
+
for (const [token, amount] of tokenDeltas) {
|
|
76
|
+
mapping[token] ??= 0n;
|
|
77
|
+
mapping[token] += amount;
|
|
78
|
+
}
|
|
79
|
+
return computeTotalBalanceDifferentDecimals(tokens, mapping, { strict: false }) ?? {
|
|
80
|
+
amount: 0n,
|
|
81
|
+
decimals: 0
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Convert a unified token to a base token, by getting the first token in the group.
|
|
86
|
+
* It should be used when you need to get *ANY* single token from a unified token.
|
|
87
|
+
*/
|
|
88
|
+
function getAnyBaseTokenInfo(token) {
|
|
89
|
+
const t = getUnderlyingBaseTokenInfos(token)[0];
|
|
90
|
+
assert(t != null, "Token is undefined");
|
|
91
|
+
return t;
|
|
92
|
+
}
|
|
93
|
+
function getUnderlyingBaseTokenInfos(token) {
|
|
94
|
+
let tokens;
|
|
95
|
+
if (Array.isArray(token)) tokens = token;
|
|
96
|
+
else tokens = isBaseToken(token) ? [token] : token.groupedTokens;
|
|
97
|
+
return deduplicateTokens(tokens);
|
|
98
|
+
}
|
|
99
|
+
function getDerivedToken(tokenIn, chainName) {
|
|
100
|
+
if (isBaseToken(tokenIn)) return chainName === tokenIn.chainName ? tokenIn : null;
|
|
101
|
+
if (chainName != null) {
|
|
102
|
+
const tokenOut = tokenIn.groupedTokens.find((token) => token.chainName === chainName);
|
|
103
|
+
if (tokenOut != null) return tokenOut;
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
function getTokenMaxDecimals(token) {
|
|
108
|
+
const tokens = getUnderlyingBaseTokenInfos(token);
|
|
109
|
+
return Math.max(...tokens.map((t) => t.decimals));
|
|
110
|
+
}
|
|
111
|
+
function compareAmounts(value1, value2) {
|
|
112
|
+
const maxDecimals = Math.max(value1.decimals, value2.decimals);
|
|
113
|
+
const normalizedAmount1 = adjustDecimals(value1.amount, value1.decimals, maxDecimals);
|
|
114
|
+
const normalizedAmount2 = adjustDecimals(value2.amount, value2.decimals, maxDecimals);
|
|
115
|
+
if (normalizedAmount1 < normalizedAmount2) return -1;
|
|
116
|
+
if (normalizedAmount1 > normalizedAmount2) return 1;
|
|
117
|
+
return 0;
|
|
118
|
+
}
|
|
119
|
+
function minAmounts(value1, value2) {
|
|
120
|
+
return compareAmounts(value1, value2) <= 0 ? value1 : value2;
|
|
121
|
+
}
|
|
122
|
+
function addAmounts(...values) {
|
|
123
|
+
const maxDecimals = Math.max(...values.map((v) => v.decimals));
|
|
124
|
+
let sum = 0n;
|
|
125
|
+
for (const v of values) sum += adjustDecimals(v.amount, v.decimals, maxDecimals);
|
|
126
|
+
return {
|
|
127
|
+
amount: sum,
|
|
128
|
+
decimals: maxDecimals
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function subtractAmounts(value1, token2) {
|
|
132
|
+
return addAmounts(value1, {
|
|
133
|
+
amount: -token2.amount,
|
|
134
|
+
decimals: token2.decimals
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
function adjustDecimalsTokenValue(value, toDecimals) {
|
|
138
|
+
return {
|
|
139
|
+
amount: adjustDecimals(value.amount, value.decimals, toDecimals),
|
|
140
|
+
decimals: toDecimals
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function truncateTokenValue(value, decimals) {
|
|
144
|
+
return adjustDecimalsTokenValue(adjustDecimalsTokenValue(value, decimals), value.decimals);
|
|
145
|
+
}
|
|
146
|
+
function negateTokenValue(value) {
|
|
147
|
+
return {
|
|
148
|
+
amount: -value.amount,
|
|
149
|
+
decimals: value.decimals
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* 1 bip = 0.0001% = 0.000001
|
|
154
|
+
* 3000 bips = 0.3% = 0.003
|
|
155
|
+
* 1000000 bips = 100% = 1
|
|
156
|
+
*/
|
|
157
|
+
const BASIS_POINTS_DENOMINATOR = 1000000n;
|
|
158
|
+
/**
|
|
159
|
+
* Calculates net amount by deducting fee from gross amount.
|
|
160
|
+
* @example
|
|
161
|
+
* // If gross amount is 100000n with 0.3% fee, net amount is 99700n
|
|
162
|
+
* netDownAmount(100000n, 3000) == 99700n
|
|
163
|
+
*/
|
|
164
|
+
function netDownAmount(amount, feeBip) {
|
|
165
|
+
if (feeBip < 0 || feeBip > Number(BASIS_POINTS_DENOMINATOR)) throw new Error(`Invalid feeBip value. It must be between 0 and ${BASIS_POINTS_DENOMINATOR}.`);
|
|
166
|
+
if (amount < 0n) throw new Error("Amount must be non-negative.");
|
|
167
|
+
if (amount === 0n || feeBip === 0) return amount;
|
|
168
|
+
return amount - (amount * BigInt(feeBip) + (BASIS_POINTS_DENOMINATOR - 1n)) / BASIS_POINTS_DENOMINATOR;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Calculates gross amount needed to achieve desired net amount after fee.
|
|
172
|
+
* @example
|
|
173
|
+
* // To receive net 100000n after 0.3% fee, gross amount needed is 100300n
|
|
174
|
+
* grossUpAmount(100000n, 3000) == 100300n
|
|
175
|
+
*/
|
|
176
|
+
function grossUpAmount(amount, feeBip) {
|
|
177
|
+
if (feeBip < 0 || feeBip > Number(BASIS_POINTS_DENOMINATOR)) throw new Error(`Invalid feeBip value. It must be between 0 and ${BASIS_POINTS_DENOMINATOR}.`);
|
|
178
|
+
if (amount < 0n) throw new Error("Amount must be non-negative.");
|
|
179
|
+
if (amount === 0n || feeBip === 0) return amount;
|
|
180
|
+
const feeMultiplier = BASIS_POINTS_DENOMINATOR - BigInt(feeBip);
|
|
181
|
+
return (amount * BASIS_POINTS_DENOMINATOR + (feeMultiplier - 1n)) / feeMultiplier;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Slippage can affect only positive numbers, because positive delta mean
|
|
185
|
+
* that much will receive, and user can receive a bit less than that
|
|
186
|
+
* depending on market conditions.
|
|
187
|
+
*/
|
|
188
|
+
function accountSlippageExactIn(delta, slippageBasisPoints) {
|
|
189
|
+
return delta.map(([token, amount]) => {
|
|
190
|
+
if (amount > 0n) return [token, netDownAmount(amount, slippageBasisPoints)];
|
|
191
|
+
return [token, amount];
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
function filterOutPoaBridgeTokens(token) {
|
|
195
|
+
if (isBaseToken(token)) return token.bridge === "poa" ? [token] : [];
|
|
196
|
+
return token.groupedTokens.filter((t) => t.bridge === "poa");
|
|
197
|
+
}
|
|
198
|
+
function getTokenAccountIds(tokens) {
|
|
199
|
+
return tokens.map((t) => getTokenAccountId(t.defuseAssetId));
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Converts Defuse asset ID to token contract ID.
|
|
203
|
+
* nep141:wrap.near → wrap.near
|
|
204
|
+
* nep245:v2_1.omni.hot.tg:56_11111111111111111111 → v2_1.omni.hot.tg
|
|
205
|
+
*/
|
|
206
|
+
function getTokenAccountId(assetId) {
|
|
207
|
+
const { contractId } = parseDefuseAssetId(assetId);
|
|
208
|
+
return contractId;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Parses Defuse asset ID into its components based on the token standard.
|
|
212
|
+
* nep141:wrap.near → { standard: nep141, contractId: wrap.near }
|
|
213
|
+
* nep245:v2_1.omni.hot.tg:56_11111111111111111111 -> { standard: nep245, contractId: v2_1.omni.hot.tg, tokenId: 56_11111111111111111111 }
|
|
214
|
+
*/
|
|
215
|
+
function parseDefuseAssetId(assetId) {
|
|
216
|
+
const [tokenStandard, tokenContractId, multiTokenId] = assetId.split(":");
|
|
217
|
+
assert(tokenContractId != null && validateNearAddress(tokenContractId), "Incorrect format of assetId");
|
|
218
|
+
switch (tokenStandard) {
|
|
219
|
+
case "nep141": return {
|
|
220
|
+
standard: "nep141",
|
|
221
|
+
contractId: tokenContractId
|
|
222
|
+
};
|
|
223
|
+
case "nep245":
|
|
224
|
+
assert(multiTokenId != null, "Incorrect NEP-245 token format");
|
|
225
|
+
return {
|
|
226
|
+
standard: "nep245",
|
|
227
|
+
contractId: tokenContractId,
|
|
228
|
+
tokenId: multiTokenId
|
|
229
|
+
};
|
|
230
|
+
default: assert(false, `Unsupported token standard: ${tokenStandard}`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
function tokenAccountIdToDefuseAssetId(address) {
|
|
234
|
+
return `nep141:${address}`;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
//#endregion
|
|
238
|
+
export { BASIS_POINTS_DENOMINATOR, DuplicateTokenError, accountSlippageExactIn, addAmounts, adjustDecimals, adjustDecimalsTokenValue, compareAmounts, computeTotalBalance, computeTotalBalanceDifferentDecimals, computeTotalDeltaDifferentDecimals, deduplicateTokens, filterOutPoaBridgeTokens, getAnyBaseTokenInfo, getDerivedToken, getTokenAccountId, getTokenAccountIds, getTokenMaxDecimals, getUnderlyingBaseTokenInfos, grossUpAmount, minAmounts, negateTokenValue, netDownAmount, parseDefuseAssetId, subtractAmounts, tokenAccountIdToDefuseAssetId, truncateTokenValue };
|