@swapkit/helpers 4.5.8 → 4.12.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.
Files changed (111) hide show
  1. package/dist/LICENSE +246 -0
  2. package/dist/api/index.cjs +0 -4
  3. package/dist/api/index.js +1 -4
  4. package/dist/chunk-1m30h0t9.js +1 -0
  5. package/dist/chunk-jsgxsr8a.js +4 -0
  6. package/dist/chunk-z5an6869.js +5 -0
  7. package/dist/contracts.cjs +0 -3
  8. package/dist/contracts.js +0 -3
  9. package/dist/index.cjs +1 -7
  10. package/dist/index.js +1 -7
  11. package/dist/tokens.cjs +0 -3
  12. package/dist/tokens.js +0 -3
  13. package/dist/types/api/index.d.ts +126 -153
  14. package/dist/types/api/index.d.ts.map +1 -1
  15. package/dist/types/api/midgard/endpoints.d.ts +2 -1
  16. package/dist/types/api/midgard/endpoints.d.ts.map +1 -1
  17. package/dist/types/api/swapkitApi/endpoints.d.ts +134 -159
  18. package/dist/types/api/swapkitApi/endpoints.d.ts.map +1 -1
  19. package/dist/types/api/swapkitApi/types.d.ts +1038 -23
  20. package/dist/types/api/swapkitApi/types.d.ts.map +1 -1
  21. package/dist/types/api/thornode/endpoints.d.ts +1 -1
  22. package/dist/types/api/thornode/endpoints.d.ts.map +1 -1
  23. package/dist/types/index.d.ts +5 -0
  24. package/dist/types/index.d.ts.map +1 -1
  25. package/dist/types/modules/assetValue.d.ts +6 -7
  26. package/dist/types/modules/assetValue.d.ts.map +1 -1
  27. package/dist/types/modules/bigIntArithmetics.d.ts +2 -1
  28. package/dist/types/modules/bigIntArithmetics.d.ts.map +1 -1
  29. package/dist/types/modules/requestClient.d.ts +1 -1
  30. package/dist/types/modules/requestClient.d.ts.map +1 -1
  31. package/dist/types/modules/swapKitConfig.d.ts +24 -78
  32. package/dist/types/modules/swapKitConfig.d.ts.map +1 -1
  33. package/dist/types/modules/swapKitError.d.ts +146 -14
  34. package/dist/types/modules/swapKitError.d.ts.map +1 -1
  35. package/dist/types/modules/widgetAuth.d.ts +6 -0
  36. package/dist/types/modules/widgetAuth.d.ts.map +1 -0
  37. package/dist/types/types/derivationPath.d.ts +1 -1
  38. package/dist/types/types/derivationPath.d.ts.map +1 -1
  39. package/dist/types/types/quotes.d.ts +2 -6
  40. package/dist/types/types/quotes.d.ts.map +1 -1
  41. package/dist/types/types/sdk.d.ts +6 -0
  42. package/dist/types/types/sdk.d.ts.map +1 -1
  43. package/dist/types/types/wallet.d.ts +12 -3
  44. package/dist/types/types/wallet.d.ts.map +1 -1
  45. package/dist/types/utils/asset.d.ts +17 -1
  46. package/dist/types/utils/asset.d.ts.map +1 -1
  47. package/dist/types/utils/chains.d.ts +5 -0
  48. package/dist/types/utils/chains.d.ts.map +1 -1
  49. package/dist/types/utils/derivationPath.d.ts +4 -2
  50. package/dist/types/utils/derivationPath.d.ts.map +1 -1
  51. package/dist/types/utils/wallets.d.ts +18 -2
  52. package/dist/types/utils/wallets.d.ts.map +1 -1
  53. package/package.json +12 -30
  54. package/dist/api/index.cjs.map +0 -14
  55. package/dist/api/index.js.map +0 -14
  56. package/dist/chunk-pfmeq01a.js +0 -5
  57. package/dist/chunk-pfmeq01a.js.map +0 -9
  58. package/dist/chunk-vb4wtm2w.js +0 -4
  59. package/dist/chunk-vb4wtm2w.js.map +0 -9
  60. package/dist/contracts.cjs.map +0 -10
  61. package/dist/contracts.js.map +0 -10
  62. package/dist/index.cjs.map +0 -30
  63. package/dist/index.js.map +0 -30
  64. package/dist/tokens.cjs.map +0 -10
  65. package/dist/tokens.js.map +0 -10
  66. package/src/api/index.ts +0 -9
  67. package/src/api/midgard/endpoints.ts +0 -348
  68. package/src/api/midgard/types.ts +0 -515
  69. package/src/api/swapkitApi/endpoints.ts +0 -247
  70. package/src/api/swapkitApi/types.ts +0 -624
  71. package/src/api/thornode/endpoints.ts +0 -105
  72. package/src/api/thornode/types.ts +0 -247
  73. package/src/contracts.ts +0 -1
  74. package/src/index.ts +0 -28
  75. package/src/modules/__tests__/assetValue.test.ts +0 -1892
  76. package/src/modules/__tests__/bigIntArithmetics.test.ts +0 -408
  77. package/src/modules/__tests__/feeMultiplier.test.ts +0 -125
  78. package/src/modules/__tests__/swapKitConfig.test.ts +0 -425
  79. package/src/modules/__tests__/swapKitNumber.test.ts +0 -435
  80. package/src/modules/assetValue.ts +0 -532
  81. package/src/modules/bigIntArithmetics.ts +0 -368
  82. package/src/modules/feeMultiplier.ts +0 -80
  83. package/src/modules/requestClient.ts +0 -110
  84. package/src/modules/swapKitConfig.ts +0 -174
  85. package/src/modules/swapKitError.ts +0 -470
  86. package/src/modules/swapKitNumber.ts +0 -13
  87. package/src/tokens.ts +0 -1
  88. package/src/types/commonTypes.ts +0 -10
  89. package/src/types/derivationPath.ts +0 -11
  90. package/src/types/errors/apiV1.ts +0 -0
  91. package/src/types/index.ts +0 -5
  92. package/src/types/quotes.ts +0 -174
  93. package/src/types/sdk.ts +0 -38
  94. package/src/types/wallet.ts +0 -124
  95. package/src/utils/__tests__/asset.test.ts +0 -186
  96. package/src/utils/__tests__/derivationPath.test.ts +0 -142
  97. package/src/utils/__tests__/explorerUrls.test.ts +0 -59
  98. package/src/utils/__tests__/liquidity.test.ts +0 -302
  99. package/src/utils/__tests__/memo.test.ts +0 -99
  100. package/src/utils/__tests__/others.test.ts +0 -165
  101. package/src/utils/__tests__/validators.test.ts +0 -84
  102. package/src/utils/__tests__/wallets.test.ts +0 -621
  103. package/src/utils/asset.ts +0 -399
  104. package/src/utils/chains.ts +0 -100
  105. package/src/utils/derivationPath.ts +0 -101
  106. package/src/utils/explorerUrls.ts +0 -32
  107. package/src/utils/liquidity.ts +0 -150
  108. package/src/utils/memo.ts +0 -102
  109. package/src/utils/others.ts +0 -62
  110. package/src/utils/validators.ts +0 -32
  111. package/src/utils/wallets.ts +0 -237
@@ -1,532 +0,0 @@
1
- import type { TokenListName, TokenNames, TokenTax } from "@swapkit/tokens";
2
- import { AllChains, Chain, type ChainId, type EVMChain, EVMChains, getChainConfig } from "@swapkit/types";
3
- import { getAddress } from "ethers";
4
- import { match } from "ts-pattern";
5
- import {
6
- assetFromString,
7
- type CommonAssetString,
8
- fetchTokenInfo,
9
- getAssetType,
10
- getCommonAssetInfo,
11
- isGasAsset,
12
- } from "../utils/asset";
13
- import { warnOnce } from "../utils/others";
14
- import { validateIdentifier } from "../utils/validators";
15
-
16
- import type { NumberPrimitives } from "./bigIntArithmetics";
17
- import { BigIntArithmetics, formatBigIntToSafeValue } from "./bigIntArithmetics";
18
- import { SwapKitError } from "./swapKitError";
19
- import type { SwapKitValueType } from "./swapKitNumber";
20
-
21
- const CASE_SENSITIVE_CHAINS: Chain[] = [Chain.Solana, Chain.Tron, Chain.Near, Chain.Sui];
22
- const TC_CHAINS: Chain[] = [Chain.THORChain, Chain.Maya];
23
-
24
- const staticTokensMap = new Map<
25
- TokenNames | (string & {}),
26
- { tax?: TokenTax; decimal: number; identifier: string; logoURI?: string }
27
- >();
28
-
29
- const chainAddressIdentifierMap = new Map<string, string>();
30
-
31
- const asyncTokenCache = new Map<string, { identifier: string; decimals: number; timestamp: number }>();
32
- const CACHE_TTL = 3600000;
33
-
34
- function getCachedTokenInfo(key: string) {
35
- const cached = asyncTokenCache.get(key);
36
-
37
- if (cached?.timestamp && Date.now() - cached.timestamp > CACHE_TTL) {
38
- asyncTokenCache.delete(key);
39
- return undefined;
40
- }
41
-
42
- return cached;
43
- }
44
-
45
- function setCachedTokenInfo(key: string, info: { identifier: string; decimals: number }) {
46
- if (asyncTokenCache.size > 1000) {
47
- const firstKey = asyncTokenCache.keys().next().value;
48
- if (firstKey) asyncTokenCache.delete(firstKey);
49
- }
50
-
51
- asyncTokenCache.set(key, { ...info, timestamp: Date.now() });
52
- }
53
-
54
- type ConditionalAssetValueReturn<T extends { asyncTokenLookup?: boolean }> = T["asyncTokenLookup"] extends true
55
- ? Promise<AssetValue>
56
- : AssetValue;
57
-
58
- type AssetIdentifier =
59
- | { asset: CommonAssetString | TokenNames }
60
- | { asset: string }
61
- | { chain: Chain; address?: string };
62
-
63
- type AssetValueFromParams = AssetIdentifier & {
64
- value?: NumberPrimitives | SwapKitValueType;
65
- fromBaseDecimal?: number;
66
- asyncTokenLookup?: boolean;
67
- };
68
-
69
- export class AssetValue extends BigIntArithmetics {
70
- address?: string;
71
- chain: Chain;
72
- isGasAsset = false;
73
- isSynthetic = false;
74
- isTradeAsset = false;
75
- symbol: string;
76
- tax?: TokenTax;
77
- ticker: string;
78
- type: ReturnType<typeof getAssetType>;
79
- chainId: ChainId;
80
-
81
- constructor({
82
- value,
83
- decimal,
84
- tax,
85
- chain,
86
- symbol,
87
- identifier,
88
- }: { decimal: number; value: SwapKitValueType; tax?: TokenTax } & (
89
- | { chain: Chain; symbol: string; identifier?: never }
90
- | { identifier: string; chain?: never; symbol?: never }
91
- )) {
92
- super(typeof value === "object" ? value : { decimal, value });
93
-
94
- const assetInfo = getAssetInfo(identifier || `${chain}.${symbol}`);
95
-
96
- this.type = getAssetType(assetInfo);
97
- this.tax = tax;
98
- this.chain = assetInfo.chain;
99
- this.ticker = assetInfo.ticker;
100
- this.symbol = assetInfo.symbol;
101
- this.address = assetInfo.address;
102
- this.isSynthetic = assetInfo.isSynthetic;
103
- this.isTradeAsset = assetInfo.isTradeAsset;
104
- this.isGasAsset = assetInfo.isGasAsset;
105
- this.chainId = getChainConfig(assetInfo.chain).chainId;
106
- }
107
-
108
- toString({ includeSynthProtocol }: { includeSynthProtocol?: boolean } = {}) {
109
- return (this.isSynthetic || this.isTradeAsset) && !includeSynthProtocol
110
- ? this.symbol
111
- : `${this.chain}.${this.symbol}`;
112
- }
113
-
114
- toUrl() {
115
- if (this.isSynthetic) {
116
- return `${this.chain}.${this.symbol.replace(/\//g, ".")}`;
117
- }
118
-
119
- if (this.isTradeAsset) {
120
- return `${this.chain}.${this.symbol.replace(/~/g, "..")}`;
121
- }
122
-
123
- const encodedSymbol = this.symbol.replace(/\./g, "__");
124
- return `${this.chain}.${encodedSymbol}`;
125
- }
126
-
127
- getIconUrl() {
128
- const token = staticTokensMap.get(this.toString());
129
- return token?.logoURI;
130
- }
131
-
132
- eqAsset({ chain, symbol }: { chain: Chain; symbol: string }) {
133
- return this.chain === chain && this.symbol === symbol;
134
- }
135
-
136
- eq(assetValue: AssetValue) {
137
- return this.eqAsset(assetValue) && this.eqValue(assetValue);
138
- }
139
-
140
- static fromUrl(urlAsset: string, value: NumberPrimitives = 0) {
141
- const firstDotIndex = urlAsset.indexOf(".");
142
-
143
- if (firstDotIndex === -1) {
144
- throw new SwapKitError({ errorKey: "helpers_invalid_asset_url", info: { urlAsset } });
145
- }
146
-
147
- const chain = urlAsset.slice(0, firstDotIndex);
148
- const rest = urlAsset.slice(firstDotIndex + 1);
149
-
150
- const asset = match({ chain: chain as Chain, rest })
151
- .when(
152
- ({ rest }) => rest.includes(".."),
153
- ({ chain, rest }) => `${chain}.${rest.replace(/\.\./g, "~")}`,
154
- )
155
- .when(
156
- ({ chain, rest }) => TC_CHAINS.includes(chain) && rest.includes("."),
157
- ({ chain, rest }) => `${chain}.${rest.replace(/\./g, "/")}`,
158
- )
159
- .otherwise(({ chain, rest }) => `${chain}.${rest.replace(/__/g, ".")}`);
160
-
161
- return AssetValue.from({ asset, value });
162
- }
163
-
164
- static from<T extends {}>({
165
- value = 0,
166
- fromBaseDecimal,
167
- asyncTokenLookup,
168
- ...fromAssetOrChain
169
- }: T & AssetValueFromParams): ConditionalAssetValueReturn<T> {
170
- const parsedValue = value instanceof BigIntArithmetics ? value.getValue("string") : value;
171
- const assetOrChain = getAssetString(fromAssetOrChain);
172
-
173
- const isChainAddressCombo = !assetOrChain.startsWith(Chain.Sui) && assetOrChain.includes(":");
174
-
175
- if (asyncTokenLookup && isChainAddressCombo) {
176
- const [chain, address] = assetOrChain.split(":") as [Chain, string];
177
-
178
- return createAsyncAssetValue({ address, chain, fromBaseDecimal, parsedValue }) as ConditionalAssetValueReturn<T>;
179
- }
180
-
181
- const fallbackIdentifier = isChainAddressCombo ? assetOrChain.split(":").join(".UNKNOWN-") : assetOrChain;
182
-
183
- const { identifier: unsafeIdentifier, decimal: commonAssetDecimal } = getCommonAssetInfo(
184
- fallbackIdentifier as CommonAssetString,
185
- );
186
-
187
- const { chain, isSynthetic, isTradeAsset, address } = getAssetInfo(unsafeIdentifier);
188
- const { baseDecimal } = getChainConfig(chain);
189
-
190
- const token = staticTokensMap.get(
191
- CASE_SENSITIVE_CHAINS.includes(chain)
192
- ? (unsafeIdentifier as TokenNames)
193
- : (unsafeIdentifier.toUpperCase() as TokenNames),
194
- );
195
-
196
- if (!token && asyncTokenLookup && !isSynthetic && !isTradeAsset) {
197
- return (async () => {
198
- const { ticker } = assetFromString(unsafeIdentifier);
199
- const tokenData = await fetchTokenData({ address, chain, ticker });
200
- return createAssetValue({
201
- decimal: tokenData.decimals,
202
- identifier: tokenData.identifier,
203
- value: fromBaseDecimal ? safeValue(BigInt(parsedValue), fromBaseDecimal) : parsedValue,
204
- });
205
- })() as ConditionalAssetValueReturn<T>;
206
- }
207
-
208
- const tokenDecimal = token?.decimal || commonAssetDecimal;
209
-
210
- warnOnce({
211
- condition: !tokenDecimal && !asyncTokenLookup,
212
- id: `assetValue_static_decimal_not_found_${chain}`,
213
- warning: `Couldn't find static decimal for one or more tokens on ${chain} (Using default ${baseDecimal} decimal as fallback).
214
- This can result in incorrect calculations and mess with amount sent on transactions.
215
- You can load static assets by installing @swapkit/tokens package and calling AssetValue.loadStaticAssets()
216
- or by passing asyncTokenLookup: true to the from() function, which will make it async and return a promise.`,
217
- });
218
-
219
- const { decimal, identifier, tax } = token || {
220
- decimal: tokenDecimal || baseDecimal,
221
- identifier: unsafeIdentifier,
222
- };
223
-
224
- const adjustedValue = fromBaseDecimal
225
- ? safeValue(BigInt(parsedValue), fromBaseDecimal)
226
- : safeValue(parsedValue, decimal);
227
-
228
- const assetValue =
229
- isSynthetic || isTradeAsset
230
- ? createSyntheticAssetValue(identifier, adjustedValue)
231
- : createAssetValue({ decimal, identifier, tax, value: adjustedValue });
232
-
233
- return assetValue as ConditionalAssetValueReturn<T>;
234
- }
235
-
236
- static async loadStaticAssets(listNames?: TokenListName[]) {
237
- const { loadTokenLists } = await import("@swapkit/tokens");
238
- const lists = await loadTokenLists(listNames);
239
-
240
- for (const { tokens } of Object.values(lists)) {
241
- for (const { identifier, chain, ...rest } of tokens) {
242
- const chainConfig = getChainConfig(chain as Chain);
243
-
244
- const tokenKey = (
245
- CASE_SENSITIVE_CHAINS.includes(chainConfig.chain) ? identifier : identifier.toUpperCase()
246
- ) as TokenNames;
247
- const tokenDecimal = "decimals" in rest ? rest.decimals : chainConfig.baseDecimal;
248
-
249
- const tokenInfo = {
250
- decimal: tokenDecimal,
251
- identifier,
252
- logoURI: "logoURI" in rest ? (rest.logoURI as string) : undefined,
253
- tax: "tax" in rest ? (rest.tax as TokenTax) : undefined,
254
- };
255
-
256
- staticTokensMap.set(tokenKey, tokenInfo);
257
-
258
- // Also populate chain:address map for quick lookups
259
- if ("address" in rest && rest.address) {
260
- const lookupKey = CASE_SENSITIVE_CHAINS.includes(chainConfig.chain)
261
- ? `${chainConfig.chain}:${rest.address}`
262
- : `${chainConfig.chain}:${rest.address.toUpperCase()}`;
263
- chainAddressIdentifierMap.set(lookupKey, identifier);
264
- }
265
- }
266
- }
267
-
268
- return true;
269
- }
270
-
271
- static setStaticAssets(
272
- tokenMap: Map<
273
- string,
274
- { tax?: TokenTax; identifier: string; chain: Chain; address?: string } & (
275
- | { decimal: number }
276
- | { decimals: number }
277
- )
278
- >,
279
- ) {
280
- staticTokensMap.clear();
281
- chainAddressIdentifierMap.clear();
282
-
283
- for (const [key, value] of tokenMap.entries()) {
284
- const tokenKey = (
285
- CASE_SENSITIVE_CHAINS.includes(value.chain) ? value.identifier : value.identifier.toUpperCase()
286
- ) as TokenNames;
287
- const tokenDecimal = "decimals" in value ? value.decimals : value.decimal;
288
- const tokenInfo = { ...value, decimal: tokenDecimal, identifier: tokenKey };
289
-
290
- staticTokensMap.set(key, tokenInfo);
291
-
292
- if (value.address) {
293
- const lookupKey = CASE_SENSITIVE_CHAINS.includes(value.chain)
294
- ? `${value.chain}:${value.address}`
295
- : `${value.chain}:${value.address.toUpperCase()}`;
296
- chainAddressIdentifierMap.set(lookupKey, value.identifier);
297
- }
298
- }
299
- return true;
300
- }
301
-
302
- static get staticAssets() {
303
- return staticTokensMap;
304
- }
305
- }
306
-
307
- export function getMinAmountByChain(chain: Chain) {
308
- const asset = AssetValue.from({ chain });
309
-
310
- return match(chain)
311
- .with(Chain.Bitcoin, Chain.Litecoin, Chain.BitcoinCash, Chain.Dash, () => asset.set(0.00010001))
312
- .with(Chain.Dogecoin, () => asset.set(1.00000001))
313
- .with(Chain.Avalanche, Chain.Ethereum, Chain.Arbitrum, Chain.BinanceSmartChain, () => asset.set(0.00000001))
314
- .with(Chain.THORChain, Chain.Maya, () => asset.set(0))
315
- .with(Chain.Cosmos, Chain.Kujira, () => asset.set(0.000001))
316
- .otherwise(() => asset.set(0.00000001));
317
- }
318
-
319
- async function fetchTokenData({ chain, address, ticker }: { chain: Chain; address?: string; ticker?: string }) {
320
- const isCaseSensitiveChain = CASE_SENSITIVE_CHAINS.includes(chain);
321
-
322
- const cacheKey = isCaseSensitiveChain
323
- ? `${chain}:${address || ticker}`
324
- : `${chain}:${address || ticker}`.toUpperCase();
325
-
326
- const cached = getCachedTokenInfo(cacheKey);
327
- if (cached) {
328
- return cached;
329
- }
330
-
331
- if (!address) {
332
- const { baseDecimal } = getChainConfig(chain);
333
- return { decimals: baseDecimal, identifier: `${chain}.${ticker || "UNKNOWN"}` };
334
- }
335
-
336
- const tokenInfo = await fetchTokenInfo({ address, chain });
337
-
338
- const identifier = `${chain}.${tokenInfo.ticker || ticker || "UNKNOWN"}-${address}`;
339
-
340
- warnOnce({
341
- condition: !!(!tokenInfo.ticker && ticker),
342
- id: `async_token_lookup_failed_${chain}_${address}`,
343
- warning: `Could not fetch token metadata for ${chain}:${address} from chain. Using user-provided ticker (${ticker}) with baseDecimal (${tokenInfo.decimals}).`,
344
- });
345
-
346
- // only cache if we got a proper ticker back
347
- tokenInfo.ticker && setCachedTokenInfo(cacheKey, { decimals: tokenInfo.decimals, identifier });
348
-
349
- return { decimals: tokenInfo.decimals, identifier };
350
- }
351
-
352
- function createAssetValue({
353
- identifier,
354
- decimal,
355
- value,
356
- tax,
357
- }: {
358
- identifier: string;
359
- decimal: number;
360
- value: NumberPrimitives;
361
- tax?: TokenTax;
362
- }) {
363
- validateIdentifier(identifier);
364
- return new AssetValue({ decimal, identifier, tax, value: safeValue(value, decimal) });
365
- }
366
-
367
- function createSyntheticAssetValue(identifier: string, value: NumberPrimitives = 0) {
368
- const chain = identifier.includes(".") ? (identifier.split(".")?.[0]?.toUpperCase() as Chain) : undefined;
369
- const isMayaOrThor = chain ? TC_CHAINS.includes(chain) : false;
370
-
371
- const assetSeparator = identifier.slice(0, 14).includes("~") ? "~" : "/";
372
-
373
- const [synthChain, symbol] = isMayaOrThor
374
- ? identifier.split(".").slice(1).join().split(assetSeparator)
375
- : identifier.split(assetSeparator);
376
-
377
- if (!(synthChain && symbol)) {
378
- throw new SwapKitError({ errorKey: "helpers_invalid_asset_identifier", info: { identifier } });
379
- }
380
-
381
- return new AssetValue({
382
- decimal: 8,
383
- identifier: `${chain || Chain.THORChain}.${synthChain}${assetSeparator}${symbol}`,
384
- value: safeValue(value, 8),
385
- });
386
- }
387
-
388
- async function createAsyncAssetValue({
389
- address,
390
- chain,
391
- fromBaseDecimal,
392
- parsedValue,
393
- }: {
394
- address: string;
395
- chain: Chain;
396
- fromBaseDecimal?: number;
397
- parsedValue: NumberPrimitives;
398
- }): Promise<AssetValue> {
399
- const { decimals, identifier } = await fetchTokenData({ address, chain });
400
- const value = fromBaseDecimal ? safeValue(BigInt(parsedValue), fromBaseDecimal) : parsedValue;
401
- return createAssetValue({ decimal: decimals, identifier, value });
402
- }
403
-
404
- function safeValue(value: NumberPrimitives, decimal: number) {
405
- return typeof value === "bigint" ? formatBigIntToSafeValue({ bigIntDecimal: decimal, decimal, value }) : value;
406
- }
407
-
408
- function validateAssetChain(assetOrChain: AssetIdentifier) {
409
- const chain = match(assetOrChain)
410
- .when(
411
- (x): x is { chain: Chain } => "chain" in x && x.chain !== undefined,
412
- ({ chain }) => chain,
413
- )
414
- .otherwise((x) => {
415
- const assetInfo = assetFromString((x as { asset: string }).asset);
416
- return assetInfo.synth ? Chain.THORChain : assetInfo.chain;
417
- });
418
-
419
- // TODO: move to SKConfig chains once we support it throughout sdk
420
- if (!AllChains.includes(chain.toUpperCase() as Chain)) {
421
- throw new SwapKitError({
422
- errorKey: "helpers_invalid_asset_identifier",
423
- info: { message: "Please use the AssetValue constructor for unsupported chains" },
424
- });
425
- }
426
- }
427
-
428
- function getAssetString(assetOrChain: AssetIdentifier) {
429
- validateAssetChain(assetOrChain);
430
-
431
- if ("chain" in assetOrChain) {
432
- const { chain, address } = assetOrChain;
433
-
434
- if (address) {
435
- const lookupKey = CASE_SENSITIVE_CHAINS.includes(chain as Chain)
436
- ? `${chain}:${address}`
437
- : `${chain}:${address.toUpperCase()}`;
438
- const identifier = chainAddressIdentifierMap.get(lookupKey);
439
- if (identifier) return identifier;
440
- return lookupKey;
441
- }
442
-
443
- return chain;
444
- }
445
-
446
- const { chain, symbol } = assetFromString(assetOrChain.asset);
447
- const isNativeChain = getAssetType({ chain, symbol }) === "Native";
448
-
449
- return isNativeChain ? chain : assetOrChain.asset;
450
- }
451
-
452
- function getSyntheticOrTradeAssetInfo(identifier: string, isSynthetic: boolean, isTradeAsset: boolean) {
453
- const splitIdentifier = identifier.split(".");
454
- const identifierChain = splitIdentifier[0]?.toUpperCase() as Chain;
455
- const isThorOrMaya = TC_CHAINS.includes(identifierChain);
456
-
457
- const assetSeparator = isTradeAsset ? "~" : "/";
458
-
459
- const [synthChain, synthSymbol = ""] = isThorOrMaya
460
- ? splitIdentifier.slice(1).join(".").split(assetSeparator)
461
- : identifier.split(assetSeparator);
462
-
463
- if (!(synthChain && synthSymbol)) {
464
- throw new SwapKitError({ errorKey: "helpers_invalid_asset_identifier", info: { identifier } });
465
- }
466
-
467
- // Get the ticker from the base symbol (e.g., "AVAX" from "AVAX/AVAX")
468
- const { ticker, address } = getAssetBaseInfo({ chain: synthChain as Chain, symbol: synthSymbol });
469
- const finalSymbol = `${synthChain}${assetSeparator}${synthSymbol}`;
470
-
471
- return { address, chain: identifierChain, isGasAsset: false, isSynthetic, isTradeAsset, symbol: finalSymbol, ticker };
472
- }
473
-
474
- function getNormalAssetInfo(identifier: string) {
475
- const firstDotIndex = identifier.indexOf(".");
476
- const chain = (firstDotIndex === -1 ? identifier : identifier.slice(0, firstDotIndex)).toUpperCase() as Chain;
477
- const assetSymbol = firstDotIndex === -1 ? identifier : identifier.slice(firstDotIndex + 1);
478
-
479
- const { address, ticker } = getAssetBaseInfo({ chain, symbol: assetSymbol });
480
-
481
- let formattedAddress: string | undefined;
482
- try {
483
- formattedAddress =
484
- address && EVMChains.includes(chain as EVMChain) && getAddress(address) ? getAddress(address) : address;
485
- } catch {
486
- formattedAddress = address;
487
- }
488
-
489
- const finalSymbol = formattedAddress ? `${ticker}-${formattedAddress}` : assetSymbol;
490
-
491
- return {
492
- address: formattedAddress,
493
- chain,
494
- isGasAsset: isGasAsset({ chain, symbol: assetSymbol }),
495
- isSynthetic: false,
496
- isTradeAsset: false,
497
- symbol: finalSymbol,
498
- ticker,
499
- };
500
- }
501
-
502
- function getAssetInfo(identifier: string) {
503
- const shortIdentifier = identifier.slice(0, 14);
504
- const isSynthetic = shortIdentifier.includes("/");
505
- const isTradeAsset = shortIdentifier.includes("~");
506
-
507
- if (isSynthetic || isTradeAsset) {
508
- return getSyntheticOrTradeAssetInfo(identifier, isSynthetic, isTradeAsset);
509
- }
510
-
511
- return getNormalAssetInfo(identifier);
512
- }
513
-
514
- function parseSymbolWithSeparator(symbol: string, useFirst = false) {
515
- const dashIndex = useFirst ? symbol.indexOf("-") : symbol.lastIndexOf("-");
516
-
517
- if (dashIndex === -1) {
518
- return { address: undefined, ticker: symbol };
519
- }
520
-
521
- const ticker = symbol.slice(0, dashIndex);
522
- const address = symbol.slice(dashIndex + 1);
523
- return { address, ticker };
524
- }
525
-
526
- function getAssetBaseInfo({ symbol, chain }: { symbol: string; chain: Chain }) {
527
- const { ticker, address } = parseSymbolWithSeparator(symbol, chain === Chain.Near);
528
-
529
- const finalAddress = address && !CASE_SENSITIVE_CHAINS.includes(chain) ? address.toLowerCase() : address;
530
-
531
- return { address: finalAddress, ticker };
532
- }