@ledgerhq/live-common 34.38.1 → 34.39.0-nightly.0

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 (154) hide show
  1. package/lib/__tests__/hw/getLatestFirmwareForDevice.js +4 -0
  2. package/lib/__tests__/hw/getLatestFirmwareForDevice.js.map +1 -1
  3. package/lib/__tests__/test-helpers/deviceInfos.d.ts.map +1 -1
  4. package/lib/__tests__/test-helpers/deviceInfos.js +5 -0
  5. package/lib/__tests__/test-helpers/deviceInfos.js.map +1 -1
  6. package/lib/apps/mock.d.ts +2 -32
  7. package/lib/apps/mock.d.ts.map +1 -1
  8. package/lib/apps/mock.js +3 -0
  9. package/lib/apps/mock.js.map +1 -1
  10. package/lib/apps/polyfill.d.ts +4 -1
  11. package/lib/apps/polyfill.d.ts.map +1 -1
  12. package/lib/deposit/deposit.test.js +418 -74
  13. package/lib/deposit/deposit.test.js.map +1 -1
  14. package/lib/deposit/helper.d.ts +1 -0
  15. package/lib/deposit/helper.d.ts.map +1 -1
  16. package/lib/deposit/helper.js +19 -6
  17. package/lib/deposit/helper.js.map +1 -1
  18. package/lib/deviceSDK/tasks/getDeviceInfo.d.ts.map +1 -1
  19. package/lib/deviceSDK/tasks/getDeviceInfo.js +3 -1
  20. package/lib/deviceSDK/tasks/getDeviceInfo.js.map +1 -1
  21. package/lib/e2e/enum/Provider.d.ts +1 -1
  22. package/lib/e2e/enum/Provider.d.ts.map +1 -1
  23. package/lib/e2e/enum/Provider.js +1 -1
  24. package/lib/e2e/enum/Provider.js.map +1 -1
  25. package/lib/e2e/index.d.ts +2 -0
  26. package/lib/e2e/index.d.ts.map +1 -1
  27. package/lib/e2e/swap.d.ts.map +1 -1
  28. package/lib/e2e/swap.js +10 -7
  29. package/lib/e2e/swap.js.map +1 -1
  30. package/lib/featureFlags/defaultFeatures.d.ts.map +1 -1
  31. package/lib/featureFlags/defaultFeatures.js +24 -0
  32. package/lib/featureFlags/defaultFeatures.js.map +1 -1
  33. package/lib/featureFlags/useFeature.d.ts +1 -1
  34. package/lib/featureFlags/useFeature.d.ts.map +1 -1
  35. package/lib/hw/connectManager.d.ts.map +1 -1
  36. package/lib/hw/connectManager.js +9 -0
  37. package/lib/hw/connectManager.js.map +1 -1
  38. package/lib/hw/customLockScreenLoad.d.ts.map +1 -1
  39. package/lib/hw/customLockScreenLoad.js +22 -18
  40. package/lib/hw/customLockScreenLoad.js.map +1 -1
  41. package/lib/hw/customLockScreenLoad.test.d.ts +2 -0
  42. package/lib/hw/customLockScreenLoad.test.d.ts.map +1 -0
  43. package/lib/hw/customLockScreenLoad.test.js +63 -0
  44. package/lib/hw/customLockScreenLoad.test.js.map +1 -0
  45. package/lib/hw/extractOnboardingState.d.ts +15 -2
  46. package/lib/hw/extractOnboardingState.d.ts.map +1 -1
  47. package/lib/hw/extractOnboardingState.js +67 -19
  48. package/lib/hw/extractOnboardingState.js.map +1 -1
  49. package/lib/hw/extractOnboardingState.test.js +96 -1
  50. package/lib/hw/extractOnboardingState.test.js.map +1 -1
  51. package/lib/hw/getDeviceInfo.d.ts.map +1 -1
  52. package/lib/hw/getDeviceInfo.js +3 -1
  53. package/lib/hw/getDeviceInfo.js.map +1 -1
  54. package/lib/hw/getGenuineCheckFromDeviceId.test.js +1 -0
  55. package/lib/hw/getGenuineCheckFromDeviceId.test.js.map +1 -1
  56. package/lib/hw/getOnboardingStatePolling.js +1 -1
  57. package/lib/hw/getOnboardingStatePolling.js.map +1 -1
  58. package/lib/hw/getOnboardingStatePolling.test.js +2 -0
  59. package/lib/hw/getOnboardingStatePolling.test.js.map +1 -1
  60. package/lib/hw/isFirmwareUpdateVersionSupported.test.js +2 -1
  61. package/lib/hw/isFirmwareUpdateVersionSupported.test.js.map +1 -1
  62. package/lib/mock/fixtures/aDeviceInfo.d.ts.map +1 -1
  63. package/lib/mock/fixtures/aDeviceInfo.js +1 -0
  64. package/lib/mock/fixtures/aDeviceInfo.js.map +1 -1
  65. package/lib/onboarding/hooks/useOnboardingStatePolling.test.js +2 -0
  66. package/lib/onboarding/hooks/useOnboardingStatePolling.test.js.map +1 -1
  67. package/lib-es/__tests__/hw/getLatestFirmwareForDevice.js +4 -0
  68. package/lib-es/__tests__/hw/getLatestFirmwareForDevice.js.map +1 -1
  69. package/lib-es/__tests__/test-helpers/deviceInfos.d.ts.map +1 -1
  70. package/lib-es/__tests__/test-helpers/deviceInfos.js +5 -0
  71. package/lib-es/__tests__/test-helpers/deviceInfos.js.map +1 -1
  72. package/lib-es/apps/mock.d.ts +2 -32
  73. package/lib-es/apps/mock.d.ts.map +1 -1
  74. package/lib-es/apps/mock.js +3 -0
  75. package/lib-es/apps/mock.js.map +1 -1
  76. package/lib-es/apps/polyfill.d.ts +4 -1
  77. package/lib-es/apps/polyfill.d.ts.map +1 -1
  78. package/lib-es/deposit/deposit.test.js +419 -75
  79. package/lib-es/deposit/deposit.test.js.map +1 -1
  80. package/lib-es/deposit/helper.d.ts +1 -0
  81. package/lib-es/deposit/helper.d.ts.map +1 -1
  82. package/lib-es/deposit/helper.js +18 -6
  83. package/lib-es/deposit/helper.js.map +1 -1
  84. package/lib-es/deviceSDK/tasks/getDeviceInfo.d.ts.map +1 -1
  85. package/lib-es/deviceSDK/tasks/getDeviceInfo.js +3 -1
  86. package/lib-es/deviceSDK/tasks/getDeviceInfo.js.map +1 -1
  87. package/lib-es/e2e/enum/Provider.d.ts +1 -1
  88. package/lib-es/e2e/enum/Provider.d.ts.map +1 -1
  89. package/lib-es/e2e/enum/Provider.js +1 -1
  90. package/lib-es/e2e/enum/Provider.js.map +1 -1
  91. package/lib-es/e2e/index.d.ts +2 -0
  92. package/lib-es/e2e/index.d.ts.map +1 -1
  93. package/lib-es/e2e/swap.d.ts.map +1 -1
  94. package/lib-es/e2e/swap.js +10 -7
  95. package/lib-es/e2e/swap.js.map +1 -1
  96. package/lib-es/featureFlags/defaultFeatures.d.ts.map +1 -1
  97. package/lib-es/featureFlags/defaultFeatures.js +24 -0
  98. package/lib-es/featureFlags/defaultFeatures.js.map +1 -1
  99. package/lib-es/featureFlags/useFeature.d.ts +1 -1
  100. package/lib-es/featureFlags/useFeature.d.ts.map +1 -1
  101. package/lib-es/hw/connectManager.d.ts.map +1 -1
  102. package/lib-es/hw/connectManager.js +9 -0
  103. package/lib-es/hw/connectManager.js.map +1 -1
  104. package/lib-es/hw/customLockScreenLoad.d.ts.map +1 -1
  105. package/lib-es/hw/customLockScreenLoad.js +22 -18
  106. package/lib-es/hw/customLockScreenLoad.js.map +1 -1
  107. package/lib-es/hw/customLockScreenLoad.test.d.ts +2 -0
  108. package/lib-es/hw/customLockScreenLoad.test.d.ts.map +1 -0
  109. package/lib-es/hw/customLockScreenLoad.test.js +58 -0
  110. package/lib-es/hw/customLockScreenLoad.test.js.map +1 -0
  111. package/lib-es/hw/extractOnboardingState.d.ts +15 -2
  112. package/lib-es/hw/extractOnboardingState.d.ts.map +1 -1
  113. package/lib-es/hw/extractOnboardingState.js +66 -18
  114. package/lib-es/hw/extractOnboardingState.js.map +1 -1
  115. package/lib-es/hw/extractOnboardingState.test.js +97 -2
  116. package/lib-es/hw/extractOnboardingState.test.js.map +1 -1
  117. package/lib-es/hw/getDeviceInfo.d.ts.map +1 -1
  118. package/lib-es/hw/getDeviceInfo.js +3 -1
  119. package/lib-es/hw/getDeviceInfo.js.map +1 -1
  120. package/lib-es/hw/getGenuineCheckFromDeviceId.test.js +1 -0
  121. package/lib-es/hw/getGenuineCheckFromDeviceId.test.js.map +1 -1
  122. package/lib-es/hw/getOnboardingStatePolling.js +1 -1
  123. package/lib-es/hw/getOnboardingStatePolling.js.map +1 -1
  124. package/lib-es/hw/getOnboardingStatePolling.test.js +2 -0
  125. package/lib-es/hw/getOnboardingStatePolling.test.js.map +1 -1
  126. package/lib-es/hw/isFirmwareUpdateVersionSupported.test.js +2 -1
  127. package/lib-es/hw/isFirmwareUpdateVersionSupported.test.js.map +1 -1
  128. package/lib-es/mock/fixtures/aDeviceInfo.d.ts.map +1 -1
  129. package/lib-es/mock/fixtures/aDeviceInfo.js +1 -0
  130. package/lib-es/mock/fixtures/aDeviceInfo.js.map +1 -1
  131. package/lib-es/onboarding/hooks/useOnboardingStatePolling.test.js +2 -0
  132. package/lib-es/onboarding/hooks/useOnboardingStatePolling.test.js.map +1 -1
  133. package/package.json +43 -43
  134. package/src/__tests__/hw/getLatestFirmwareForDevice.ts +8 -3
  135. package/src/__tests__/test-helpers/deviceInfos.ts +5 -0
  136. package/src/apps/mock.ts +5 -2
  137. package/src/deposit/deposit.test.ts +611 -136
  138. package/src/deposit/helper.ts +27 -9
  139. package/src/deviceSDK/tasks/getDeviceInfo.ts +3 -0
  140. package/src/e2e/enum/Provider.ts +1 -1
  141. package/src/e2e/swap.ts +12 -7
  142. package/src/featureFlags/defaultFeatures.ts +24 -0
  143. package/src/hw/connectManager.ts +18 -0
  144. package/src/hw/customLockScreenLoad.test.ts +86 -0
  145. package/src/hw/customLockScreenLoad.ts +31 -17
  146. package/src/hw/extractOnboardingState.test.ts +122 -2
  147. package/src/hw/extractOnboardingState.ts +81 -18
  148. package/src/hw/getDeviceInfo.ts +4 -1
  149. package/src/hw/getGenuineCheckFromDeviceId.test.ts +2 -1
  150. package/src/hw/getOnboardingStatePolling.test.ts +2 -0
  151. package/src/hw/getOnboardingStatePolling.ts +1 -1
  152. package/src/hw/isFirmwareUpdateVersionSupported.test.ts +3 -1
  153. package/src/mock/fixtures/aDeviceInfo.ts +1 -0
  154. package/src/onboarding/hooks/useOnboardingStatePolling.test.ts +2 -0
@@ -1,4 +1,10 @@
1
- import { groupCurrenciesByProvider, searchByNameOrTicker, searchByProviderId } from "./helper";
1
+ import {
2
+ groupCurrenciesByProvider,
3
+ searchByNameOrTicker,
4
+ searchByProviderId,
5
+ loadCurrenciesByProvider,
6
+ getTokenOrCryptoCurrencyById,
7
+ } from "./helper";
2
8
  import { MOCK_TOKENS_ONLY, MOCK_WITH_TOKEN_AND_CURRENCY_ASSET, MOCK_IDS, MOCK_POL } from "./mock";
3
9
  import { MappedAsset } from "./type";
4
10
  import {
@@ -18,157 +24,626 @@ describe("Deposit logic", () => {
18
24
  afterEach(() => {
19
25
  setSupportedCurrencies([]);
20
26
  });
21
- test("searchByProviderId", () => {
22
- const result = searchByProviderId(TOKEN_ONLY_ASSETS, "tether");
23
- expect(result).toEqual(TOKEN_ONLY_ASSETS);
24
- });
25
27
 
26
- test("searchByNameOrTicker", () => {
27
- const result = searchByNameOrTicker(TOKEN_ONLY_ASSETS, "usdt");
28
- expect(result.length).toBeGreaterThan(0);
28
+ describe("searchByProviderId", () => {
29
+ test("should find assets by provider ID", () => {
30
+ const result = searchByProviderId(TOKEN_ONLY_ASSETS, "tether");
31
+ expect(result).toEqual(TOKEN_ONLY_ASSETS);
32
+ });
33
+
34
+ test("should return empty array for non-existent provider ID", () => {
35
+ const result = searchByProviderId(TOKEN_ONLY_ASSETS, "non-existent-provider");
36
+ expect(result).toEqual([]);
37
+ });
38
+
39
+ test("should handle case insensitive search", () => {
40
+ const result = searchByProviderId(TOKEN_ONLY_ASSETS, "TETHER");
41
+ expect(result).toEqual(TOKEN_ONLY_ASSETS);
42
+ });
43
+
44
+ test("should handle empty assets list", () => {
45
+ const result = searchByProviderId([], "tether");
46
+ expect(result).toEqual([]);
47
+ });
48
+
49
+ test("should handle empty provider ID", () => {
50
+ const result = searchByProviderId(TOKEN_ONLY_ASSETS, "");
51
+ expect(result).toEqual([]);
52
+ });
53
+
54
+ test("should handle special characters in provider ID", () => {
55
+ const mockAssets = [
56
+ { ...TOKEN_ONLY_ASSETS[0], providerId: "test-provider_123" },
57
+ ] as MappedAsset[];
58
+ const result = searchByProviderId(mockAssets, "test-provider_123");
59
+ expect(result).toHaveLength(1);
60
+ });
29
61
  });
30
62
 
31
- test("groupCurrenciesByProvider", () => {
32
- const currencies = TOKEN_ONLY_ASSETS.map(asset => getTokenById(asset.ledgerId));
33
- const { currenciesByProvider } = groupCurrenciesByProvider(TOKEN_ONLY_ASSETS, currencies);
34
-
35
- expect(currenciesByProvider).toEqual([
36
- {
37
- providerId: "tether",
38
- currenciesByNetwork: currencies,
39
- },
40
- ]);
41
-
42
- const currenciesPol = MOCK_POL.map(asset =>
43
- asset.$type === "Token"
44
- ? getTokenById(asset.ledgerId)
45
- : getCryptoCurrencyById(asset.ledgerId),
46
- );
47
-
48
- setSupportedCurrencies(["polygon", "ethereum", "bsc"]);
49
-
50
- const supportedCurrencies = sortCurrenciesByIds(
51
- (listSupportedCurrencies() as CryptoOrTokenCurrency[]).concat(listSupportedTokens()),
52
- MOCK_IDS,
53
- );
54
- const { currenciesByProvider: currenciesByProviderBis, sortedCryptoCurrencies } =
55
- groupCurrenciesByProvider(MOCK_POL as MappedAsset[], supportedCurrencies);
56
- expect(currenciesByProviderBis).toEqual([
57
- {
58
- providerId: "matic-network",
59
- currenciesByNetwork: currenciesPol,
60
- },
61
- ]);
62
-
63
- expect(sortedCryptoCurrencies).toEqual(currenciesPol);
63
+ describe("searchByNameOrTicker", () => {
64
+ test("should find assets by name or ticker", () => {
65
+ const result = searchByNameOrTicker(TOKEN_ONLY_ASSETS, "usdt");
66
+ expect(result.length).toBeGreaterThan(0);
67
+ });
68
+
69
+ test("should handle case insensitive search", () => {
70
+ const result = searchByNameOrTicker(TOKEN_ONLY_ASSETS, "USDT");
71
+ expect(result.length).toBeGreaterThan(0);
72
+ });
73
+
74
+ test("should find partial matches", () => {
75
+ const result = searchByNameOrTicker(TOKEN_ONLY_ASSETS, "usd");
76
+ expect(result.length).toBeGreaterThan(0);
77
+ });
78
+
79
+ test("should return empty array for non-matching search", () => {
80
+ const result = searchByNameOrTicker(TOKEN_ONLY_ASSETS, "non-existent-token");
81
+ expect(result).toEqual([]);
82
+ });
83
+
84
+ test("should handle empty search term", () => {
85
+ const result = searchByNameOrTicker(TOKEN_ONLY_ASSETS, "");
86
+ expect(result).toEqual(TOKEN_ONLY_ASSETS);
87
+ });
88
+
89
+ test("should handle empty assets list", () => {
90
+ const result = searchByNameOrTicker([], "usdt");
91
+ expect(result).toEqual([]);
92
+ });
93
+
94
+ test("should search in both name and ticker fields", () => {
95
+ const mockAssets = [
96
+ { ...TOKEN_ONLY_ASSETS[0], name: "Test Token", ticker: "TTK" },
97
+ { ...TOKEN_ONLY_ASSETS[0], name: "Another Token", ticker: "USDT" },
98
+ ] as MappedAsset[];
99
+
100
+ const nameResult = searchByNameOrTicker(mockAssets, "Test");
101
+ const tickerResult = searchByNameOrTicker(mockAssets, "USDT");
102
+
103
+ expect(nameResult).toHaveLength(1);
104
+ expect(tickerResult).toHaveLength(1);
105
+ });
64
106
  });
65
107
 
66
- it("should return Arbitrum and not Optimism in the sortedCryptoCurrencies", () => {
67
- setSupportedCurrencies(["arbitrum", "arbitrum_sepolia"]);
68
- const currencies = sortCurrenciesByIds(
69
- (listSupportedCurrencies() as CryptoOrTokenCurrency[]).concat(listSupportedTokens()),
70
- MOCK_IDS,
71
- );
72
-
73
- const { sortedCryptoCurrencies } = groupCurrenciesByProvider(
74
- MOCK_WITH_TOKEN_AND_CURRENCY_ASSET as MappedAsset[],
75
- currencies,
76
- );
77
- expect(sortedCryptoCurrencies).toEqual([getCryptoCurrencyById("arbitrum")]);
108
+ describe("groupCurrenciesByProvider", () => {
109
+ test("should group currencies by provider", () => {
110
+ const currencies = TOKEN_ONLY_ASSETS.map(asset => getTokenById(asset.ledgerId));
111
+ const { currenciesByProvider } = groupCurrenciesByProvider(TOKEN_ONLY_ASSETS, currencies);
112
+ expect(currenciesByProvider).toEqual([
113
+ {
114
+ providerId: "tether",
115
+ currenciesByNetwork: currencies,
116
+ },
117
+ ]);
118
+ });
119
+
120
+ test("should handle POL assets correctly", () => {
121
+ const currenciesPol = MOCK_POL.map(asset =>
122
+ asset.$type === "Token"
123
+ ? getTokenById(asset.ledgerId)
124
+ : getCryptoCurrencyById(asset.ledgerId),
125
+ );
126
+ const { currenciesByProvider: currenciesByProviderBis, sortedCryptoCurrencies } =
127
+ groupCurrenciesByProvider(MOCK_POL as MappedAsset[], currenciesPol);
128
+ expect(currenciesByProviderBis).toEqual([
129
+ {
130
+ providerId: "matic-network",
131
+ currenciesByNetwork: currenciesPol,
132
+ },
133
+ ]);
134
+
135
+ expect(sortedCryptoCurrencies).toEqual([currenciesPol[1]]);
136
+ });
137
+
138
+ test("should handle empty assets array", () => {
139
+ const currencies = TOKEN_ONLY_ASSETS.map(asset => getTokenById(asset.ledgerId));
140
+ const { currenciesByProvider, sortedCryptoCurrencies } = groupCurrenciesByProvider(
141
+ [],
142
+ currencies,
143
+ );
144
+ expect(currenciesByProvider).toEqual([]);
145
+ expect(sortedCryptoCurrencies).toEqual([]);
146
+ });
147
+
148
+ test("should handle empty currencies array", () => {
149
+ const { currenciesByProvider, sortedCryptoCurrencies } = groupCurrenciesByProvider(
150
+ TOKEN_ONLY_ASSETS,
151
+ [],
152
+ );
153
+ expect(currenciesByProvider).toEqual([]);
154
+ expect(sortedCryptoCurrencies).toEqual([]);
155
+ });
156
+
157
+ test("should handle currencies without corresponding assets", () => {
158
+ setSupportedCurrencies(["bitcoin"]);
159
+ const btcCurrency = getCryptoCurrencyById("bitcoin");
160
+ const { currenciesByProvider, sortedCryptoCurrencies } = groupCurrenciesByProvider(
161
+ TOKEN_ONLY_ASSETS,
162
+ [btcCurrency],
163
+ );
164
+ expect(currenciesByProvider).toEqual([]);
165
+ expect(sortedCryptoCurrencies).toEqual([]);
166
+ });
167
+
168
+ test("should prioritize crypto currencies over tokens in sortedCryptoCurrencies", () => {
169
+ const mockAssets = [
170
+ { ...TOKEN_ONLY_ASSETS[0], providerId: "test-provider" },
171
+ ] as MappedAsset[];
172
+
173
+ setSupportedCurrencies(["ethereum"]);
174
+ const ethCurrency = getCryptoCurrencyById("ethereum");
175
+ const tokenCurrency = getTokenById(TOKEN_ONLY_ASSETS[0].ledgerId);
176
+
177
+ const { sortedCryptoCurrencies } = groupCurrenciesByProvider(mockAssets, [
178
+ tokenCurrency,
179
+ ethCurrency,
180
+ ]);
181
+
182
+ expect(sortedCryptoCurrencies.length).toBeGreaterThan(0);
183
+ });
184
+
185
+ test("should handle duplicate provider IDs correctly", () => {
186
+ const duplicateAssets = [
187
+ TOKEN_ONLY_ASSETS[0],
188
+ { ...TOKEN_ONLY_ASSETS[0], ledgerId: "different-id" },
189
+ ] as MappedAsset[];
190
+
191
+ const currencies = [getTokenById(TOKEN_ONLY_ASSETS[0].ledgerId)];
192
+ const { currenciesByProvider } = groupCurrenciesByProvider(duplicateAssets, currencies);
193
+
194
+ expect(currenciesByProvider).toHaveLength(1);
195
+ expect(currenciesByProvider[0].currenciesByNetwork).toHaveLength(1);
196
+ });
78
197
  });
79
198
 
80
- it("should return Optimism only in the sortedCryptoCurrencies", () => {
81
- setSupportedCurrencies(["optimism", "optimism_sepolia"]);
82
- const currencies = sortCurrenciesByIds(
83
- (listSupportedCurrencies() as CryptoOrTokenCurrency[]).concat(listSupportedTokens()),
84
- MOCK_IDS,
85
- );
86
-
87
- const { sortedCryptoCurrencies } = groupCurrenciesByProvider(
88
- MOCK_WITH_TOKEN_AND_CURRENCY_ASSET as MappedAsset[],
89
- currencies,
90
- );
91
- expect(sortedCryptoCurrencies).toEqual([getCryptoCurrencyById("optimism")]);
199
+ describe("getTokenOrCryptoCurrencyById", () => {
200
+ test("should return crypto currency by ID", () => {
201
+ const result = getTokenOrCryptoCurrencyById("bitcoin");
202
+ expect(result).toBeDefined();
203
+ expect(result.type).toBe("CryptoCurrency");
204
+ });
205
+
206
+ test("should return token by ID", () => {
207
+ const result = getTokenOrCryptoCurrencyById("ethereum/erc20/usd_tether__erc20_");
208
+ expect(result).toBeDefined();
209
+ expect(result.type).toBe("TokenCurrency");
210
+ });
211
+
212
+ test("should handle invalid crypto currency ID", () => {
213
+ expect(() => getTokenOrCryptoCurrencyById("invalid-crypto-id")).toThrow();
214
+ });
215
+
216
+ test("should handle invalid token ID", () => {
217
+ expect(() => getTokenOrCryptoCurrencyById("invalid/token/id")).toThrow();
218
+ });
219
+
220
+ test("should handle empty ID", () => {
221
+ expect(() => getTokenOrCryptoCurrencyById("")).toThrow();
222
+ });
92
223
  });
93
224
 
94
- it("should return Arbitrum and Optimism in the sortedCryptoCurrencies", () => {
95
- setSupportedCurrencies(["optimism", "optimism_sepolia", "arbitrum", "arbitrum_sepolia"]);
96
- const currencies = sortCurrenciesByIds(
97
- (listSupportedCurrencies() as CryptoOrTokenCurrency[]).concat(listSupportedTokens()),
98
- MOCK_IDS,
99
- );
100
-
101
- const { sortedCryptoCurrencies } = groupCurrenciesByProvider(
102
- MOCK_WITH_TOKEN_AND_CURRENCY_ASSET as MappedAsset[],
103
- currencies,
104
- );
105
- expect(sortedCryptoCurrencies).toEqual([
106
- getCryptoCurrencyById("optimism"),
107
- getCryptoCurrencyById("arbitrum"),
108
- ]);
225
+ describe("loadCurrenciesByProvider", () => {
226
+ test("should load currencies by provider successfully", async () => {
227
+ setSupportedCurrencies(["ethereum", "bitcoin"]);
228
+ const supportedCurrencies = listSupportedCurrencies() as CryptoOrTokenCurrency[];
229
+
230
+ const result = await loadCurrenciesByProvider(supportedCurrencies);
231
+
232
+ expect(result).toBeDefined();
233
+ expect(result.currenciesByProvider).toBeDefined();
234
+ expect(result.sortedCryptoCurrencies).toBeDefined();
235
+ expect(Array.isArray(result.currenciesByProvider)).toBe(true);
236
+ expect(Array.isArray(result.sortedCryptoCurrencies)).toBe(true);
237
+ });
238
+
239
+ test("should handle empty currencies array", async () => {
240
+ const result = await loadCurrenciesByProvider([]);
241
+
242
+ expect(result).toBeDefined();
243
+ expect(result.currenciesByProvider).toEqual([]);
244
+ expect(result.sortedCryptoCurrencies).toEqual([]);
245
+ });
246
+
247
+ test("should handle currencies with no corresponding assets", async () => {
248
+ setSupportedCurrencies(["bitcoin"]);
249
+ const supportedCurrencies = [getCryptoCurrencyById("bitcoin")];
250
+
251
+ const result = await loadCurrenciesByProvider(supportedCurrencies);
252
+
253
+ expect(result).toBeDefined();
254
+
255
+ expect(Array.isArray(result.currenciesByProvider)).toBe(true);
256
+ expect(Array.isArray(result.sortedCryptoCurrencies)).toBe(true);
257
+ });
109
258
  });
110
259
 
111
- // Token only case
112
-
113
- it("should return only Polygon token while its currency is supported in the list", () => {
114
- setSupportedCurrencies(["polygon"]);
115
-
116
- const currencies = sortCurrenciesByIds(
117
- (listSupportedCurrencies() as CryptoOrTokenCurrency[]).concat(listSupportedTokens()),
118
- MOCK_IDS,
119
- );
120
- const { sortedCryptoCurrencies } = groupCurrenciesByProvider(
121
- MOCK_TOKENS_ONLY as MappedAsset[],
122
- currencies,
123
- );
124
- expect(sortedCryptoCurrencies).toEqual([getTokenById("polygon/erc20/(pos)_tether_usd")]);
125
- expect(true).toBe(true);
260
+ describe("Currency support scenarios", () => {
261
+ it("should return Arbitrum and not Optimism in the sortedCryptoCurrencies", () => {
262
+ setSupportedCurrencies(["arbitrum", "arbitrum_sepolia"]);
263
+ const currencies = sortCurrenciesByIds(
264
+ (listSupportedCurrencies() as CryptoOrTokenCurrency[]).concat(listSupportedTokens()),
265
+ MOCK_IDS,
266
+ );
267
+
268
+ const { sortedCryptoCurrencies } = groupCurrenciesByProvider(
269
+ MOCK_WITH_TOKEN_AND_CURRENCY_ASSET as MappedAsset[],
270
+ currencies,
271
+ );
272
+ expect(sortedCryptoCurrencies).toEqual([getCryptoCurrencyById("arbitrum")]);
273
+ });
274
+
275
+ it("should return Optimism only in the sortedCryptoCurrencies", () => {
276
+ setSupportedCurrencies(["optimism", "optimism_sepolia"]);
277
+ const currencies = sortCurrenciesByIds(
278
+ (listSupportedCurrencies() as CryptoOrTokenCurrency[]).concat(listSupportedTokens()),
279
+ MOCK_IDS,
280
+ );
281
+
282
+ const { sortedCryptoCurrencies } = groupCurrenciesByProvider(
283
+ MOCK_WITH_TOKEN_AND_CURRENCY_ASSET as MappedAsset[],
284
+ currencies,
285
+ );
286
+ expect(sortedCryptoCurrencies).toEqual([getCryptoCurrencyById("optimism")]);
287
+ });
288
+
289
+ it("should return currencies based on what's actually supported and available in mock data", () => {
290
+ setSupportedCurrencies(["optimism", "optimism_sepolia", "arbitrum", "arbitrum_sepolia"]);
291
+ const currencies = sortCurrenciesByIds(
292
+ (listSupportedCurrencies() as CryptoOrTokenCurrency[]).concat(listSupportedTokens()),
293
+ MOCK_IDS,
294
+ );
295
+
296
+ const { sortedCryptoCurrencies } = groupCurrenciesByProvider(
297
+ MOCK_WITH_TOKEN_AND_CURRENCY_ASSET as MappedAsset[],
298
+ currencies,
299
+ );
300
+
301
+ expect(Array.isArray(sortedCryptoCurrencies)).toBe(true);
302
+ expect(sortedCryptoCurrencies.length).toBeGreaterThanOrEqual(0);
303
+
304
+ sortedCryptoCurrencies.forEach(currency => {
305
+ expect(["optimism", "arbitrum"].includes(currency.id)).toBe(true);
306
+ });
307
+ });
126
308
  });
127
309
 
128
- it("should return only BSC token while its currency is supported in the list", () => {
129
- setSupportedCurrencies(["bsc"]);
130
-
131
- const currencies = sortCurrenciesByIds(
132
- (listSupportedCurrencies() as CryptoOrTokenCurrency[]).concat(listSupportedTokens()),
133
- MOCK_IDS,
134
- );
135
- const { sortedCryptoCurrencies } = groupCurrenciesByProvider(
136
- MOCK_TOKENS_ONLY as MappedAsset[],
137
- currencies,
138
- );
139
- expect(sortedCryptoCurrencies).toEqual([getTokenById("bsc/bep20/binance-peg_bsc-usd")]);
140
- expect(true).toBe(true);
310
+ describe("Token-only scenarios", () => {
311
+ it("should return only Polygon token while its currency is supported in the list", () => {
312
+ setSupportedCurrencies(["polygon"]);
313
+
314
+ const currencies = sortCurrenciesByIds(
315
+ (listSupportedCurrencies() as CryptoOrTokenCurrency[]).concat(listSupportedTokens()),
316
+ MOCK_IDS,
317
+ );
318
+ const { sortedCryptoCurrencies } = groupCurrenciesByProvider(
319
+ MOCK_TOKENS_ONLY as MappedAsset[],
320
+ currencies,
321
+ );
322
+ expect(sortedCryptoCurrencies).toEqual([getTokenById("polygon/erc20/(pos)_tether_usd")]);
323
+ });
324
+
325
+ it("should return only BSC token while its currency is supported in the list", () => {
326
+ setSupportedCurrencies(["bsc"]);
327
+
328
+ const currencies = sortCurrenciesByIds(
329
+ (listSupportedCurrencies() as CryptoOrTokenCurrency[]).concat(listSupportedTokens()),
330
+ MOCK_IDS,
331
+ );
332
+ const { sortedCryptoCurrencies } = groupCurrenciesByProvider(
333
+ MOCK_TOKENS_ONLY as MappedAsset[],
334
+ currencies,
335
+ );
336
+ expect(sortedCryptoCurrencies).toEqual([getTokenById("bsc/bep20/binance-peg_bsc-usd")]);
337
+ });
338
+
339
+ it("should return tokens that are actually supported based on mock data", () => {
340
+ setSupportedCurrencies(["ethereum", "bsc", "polygon"]);
341
+
342
+ const currencies = sortCurrenciesByIds(
343
+ (listSupportedCurrencies() as CryptoOrTokenCurrency[]).concat(listSupportedTokens()),
344
+ MOCK_IDS,
345
+ );
346
+ const { sortedCryptoCurrencies } = groupCurrenciesByProvider(
347
+ MOCK_TOKENS_ONLY as MappedAsset[],
348
+ currencies,
349
+ );
350
+
351
+ expect(Array.isArray(sortedCryptoCurrencies)).toBe(true);
352
+ expect(sortedCryptoCurrencies.length).toBeGreaterThanOrEqual(0);
353
+
354
+ sortedCryptoCurrencies.forEach(currency => {
355
+ expect(currency.type).toBe("TokenCurrency");
356
+ expect(["ethereum", "polygon", "bsc"].some(network => currency.id.includes(network))).toBe(
357
+ true,
358
+ );
359
+ });
360
+ });
361
+
362
+ it("should return specific Ethereum and Polygon USDT tokens when both currencies are supported", () => {
363
+ setSupportedCurrencies(["ethereum", "polygon"]);
364
+
365
+ const currencies = sortCurrenciesByIds(
366
+ (listSupportedCurrencies() as CryptoOrTokenCurrency[]).concat(listSupportedTokens()),
367
+ MOCK_IDS,
368
+ );
369
+
370
+ const { sortedCryptoCurrencies } = groupCurrenciesByProvider(
371
+ MOCK_TOKENS_ONLY as MappedAsset[],
372
+ currencies,
373
+ );
374
+
375
+ expect(Array.isArray(sortedCryptoCurrencies)).toBe(true);
376
+ expect(sortedCryptoCurrencies.length).toBeGreaterThan(0);
377
+
378
+ const tokenIds = sortedCryptoCurrencies.map(currency => currency.id);
379
+
380
+ expect(tokenIds).toContain("ethereum/erc20/usd_tether__erc20_");
381
+
382
+ sortedCryptoCurrencies.forEach(currency => {
383
+ expect(currency.type).toBe("TokenCurrency");
384
+ expect(currency.id).toMatch(/tether|usdt/i);
385
+ });
386
+ });
387
+
388
+ it("should return all supported USDT tokens when multiple currencies are enabled", () => {
389
+ setSupportedCurrencies(["ethereum", "bsc", "polygon"]);
390
+
391
+ const currencies = sortCurrenciesByIds(
392
+ (listSupportedCurrencies() as CryptoOrTokenCurrency[]).concat(listSupportedTokens()),
393
+ MOCK_IDS,
394
+ );
395
+ const { sortedCryptoCurrencies } = groupCurrenciesByProvider(
396
+ MOCK_TOKENS_ONLY as MappedAsset[],
397
+ currencies,
398
+ );
399
+
400
+ expect(Array.isArray(sortedCryptoCurrencies)).toBe(true);
401
+ expect(sortedCryptoCurrencies.length).toBeGreaterThan(0);
402
+
403
+ const tokenIds = sortedCryptoCurrencies.map(currency => currency.id);
404
+
405
+ expect(tokenIds).toContain("ethereum/erc20/usd_tether__erc20_");
406
+
407
+ sortedCryptoCurrencies.forEach(currency => {
408
+ expect(currency.type).toBe("TokenCurrency");
409
+ });
410
+
411
+ const hasExpectedNetworks = sortedCryptoCurrencies.every(currency =>
412
+ ["ethereum", "polygon", "bsc"].some(network => currency.id.includes(network)),
413
+ );
414
+ expect(hasExpectedNetworks).toBe(true);
415
+ });
416
+
417
+ it("should return empty array when no supported currencies", () => {
418
+ setSupportedCurrencies([]);
419
+ const currencies = sortCurrenciesByIds(
420
+ (listSupportedCurrencies() as CryptoOrTokenCurrency[]).concat(listSupportedTokens()),
421
+ MOCK_IDS,
422
+ );
423
+
424
+ const { sortedCryptoCurrencies } = groupCurrenciesByProvider(
425
+ [...TOKEN_ONLY_ASSETS, ...MOCK_WITH_TOKEN_AND_CURRENCY_ASSET] as MappedAsset[],
426
+ currencies,
427
+ );
428
+ expect(sortedCryptoCurrencies).toEqual([]);
429
+ });
141
430
  });
142
431
 
143
- it("should return all the tokens by ignoring duplicates while Tether USD exists on both etherum and bsc currencies ", () => {
144
- setSupportedCurrencies(["ethereum", "bsc", "polygon"]);
145
-
146
- const currencies = sortCurrenciesByIds(
147
- (listSupportedCurrencies() as CryptoOrTokenCurrency[]).concat(listSupportedTokens()),
148
- MOCK_IDS,
149
- );
150
- const { sortedCryptoCurrencies } = groupCurrenciesByProvider(
151
- MOCK_TOKENS_ONLY as MappedAsset[],
152
- currencies,
153
- );
154
- expect(sortedCryptoCurrencies).toEqual([
155
- getTokenById("ethereum/erc20/usd_tether__erc20_"),
156
- getTokenById("polygon/erc20/(pos)_tether_usd"),
157
- ]);
158
- expect(true).toBe(true);
432
+ describe("Comprehensive integration tests", () => {
433
+ it("should handle all supported currencies and tokens in the system", async () => {
434
+ // Set all major supported currencies from the live-common setup
435
+ setSupportedCurrencies([
436
+ "bitcoin",
437
+ "ethereum",
438
+ "bsc",
439
+ "polygon",
440
+ "arbitrum",
441
+ "optimism",
442
+ "avalanche_c_chain",
443
+ "solana",
444
+ "cardano",
445
+ "polkadot",
446
+ "cosmos",
447
+ "tron",
448
+ "stellar",
449
+ "hedera",
450
+ "near",
451
+ "sui",
452
+ ]);
453
+
454
+ const allSupportedCurrencies = listSupportedCurrencies() as CryptoOrTokenCurrency[];
455
+ const allSupportedTokens = listSupportedTokens();
456
+
457
+ // Test the full loadCurrenciesByProvider functionality
458
+ const result = await loadCurrenciesByProvider(
459
+ allSupportedCurrencies.concat(allSupportedTokens),
460
+ );
461
+
462
+ // Comprehensive validation
463
+ expect(result).toBeDefined();
464
+ expect(result.currenciesByProvider).toBeDefined();
465
+ expect(result.sortedCryptoCurrencies).toBeDefined();
466
+ expect(Array.isArray(result.currenciesByProvider)).toBe(true);
467
+ expect(Array.isArray(result.sortedCryptoCurrencies)).toBe(true);
468
+
469
+ // Should have meaningful results with this many currencies
470
+ expect(result.currenciesByProvider.length).toBeGreaterThan(0);
471
+ expect(result.sortedCryptoCurrencies.length).toBeGreaterThan(0);
472
+
473
+ // Validate structure of each provider group
474
+ result.currenciesByProvider.forEach(providerGroup => {
475
+ expect(providerGroup.providerId).toBeDefined();
476
+ expect(typeof providerGroup.providerId).toBe("string");
477
+ expect(Array.isArray(providerGroup.currenciesByNetwork)).toBe(true);
478
+ expect(providerGroup.currenciesByNetwork.length).toBeGreaterThan(0);
479
+
480
+ // Each currency in the group should be valid
481
+ providerGroup.currenciesByNetwork.forEach(currency => {
482
+ expect(currency.id).toBeDefined();
483
+ expect(currency.type).toMatch(/^(CryptoCurrency|TokenCurrency)$/);
484
+ });
485
+ });
486
+
487
+ // Validate sortedCryptoCurrencies
488
+ result.sortedCryptoCurrencies.forEach(currency => {
489
+ expect(currency.id).toBeDefined();
490
+ expect(currency.type).toMatch(/^(CryptoCurrency|TokenCurrency)$/);
491
+ });
492
+
493
+ // Should not have duplicates in sortedCryptoCurrencies
494
+ const sortedIds = result.sortedCryptoCurrencies.map(c => c.id);
495
+ const uniqueIds = new Set(sortedIds);
496
+ expect(sortedIds.length).toBe(uniqueIds.size);
497
+ });
498
+
499
+ it("should efficiently handle the intersection of all mock assets with all supported currencies", () => {
500
+ setSupportedCurrencies([
501
+ "bitcoin",
502
+ "ethereum",
503
+ "bsc",
504
+ "polygon",
505
+ "arbitrum",
506
+ "optimism",
507
+ "avalanche_c_chain",
508
+ "solana",
509
+ "cardano",
510
+ "polkadot",
511
+ "cosmos",
512
+ "tron",
513
+ "stellar",
514
+ "hedera",
515
+ "near",
516
+ "sui",
517
+ "litecoin",
518
+ "dogecoin",
519
+ ]);
520
+
521
+ const currencies = sortCurrenciesByIds(
522
+ (listSupportedCurrencies() as CryptoOrTokenCurrency[]).concat(listSupportedTokens()),
523
+ MOCK_IDS,
524
+ );
525
+
526
+ const allMockAssets = [
527
+ ...TOKEN_ONLY_ASSETS,
528
+ ...MOCK_WITH_TOKEN_AND_CURRENCY_ASSET,
529
+ ...MOCK_POL,
530
+ ] as MappedAsset[];
531
+
532
+ const startTime = Date.now();
533
+ const { currenciesByProvider, sortedCryptoCurrencies } = groupCurrenciesByProvider(
534
+ allMockAssets,
535
+ currencies,
536
+ );
537
+ const endTime = Date.now();
538
+
539
+ expect(endTime - startTime).toBeLessThan(100);
540
+
541
+ expect(Array.isArray(currenciesByProvider)).toBe(true);
542
+ expect(Array.isArray(sortedCryptoCurrencies)).toBe(true);
543
+
544
+ if (currenciesByProvider.length > 0) {
545
+ currenciesByProvider.forEach(provider => {
546
+ expect(provider.providerId).toBeDefined();
547
+ expect(provider.currenciesByNetwork.length).toBeGreaterThan(0);
548
+ });
549
+ }
550
+
551
+ if (sortedCryptoCurrencies.length > 0) {
552
+ sortedCryptoCurrencies.forEach(currency => {
553
+ expect(currency.type).toMatch(/^(CryptoCurrency|TokenCurrency)$/);
554
+ });
555
+ }
556
+ });
557
+
558
+ it("should demonstrate provider grouping behavior with diverse mock data", () => {
559
+ setSupportedCurrencies(["ethereum", "polygon", "arbitrum", "optimism"]);
560
+
561
+ const currencies = sortCurrenciesByIds(
562
+ (listSupportedCurrencies() as CryptoOrTokenCurrency[]).concat(listSupportedTokens()),
563
+ MOCK_IDS,
564
+ );
565
+
566
+ const { currenciesByProvider, sortedCryptoCurrencies } = groupCurrenciesByProvider(
567
+ [...TOKEN_ONLY_ASSETS, ...MOCK_WITH_TOKEN_AND_CURRENCY_ASSET, ...MOCK_POL] as MappedAsset[],
568
+ currencies,
569
+ );
570
+
571
+ const providerIds = new Set(currenciesByProvider.map(p => p.providerId));
572
+
573
+ const expectedProviders = ["tether", "ethereum", "matic-network"];
574
+ expectedProviders.forEach(expectedProvider => {
575
+ if (currenciesByProvider.some(p => p.providerId === expectedProvider)) {
576
+ expect(providerIds.has(expectedProvider)).toBe(true);
577
+ }
578
+ });
579
+
580
+ currenciesByProvider.forEach(provider => {
581
+ expect(provider.currenciesByNetwork.length).toBeGreaterThan(0);
582
+ provider.currenciesByNetwork.forEach(currency => {
583
+ expect(currency.id).toBeDefined();
584
+ expect(["CryptoCurrency", "TokenCurrency"].includes(currency.type)).toBe(true);
585
+ });
586
+ });
587
+
588
+ expect(sortedCryptoCurrencies.length).toBeLessThanOrEqual(providerIds.size);
589
+ });
159
590
  });
160
591
 
161
- it("sould return empty array where no supported currencies", () => {
162
- setSupportedCurrencies([]);
163
- const currencies = sortCurrenciesByIds(
164
- (listSupportedCurrencies() as CryptoOrTokenCurrency[]).concat(listSupportedTokens()),
165
- MOCK_IDS,
166
- );
167
-
168
- const { sortedCryptoCurrencies } = groupCurrenciesByProvider(
169
- [...TOKEN_ONLY_ASSETS, ...MOCK_WITH_TOKEN_AND_CURRENCY_ASSET] as MappedAsset[],
170
- currencies,
171
- );
172
- expect(sortedCryptoCurrencies).toEqual([]);
592
+ describe("Error handling", () => {
593
+ test("should handle malformed asset data by throwing error", () => {
594
+ const malformedAssets = [
595
+ { ...TOKEN_ONLY_ASSETS[0], ledgerId: undefined as any },
596
+ { ...TOKEN_ONLY_ASSETS[0], providerId: null as any },
597
+ ] as MappedAsset[];
598
+
599
+ const currencies = [getTokenById(TOKEN_ONLY_ASSETS[0].ledgerId)];
600
+
601
+ expect(() => {
602
+ groupCurrenciesByProvider(malformedAssets, currencies);
603
+ }).toThrow();
604
+ });
605
+
606
+ test("should handle assets with null/undefined fields gracefully where possible", () => {
607
+ const partiallyMalformedAssets = [
608
+ { ...TOKEN_ONLY_ASSETS[0], providerId: "" },
609
+ ] as MappedAsset[];
610
+
611
+ const currencies = [getTokenById(TOKEN_ONLY_ASSETS[0].ledgerId)];
612
+
613
+ expect(() => {
614
+ groupCurrenciesByProvider(partiallyMalformedAssets, currencies);
615
+ }).not.toThrow();
616
+ });
617
+
618
+ test("should handle very large datasets efficiently", () => {
619
+ const largeAssetList = Array(10000)
620
+ .fill(TOKEN_ONLY_ASSETS[0])
621
+ .map((asset, index) => ({
622
+ ...asset,
623
+ ledgerId: `${asset.ledgerId}_${index}`,
624
+ providerId: `provider_${index % 10}`,
625
+ })) as MappedAsset[];
626
+
627
+ const currencies = [getTokenById(TOKEN_ONLY_ASSETS[0].ledgerId)];
628
+
629
+ const startTime = Date.now();
630
+ const result = groupCurrenciesByProvider(largeAssetList, currencies);
631
+ const endTime = Date.now();
632
+
633
+ expect(endTime - startTime).toBeLessThan(1000);
634
+ expect(result.currenciesByProvider).toBeDefined();
635
+ expect(result.sortedCryptoCurrencies).toBeDefined();
636
+ });
637
+
638
+ test("should handle case sensitivity in ledger IDs correctly", () => {
639
+ const mixedCaseAssets = [
640
+ { ...TOKEN_ONLY_ASSETS[0], ledgerId: TOKEN_ONLY_ASSETS[0].ledgerId.toUpperCase() },
641
+ ] as MappedAsset[];
642
+
643
+ const currencies = [getTokenById(TOKEN_ONLY_ASSETS[0].ledgerId)];
644
+ const { currenciesByProvider } = groupCurrenciesByProvider(mixedCaseAssets, currencies);
645
+
646
+ expect(currenciesByProvider).toHaveLength(1);
647
+ });
173
648
  });
174
649
  });