@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,1892 +0,0 @@
1
- import { describe, expect, test } from "bun:test";
2
-
3
- import { Chain, getChainConfig } from "@swapkit/types";
4
- import { AssetValue, getMinAmountByChain } from "../assetValue";
5
-
6
- describe("AssetValue", () => {
7
- describe("creation", () => {
8
- test("regression cases", () => {
9
- const arbWeth = AssetValue.from({ asset: "ARB.WETH-0x82aF49447D8a07e3bd95BD0d56f35241523fBab1" });
10
- expect(arbWeth.toString()).toBe("ARB.WETH-0x82aF49447D8a07e3bd95BD0d56f35241523fBab1");
11
-
12
- const baseAssetFromString = AssetValue.from({ asset: "BASE.USDC-0x833589fcd6edb6e08f4c7c32d4f71b54bda02913" });
13
- expect(baseAssetFromString.toString()).toBe("BASE.USDC-0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913");
14
-
15
- const avaxSolanaAsset = AssetValue.from({ asset: "AVAX.SOL-0XFE6B19286885A4F7F55ADAD09C3CD1F906D2478F" });
16
- expect(avaxSolanaAsset.toString()).toBe("AVAX.SOL-0xFE6B19286885a4F7F55AdAD09C3Cd1f906D2478F");
17
- });
18
-
19
- test("returns asset ticker with value", () => {
20
- const fakeAvaxUSDCAsset = new AssetValue({
21
- chain: Chain.Avalanche,
22
- decimal: 6,
23
- symbol: "USDC-0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e",
24
- value: 1234567890,
25
- });
26
- expect(fakeAvaxUSDCAsset.toString()).toBe("AVAX.USDC-0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E");
27
-
28
- const ethSynth = new AssetValue({ chain: Chain.THORChain, decimal: 8, symbol: "ETH/ETH", value: 1234567890 });
29
-
30
- expect(ethSynth.toString()).toBe("ETH/ETH");
31
- expect(ethSynth.mul(21.37).getValue("string")).toBe("26382715809.3");
32
-
33
- const ethTrade = new AssetValue({ chain: Chain.THORChain, decimal: 8, symbol: "ETH~ETH", value: 1234567890 });
34
-
35
- expect(ethTrade.toString()).toBe("ETH~ETH");
36
- expect(ethTrade.mul(21.37).getValue("string")).toBe("26382715809.3");
37
-
38
- const ethThorTrade = new AssetValue({
39
- chain: Chain.THORChain,
40
- decimal: 8,
41
- symbol: "ETH~THOR-0xa5f2211b9b8170f694421f2046281775e8468044",
42
- value: 1234567890,
43
- });
44
-
45
- expect(ethThorTrade.toString()).toBe("ETH~THOR-0xa5f2211b9b8170f694421f2046281775e8468044");
46
- expect(ethThorTrade.chain).toBe(Chain.THORChain);
47
-
48
- const ethThorSynth = new AssetValue({
49
- chain: Chain.THORChain,
50
- decimal: 8,
51
- symbol: "ETH/THOR-0xa5f2211b9b8170f694421f2046281775e8468044",
52
- value: 1234567890,
53
- });
54
- expect(ethThorSynth.toString()).toBe("ETH/THOR-0xa5f2211b9b8170f694421f2046281775e8468044");
55
- expect(ethThorSynth.chain).toBe(Chain.THORChain);
56
-
57
- const mayaEthSynth = new AssetValue({ chain: Chain.Maya, decimal: 8, symbol: "ETH/ETH", value: 1234567890 });
58
- expect(mayaEthSynth.toString()).toBe("ETH/ETH");
59
- expect(mayaEthSynth.chain).toBe(Chain.Maya);
60
-
61
- const mayaEthSynthFrom = AssetValue.from({ asset: "MAYA.ETH/ETH", value: 12.3456789 });
62
- expect(mayaEthSynthFrom.toString()).toBe("ETH/ETH");
63
- expect(mayaEthSynthFrom.chain).toBe(Chain.Maya);
64
-
65
- const atomDerived = new AssetValue({ decimal: 6, identifier: "THOR.ATOM", value: 123456789 });
66
-
67
- expect(atomDerived.toString()).toBe("THOR.ATOM");
68
-
69
- const value = 10;
70
- const mayaCacao = AssetValue.from({ asset: "MAYA.CACAO", value });
71
-
72
- expect(mayaCacao.toString()).toBe("MAYA.CACAO");
73
- const expectedValue = value * 10_000_000_000;
74
- expect(mayaCacao.getBaseValue("string")).toBe(expectedValue.toString());
75
-
76
- const ethMayaSynth = AssetValue.from({ asset: "MAYA.ETH/ETH", value: 10 });
77
-
78
- expect(ethMayaSynth.toString()).toBe("ETH/ETH");
79
- expect(ethMayaSynth.toString({ includeSynthProtocol: true })).toBe("MAYA.ETH/ETH");
80
- expect(ethMayaSynth.getBaseValue("string")).toBe("1000000000");
81
-
82
- const ethTCSynthFallback = AssetValue.from({ asset: "ETH/ETH", value: 10 });
83
-
84
- expect(ethTCSynthFallback.toString()).toBe("ETH/ETH");
85
- expect(ethTCSynthFallback.toString({ includeSynthProtocol: true })).toBe("THOR.ETH/ETH");
86
- expect(ethTCSynthFallback.getBaseValue("string")).toBe("1000000000");
87
-
88
- const solFromString = AssetValue.from({ asset: "SOL.SOL" });
89
- expect(solFromString.toString()).toBe("SOL.SOL");
90
- });
91
-
92
- describe("NEAR", () => {
93
- test("NEAR token assets creation", () => {
94
- // Standard NEAR token formats
95
- const wNear = AssetValue.from({ asset: "NEAR.wNEAR-wrap.near" });
96
- expect(wNear.toString()).toBe("NEAR.wNEAR-wrap.near");
97
- expect(wNear).toMatchObject({
98
- address: "wrap.near",
99
- chain: Chain.Near,
100
- symbol: "wNEAR-wrap.near",
101
- ticker: "wNEAR",
102
- });
103
-
104
- const ethBridge = AssetValue.from({ asset: "NEAR.ETH-eth.bridge.near" });
105
- expect(ethBridge.toString()).toBe("NEAR.ETH-eth.bridge.near");
106
- expect(ethBridge).toMatchObject({
107
- address: "eth.bridge.near",
108
- chain: Chain.Near,
109
- symbol: "ETH-eth.bridge.near",
110
- ticker: "ETH",
111
- });
112
- const usdc = AssetValue.from({
113
- asset: "NEAR.USDC-17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1",
114
- });
115
- expect(usdc.toString()).toBe("NEAR.USDC-17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1");
116
- expect(usdc).toMatchObject({
117
- address: "17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1",
118
- chain: Chain.Near,
119
- symbol: "USDC-17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1",
120
- ticker: "USDC",
121
- });
122
-
123
- const usdt = AssetValue.from({ asset: "NEAR.USDT-usdt.tether-token.near" });
124
- expect(usdt.toString()).toBe("NEAR.USDT-usdt.tether-token.near");
125
- expect(usdt).toMatchObject({
126
- address: "usdt.tether-token.near",
127
- chain: Chain.Near,
128
- symbol: "USDT-usdt.tether-token.near",
129
- ticker: "USDT",
130
- });
131
-
132
- // Factory bridge format
133
- const frax = AssetValue.from({
134
- asset: "NEAR.FRAX-853d955acef822db058eb8505911ed77f175b99e.factory.bridge.near",
135
- });
136
- expect(frax.toString()).toBe("NEAR.FRAX-853d955acef822db058eb8505911ed77f175b99e.factory.bridge.near");
137
- expect(frax).toMatchObject({
138
- address: "853d955acef822db058eb8505911ed77f175b99e.factory.bridge.near",
139
- chain: Chain.Near,
140
- symbol: "FRAX-853d955acef822db058eb8505911ed77f175b99e.factory.bridge.near",
141
- ticker: "FRAX",
142
- });
143
-
144
- const aurora = AssetValue.from({
145
- asset: "NEAR.AURORA-aaaaaa20d9e0e2461697782ef11675f668207961.factory.bridge.near",
146
- });
147
- expect(aurora.toString()).toBe("NEAR.AURORA-aaaaaa20d9e0e2461697782ef11675f668207961.factory.bridge.near");
148
- expect(aurora).toMatchObject({
149
- address: "aaaaaa20d9e0e2461697782ef11675f668207961.factory.bridge.near",
150
- chain: Chain.Near,
151
- symbol: "AURORA-aaaaaa20d9e0e2461697782ef11675f668207961.factory.bridge.near",
152
- ticker: "AURORA",
153
- });
154
-
155
- const wBTC = AssetValue.from({
156
- asset: "NEAR.wBTC-2260fac5e5542a773aa44fbcfedf7c193bc2c599.factory.bridge.near",
157
- });
158
- expect(wBTC.toString()).toBe("NEAR.wBTC-2260fac5e5542a773aa44fbcfedf7c193bc2c599.factory.bridge.near");
159
- expect(wBTC).toMatchObject({
160
- address: "2260fac5e5542a773aa44fbcfedf7c193bc2c599.factory.bridge.near",
161
- chain: Chain.Near,
162
- symbol: "wBTC-2260fac5e5542a773aa44fbcfedf7c193bc2c599.factory.bridge.near",
163
- ticker: "wBTC",
164
- });
165
-
166
- const blackdragon = AssetValue.from({ asset: "NEAR.BLACKDRAGON-blackdragon.tkn.near" });
167
- expect(blackdragon.toString()).toBe("NEAR.BLACKDRAGON-blackdragon.tkn.near");
168
- expect(blackdragon).toMatchObject({
169
- address: "blackdragon.tkn.near",
170
- chain: Chain.Near,
171
- symbol: "BLACKDRAGON-blackdragon.tkn.near",
172
- ticker: "BLACKDRAGON",
173
- });
174
-
175
- const shitzu = AssetValue.from({ asset: "NEAR.SHITZU-token.0xshitzu.near" });
176
- expect(shitzu.toString()).toBe("NEAR.SHITZU-token.0xshitzu.near");
177
- expect(shitzu).toMatchObject({
178
- address: "token.0xshitzu.near",
179
- chain: Chain.Near,
180
- symbol: "SHITZU-token.0xshitzu.near",
181
- ticker: "SHITZU",
182
- });
183
-
184
- const abg = AssetValue.from({ asset: "NEAR.ABG-abg-966.meme-cooking.near" });
185
- expect(abg.toString()).toBe("NEAR.ABG-abg-966.meme-cooking.near");
186
- expect(abg).toMatchObject({
187
- address: "abg-966.meme-cooking.near",
188
- chain: Chain.Near,
189
- symbol: "ABG-abg-966.meme-cooking.near",
190
- ticker: "ABG",
191
- });
192
- const noear = AssetValue.from({ asset: "NEAR.NOEAR-noear-324.meme-cooking.near" });
193
- expect(noear.toString()).toBe("NEAR.NOEAR-noear-324.meme-cooking.near");
194
- expect(noear).toMatchObject({
195
- address: "noear-324.meme-cooking.near",
196
- chain: Chain.Near,
197
- symbol: "NOEAR-noear-324.meme-cooking.near",
198
- ticker: "NOEAR",
199
- });
200
-
201
- const jambo = AssetValue.from({ asset: "NEAR.JAMBO-jambo-1679.meme-cooking.near" });
202
- expect(jambo.toString()).toBe("NEAR.JAMBO-jambo-1679.meme-cooking.near");
203
- expect(jambo).toMatchObject({
204
- address: "jambo-1679.meme-cooking.near",
205
- chain: Chain.Near,
206
- symbol: "JAMBO-jambo-1679.meme-cooking.near",
207
- ticker: "JAMBO",
208
- });
209
-
210
- const gnear = AssetValue.from({ asset: "NEAR.GNEAR-gnear-229.meme-cooking.near" });
211
- expect(gnear.toString()).toBe("NEAR.GNEAR-gnear-229.meme-cooking.near");
212
- expect(gnear).toMatchObject({
213
- address: "gnear-229.meme-cooking.near",
214
- chain: Chain.Near,
215
- symbol: "GNEAR-gnear-229.meme-cooking.near",
216
- ticker: "GNEAR",
217
- });
218
-
219
- const purge = AssetValue.from({ asset: "NEAR.PURGE-purge-558.meme-cooking.near" });
220
- expect(purge.toString()).toBe("NEAR.PURGE-purge-558.meme-cooking.near");
221
- expect(purge).toMatchObject({
222
- address: "purge-558.meme-cooking.near",
223
- chain: Chain.Near,
224
- symbol: "PURGE-purge-558.meme-cooking.near",
225
- ticker: "PURGE",
226
- });
227
-
228
- // Various token formats
229
- const mpDAO = AssetValue.from({ asset: "NEAR.mpDAO-mpdao-token.near" });
230
- expect(mpDAO.toString()).toBe("NEAR.mpDAO-mpdao-token.near");
231
- expect(mpDAO).toMatchObject({
232
- address: "mpdao-token.near",
233
- chain: Chain.Near,
234
- symbol: "mpDAO-mpdao-token.near",
235
- ticker: "mpDAO",
236
- });
237
-
238
- const nearKat = AssetValue.from({ asset: "NEAR.NearKat-kat.token0.near" });
239
- expect(nearKat.toString()).toBe("NEAR.NearKat-kat.token0.near");
240
- expect(nearKat).toMatchObject({
241
- address: "kat.token0.near",
242
- chain: Chain.Near,
243
- symbol: "NearKat-kat.token0.near",
244
- ticker: "NearKat",
245
- });
246
-
247
- const testNebula = AssetValue.from({ asset: "NEAR.TESTNEBULA-test-token.highdome3013.near" });
248
- expect(testNebula.toString()).toBe("NEAR.TESTNEBULA-test-token.highdome3013.near");
249
- expect(testNebula).toMatchObject({
250
- address: "test-token.highdome3013.near",
251
- chain: Chain.Near,
252
- symbol: "TESTNEBULA-test-token.highdome3013.near",
253
- ticker: "TESTNEBULA",
254
- });
255
-
256
- const sweat = AssetValue.from({ asset: "NEAR.SWEAT-token.sweat" });
257
- expect(sweat.toString()).toBe("NEAR.SWEAT-token.sweat");
258
- expect(sweat).toMatchObject({
259
- address: "token.sweat",
260
- chain: Chain.Near,
261
- symbol: "SWEAT-token.sweat",
262
- ticker: "SWEAT",
263
- });
264
- const rhea = AssetValue.from({ asset: "NEAR.RHEA-token.rhealab.near" });
265
- expect(rhea.toString()).toBe("NEAR.RHEA-token.rhealab.near");
266
- expect(rhea).toMatchObject({
267
- address: "token.rhealab.near",
268
- chain: Chain.Near,
269
- symbol: "RHEA-token.rhealab.near",
270
- ticker: "RHEA",
271
- });
272
-
273
- const publicToken = AssetValue.from({ asset: "NEAR.PUBLIC-token.publicailab.near" });
274
- expect(publicToken.toString()).toBe("NEAR.PUBLIC-token.publicailab.near");
275
- expect(publicToken).toMatchObject({
276
- address: "token.publicailab.near",
277
- chain: Chain.Near,
278
- symbol: "PUBLIC-token.publicailab.near",
279
- ticker: "PUBLIC",
280
- });
281
-
282
- const hapi = AssetValue.from({
283
- asset: "NEAR.HAPI-d9c2d319cd7e6177336b0a9c93c21cb48d84fb54.factory.bridge.near",
284
- });
285
- expect(hapi.toString()).toBe("NEAR.HAPI-d9c2d319cd7e6177336b0a9c93c21cb48d84fb54.factory.bridge.near");
286
- expect(hapi).toMatchObject({
287
- address: "d9c2d319cd7e6177336b0a9c93c21cb48d84fb54.factory.bridge.near",
288
- chain: Chain.Near,
289
- symbol: "HAPI-d9c2d319cd7e6177336b0a9c93c21cb48d84fb54.factory.bridge.near",
290
- ticker: "HAPI",
291
- });
292
-
293
- const btc = AssetValue.from({ asset: "NEAR.BTC-nbtc.bridge.near" });
294
- expect(btc.toString()).toBe("NEAR.BTC-nbtc.bridge.near");
295
- expect(btc).toMatchObject({
296
- address: "nbtc.bridge.near",
297
- chain: Chain.Near,
298
- symbol: "BTC-nbtc.bridge.near",
299
- ticker: "BTC",
300
- });
301
-
302
- const turbo = AssetValue.from({
303
- asset: "NEAR.TURBO-a35923162c49cf95e6bf26623385eb431ad920d3.factory.bridge.near",
304
- });
305
- expect(turbo.toString()).toBe("NEAR.TURBO-a35923162c49cf95e6bf26623385eb431ad920d3.factory.bridge.near");
306
- expect(turbo).toMatchObject({
307
- address: "a35923162c49cf95e6bf26623385eb431ad920d3.factory.bridge.near",
308
- chain: Chain.Near,
309
- symbol: "TURBO-a35923162c49cf95e6bf26623385eb431ad920d3.factory.bridge.near",
310
- ticker: "TURBO",
311
- });
312
-
313
- const near = AssetValue.from({ asset: "NEAR.NEAR" });
314
- expect(near.toString()).toBe("NEAR.NEAR");
315
- expect(near).toMatchObject({ address: undefined, chain: Chain.Near, symbol: "NEAR", ticker: "NEAR" });
316
- });
317
-
318
- test("assets with values", () => {
319
- const wNearWithValue = AssetValue.from({ asset: "NEAR.wNEAR-wrap.near", value: 10.5 });
320
- expect(wNearWithValue.toString()).toBe("NEAR.wNEAR-wrap.near");
321
- expect(wNearWithValue.getValue("string")).toBe("10.5");
322
- expect(wNearWithValue.chain).toBe(Chain.Near);
323
-
324
- const usdcWithValue = AssetValue.from({
325
- asset: "NEAR.USDC-17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1",
326
- value: 1000.123456,
327
- });
328
- expect(usdcWithValue.toString()).toBe(
329
- "NEAR.USDC-17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1",
330
- );
331
- expect(usdcWithValue.getValue("string")).toBe("1000.123456");
332
- expect(usdcWithValue.chain).toBe(Chain.Near);
333
-
334
- const nearWithValue = AssetValue.from({ asset: "NEAR.NEAR", value: 0.000001 });
335
- expect(nearWithValue.toString()).toBe("NEAR.NEAR");
336
- expect(nearWithValue.getValue("string")).toBe("0.000001");
337
- expect(nearWithValue.chain).toBe(Chain.Near);
338
- });
339
- });
340
-
341
- describe("SUI", () => {
342
- test("SUI native asset creation", () => {
343
- const sui = AssetValue.from({ asset: "SUI.SUI" });
344
- expect(sui.toString()).toBe("SUI.SUI");
345
- expect(sui).toMatchObject({ address: undefined, chain: Chain.Sui, symbol: "SUI", ticker: "SUI" });
346
- });
347
-
348
- test("custom token assets creation", () => {
349
- const suiUsdc = AssetValue.from({
350
- asset: "SUI.USDC-0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC",
351
- });
352
- expect(suiUsdc.toString()).toBe(
353
- "SUI.USDC-0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC",
354
- );
355
- expect(suiUsdc).toMatchObject({
356
- address: "0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC",
357
- chain: Chain.Sui,
358
- symbol: "USDC-0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC",
359
- ticker: "USDC",
360
- });
361
- });
362
- });
363
- });
364
- });
365
-
366
- describe("set", () => {
367
- test("get a copy of an assetValue with a new value", () => {
368
- const btc = AssetValue.from({ asset: "BTC.BTC" });
369
-
370
- const btc2 = btc.set(10);
371
-
372
- expect(btc2).toEqual(
373
- expect.objectContaining({
374
- chain: Chain.Bitcoin,
375
- decimal: 8,
376
- isGasAsset: true,
377
- isSynthetic: false,
378
- symbol: "BTC",
379
- ticker: "BTC",
380
- }),
381
- );
382
-
383
- expect(btc.getValue("string")).toBe("0");
384
- expect(btc2.getValue("string")).toBe("10");
385
- });
386
-
387
- test("get a copy of a synth assetValue with a new value", () => {
388
- const synthAvax = AssetValue.from({ asset: "THOR.AVAX/AVAX", value: 1 });
389
-
390
- const synthAvax2 = synthAvax.set(10);
391
-
392
- expect(synthAvax2).toBeDefined();
393
- expect(synthAvax2).toEqual(
394
- expect.objectContaining({
395
- chain: Chain.THORChain,
396
- decimal: 8,
397
- isGasAsset: false,
398
- isSynthetic: true,
399
- symbol: "AVAX/AVAX",
400
- ticker: "AVAX",
401
- }),
402
- );
403
-
404
- expect(synthAvax.getValue("string")).toBe("1");
405
- expect(synthAvax2.getValue("string")).toBe("10");
406
- expect(synthAvax.toString({ includeSynthProtocol: true })).toBe("THOR.AVAX/AVAX");
407
- expect(synthAvax2.toString({ includeSynthProtocol: true })).toBe("THOR.AVAX/AVAX");
408
- });
409
- });
410
-
411
- describe("toUrl", () => {
412
- test("returns asset compliance with url", () => {
413
- const fakeAvaxUSDCAsset = new AssetValue({
414
- chain: Chain.Avalanche,
415
- decimal: 6,
416
- symbol: "USDC-0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e",
417
- value: 1234567890,
418
- });
419
- expect(fakeAvaxUSDCAsset.toUrl()).toBe("AVAX.USDC-0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E");
420
-
421
- const thor = AssetValue.from({ asset: "ETH.THOR" });
422
- expect(thor.toUrl()).toBe("ETH.THOR-0xa5f2211B9b8170F694421f2046281775E8468044");
423
-
424
- const ethSynth = new AssetValue({ chain: Chain.THORChain, decimal: 8, symbol: "ETH/ETH", value: 1234567890 });
425
- expect(ethSynth.toUrl()).toBe("THOR.ETH.ETH");
426
-
427
- const ethThorSynth = new AssetValue({
428
- chain: Chain.THORChain,
429
- decimal: 8,
430
- symbol: "ETH/THOR-0xa5f2211b9b8170f694421f2046281775e8468044",
431
- value: 1234567890,
432
- });
433
- expect(ethThorSynth.toUrl()).toBe("THOR.ETH.THOR-0xa5f2211b9b8170f694421f2046281775e8468044");
434
-
435
- const ethThorTrade = new AssetValue({
436
- chain: Chain.THORChain,
437
- decimal: 8,
438
- symbol: "ETH~THOR-0xa5f2211b9b8170f694421f2046281775e8468044",
439
- value: 1234567890,
440
- });
441
- expect(ethThorTrade.toUrl()).toBe("THOR.ETH..THOR-0xa5f2211b9b8170f694421f2046281775e8468044");
442
- });
443
- });
444
-
445
- describe("eq", () => {
446
- test("checks if assets are same chain and symbol", () => {
447
- const firstThor = AssetValue.from({ asset: "ETH.THOR" });
448
- const secondThor = AssetValue.from({ asset: "ETH.THOR" });
449
- const vThor = AssetValue.from({ asset: "ETH.vTHOR" });
450
- const firstUsdc = new AssetValue({
451
- chain: Chain.Avalanche,
452
- decimal: 6,
453
- symbol: "USDC-0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e",
454
- value: 1234567890,
455
- });
456
- const secondUsdc = new AssetValue({
457
- chain: Chain.Avalanche,
458
- decimal: 6,
459
- symbol: "USDC-0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e",
460
- value: 1234,
461
- });
462
-
463
- expect(firstThor.eqAsset(firstThor)).toBe(true);
464
- expect(firstThor.eqAsset(secondThor)).toBe(true);
465
- expect(firstThor.eqAsset(vThor)).toBe(false);
466
- expect(firstThor.eqAsset(firstUsdc)).toBe(false);
467
- expect(firstThor.eqAsset(secondUsdc)).toBe(false);
468
-
469
- expect(firstUsdc.eqAsset(firstThor)).toBe(false);
470
- expect(firstUsdc.eqAsset(secondThor)).toBe(false);
471
- expect(firstUsdc.eqAsset(vThor)).toBe(false);
472
- expect(firstUsdc.eqAsset(firstUsdc)).toBe(true);
473
- expect(firstUsdc.eqAsset(secondUsdc)).toBe(true);
474
- });
475
-
476
- test("check if assets have same value, even if not same asset", () => {
477
- const firstThor = AssetValue.from({ asset: "ETH.THOR", value: "20" });
478
- const secondThor = AssetValue.from({ asset: "ETH.THOR", value: "35" });
479
- const thirdThor = AssetValue.from({ asset: "ETH.THOR", value: "35" });
480
- const vThor = AssetValue.from({ asset: "ETH.vTHOR", value: "20" });
481
-
482
- expect(firstThor.eqValue(firstThor)).toBe(true);
483
- expect(firstThor.eqValue(secondThor)).toBe(false);
484
- expect(secondThor.eqValue(thirdThor)).toBe(true);
485
- expect(firstThor.eqValue(vThor)).toBe(true);
486
- });
487
-
488
- test("check if assets have identical asset and value", () => {
489
- const firstThor = AssetValue.from({ asset: "ETH.THOR", value: "20" });
490
- const secondThor = AssetValue.from({ asset: "ETH.THOR", value: "35" });
491
- const thirdThor = AssetValue.from({ asset: "ETH.THOR", value: "35" });
492
- const vThor = AssetValue.from({ asset: "ETH.vTHOR", value: "20" });
493
-
494
- expect(firstThor.eq(firstThor)).toBe(true);
495
- expect(firstThor.eq(secondThor)).toBe(false);
496
- expect(secondThor.eq(thirdThor)).toBe(true);
497
- expect(firstThor.eq(vThor)).toBe(false);
498
- });
499
- });
500
-
501
- describe("from bigint", () => {
502
- test("returns asset value with correct decimal", async () => {
503
- const avaxUSDCAsset = await AssetValue.from({
504
- asset: `${Chain.Avalanche}.USDC-0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e`,
505
- asyncTokenLookup: true,
506
- value: 1234567800n,
507
- });
508
- expect(avaxUSDCAsset.getValue("string")).toBe("1234.5678");
509
- });
510
- });
511
-
512
- describe("toString", () => {
513
- test("returns asset value string/identifier", async () => {
514
- const avaxUSDCAsset = new AssetValue({
515
- chain: Chain.Avalanche,
516
- decimal: 6,
517
- symbol: "USDC-0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e",
518
- value: 1234567890,
519
- });
520
- expect(avaxUSDCAsset.toString()).toBe("AVAX.USDC-0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E");
521
-
522
- const thor = AssetValue.from({ asset: "ETH.THOR" });
523
- expect(thor.toString()).toBe("ETH.THOR-0xa5f2211B9b8170F694421f2046281775E8468044");
524
-
525
- const ethSynth = await AssetValue.from({ asset: "ETH/ETH", asyncTokenLookup: true });
526
- expect(ethSynth.toString()).toBe("ETH/ETH");
527
-
528
- const eth = await AssetValue.from({ asset: "eth.eth" });
529
- expect(eth.toString()).toBe("ETH.ETH");
530
-
531
- const ethFromChain = await AssetValue.from({ chain: Chain.Ethereum });
532
- expect(ethFromChain.toString()).toBe("ETH.ETH");
533
- });
534
- });
535
-
536
- describe("fromIdentifier", () => {
537
- test("creates AssetValue from known token identifier", async () => {
538
- const avaxUSDCAsset = await AssetValue.from({
539
- asset: "AVAX.USDC-0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e",
540
- asyncTokenLookup: true,
541
- });
542
-
543
- expect(avaxUSDCAsset).toEqual(
544
- expect.objectContaining({
545
- address: "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
546
- chain: Chain.Avalanche,
547
- decimal: 6,
548
- isGasAsset: false,
549
- isSynthetic: false,
550
- symbol: "USDC-0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
551
- ticker: "USDC",
552
- }),
553
- );
554
- });
555
-
556
- test("creates AssetValue from identifier with multiple dashes", async () => {
557
- const ethPendleLptAsset = await AssetValue.from({ asset: "ETH.PENDLE-LPT-0x1234", asyncTokenLookup: true });
558
-
559
- expect(ethPendleLptAsset).toEqual(
560
- expect.objectContaining({
561
- address: "0x1234",
562
- chain: Chain.Ethereum,
563
- decimal: 18,
564
- isGasAsset: false,
565
- isSynthetic: false,
566
- symbol: "PENDLE-LPT-0x1234",
567
- ticker: "PENDLE-LPT",
568
- }),
569
- );
570
- });
571
- });
572
-
573
- describe("fromString", () => {
574
- test("creates AssetValue from unknown token string", async () => {
575
- const fakeAvaxAssetString = "AVAX.ASDF-1234";
576
- const fakeAvaxAsset = await AssetValue.from({ asset: fakeAvaxAssetString, asyncTokenLookup: true });
577
-
578
- expect(fakeAvaxAsset).toEqual(
579
- expect.objectContaining({
580
- address: "1234",
581
- chain: Chain.Avalanche,
582
- decimal: 18,
583
- isGasAsset: false,
584
- isSynthetic: false,
585
- symbol: "ASDF-1234",
586
- ticker: "ASDF",
587
- }),
588
- );
589
- });
590
-
591
- test("creates AssetValue from unknown token string with multiple dashes", async () => {
592
- const fakeAvaxAssetString = "AVAX.ASDF-LP-1234";
593
- const fakeAvaxAsset = await AssetValue.from({ asset: fakeAvaxAssetString, asyncTokenLookup: true });
594
-
595
- expect(fakeAvaxAsset).toEqual(
596
- expect.objectContaining({
597
- address: "1234",
598
- chain: Chain.Avalanche,
599
- decimal: 18,
600
- isGasAsset: false,
601
- isSynthetic: false,
602
- symbol: "ASDF-LP-1234",
603
- ticker: "ASDF-LP",
604
- }),
605
- );
606
- });
607
-
608
- test("creates AssetValue with _ symbol", async () => {
609
- const radixXWBTC = await AssetValue.from({
610
- asset: "XRD.XWBTC-resource_rdx1t580qxc7upat7lww4l2c4jckacafjeudxj5wpjrrct0p3e82sq4y75",
611
- asyncTokenLookup: true,
612
- });
613
-
614
- expect(radixXWBTC).toEqual(
615
- expect.objectContaining({
616
- address: "resource_rdx1t580qxc7upat7lww4l2c4jckacafjeudxj5wpjrrct0p3e82sq4y75",
617
- chain: Chain.Radix,
618
- // TODO: Failed to fetch Radix asset decimals for resource_rdx1t580qxc7upat7lww4l2c4jckacafjeudxj5wpjrrct0p3e82sq4y75: helpers_invalid_response: {"status":404,"statusText":"Not Found"}
619
- // decimal: 8,
620
- isGasAsset: false,
621
- isSynthetic: false,
622
- symbol: "xwBTC-resource_rdx1t580qxc7upat7lww4l2c4jckacafjeudxj5wpjrrct0p3e82sq4y75",
623
- ticker: "xwBTC",
624
- }),
625
- );
626
- });
627
- });
628
-
629
- describe("fromStringWithBase", () => {
630
- test("creates AssetValue from string with base", async () => {
631
- const fakeAvaxAssetString = "AVAX.ASDF-1234";
632
- const fakeAvaxAsset = await AssetValue.from({
633
- asset: fakeAvaxAssetString,
634
- asyncTokenLookup: true,
635
- fromBaseDecimal: 8,
636
- value: 1,
637
- });
638
-
639
- expect(fakeAvaxAsset).toEqual(
640
- expect.objectContaining({
641
- address: "1234",
642
- chain: Chain.Avalanche,
643
- decimal: 18,
644
- isGasAsset: false,
645
- isSynthetic: false,
646
- symbol: "ASDF-1234",
647
- ticker: "ASDF",
648
- }),
649
- );
650
- expect(fakeAvaxAsset.getValue("string")).toBe("0.00000001");
651
- expect(fakeAvaxAsset.getBaseValue("string")).toBe("10000000000");
652
- });
653
- });
654
-
655
- describe("fromUrl", () => {
656
- test("creates AssetValue from url like format", () => {
657
- const synthETHString = "THOR.ETH.ETH";
658
- const ethString = "ETH.ETH";
659
- const thorString = "ETH.THOR-0xa5f2211b9b8170f694421f2046281775e8468044";
660
- const synthThorString = "THOR.ETH.THOR-0xa5f2211b9b8170f694421f2046281775e8468044";
661
- const synthDashesString = "THOR.ETH.PENDLE-LPT-0x1234";
662
-
663
- const synthETH = AssetValue.fromUrl(synthETHString);
664
- const eth = AssetValue.fromUrl(ethString);
665
- const thor = AssetValue.fromUrl(thorString);
666
- const synthThor = AssetValue.fromUrl(synthThorString);
667
- const synthDashes = AssetValue.fromUrl(synthDashesString);
668
-
669
- expect(synthETH.toString()).toBe("ETH/ETH");
670
- expect(eth.toString()).toBe("ETH.ETH");
671
- expect(thor.toString()).toBe("ETH.THOR-0xa5f2211B9b8170F694421f2046281775E8468044");
672
- expect(synthThor.toString()).toBe("ETH/THOR-0xa5f2211b9b8170f694421f2046281775e8468044");
673
- expect(synthDashes.toString()).toBe("ETH/PENDLE-LPT-0x1234");
674
- });
675
-
676
- test("fromUrl and toUrl roundtrip for all chains", () => {
677
- // Native gas assets
678
- const testCases = [
679
- // EVM chains
680
- { asset: "ETH.ETH", url: "ETH.ETH" },
681
- { asset: "AVAX.AVAX", url: "AVAX.AVAX" },
682
- { asset: "BSC.BNB", url: "BSC.BNB" },
683
- { asset: "ARB.ETH", url: "ARB.ETH" },
684
- { asset: "OP.ETH", url: "OP.ETH" },
685
- { asset: "POL.POL", url: "POL.POL" },
686
- { asset: "BASE.ETH", url: "BASE.ETH" },
687
- { asset: "GNO.XDAI", url: "GNO.XDAI" }, // Gnosis uses XDAI in URLs
688
- { asset: "AURORA.ETH", url: "AURORA.ETH" },
689
- { asset: "BERA.BERA", url: "BERA.BERA" },
690
-
691
- // UTXO chains
692
- { asset: "BTC.BTC", url: "BTC.BTC" },
693
- { asset: "BCH.BCH", url: "BCH.BCH" },
694
- { asset: "LTC.LTC", url: "LTC.LTC" },
695
- { asset: "DOGE.DOGE", url: "DOGE.DOGE" },
696
- { asset: "DASH.DASH", url: "DASH.DASH" },
697
- { asset: "ZEC.ZEC", url: "ZEC.ZEC" },
698
-
699
- // Cosmos chains
700
- { asset: "THOR.RUNE", url: "THOR.RUNE" },
701
- { asset: "MAYA.CACAO", url: "MAYA.CACAO" },
702
- { asset: "GAIA.ATOM", url: "GAIA.ATOM" },
703
- { asset: "KUJI.KUJI", url: "KUJI.KUJI" },
704
- { asset: "NOBLE.USDC", url: "NOBLE.USDC" },
705
-
706
- // Other chains
707
- { asset: "SOL.SOL", url: "SOL.SOL" },
708
- { asset: "TRON.TRX", url: "TRON.TRX" },
709
- { asset: "XRD.XRD", url: "XRD.XRD" },
710
- { asset: "XRP.XRP", url: "XRP.XRP" },
711
- { asset: "DOT.DOT", url: "DOT.DOT" },
712
- { asset: "FLIP.FLIP", url: "FLIP.FLIP" },
713
- { asset: "NEAR.NEAR", url: "NEAR.NEAR" },
714
-
715
- // Tokens with addresses
716
- {
717
- asset: "ETH.USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
718
- url: "ETH.USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
719
- },
720
- {
721
- asset: "BSC.USDT-0x55d398326f99059fF775485246999027B3197955",
722
- url: "BSC.USDT-0x55d398326f99059fF775485246999027B3197955",
723
- },
724
- {
725
- asset: "AVAX.USDC.e-0xA7D7079b0FEaD91F3e65f86E8915Cb59c1a4C664",
726
- url: "AVAX.USDC__e-0xA7D7079b0FEaD91F3e65f86E8915Cb59c1a4C664",
727
- },
728
- {
729
- asset: "ARB.WETH-0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
730
- url: "ARB.WETH-0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
731
- },
732
- {
733
- asset: "POL.USDC-0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
734
- url: "POL.USDC-0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
735
- },
736
- {
737
- asset: "BASE.USDC-0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
738
- url: "BASE.USDC-0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
739
- },
740
-
741
- // Near tokens - dots are encoded as __
742
- { asset: "NEAR.wNEAR-wrap.near", url: "NEAR.wNEAR-wrap__near" },
743
- { asset: "NEAR.ETH-eth.bridge.near", url: "NEAR.ETH-eth__bridge__near" },
744
- { asset: "NEAR.USDT-usdt.tether-token.near", url: "NEAR.USDT-usdt__tether-token__near" },
745
- { asset: "NEAR.BLACKDRAGON-blackdragon.tkn.near", url: "NEAR.BLACKDRAGON-blackdragon__tkn__near" },
746
- { asset: "NEAR.SHITZU-token.0xshitzu.near", url: "NEAR.SHITZU-token__0xshitzu__near" },
747
- { asset: "NEAR.BTC-nbtc.bridge.near", url: "NEAR.BTC-nbtc__bridge__near" },
748
- {
749
- asset: "NEAR.AURORA-aaaaaa20d9e0e2461697782ef11675f668207961.factory.bridge.near",
750
- url: "NEAR.AURORA-aaaaaa20d9e0e2461697782ef11675f668207961__factory__bridge__near",
751
- },
752
- {
753
- asset: "NEAR.FRAX-853d955acef822db058eb8505911ed77f175b99e.factory.bridge.near",
754
- url: "NEAR.FRAX-853d955acef822db058eb8505911ed77f175b99e__factory__bridge__near",
755
- },
756
- {
757
- asset: "NEAR.wBTC-2260fac5e5542a773aa44fbcfedf7c193bc2c599.factory.bridge.near",
758
- url: "NEAR.wBTC-2260fac5e5542a773aa44fbcfedf7c193bc2c599__factory__bridge__near",
759
- },
760
- {
761
- asset: "NEAR.HAPI-d9c2d319cd7e6177336b0a9c93c21cb48d84fb54.factory.bridge.near",
762
- url: "NEAR.HAPI-d9c2d319cd7e6177336b0a9c93c21cb48d84fb54__factory__bridge__near",
763
- },
764
- { asset: "NEAR.PURGE-purge-558.meme-cooking.near", url: "NEAR.PURGE-purge-558__meme-cooking__near" },
765
- { asset: "NEAR.ABG-abg-966.meme-cooking.near", url: "NEAR.ABG-abg-966__meme-cooking__near" },
766
- { asset: "NEAR.NOEAR-noear-324.meme-cooking.near", url: "NEAR.NOEAR-noear-324__meme-cooking__near" },
767
- { asset: "NEAR.JAMBO-jambo-1679.meme-cooking.near", url: "NEAR.JAMBO-jambo-1679__meme-cooking__near" },
768
- { asset: "NEAR.GNEAR-gnear-229.meme-cooking.near", url: "NEAR.GNEAR-gnear-229__meme-cooking__near" },
769
- { asset: "NEAR.mpDAO-mpdao-token.near", url: "NEAR.mpDAO-mpdao-token__near" },
770
- { asset: "NEAR.NearKat-kat.token0.near", url: "NEAR.NearKat-kat__token0__near" },
771
- { asset: "NEAR.TESTNEBULA-test-token.highdome3013.near", url: "NEAR.TESTNEBULA-test-token__highdome3013__near" },
772
- { asset: "NEAR.RHEA-token.rhealab.near", url: "NEAR.RHEA-token__rhealab__near" },
773
- { asset: "NEAR.PUBLIC-token.publicailab.near", url: "NEAR.PUBLIC-token__publicailab__near" },
774
- { asset: "NEAR.SWEAT-token.sweat", url: "NEAR.SWEAT-token__sweat" },
775
- {
776
- asset: "NEAR.USDC-17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1",
777
- url: "NEAR.USDC-17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1",
778
- },
779
-
780
- // THORChain Synths - THOR prefix for chain, then chain.symbol
781
- { asset: "THOR.ETH/ETH", url: "THOR.ETH.ETH" },
782
- { asset: "THOR.BTC/BTC", url: "THOR.BTC.BTC" },
783
- { asset: "THOR.AVAX/AVAX", url: "THOR.AVAX.AVAX" },
784
- { asset: "THOR.BSC/BNB", url: "THOR.BSC.BNB" },
785
- { asset: "THOR.GAIA/ATOM", url: "THOR.GAIA.ATOM" },
786
-
787
- // THORChain Trade assets - THOR prefix, then chain..symbol (double dot)
788
- { asset: "THOR.ETH~ETH", url: "THOR.ETH..ETH" },
789
- { asset: "THOR.BTC~BTC", url: "THOR.BTC..BTC" },
790
- { asset: "THOR.AVAX~AVAX", url: "THOR.AVAX..AVAX" },
791
-
792
- // Maya synths - MAYA prefix for chain, then chain.symbol
793
- { asset: "MAYA.ETH/ETH", url: "MAYA.ETH.ETH" },
794
- { asset: "MAYA.BTC/BTC", url: "MAYA.BTC.BTC" },
795
-
796
- // Synths with tokens
797
- {
798
- asset: "MAYA.ETH/USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
799
- url: "MAYA.ETH.USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
800
- },
801
- {
802
- asset: "THOR.BSC/USDT-0x55d398326f99059fF775485246999027B3197955",
803
- url: "THOR.BSC.USDT-0x55d398326f99059fF775485246999027B3197955",
804
- },
805
-
806
- // Trade assets with tokens
807
- {
808
- asset: "THOR.ETH~USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
809
- url: "THOR.ETH..USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
810
- },
811
- {
812
- asset: "THOR.BSC~USDT-0x55d398326f99059fF775485246999027B3197955",
813
- url: "THOR.BSC..USDT-0x55d398326f99059fF775485246999027B3197955",
814
- },
815
- ];
816
-
817
- for (const { asset, url } of testCases) {
818
- const assetValue = AssetValue.from({ asset });
819
- expect(assetValue.toUrl()).toBe(url);
820
-
821
- const fromUrl = AssetValue.fromUrl(url);
822
- // Synths and trade assets need special handling with includeSynthProtocol
823
- if ((asset.startsWith("MAYA.") || asset.startsWith("THOR.")) && (asset.includes("/") || asset.includes("~"))) {
824
- expect(fromUrl.toString({ includeSynthProtocol: true })).toBe(asset);
825
- } else {
826
- expect(fromUrl.toString()).toBe(asset);
827
- }
828
- }
829
- });
830
-
831
- test("handles complex token symbols in URLs", () => {
832
- // Tokens with multiple dashes in symbol
833
- const pendle = AssetValue.from({ asset: "ETH.PENDLE-LPT-0x1234567890abcdef" });
834
- expect(pendle.toUrl()).toBe("ETH.PENDLE-LPT-0x1234567890abcdef");
835
- expect(pendle.ticker).toBe("PENDLE-LPT");
836
- expect(pendle.address).toBe("0x1234567890abcdef");
837
-
838
- const fromUrlPendle = AssetValue.fromUrl("ETH.PENDLE-LPT-0x1234567890abcdef");
839
- expect(fromUrlPendle.toString()).toBe("ETH.PENDLE-LPT-0x1234567890abcdef");
840
- expect(fromUrlPendle.ticker).toBe("PENDLE-LPT");
841
- expect(fromUrlPendle.address).toBe("0x1234567890abcdef");
842
-
843
- // Synth with complex symbol
844
- const synthPendle = AssetValue.from({ asset: "THOR.ETH/PENDLE-LPT-0x1234567890abcdef" });
845
- expect(synthPendle.toUrl()).toBe("THOR.ETH.PENDLE-LPT-0x1234567890abcdef");
846
-
847
- const fromUrlSynthPendle = AssetValue.fromUrl("THOR.ETH.PENDLE-LPT-0x1234567890abcdef");
848
- expect(fromUrlSynthPendle.toString({ includeSynthProtocol: true })).toBe("THOR.ETH/PENDLE-LPT-0x1234567890abcdef");
849
- expect(fromUrlSynthPendle.ticker).toBe("PENDLE-LPT");
850
- expect(fromUrlSynthPendle.address).toBe("0x1234567890abcdef");
851
-
852
- // Trade asset with complex symbol
853
- const tradePendle = AssetValue.from({ asset: "THOR.ETH~PENDLE-LPT-0x1234567890abcdef" });
854
- expect(tradePendle.toUrl()).toBe("THOR.ETH..PENDLE-LPT-0x1234567890abcdef");
855
-
856
- const fromUrlTradePendle = AssetValue.fromUrl("THOR.ETH..PENDLE-LPT-0x1234567890abcdef");
857
- expect(fromUrlTradePendle.toString({ includeSynthProtocol: true })).toBe("THOR.ETH~PENDLE-LPT-0x1234567890abcdef");
858
- expect(fromUrlTradePendle.ticker).toBe("PENDLE-LPT");
859
- expect(fromUrlTradePendle.address).toBe("0x1234567890abcdef");
860
- });
861
-
862
- test("handles special chain cases in URLs", () => {
863
- // Gnosis chain special case (GNO -> XDAI)
864
- const gnosis = AssetValue.from({ asset: "GNO.XDAI" });
865
- expect(gnosis.toUrl()).toBe("GNO.XDAI");
866
-
867
- const fromUrlGnosis = AssetValue.fromUrl("GNO.XDAI");
868
- expect(fromUrlGnosis.toString()).toBe("GNO.XDAI");
869
- expect(fromUrlGnosis.ticker).toBe("XDAI");
870
- expect(fromUrlGnosis.isGasAsset).toBe(true);
871
-
872
- // Tron TRX
873
- const tron = AssetValue.from({ asset: "TRON.TRX" });
874
- expect(tron.toUrl()).toBe("TRON.TRX");
875
-
876
- const fromUrlTron = AssetValue.fromUrl("TRON.TRX");
877
- expect(fromUrlTron.toString()).toBe("TRON.TRX");
878
- expect(fromUrlTron.ticker).toBe("TRX");
879
- expect(fromUrlTron.isGasAsset).toBe(true);
880
- });
881
-
882
- test("throws error for invalid URL without dot separator", () => {
883
- expect(() => AssetValue.fromUrl("INVALIDURL")).toThrow("helpers_invalid_asset_url");
884
- expect(() => AssetValue.fromUrl("")).toThrow("helpers_invalid_asset_url");
885
- });
886
- });
887
-
888
- describe("fromIdentifierSync", () => {
889
- test("(same as fromIdentifier) - creates AssetValue from string via `@swapkit/tokens` lists", async () => {
890
- await AssetValue.loadStaticAssets();
891
- const thor = AssetValue.from({ asset: "ARB.USDT-0XFD086BC7CD5C481DCC9C85EBE478A1C0B69FCBB9" });
892
-
893
- expect(thor).toBeDefined();
894
- expect(thor).toEqual(
895
- expect.objectContaining({
896
- address: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",
897
- chain: Chain.Arbitrum,
898
- decimal: 6,
899
- isGasAsset: false,
900
- isSynthetic: false,
901
- symbol: "USDT-0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",
902
- ticker: "USDT",
903
- }),
904
- );
905
- });
906
- });
907
-
908
- describe("fromStringSync", () => {
909
- test("creates AssetValue from string via `@swapkit/tokens` lists", async () => {
910
- await AssetValue.loadStaticAssets();
911
- const thor = AssetValue.from({ asset: "ETH.THOR-0xa5f2211b9b8170f694421f2046281775e8468044" });
912
-
913
- expect(thor).toBeDefined();
914
- expect(thor).toEqual(
915
- expect.objectContaining({
916
- address: "0xa5f2211B9b8170F694421f2046281775E8468044",
917
- chain: Chain.Ethereum,
918
- decimal: 18,
919
- isGasAsset: false,
920
- isSynthetic: false,
921
- symbol: "THOR-0xa5f2211B9b8170F694421f2046281775E8468044",
922
- ticker: "THOR",
923
- }),
924
- );
925
-
926
- const usdc = AssetValue.from({ asset: "ETH.USDC-0XA0B86991C6218B36C1D19D4A2E9EB0CE3606EB48" });
927
- expect(usdc).toBeDefined();
928
- expect(usdc).toEqual(
929
- expect.objectContaining({
930
- address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
931
- chain: Chain.Ethereum,
932
- decimal: 6,
933
- isGasAsset: false,
934
- isSynthetic: false,
935
- symbol: "USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
936
- ticker: "USDC",
937
- }),
938
- );
939
- });
940
-
941
- test("returns safe decimals for unknown token sync", async () => {
942
- await AssetValue.loadStaticAssets();
943
- const fakeAvaxUSDCAssetString = "AVAX.USDC-1234";
944
- const fakeAvaxUSDCAsset = AssetValue.from({ asset: fakeAvaxUSDCAssetString });
945
-
946
- expect(fakeAvaxUSDCAsset).toBeDefined();
947
- expect(fakeAvaxUSDCAsset).toEqual(
948
- expect.objectContaining({
949
- address: "1234",
950
- chain: Chain.Avalanche,
951
- decimal: 18,
952
- isGasAsset: false,
953
- isSynthetic: false,
954
- symbol: "USDC-1234",
955
- ticker: "USDC",
956
- }),
957
- );
958
- });
959
-
960
- test("returns safe decimals for unknown token sync with multiple dashes", async () => {
961
- await AssetValue.loadStaticAssets();
962
- const fakeAvaxUSDCAssetString = "AVAX.USDC-LPT-1234";
963
- const fakeAvaxUSDCAsset2 = AssetValue.from({ asset: fakeAvaxUSDCAssetString });
964
-
965
- expect(fakeAvaxUSDCAsset2).toBeDefined();
966
- expect(fakeAvaxUSDCAsset2).toEqual(
967
- expect.objectContaining({
968
- address: "1234",
969
- chain: Chain.Avalanche,
970
- decimal: 18,
971
- isGasAsset: false,
972
- isSynthetic: false,
973
- symbol: "USDC-LPT-1234",
974
- ticker: "USDC-LPT",
975
- }),
976
- );
977
- });
978
-
979
- test("returns proper BTC.b token with address from static lists", async () => {
980
- await AssetValue.loadStaticAssets();
981
- const avaxBTCb = "AVAX.BTC.b-0x152b9d0fdc40c096757f570a51e494bd4b943e50";
982
- const AvaxBTCb = AssetValue.from({ asset: avaxBTCb });
983
-
984
- expect(AvaxBTCb).toBeDefined();
985
- expect(AvaxBTCb).toEqual(
986
- expect.objectContaining({
987
- address: "0x152b9d0FdC40C096757F570A51E494bd4b943E50",
988
- chain: Chain.Avalanche,
989
- decimal: 8,
990
- isGasAsset: false,
991
- isSynthetic: false,
992
- symbol: "BTC.B-0x152b9d0FdC40C096757F570A51E494bd4b943E50",
993
- ticker: "BTC.B",
994
- }),
995
- );
996
- });
997
- });
998
-
999
- describe("fromStringWithBaseSync", () => {
1000
- test("creates AssetValue from string with base decimals via `@swapkit/tokens` lists", async () => {
1001
- await AssetValue.loadStaticAssets();
1002
- const btc = AssetValue.from({ asset: "BTC.BTC", fromBaseDecimal: 8, value: 5200000000000 });
1003
-
1004
- expect(btc).toBeDefined();
1005
- expect(btc).toEqual(
1006
- expect.objectContaining({
1007
- chain: Chain.Bitcoin,
1008
- decimal: 8,
1009
- isGasAsset: true,
1010
- isSynthetic: false,
1011
- symbol: "BTC",
1012
- ticker: "BTC",
1013
- }),
1014
- );
1015
-
1016
- expect(btc.getValue("string")).toBe("52000");
1017
- expect(btc.getBaseValue("string")).toBe("5200000000000");
1018
- });
1019
-
1020
- test("returns safe decimals for unknown token with base decimal conversion", async () => {
1021
- await AssetValue.loadStaticAssets();
1022
- const fakeAvaxUSDCAssetString = "AVAX.USDC-1234";
1023
- const fakeAvaxUSDCAsset = AssetValue.from({ asset: fakeAvaxUSDCAssetString, fromBaseDecimal: 8, value: 1 });
1024
-
1025
- expect(fakeAvaxUSDCAsset).toBeDefined();
1026
- expect(fakeAvaxUSDCAsset).toEqual(
1027
- expect.objectContaining({
1028
- address: "1234",
1029
- chain: Chain.Avalanche,
1030
- decimal: 18,
1031
- isGasAsset: false,
1032
- isSynthetic: false,
1033
- symbol: "USDC-1234",
1034
- ticker: "USDC",
1035
- }),
1036
- );
1037
-
1038
- expect(fakeAvaxUSDCAsset.getValue("string")).toBe("0.00000001");
1039
- expect(fakeAvaxUSDCAsset.getBaseValue("string")).toBe("10000000000");
1040
- });
1041
-
1042
- test("returns proper USDC token with base decimal conversion from static lists", async () => {
1043
- await AssetValue.loadStaticAssets();
1044
- const avaxUSDC = "AVAX.USDC-0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e";
1045
- const AvaxUSDC = AssetValue.from({ asset: avaxUSDC, fromBaseDecimal: 8, value: 100000000 });
1046
-
1047
- expect(AvaxUSDC).toBeDefined();
1048
- expect(AvaxUSDC).toEqual(
1049
- expect.objectContaining({
1050
- address: "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
1051
- chain: Chain.Avalanche,
1052
- decimal: 6,
1053
- isGasAsset: false,
1054
- isSynthetic: false,
1055
- symbol: "USDC-0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
1056
- ticker: "USDC",
1057
- }),
1058
- );
1059
-
1060
- expect(AvaxUSDC.getValue("string")).toBe("1");
1061
- expect(AvaxUSDC.getBaseValue("string")).toBe("1000000");
1062
- });
1063
- });
1064
-
1065
- describe("fromChainOrSignature", () => {
1066
- test("creates AssetValue from common asset string or chain", () => {
1067
- const cosmosAsset = AssetValue.from({ chain: Chain.Cosmos });
1068
- const { baseDecimal: gaiaDecimal } = getChainConfig(Chain.Cosmos);
1069
- expect(cosmosAsset).toEqual(
1070
- expect.objectContaining({
1071
- address: undefined,
1072
- chain: Chain.Cosmos,
1073
- decimal: gaiaDecimal,
1074
- isGasAsset: true,
1075
- isSynthetic: false,
1076
- symbol: "ATOM",
1077
- ticker: "ATOM",
1078
- type: "Native",
1079
- }),
1080
- );
1081
-
1082
- const bscAsset = AssetValue.from({ chain: Chain.BinanceSmartChain });
1083
- const { baseDecimal: bscDecimal } = getChainConfig(Chain.BinanceSmartChain);
1084
- expect(bscAsset).toEqual(
1085
- expect.objectContaining({
1086
- address: undefined,
1087
- chain: Chain.BinanceSmartChain,
1088
- decimal: bscDecimal,
1089
- isGasAsset: true,
1090
- isSynthetic: false,
1091
- symbol: "BNB",
1092
- ticker: "BNB",
1093
- type: "Native",
1094
- }),
1095
- );
1096
-
1097
- const monadAsset = AssetValue.from({ chain: Chain.Monad });
1098
- const { baseDecimal: monadDecimal } = getChainConfig(Chain.Monad);
1099
- expect(monadAsset).toEqual(
1100
- expect.objectContaining({
1101
- address: undefined,
1102
- chain: Chain.Monad,
1103
- decimal: monadDecimal,
1104
- isGasAsset: true,
1105
- isSynthetic: false,
1106
- symbol: "MON",
1107
- ticker: "MON",
1108
- type: "Native",
1109
- }),
1110
- );
1111
-
1112
- const thorAsset = AssetValue.from({ chain: Chain.THORChain });
1113
- const { baseDecimal: thorDecimal } = getChainConfig(Chain.THORChain);
1114
- expect(thorAsset).toEqual(
1115
- expect.objectContaining({
1116
- address: undefined,
1117
- chain: Chain.THORChain,
1118
- decimal: thorDecimal,
1119
- isGasAsset: true,
1120
- isSynthetic: false,
1121
- symbol: "RUNE",
1122
- ticker: "RUNE",
1123
- type: "Native",
1124
- }),
1125
- );
1126
-
1127
- const cacaoAsset = AssetValue.from({ chain: Chain.Maya });
1128
- expect(cacaoAsset).toEqual(
1129
- expect.objectContaining({
1130
- address: undefined,
1131
- chain: Chain.Maya,
1132
- decimal: 10,
1133
- isGasAsset: true,
1134
- isSynthetic: false,
1135
- symbol: "CACAO",
1136
- ticker: "CACAO",
1137
- type: "Native",
1138
- }),
1139
- );
1140
-
1141
- const thor = AssetValue.from({ asset: "ETH.THOR" });
1142
- expect(thor).toEqual(
1143
- expect.objectContaining({
1144
- address: "0xa5f2211B9b8170F694421f2046281775E8468044",
1145
- chain: Chain.Ethereum,
1146
- decimal: 18,
1147
- isGasAsset: false,
1148
- isSynthetic: false,
1149
- symbol: "THOR-0xa5f2211B9b8170F694421f2046281775E8468044",
1150
- ticker: "THOR",
1151
- }),
1152
- );
1153
-
1154
- // FIXME: just some casing? is it safe to change
1155
- // const vthor = AssetValue.from({ asset: "ETH.vTHOR" });
1156
- // expect(vthor).toEqual(
1157
- // expect.objectContaining({
1158
- // address: "0x815c23eca83261b6ec689b60cc4a58b54bc24d8d",
1159
- // chain: Chain.Ethereum,
1160
- // decimal: 18,
1161
- // isGasAsset: false,
1162
- // isSynthetic: false,
1163
- // symbol: "vTHOR-0x815c23eca83261b6ec689b60cc4a58b54bc24d8d",
1164
- // ticker: "vTHOR",
1165
- // }),
1166
- // );
1167
-
1168
- const arbAsset = AssetValue.from({ chain: Chain.Arbitrum });
1169
- const { baseDecimal: arbDecimal } = getChainConfig(Chain.Arbitrum);
1170
- expect(arbAsset).toEqual(
1171
- expect.objectContaining({
1172
- address: undefined,
1173
- chain: Chain.Arbitrum,
1174
- decimal: arbDecimal,
1175
- isGasAsset: true,
1176
- isSynthetic: false,
1177
- symbol: "ETH",
1178
- ticker: "ETH",
1179
- type: "Native",
1180
- }),
1181
- );
1182
-
1183
- const opAsset = AssetValue.from({ chain: Chain.Optimism });
1184
- const { baseDecimal: opDecimal } = getChainConfig(Chain.Optimism);
1185
- expect(opAsset).toEqual(
1186
- expect.objectContaining({
1187
- address: undefined,
1188
- chain: Chain.Optimism,
1189
- decimal: opDecimal,
1190
- isGasAsset: true,
1191
- isSynthetic: false,
1192
- symbol: "ETH",
1193
- ticker: "ETH",
1194
- type: "Native",
1195
- }),
1196
- );
1197
-
1198
- const xrdAsset = AssetValue.from({ chain: Chain.Radix });
1199
- const { baseDecimal: xrdDecimal } = getChainConfig(Chain.Radix);
1200
- expect(xrdAsset).toEqual(
1201
- expect.objectContaining({
1202
- chain: Chain.Radix,
1203
- decimal: xrdDecimal,
1204
- isGasAsset: true,
1205
- isSynthetic: false,
1206
- ticker: "XRD",
1207
- type: "Native",
1208
- }),
1209
- );
1210
-
1211
- const trxAsset = AssetValue.from({ chain: Chain.Tron });
1212
- const { baseDecimal: trxDecimal } = getChainConfig(Chain.Tron);
1213
- expect(trxAsset).toEqual(
1214
- expect.objectContaining({
1215
- chain: Chain.Tron,
1216
- decimal: trxDecimal,
1217
- isGasAsset: true,
1218
- isSynthetic: false,
1219
- symbol: "TRX",
1220
- ticker: "TRX",
1221
- type: "Native",
1222
- }),
1223
- );
1224
-
1225
- const trxAssetFromString = AssetValue.from({ asset: "TRON.TRX" });
1226
- const { baseDecimal: trxDecimalFromString } = getChainConfig(Chain.Tron);
1227
- expect(trxAssetFromString).toEqual(
1228
- expect.objectContaining({
1229
- chain: Chain.Tron,
1230
- decimal: trxDecimalFromString,
1231
- isGasAsset: true,
1232
- isSynthetic: false,
1233
- symbol: "TRX",
1234
- ticker: "TRX",
1235
- type: "Native",
1236
- }),
1237
- );
1238
- });
1239
-
1240
- test("keep SOL address casing", () => {
1241
- const solUsdc = AssetValue.from({ asset: "SOL.USDC-EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" });
1242
- expect(solUsdc).toEqual(
1243
- expect.objectContaining({
1244
- address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
1245
- chain: Chain.Solana,
1246
- isGasAsset: false,
1247
- isSynthetic: false,
1248
- symbol: "USDC-EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
1249
- ticker: "USDC",
1250
- }),
1251
- );
1252
- });
1253
-
1254
- test("TRC20 tokens are not marked as gas assets", () => {
1255
- const tronUsdt = AssetValue.from({ asset: "TRON.USDT-TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t" });
1256
-
1257
- expect(tronUsdt).toEqual(
1258
- expect.objectContaining({
1259
- address: "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
1260
- chain: Chain.Tron,
1261
- isGasAsset: false,
1262
- isSynthetic: false,
1263
- symbol: "USDT-TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
1264
- ticker: "USDT",
1265
- }),
1266
- );
1267
- });
1268
- });
1269
-
1270
- describe("getMinAmountByChain", () => {
1271
- test("returns min amount for chain", () => {
1272
- expect(getMinAmountByChain(Chain.THORChain).getValue("string")).toBe("0");
1273
- expect(getMinAmountByChain(Chain.Maya).getValue("string")).toBe("0");
1274
- expect(getMinAmountByChain(Chain.Cosmos).getValue("string")).toBe("0.000001");
1275
-
1276
- expect(getMinAmountByChain(Chain.Bitcoin).getValue("string")).toBe("0.00010001");
1277
- expect(getMinAmountByChain(Chain.Litecoin).getValue("string")).toBe("0.00010001");
1278
- expect(getMinAmountByChain(Chain.BitcoinCash).getValue("string")).toBe("0.00010001");
1279
- expect(getMinAmountByChain(Chain.Dogecoin).getValue("string")).toBe("1.00000001");
1280
-
1281
- expect(getMinAmountByChain(Chain.BinanceSmartChain).getValue("string")).toBe("0.00000001");
1282
- expect(getMinAmountByChain(Chain.Ethereum).getValue("string")).toBe("0.00000001");
1283
- expect(getMinAmountByChain(Chain.Avalanche).getValue("string")).toBe("0.00000001");
1284
- expect(getMinAmountByChain(Chain.Arbitrum).getValue("string")).toBe("0.00000001");
1285
- expect(getMinAmountByChain(Chain.Optimism).getValue("string")).toBe("0.00000001");
1286
- });
1287
- });
1288
-
1289
- describe("asyncTokenLookup", () => {
1290
- describe("EVM chains with asyncTokenLookup", () => {
1291
- test("fetches Ethereum USDC token info with chain and address only", async () => {
1292
- const assetValue = await AssetValue.from({
1293
- address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
1294
- asyncTokenLookup: true,
1295
- chain: Chain.Ethereum,
1296
- value: 1000,
1297
- });
1298
-
1299
- expect(assetValue.decimal).toBe(6); // USDC has 6 decimals
1300
- expect(assetValue.symbol).toContain("USDC");
1301
- expect(assetValue.getValue("string")).toBe("1000");
1302
- });
1303
-
1304
- test("fetches Ethereum WETH token info with asset string and asyncTokenLookup", async () => {
1305
- const assetValue = await AssetValue.from({
1306
- asset: "ETH.WETH-0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
1307
- asyncTokenLookup: true,
1308
- value: 0.5,
1309
- });
1310
-
1311
- expect(assetValue.decimal).toBe(18);
1312
- expect(assetValue.symbol).toBe("WETH-0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2");
1313
- expect(assetValue.ticker).toBe("WETH");
1314
- expect(assetValue.getValue("string")).toBe("0.5");
1315
- });
1316
-
1317
- test("fetches Avalanche USDC.e with chain and address", async () => {
1318
- const assetValue = await AssetValue.from({
1319
- address: "0xA7D7079b0FEaD91F3e65f86E8915Cb59c1a4C664",
1320
- asyncTokenLookup: true,
1321
- chain: Chain.Avalanche,
1322
- value: 100,
1323
- });
1324
-
1325
- expect(assetValue.decimal).toBe(6);
1326
- expect(assetValue.symbol).toContain("USDC");
1327
- expect(assetValue.getValue("string")).toBe("100");
1328
- });
1329
-
1330
- test("fetches BSC BUSD with full asset string", async () => {
1331
- const assetValue = await AssetValue.from({
1332
- asset: "BSC.BUSD-0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56",
1333
- asyncTokenLookup: true,
1334
- value: 50.25,
1335
- });
1336
-
1337
- expect(assetValue.decimal).toBe(18);
1338
- expect(assetValue.symbol).toBe("BUSD-0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56");
1339
- expect(assetValue.ticker).toBe("BUSD");
1340
- expect(assetValue.getValue("string")).toBe("50.25");
1341
- });
1342
-
1343
- test("fetches Arbitrum USDC native with chain and address", async () => {
1344
- const assetValue = await AssetValue.from({
1345
- address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
1346
- asyncTokenLookup: true,
1347
- chain: Chain.Arbitrum,
1348
- fromBaseDecimal: 6,
1349
- value: 1000000,
1350
- });
1351
-
1352
- expect(assetValue.decimal).toBe(6);
1353
- expect(assetValue.getBaseValue("string")).toBe("1000000");
1354
- expect(assetValue.getValue("string")).toBe("1");
1355
- expect(assetValue.toString()).toBe("ARB.USDC-0xaf88d065e77c8cC2239327C5EDb3A432268e5831");
1356
- });
1357
- });
1358
-
1359
- describe("Solana with asyncTokenLookup", () => {
1360
- test("fetches Solana USDC with chain and address", async () => {
1361
- const assetValue = await AssetValue.from({
1362
- address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
1363
- asyncTokenLookup: true,
1364
- chain: Chain.Solana,
1365
- value: 250.75,
1366
- });
1367
-
1368
- expect(assetValue.decimal).toBe(6);
1369
- expect(assetValue.symbol).toContain("USDC");
1370
- expect(assetValue.getValue("string")).toBe("250.75");
1371
- });
1372
-
1373
- test("fetches Solana token with asset string", async () => {
1374
- const assetValue = await AssetValue.from({
1375
- asset: "SOL.USDT-Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
1376
- asyncTokenLookup: true,
1377
- value: 100,
1378
- });
1379
-
1380
- expect(assetValue.decimal).toBe(6);
1381
- expect(assetValue.symbol).toBe("USDT-Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB");
1382
- expect(assetValue.ticker).toBe("USDT");
1383
- });
1384
- });
1385
-
1386
- describe("Tron with asyncTokenLookup", () => {
1387
- test("fetches Tron USDT with chain and address", async () => {
1388
- const assetValue = await AssetValue.from({
1389
- address: "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
1390
- asyncTokenLookup: true,
1391
- chain: Chain.Tron,
1392
- value: 500,
1393
- });
1394
-
1395
- expect(assetValue.decimal).toBe(6);
1396
- expect(assetValue.symbol).toContain("USDT");
1397
- expect(assetValue.getValue("string")).toBe("500");
1398
- });
1399
-
1400
- test("fetches Tron token with asset string", async () => {
1401
- const assetValue = await AssetValue.from({
1402
- asset: "TRON.USDC-TEkxiTehnzSmSe2XqrBj4w32RUN966rdz8",
1403
- asyncTokenLookup: true,
1404
- value: 1234.56,
1405
- });
1406
-
1407
- expect(assetValue.decimal).toBe(6);
1408
- expect(assetValue.symbol).toBe("USDC-TEkxiTehnzSmSe2XqrBj4w32RUN966rdz8");
1409
- expect(assetValue.getValue("string")).toBe("1234.56");
1410
- });
1411
- });
1412
-
1413
- describe("Near with asyncTokenLookup", () => {
1414
- test("fetches Near wNEAR with chain and address", async () => {
1415
- const assetValue = await AssetValue.from({
1416
- address: "wrap.near",
1417
- asyncTokenLookup: true,
1418
- chain: Chain.Near,
1419
- value: 10,
1420
- });
1421
-
1422
- expect(assetValue.decimal).toBe(24);
1423
- expect(assetValue.symbol).toContain("wNEAR");
1424
- expect(assetValue.getValue("string")).toBe("10");
1425
- });
1426
-
1427
- test("fetches Near USDC with asset string", async () => {
1428
- const assetValue = await AssetValue.from({
1429
- asset: "NEAR.USDC-17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1",
1430
- asyncTokenLookup: true,
1431
- value: 999.99,
1432
- });
1433
-
1434
- expect(assetValue.decimal).toBe(6);
1435
- expect(assetValue.symbol).toBe("USDC-17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1");
1436
- expect(assetValue.ticker).toBe("USDC");
1437
- expect(assetValue.getValue("string")).toBe("999.99");
1438
- });
1439
-
1440
- test("fetches Near token with .near address format", async () => {
1441
- const assetValue = await AssetValue.from({
1442
- address: "usdt.tether-token.near",
1443
- asyncTokenLookup: true,
1444
- chain: Chain.Near,
1445
- value: 2500,
1446
- });
1447
-
1448
- expect(assetValue.decimal).toBe(6);
1449
- expect(assetValue.toString()).toBe("NEAR.USDT-usdt.tether-token.near");
1450
- expect(assetValue.getValue("string")).toBe("2500");
1451
- });
1452
- });
1453
-
1454
- describe("Edge cases and caching", () => {
1455
- test("handles invalid token address gracefully", async () => {
1456
- const assetValue = await AssetValue.from({
1457
- address: "0xinvalidaddress",
1458
- asyncTokenLookup: true,
1459
- chain: Chain.Ethereum,
1460
- value: 10,
1461
- });
1462
-
1463
- expect(assetValue.decimal).toBe(18);
1464
- expect(assetValue.getValue("string")).toBe("10");
1465
- });
1466
-
1467
- test("works with fromBaseDecimal parameter", async () => {
1468
- const assetValue = await AssetValue.from({
1469
- address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
1470
- asyncTokenLookup: true,
1471
- chain: Chain.Ethereum,
1472
- fromBaseDecimal: 6,
1473
- value: 1000000,
1474
- });
1475
-
1476
- expect(assetValue.decimal).toBe(6);
1477
- expect(assetValue.getBaseValue("string")).toBe("1000000");
1478
- expect(assetValue.getValue("string")).toBe("1");
1479
- });
1480
-
1481
- test("synchronous call without asyncTokenLookup", async () => {
1482
- await AssetValue.loadStaticAssets();
1483
-
1484
- const assetValue = AssetValue.from({
1485
- address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
1486
- chain: Chain.Ethereum,
1487
- value: 100,
1488
- });
1489
-
1490
- expect(assetValue.decimal).toBe(6);
1491
- expect(assetValue.getValue("string")).toBe("100");
1492
- expect(assetValue.symbol).toBe("USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48");
1493
-
1494
- const assetValueWrongAddress = AssetValue.from({ address: "0xVERYWRONG", chain: Chain.Ethereum, value: 100 });
1495
-
1496
- expect(assetValueWrongAddress.decimal).toBe(18);
1497
- expect(assetValueWrongAddress.getValue("string")).toBe("100");
1498
- expect(assetValueWrongAddress.toString()).toBe("ETH.UNKNOWN-0xverywrong");
1499
- });
1500
-
1501
- test("handles Radix with symbol lookup", async () => {
1502
- const assetValue = await AssetValue.from({
1503
- asyncTokenLookup: true,
1504
- chain: Chain.Radix,
1505
- symbol: "XRD",
1506
- value: 50,
1507
- });
1508
-
1509
- expect(assetValue.decimal).toBe(18);
1510
- expect(assetValue.symbol).toBe("XRD");
1511
- expect(assetValue.getValue("string")).toBe("50");
1512
- });
1513
- });
1514
-
1515
- describe("Mixed symbol and address scenarios", () => {
1516
- test("uses on-chain data when both symbol and address provided", async () => {
1517
- const assetValue = await AssetValue.from({
1518
- asset: "ETH.WRONG-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
1519
- asyncTokenLookup: true,
1520
- value: 100,
1521
- });
1522
-
1523
- expect(assetValue.decimal).toBe(6);
1524
- expect(assetValue.symbol).toContain("USDC");
1525
- expect(assetValue.address).toBe("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48");
1526
- });
1527
- });
1528
-
1529
- describe("getIconUrl", () => {
1530
- test("returns logoURI when token is in static map", async () => {
1531
- await AssetValue.loadStaticAssets();
1532
- const asset = AssetValue.from({ asset: "BTC.BTC" });
1533
-
1534
- expect(asset.getIconUrl()).toBeString();
1535
- expect(asset.getIconUrl()?.length).toBeGreaterThan(0);
1536
- });
1537
-
1538
- test("returns undefined for custom token not in map", () => {
1539
- AssetValue.setStaticAssets(new Map());
1540
-
1541
- const asset = AssetValue.from({ asset: "BTC.BTC" });
1542
- expect(asset.getIconUrl()).toBeUndefined();
1543
-
1544
- void AssetValue.loadStaticAssets();
1545
- });
1546
- });
1547
-
1548
- describe("setStaticAssets", () => {
1549
- test("sets custom static assets map", () => {
1550
- const customMap = new Map();
1551
-
1552
- customMap.set("ETH.CUSTOMTOKEN-0X123", {
1553
- address: "0x123",
1554
- chain: Chain.Ethereum,
1555
- decimal: 18,
1556
- identifier: "ETH.CUSTOMTOKEN-0x123",
1557
- tax: undefined,
1558
- });
1559
-
1560
- const result = AssetValue.setStaticAssets(customMap);
1561
- expect(result).toBe(true);
1562
-
1563
- const asset = AssetValue.from({ asset: "ETH.CUSTOMTOKEN-0X123" });
1564
- expect(asset.decimal).toBe(18);
1565
- expect(asset.toString()).toBe("ETH.CUSTOMTOKEN-0x123");
1566
- });
1567
-
1568
- test("clears existing static assets when setting new ones", () => {
1569
- const map1 = new Map();
1570
- map1.set("BTC.TOKEN1", { chain: Chain.Bitcoin, decimal: 8, identifier: "BTC.TOKEN1" });
1571
-
1572
- AssetValue.setStaticAssets(map1);
1573
-
1574
- const map2 = new Map();
1575
- map2.set("ETH.TOKEN2-0xABC", {
1576
- address: "0xABC",
1577
- chain: Chain.Ethereum,
1578
- decimal: 18,
1579
- identifier: "ETH.TOKEN2-0xABC",
1580
- });
1581
-
1582
- AssetValue.setStaticAssets(map2);
1583
-
1584
- // TOKEN2 should exist
1585
- const asset2 = AssetValue.from({ asset: "ETH.TOKEN2-0xABC" });
1586
- expect(asset2.decimal).toBe(18);
1587
- });
1588
-
1589
- test("handles token with decimals property", () => {
1590
- const customMap = new Map();
1591
-
1592
- customMap.set("AVAX.CUSTOMUSDC-0X456", {
1593
- address: "0x456",
1594
- chain: Chain.Avalanche,
1595
- decimals: 6,
1596
- identifier: "AVAX.CUSTOMUSDC-0x456",
1597
- });
1598
-
1599
- AssetValue.setStaticAssets(customMap);
1600
-
1601
- const asset = AssetValue.from({ asset: "AVAX.CUSTOMUSDC-0X456" });
1602
- expect(asset.decimal).toBe(6);
1603
- });
1604
-
1605
- test("handles case sensitive chains correctly", () => {
1606
- const customMap = new Map();
1607
-
1608
- // SOL is case sensitive
1609
- customMap.set("SOL.CUSTOMTOKEN-ADDRESS123", {
1610
- address: "ADDRESS123",
1611
- chain: Chain.Solana,
1612
- decimal: 9,
1613
- identifier: "SOL.CUSTOMTOKEN-ADDRESS123",
1614
- });
1615
-
1616
- AssetValue.setStaticAssets(customMap);
1617
-
1618
- const asset = AssetValue.from({ asset: "SOL.CUSTOMTOKEN-ADDRESS123" });
1619
- expect(asset.decimal).toBe(9);
1620
- expect(asset.address).toBe("ADDRESS123");
1621
- });
1622
-
1623
- test("populates chain:address map for lookups", () => {
1624
- const customMap = new Map();
1625
-
1626
- customMap.set("BSC.TOKEN-0XDEF", {
1627
- address: "0xDEF",
1628
- chain: Chain.BinanceSmartChain,
1629
- decimal: 18,
1630
- identifier: "BSC.TOKEN-0xDEF",
1631
- });
1632
-
1633
- AssetValue.setStaticAssets(customMap);
1634
-
1635
- // Should be able to find by chain:address
1636
- const asset = AssetValue.from({ address: "0XDEF", chain: Chain.BinanceSmartChain });
1637
- expect(asset.decimal).toBe(18);
1638
- });
1639
-
1640
- test("handles tokens with tax property", () => {
1641
- const customMap = new Map();
1642
-
1643
- const tax = { buy: 0.1, sell: 0.2 };
1644
- customMap.set("ETH.TAXTOKEN-0X789", {
1645
- address: "0x789",
1646
- chain: Chain.Ethereum,
1647
- decimal: 18,
1648
- identifier: "ETH.TAXTOKEN-0x789",
1649
- tax,
1650
- });
1651
-
1652
- AssetValue.setStaticAssets(customMap);
1653
-
1654
- const asset = AssetValue.from({ asset: "ETH.TAXTOKEN-0X789" });
1655
- expect(asset.tax).toEqual(tax);
1656
- });
1657
- });
1658
- });
1659
-
1660
- describe("arithmetic", () => {
1661
- test("add with number, string, AssetValue, and chained calls", () => {
1662
- const base = AssetValue.from({ asset: "BTC.BTC", value: 10 });
1663
- const other = AssetValue.from({ asset: "ETH.ETH", value: 5 });
1664
-
1665
- expect(base.add(5).getValue("string")).toBe("15");
1666
- expect(base.add("2.5").getValue("string")).toBe("12.5");
1667
- expect(base.add(other).getValue("string")).toBe("15");
1668
- expect(base.add(1, 2, 3).getValue("string")).toBe("16");
1669
- expect(base.add(0.00000001).getValue("string")).toBe("10.00000001");
1670
- });
1671
-
1672
- test("sub with negative result and precision edge", () => {
1673
- const base = AssetValue.from({ asset: "MAYA.CACAO", value: 100 });
1674
-
1675
- expect(base.sub(30).getValue("string")).toBe("70");
1676
- expect(base.sub(100).getValue("string")).toBe("0");
1677
- expect(base.sub(150).getValue("string")).toBe("-50");
1678
- expect(base.sub(0.00000001).getValue("string")).toBe("99.99999999");
1679
- });
1680
-
1681
- test("mul with decimals, zero, and large numbers", () => {
1682
- const base = AssetValue.from({ asset: "SOL.SOL", value: "0.00001" });
1683
-
1684
- expect(base.mul(1000000).getValue("string")).toBe("10");
1685
- expect(base.mul(0).getValue("string")).toBe("0");
1686
- expect(base.mul(0.5).getValue("string")).toBe("0.000005");
1687
-
1688
- const large = AssetValue.from({ asset: "ETH.ETH", value: "999999999" });
1689
- expect(large.mul(2).getValue("string")).toBe("1999999998");
1690
- });
1691
-
1692
- test("div with precision loss prevention and small divisors", () => {
1693
- const base = AssetValue.from({ asset: "GAIA.ATOM", value: 1 });
1694
-
1695
- expect(base.div(3).getValue("string")).toMatch(/^0\.333333/);
1696
- expect(base.div(1000000).getValue("string")).toBe("0.000001");
1697
- expect(base.div(100000000).getValue("string")).toBe("0.00000001");
1698
-
1699
- expect(() => base.div(0)).toThrow();
1700
- });
1701
-
1702
- test("chained operations preserve synth/trade identity", () => {
1703
- const synth = AssetValue.from({ asset: "THOR.BTC/BTC", value: 1 });
1704
- const trade = AssetValue.from({ asset: "THOR.ETH~ETH", value: 1 });
1705
-
1706
- const synthResult = synth.add(1).mul(2).div(4);
1707
- expect(synthResult.isSynthetic).toBe(true);
1708
- expect(synthResult.symbol).toBe("BTC/BTC");
1709
-
1710
- const tradeResult = trade.sub(0.5).mul(3);
1711
- expect(tradeResult.isTradeAsset).toBe(true);
1712
- expect(tradeResult.symbol).toBe("ETH~ETH");
1713
- });
1714
- });
1715
-
1716
- describe("comparison", () => {
1717
- test("gt/gte/lt/lte with various value types", () => {
1718
- const value = AssetValue.from({ asset: "BTC.BTC", value: "0.00000100" });
1719
-
1720
- expect(value.gt(0.00000099)).toBe(true);
1721
- expect(value.gt(0.000001)).toBe(false);
1722
- expect(value.gt("0.00000101")).toBe(false);
1723
-
1724
- expect(value.gte(0.000001)).toBe(true);
1725
- expect(value.gte("0.00000101")).toBe(false);
1726
-
1727
- expect(value.lt(0.00000101)).toBe(true);
1728
- expect(value.lt(0.000001)).toBe(false);
1729
-
1730
- expect(value.lte(0.000001)).toBe(true);
1731
- expect(value.lte(0.00000099)).toBe(false);
1732
- });
1733
-
1734
- test("eqValue across different decimals", () => {
1735
- const btc = AssetValue.from({ asset: "BTC.BTC", value: 1 });
1736
- const eth = AssetValue.from({ asset: "ETH.ETH", value: 1 });
1737
- const usdc = AssetValue.from({ asset: "ETH.USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", value: 1 });
1738
-
1739
- expect(btc.eqValue(eth)).toBe(true);
1740
- expect(btc.eqValue(usdc)).toBe(true);
1741
- expect(btc.eqValue(1)).toBe(true);
1742
- expect(btc.eqValue("1")).toBe(true);
1743
- expect(btc.eqValue(1.00000001)).toBe(false);
1744
- });
1745
-
1746
- test("comparison with zero and negative", () => {
1747
- const zero = AssetValue.from({ asset: "BTC.BTC", value: 0 });
1748
- const neg = AssetValue.from({ asset: "BTC.BTC", value: 10 }).sub(15);
1749
-
1750
- expect(zero.eqValue(0)).toBe(true);
1751
- expect(zero.gt(0)).toBe(false);
1752
- expect(zero.lt(0)).toBe(false);
1753
-
1754
- expect(neg.lt(0)).toBe(true);
1755
- expect(neg.lte(-5)).toBe(true);
1756
- expect(neg.gt(-6)).toBe(true);
1757
- });
1758
- });
1759
-
1760
- describe("getValue and getBaseValue", () => {
1761
- test("getBaseValue respects asset decimal", async () => {
1762
- await AssetValue.loadStaticAssets();
1763
-
1764
- const btc = AssetValue.from({ asset: "BTC.BTC", value: 1.5 });
1765
- expect(btc.getBaseValue("bigint")).toBe(150000000n);
1766
- expect(btc.getBaseValue("string")).toBe("150000000");
1767
-
1768
- const usdc = AssetValue.from({ asset: "AVAX.USDC-0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e", value: 100 });
1769
- expect(usdc.getBaseValue("bigint", 6)).toBe(100000000n);
1770
-
1771
- const cacao = AssetValue.from({ asset: "MAYA.CACAO", value: 1 });
1772
- expect(cacao.getBaseValue("bigint")).toBe(10000000000n);
1773
- });
1774
-
1775
- test("getValue truncates to requested decimal", () => {
1776
- const eth = AssetValue.from({ asset: "ETH.ETH", value: "1.123456789012345678" });
1777
-
1778
- expect(eth.getValue("string", 18)).toBe("1.123456789012345678");
1779
- expect(eth.getValue("string", 8)).toBe("1.12345679");
1780
- expect(eth.getValue("string", 2)).toBe("1.12");
1781
- expect(eth.getValue("number", 4)).toBe(1.1235);
1782
- });
1783
-
1784
- test("getValue bigint scaling", () => {
1785
- const value = AssetValue.from({ asset: "BTC.BTC", value: 2.5 });
1786
- expect(value.getValue("bigint")).toBe(250000000n);
1787
- });
1788
- });
1789
-
1790
- describe("formatting", () => {
1791
- test("toSignificant with integers, decimals, and edge cases", () => {
1792
- expect(AssetValue.from({ asset: "ETH.ETH", value: 123456 }).toSignificant(3)).toBe("123000");
1793
- expect(AssetValue.from({ asset: "ETH.ETH", value: 0.00012345 }).toSignificant(3)).toBe("0.000123");
1794
- expect(AssetValue.from({ asset: "ETH.ETH", value: 0 }).toSignificant(6)).toBe("0");
1795
- expect(AssetValue.from({ asset: "ETH.ETH", value: 9.99999 }).toSignificant(2)).toBe("9.9");
1796
- });
1797
-
1798
- test("toFixed rounding and padding", () => {
1799
- expect(AssetValue.from({ asset: "BTC.BTC", value: 1.005 }).toFixed(2)).toBe("1.01");
1800
- expect(AssetValue.from({ asset: "BTC.BTC", value: 1.004 }).toFixed(2)).toBe("1.00");
1801
- expect(AssetValue.from({ asset: "BTC.BTC", value: 100 }).toFixed(4)).toBe("100.0000");
1802
- expect(AssetValue.from({ asset: "BTC.BTC", value: -1.999 }).toFixed(2)).toBe("-2.00");
1803
- expect(AssetValue.from({ asset: "BTC.BTC", value: 0 }).toFixed(0)).toBe("0");
1804
- });
1805
-
1806
- test("toAbbreviation across magnitudes", () => {
1807
- expect(AssetValue.from({ asset: "ETH.ETH", value: 500 }).toAbbreviation()).toBe("500");
1808
- expect(AssetValue.from({ asset: "ETH.ETH", value: 1500 }).toAbbreviation()).toBe("1.50K");
1809
- expect(AssetValue.from({ asset: "ETH.ETH", value: 1500000 }).toAbbreviation()).toBe("1.50M");
1810
- expect(AssetValue.from({ asset: "ETH.ETH", value: 1500000000 }).toAbbreviation()).toBe("1.50B");
1811
- expect(AssetValue.from({ asset: "ETH.ETH", value: "1500000000000" }).toAbbreviation()).toBe("1.50T");
1812
- expect(AssetValue.from({ asset: "ETH.ETH", value: 1234 }).toAbbreviation(0)).toBe("1K");
1813
- });
1814
- });
1815
-
1816
- describe("toCurrency", () => {
1817
- test("small values preserve precision without floating-point artifacts", () => {
1818
- expect(AssetValue.from({ asset: "ETH.ETH", value: 0.015072 }).toCurrency("")).toBe("0.015072");
1819
- expect(AssetValue.from({ asset: "ETH.ETH", value: 0.333145 }).toCurrency("")).toBe("0.333145");
1820
- expect(AssetValue.from({ asset: "ETH.ETH", value: 0.00000548 }).toCurrency("")).toBe("0.00000548");
1821
- expect(AssetValue.from({ asset: "ETH.ETH", value: 0.1 }).toCurrency("")).toBe("0.1");
1822
- expect(AssetValue.from({ asset: "ETH.ETH", value: 0.10000001 }).toCurrency("")).toBe("0.10000001");
1823
- });
1824
-
1825
- test("negative small values handled correctly", () => {
1826
- expect(AssetValue.from({ asset: "BTC.BTC", value: -0.015072 }).toCurrency("")).toBe("-0.015072");
1827
- expect(AssetValue.from({ asset: "BTC.BTC", value: -0.00000001 }).toCurrency("")).toBe("-0.00000001");
1828
- });
1829
-
1830
- test("large values with thousand separators and rounding", () => {
1831
- expect(AssetValue.from({ asset: "ETH.ETH", value: 1234567.891 }).toCurrency("$")).toBe("$1,234,567.89");
1832
- expect(AssetValue.from({ asset: "ETH.ETH", value: 1000000 }).toCurrency("$")).toBe("$1,000,000");
1833
- expect(AssetValue.from({ asset: "ETH.ETH", value: 999.999 }).toCurrency("$")).toBe("$1,000");
1834
- });
1835
-
1836
- test("custom currency symbol and position", () => {
1837
- const v = AssetValue.from({ asset: "ETH.ETH", value: 1234.56 });
1838
- expect(v.toCurrency("€", { currencyPosition: "end" })).toBe("1,234.56€");
1839
- expect(v.toCurrency("¥", { currencyPosition: "start" })).toBe("¥1,234.56");
1840
- expect(v.toCurrency("", { decimal: 4 })).toBe("1,234.5600");
1841
- });
1842
-
1843
- test("custom separators for european format", () => {
1844
- const v = AssetValue.from({ asset: "ETH.ETH", value: 1234567.89 });
1845
- expect(v.toCurrency("€", { currencyPosition: "end", decimalSeparator: ",", thousandSeparator: "." })).toBe(
1846
- "1.234.567,89€",
1847
- );
1848
- });
1849
-
1850
- test("zero value", () => {
1851
- expect(AssetValue.from({ asset: "BTC.BTC", value: 0 }).toCurrency("$")).toBe("$0");
1852
- expect(AssetValue.from({ asset: "BTC.BTC", value: 0 }).toCurrency("")).toBe("0");
1853
- });
1854
- });
1855
-
1856
- describe("edge cases", () => {
1857
- test("set creates immutable copy", () => {
1858
- const a = AssetValue.from({ asset: "THOR.ETH/ETH", value: 10 });
1859
- const b = a.set(20);
1860
-
1861
- expect(a.getValue("string")).toBe("10");
1862
- expect(b.getValue("string")).toBe("20");
1863
- expect(b.isSynthetic).toBe(true);
1864
- expect(b.toString({ includeSynthProtocol: true })).toBe("THOR.ETH/ETH");
1865
- });
1866
-
1867
- test("minimum precision values", () => {
1868
- const btcMin = AssetValue.from({ asset: "BTC.BTC", value: 0.00000001 });
1869
- expect(btcMin.getBaseValue("bigint")).toBe(1n);
1870
- expect(btcMin.mul(2).getBaseValue("bigint")).toBe(2n);
1871
- expect(btcMin.div(2).getBaseValue("bigint")).toBe(1n);
1872
-
1873
- const ethMin = AssetValue.from({ asset: "ETH.ETH", value: "0.000000000000000001" });
1874
- expect(ethMin.getValue("string")).toBe("0.000000000000000001");
1875
- });
1876
-
1877
- test("large value arithmetic precision", () => {
1878
- const large1 = AssetValue.from({ asset: "ETH.ETH", value: "999999999999999" });
1879
- const large2 = AssetValue.from({ asset: "ETH.ETH", value: "1" });
1880
-
1881
- expect(large1.add(large2).getValue("string")).toBe("1000000000000000");
1882
- expect(large1.mul(2).getValue("string")).toBe("1999999999999998");
1883
- });
1884
-
1885
- test("fromBaseDecimal conversion", () => {
1886
- const fromBase8 = AssetValue.from({ asset: "BTC.BTC", fromBaseDecimal: 8, value: 100000000 });
1887
- expect(fromBase8.getValue("string")).toBe("1");
1888
-
1889
- const fromBase18 = AssetValue.from({ asset: "ETH.ETH", fromBaseDecimal: 18, value: "1000000000000000000" });
1890
- expect(fromBase18.getValue("string")).toBe("1");
1891
- });
1892
- });