@swapkit/helpers 4.5.9 → 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 (109) 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/requestClient.d.ts +1 -1
  28. package/dist/types/modules/requestClient.d.ts.map +1 -1
  29. package/dist/types/modules/swapKitConfig.d.ts +24 -78
  30. package/dist/types/modules/swapKitConfig.d.ts.map +1 -1
  31. package/dist/types/modules/swapKitError.d.ts +146 -14
  32. package/dist/types/modules/swapKitError.d.ts.map +1 -1
  33. package/dist/types/modules/widgetAuth.d.ts +6 -0
  34. package/dist/types/modules/widgetAuth.d.ts.map +1 -0
  35. package/dist/types/types/derivationPath.d.ts +1 -1
  36. package/dist/types/types/derivationPath.d.ts.map +1 -1
  37. package/dist/types/types/quotes.d.ts +2 -6
  38. package/dist/types/types/quotes.d.ts.map +1 -1
  39. package/dist/types/types/sdk.d.ts +6 -0
  40. package/dist/types/types/sdk.d.ts.map +1 -1
  41. package/dist/types/types/wallet.d.ts +12 -3
  42. package/dist/types/types/wallet.d.ts.map +1 -1
  43. package/dist/types/utils/asset.d.ts +17 -1
  44. package/dist/types/utils/asset.d.ts.map +1 -1
  45. package/dist/types/utils/chains.d.ts +5 -0
  46. package/dist/types/utils/chains.d.ts.map +1 -1
  47. package/dist/types/utils/derivationPath.d.ts +4 -2
  48. package/dist/types/utils/derivationPath.d.ts.map +1 -1
  49. package/dist/types/utils/wallets.d.ts +18 -2
  50. package/dist/types/utils/wallets.d.ts.map +1 -1
  51. package/package.json +12 -30
  52. package/dist/api/index.cjs.map +0 -14
  53. package/dist/api/index.js.map +0 -14
  54. package/dist/chunk-pfmeq01a.js +0 -5
  55. package/dist/chunk-pfmeq01a.js.map +0 -9
  56. package/dist/chunk-vb4wtm2w.js +0 -4
  57. package/dist/chunk-vb4wtm2w.js.map +0 -9
  58. package/dist/contracts.cjs.map +0 -10
  59. package/dist/contracts.js.map +0 -10
  60. package/dist/index.cjs.map +0 -30
  61. package/dist/index.js.map +0 -30
  62. package/dist/tokens.cjs.map +0 -10
  63. package/dist/tokens.js.map +0 -10
  64. package/src/api/index.ts +0 -9
  65. package/src/api/midgard/endpoints.ts +0 -348
  66. package/src/api/midgard/types.ts +0 -515
  67. package/src/api/swapkitApi/endpoints.ts +0 -247
  68. package/src/api/swapkitApi/types.ts +0 -624
  69. package/src/api/thornode/endpoints.ts +0 -105
  70. package/src/api/thornode/types.ts +0 -247
  71. package/src/contracts.ts +0 -1
  72. package/src/index.ts +0 -28
  73. package/src/modules/__tests__/assetValue.test.ts +0 -2452
  74. package/src/modules/__tests__/bigIntArithmetics.test.ts +0 -410
  75. package/src/modules/__tests__/feeMultiplier.test.ts +0 -125
  76. package/src/modules/__tests__/swapKitConfig.test.ts +0 -425
  77. package/src/modules/__tests__/swapKitNumber.test.ts +0 -435
  78. package/src/modules/assetValue.ts +0 -532
  79. package/src/modules/bigIntArithmetics.ts +0 -362
  80. package/src/modules/feeMultiplier.ts +0 -80
  81. package/src/modules/requestClient.ts +0 -110
  82. package/src/modules/swapKitConfig.ts +0 -174
  83. package/src/modules/swapKitError.ts +0 -470
  84. package/src/modules/swapKitNumber.ts +0 -13
  85. package/src/tokens.ts +0 -1
  86. package/src/types/commonTypes.ts +0 -10
  87. package/src/types/derivationPath.ts +0 -11
  88. package/src/types/errors/apiV1.ts +0 -0
  89. package/src/types/index.ts +0 -5
  90. package/src/types/quotes.ts +0 -174
  91. package/src/types/sdk.ts +0 -38
  92. package/src/types/wallet.ts +0 -124
  93. package/src/utils/__tests__/asset.test.ts +0 -186
  94. package/src/utils/__tests__/derivationPath.test.ts +0 -142
  95. package/src/utils/__tests__/explorerUrls.test.ts +0 -59
  96. package/src/utils/__tests__/liquidity.test.ts +0 -302
  97. package/src/utils/__tests__/memo.test.ts +0 -99
  98. package/src/utils/__tests__/others.test.ts +0 -165
  99. package/src/utils/__tests__/validators.test.ts +0 -84
  100. package/src/utils/__tests__/wallets.test.ts +0 -621
  101. package/src/utils/asset.ts +0 -399
  102. package/src/utils/chains.ts +0 -100
  103. package/src/utils/derivationPath.ts +0 -101
  104. package/src/utils/explorerUrls.ts +0 -32
  105. package/src/utils/liquidity.ts +0 -150
  106. package/src/utils/memo.ts +0 -102
  107. package/src/utils/others.ts +0 -62
  108. package/src/utils/validators.ts +0 -32
  109. 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
- }