@ledgerhq/live-common 34.51.0-nightly.2 → 34.51.0-nightly.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 (281) hide show
  1. package/lib/bridge/crypto-assets/index.d.ts.map +1 -1
  2. package/lib/bridge/crypto-assets/index.js +0 -2
  3. package/lib/bridge/crypto-assets/index.js.map +1 -1
  4. package/lib/bridge/crypto-assets/index.test.js +0 -4
  5. package/lib/bridge/crypto-assets/index.test.js.map +1 -1
  6. package/lib/currencies/index.d.ts +1 -1
  7. package/lib/currencies/index.d.ts.map +1 -1
  8. package/lib/currencies/index.js +2 -3
  9. package/lib/currencies/index.js.map +1 -1
  10. package/lib/currencies/sortByMarketcap.test.js +1 -3
  11. package/lib/currencies/sortByMarketcap.test.js.map +1 -1
  12. package/lib/e2e/enum/Account.d.ts +4 -0
  13. package/lib/e2e/enum/Account.d.ts.map +1 -1
  14. package/lib/e2e/enum/Account.js +4 -0
  15. package/lib/e2e/enum/Account.js.map +1 -1
  16. package/lib/e2e/enum/AppInfos.d.ts +1 -0
  17. package/lib/e2e/enum/AppInfos.d.ts.map +1 -1
  18. package/lib/e2e/enum/AppInfos.js +1 -0
  19. package/lib/e2e/enum/AppInfos.js.map +1 -1
  20. package/lib/e2e/enum/Currency.d.ts +2 -0
  21. package/lib/e2e/enum/Currency.d.ts.map +1 -1
  22. package/lib/e2e/enum/Currency.js +2 -0
  23. package/lib/e2e/enum/Currency.js.map +1 -1
  24. package/lib/e2e/enum/Network.d.ts +2 -1
  25. package/lib/e2e/enum/Network.d.ts.map +1 -1
  26. package/lib/e2e/enum/Network.js +1 -0
  27. package/lib/e2e/enum/Network.js.map +1 -1
  28. package/lib/e2e/enum/TokenType.d.ts +2 -1
  29. package/lib/e2e/enum/TokenType.d.ts.map +1 -1
  30. package/lib/e2e/enum/TokenType.js +1 -0
  31. package/lib/e2e/enum/TokenType.js.map +1 -1
  32. package/lib/e2e/enum/TransactionStatus.d.ts +4 -1
  33. package/lib/e2e/enum/TransactionStatus.d.ts.map +1 -1
  34. package/lib/e2e/enum/TransactionStatus.js +3 -0
  35. package/lib/e2e/enum/TransactionStatus.js.map +1 -1
  36. package/lib/e2e/families/sui.d.ts +2 -0
  37. package/lib/e2e/families/sui.d.ts.map +1 -0
  38. package/lib/e2e/families/sui.js +11 -0
  39. package/lib/e2e/families/sui.js.map +1 -0
  40. package/lib/e2e/index.d.ts +3 -0
  41. package/lib/e2e/index.d.ts.map +1 -1
  42. package/lib/e2e/speculos.d.ts +1 -0
  43. package/lib/e2e/speculos.d.ts.map +1 -1
  44. package/lib/e2e/speculos.js +23 -1
  45. package/lib/e2e/speculos.js.map +1 -1
  46. package/lib/env.react.d.ts +1 -1
  47. package/lib/env.react.d.ts.map +1 -1
  48. package/lib/exchange/providers/swap.js +4 -4
  49. package/lib/exchange/providers/swap.js.map +1 -1
  50. package/lib/exchange/swap/api/v5/__mocks__/fetchRates.mocks.d.ts.map +1 -1
  51. package/lib/exchange/swap/api/v5/__mocks__/fetchRates.mocks.js +1 -1
  52. package/lib/exchange/swap/api/v5/__mocks__/fetchRates.mocks.js.map +1 -1
  53. package/lib/exchange/swap/mock.js +1 -1
  54. package/lib/exchange/swap/mock.js.map +1 -1
  55. package/lib/featureFlags/defaultFeatures.d.ts.map +1 -1
  56. package/lib/featureFlags/defaultFeatures.js +4 -0
  57. package/lib/featureFlags/defaultFeatures.js.map +1 -1
  58. package/lib/featureFlags/useFeature.d.ts +1 -1
  59. package/lib/featureFlags/useFeature.d.ts.map +1 -1
  60. package/lib/hooks/useManifestWithSessionId.d.ts +12 -0
  61. package/lib/hooks/useManifestWithSessionId.d.ts.map +1 -0
  62. package/lib/hooks/useManifestWithSessionId.js +67 -0
  63. package/lib/hooks/useManifestWithSessionId.js.map +1 -0
  64. package/lib/hooks/useManifestWithSessionId.test.d.ts +2 -0
  65. package/lib/hooks/useManifestWithSessionId.test.d.ts.map +1 -0
  66. package/lib/hooks/useManifestWithSessionId.test.js +71 -0
  67. package/lib/hooks/useManifestWithSessionId.test.js.map +1 -0
  68. package/lib/market/utils/index.d.ts +1 -0
  69. package/lib/market/utils/index.d.ts.map +1 -1
  70. package/lib/market/utils/index.js +16 -0
  71. package/lib/market/utils/index.js.map +1 -1
  72. package/lib/modularDrawer/hooks/__tests__/useDetailedAccountsCore.test.d.ts +2 -0
  73. package/lib/modularDrawer/hooks/__tests__/useDetailedAccountsCore.test.d.ts.map +1 -0
  74. package/lib/modularDrawer/hooks/__tests__/useDetailedAccountsCore.test.js +350 -0
  75. package/lib/modularDrawer/hooks/__tests__/useDetailedAccountsCore.test.js.map +1 -0
  76. package/lib/modularDrawer/hooks/index.d.ts +2 -0
  77. package/lib/modularDrawer/hooks/index.d.ts.map +1 -0
  78. package/lib/modularDrawer/hooks/index.js +6 -0
  79. package/lib/modularDrawer/hooks/index.js.map +1 -0
  80. package/lib/modularDrawer/hooks/useDetailedAccountsCore.d.ts +14 -0
  81. package/lib/modularDrawer/hooks/useDetailedAccountsCore.d.ts.map +1 -0
  82. package/lib/modularDrawer/hooks/useDetailedAccountsCore.js +119 -0
  83. package/lib/modularDrawer/hooks/useDetailedAccountsCore.js.map +1 -0
  84. package/lib/modularDrawer/hooks/useRightBalanceAsset.d.ts.map +1 -1
  85. package/lib/modularDrawer/hooks/useRightBalanceAsset.js +9 -1
  86. package/lib/modularDrawer/hooks/useRightBalanceAsset.js.map +1 -1
  87. package/lib/modularDrawer/hooks/useRightBalanceNetwork.d.ts +6 -1
  88. package/lib/modularDrawer/hooks/useRightBalanceNetwork.d.ts.map +1 -1
  89. package/lib/modularDrawer/hooks/useRightBalanceNetwork.js +12 -4
  90. package/lib/modularDrawer/hooks/useRightBalanceNetwork.js.map +1 -1
  91. package/lib/modularDrawer/index.d.ts +4 -0
  92. package/lib/modularDrawer/index.d.ts.map +1 -0
  93. package/lib/modularDrawer/index.js +20 -0
  94. package/lib/modularDrawer/index.js.map +1 -0
  95. package/lib/modularDrawer/types/detailedAccount.d.ts +46 -0
  96. package/lib/modularDrawer/types/detailedAccount.d.ts.map +1 -0
  97. package/lib/modularDrawer/types/detailedAccount.js +3 -0
  98. package/lib/modularDrawer/types/detailedAccount.js.map +1 -0
  99. package/lib/modularDrawer/types/index.d.ts +2 -0
  100. package/lib/modularDrawer/types/index.d.ts.map +1 -0
  101. package/lib/modularDrawer/types/index.js +18 -0
  102. package/lib/modularDrawer/types/index.js.map +1 -0
  103. package/lib/modularDrawer/utils/__tests__/sortAccountsByFiatValue.test.d.ts +2 -0
  104. package/lib/modularDrawer/utils/__tests__/sortAccountsByFiatValue.test.d.ts.map +1 -0
  105. package/lib/modularDrawer/utils/__tests__/sortAccountsByFiatValue.test.js +106 -0
  106. package/lib/modularDrawer/utils/__tests__/sortAccountsByFiatValue.test.js.map +1 -0
  107. package/lib/modularDrawer/utils/getBalanceAndFiatValueByAssets.d.ts +3 -4
  108. package/lib/modularDrawer/utils/getBalanceAndFiatValueByAssets.d.ts.map +1 -1
  109. package/lib/modularDrawer/utils/getBalanceAndFiatValueByAssets.js +7 -0
  110. package/lib/modularDrawer/utils/getBalanceAndFiatValueByAssets.js.map +1 -1
  111. package/lib/modularDrawer/utils/index.d.ts +1 -0
  112. package/lib/modularDrawer/utils/index.d.ts.map +1 -1
  113. package/lib/modularDrawer/utils/index.js +3 -1
  114. package/lib/modularDrawer/utils/index.js.map +1 -1
  115. package/lib/modularDrawer/utils/sortAccountsByFiatValue.d.ts +8 -0
  116. package/lib/modularDrawer/utils/sortAccountsByFiatValue.d.ts.map +1 -0
  117. package/lib/modularDrawer/utils/sortAccountsByFiatValue.js +17 -0
  118. package/lib/modularDrawer/utils/sortAccountsByFiatValue.js.map +1 -0
  119. package/lib/modularDrawer/utils/type.d.ts +2 -2
  120. package/lib/modularDrawer/utils/type.d.ts.map +1 -1
  121. package/lib/platform/providers/RemoteLiveAppProvider/api/mock.json +3 -3
  122. package/lib/wallet-api/useDappLogic.js +1 -1
  123. package/lib/wallet-api/useDappLogic.js.map +1 -1
  124. package/lib-es/bridge/crypto-assets/index.d.ts.map +1 -1
  125. package/lib-es/bridge/crypto-assets/index.js +0 -2
  126. package/lib-es/bridge/crypto-assets/index.js.map +1 -1
  127. package/lib-es/bridge/crypto-assets/index.test.js +0 -4
  128. package/lib-es/bridge/crypto-assets/index.test.js.map +1 -1
  129. package/lib-es/currencies/index.d.ts +1 -1
  130. package/lib-es/currencies/index.d.ts.map +1 -1
  131. package/lib-es/currencies/index.js +1 -1
  132. package/lib-es/currencies/index.js.map +1 -1
  133. package/lib-es/currencies/sortByMarketcap.test.js +1 -3
  134. package/lib-es/currencies/sortByMarketcap.test.js.map +1 -1
  135. package/lib-es/e2e/enum/Account.d.ts +4 -0
  136. package/lib-es/e2e/enum/Account.d.ts.map +1 -1
  137. package/lib-es/e2e/enum/Account.js +4 -0
  138. package/lib-es/e2e/enum/Account.js.map +1 -1
  139. package/lib-es/e2e/enum/AppInfos.d.ts +1 -0
  140. package/lib-es/e2e/enum/AppInfos.d.ts.map +1 -1
  141. package/lib-es/e2e/enum/AppInfos.js +1 -0
  142. package/lib-es/e2e/enum/AppInfos.js.map +1 -1
  143. package/lib-es/e2e/enum/Currency.d.ts +2 -0
  144. package/lib-es/e2e/enum/Currency.d.ts.map +1 -1
  145. package/lib-es/e2e/enum/Currency.js +2 -0
  146. package/lib-es/e2e/enum/Currency.js.map +1 -1
  147. package/lib-es/e2e/enum/Network.d.ts +2 -1
  148. package/lib-es/e2e/enum/Network.d.ts.map +1 -1
  149. package/lib-es/e2e/enum/Network.js +1 -0
  150. package/lib-es/e2e/enum/Network.js.map +1 -1
  151. package/lib-es/e2e/enum/TokenType.d.ts +2 -1
  152. package/lib-es/e2e/enum/TokenType.d.ts.map +1 -1
  153. package/lib-es/e2e/enum/TokenType.js +1 -0
  154. package/lib-es/e2e/enum/TokenType.js.map +1 -1
  155. package/lib-es/e2e/enum/TransactionStatus.d.ts +4 -1
  156. package/lib-es/e2e/enum/TransactionStatus.d.ts.map +1 -1
  157. package/lib-es/e2e/enum/TransactionStatus.js +3 -0
  158. package/lib-es/e2e/enum/TransactionStatus.js.map +1 -1
  159. package/lib-es/e2e/families/sui.d.ts +2 -0
  160. package/lib-es/e2e/families/sui.d.ts.map +1 -0
  161. package/lib-es/e2e/families/sui.js +7 -0
  162. package/lib-es/e2e/families/sui.js.map +1 -0
  163. package/lib-es/e2e/index.d.ts +3 -0
  164. package/lib-es/e2e/index.d.ts.map +1 -1
  165. package/lib-es/e2e/speculos.d.ts +1 -0
  166. package/lib-es/e2e/speculos.d.ts.map +1 -1
  167. package/lib-es/e2e/speculos.js +21 -0
  168. package/lib-es/e2e/speculos.js.map +1 -1
  169. package/lib-es/env.react.d.ts +1 -1
  170. package/lib-es/env.react.d.ts.map +1 -1
  171. package/lib-es/exchange/providers/swap.js +4 -4
  172. package/lib-es/exchange/providers/swap.js.map +1 -1
  173. package/lib-es/exchange/swap/api/v5/__mocks__/fetchRates.mocks.d.ts.map +1 -1
  174. package/lib-es/exchange/swap/api/v5/__mocks__/fetchRates.mocks.js +1 -1
  175. package/lib-es/exchange/swap/api/v5/__mocks__/fetchRates.mocks.js.map +1 -1
  176. package/lib-es/exchange/swap/mock.js +1 -1
  177. package/lib-es/exchange/swap/mock.js.map +1 -1
  178. package/lib-es/featureFlags/defaultFeatures.d.ts.map +1 -1
  179. package/lib-es/featureFlags/defaultFeatures.js +4 -0
  180. package/lib-es/featureFlags/defaultFeatures.js.map +1 -1
  181. package/lib-es/featureFlags/useFeature.d.ts +1 -1
  182. package/lib-es/featureFlags/useFeature.d.ts.map +1 -1
  183. package/lib-es/hooks/useManifestWithSessionId.d.ts +12 -0
  184. package/lib-es/hooks/useManifestWithSessionId.d.ts.map +1 -0
  185. package/lib-es/hooks/useManifestWithSessionId.js +60 -0
  186. package/lib-es/hooks/useManifestWithSessionId.js.map +1 -0
  187. package/lib-es/hooks/useManifestWithSessionId.test.d.ts +2 -0
  188. package/lib-es/hooks/useManifestWithSessionId.test.d.ts.map +1 -0
  189. package/lib-es/hooks/useManifestWithSessionId.test.js +69 -0
  190. package/lib-es/hooks/useManifestWithSessionId.test.js.map +1 -0
  191. package/lib-es/market/utils/index.d.ts +1 -0
  192. package/lib-es/market/utils/index.d.ts.map +1 -1
  193. package/lib-es/market/utils/index.js +2 -0
  194. package/lib-es/market/utils/index.js.map +1 -1
  195. package/lib-es/modularDrawer/hooks/__tests__/useDetailedAccountsCore.test.d.ts +2 -0
  196. package/lib-es/modularDrawer/hooks/__tests__/useDetailedAccountsCore.test.d.ts.map +1 -0
  197. package/lib-es/modularDrawer/hooks/__tests__/useDetailedAccountsCore.test.js +345 -0
  198. package/lib-es/modularDrawer/hooks/__tests__/useDetailedAccountsCore.test.js.map +1 -0
  199. package/lib-es/modularDrawer/hooks/index.d.ts +2 -0
  200. package/lib-es/modularDrawer/hooks/index.d.ts.map +1 -0
  201. package/lib-es/modularDrawer/hooks/index.js +2 -0
  202. package/lib-es/modularDrawer/hooks/index.js.map +1 -0
  203. package/lib-es/modularDrawer/hooks/useDetailedAccountsCore.d.ts +14 -0
  204. package/lib-es/modularDrawer/hooks/useDetailedAccountsCore.d.ts.map +1 -0
  205. package/lib-es/modularDrawer/hooks/useDetailedAccountsCore.js +115 -0
  206. package/lib-es/modularDrawer/hooks/useDetailedAccountsCore.js.map +1 -0
  207. package/lib-es/modularDrawer/hooks/useRightBalanceAsset.d.ts.map +1 -1
  208. package/lib-es/modularDrawer/hooks/useRightBalanceAsset.js +6 -1
  209. package/lib-es/modularDrawer/hooks/useRightBalanceAsset.js.map +1 -1
  210. package/lib-es/modularDrawer/hooks/useRightBalanceNetwork.d.ts +6 -1
  211. package/lib-es/modularDrawer/hooks/useRightBalanceNetwork.d.ts.map +1 -1
  212. package/lib-es/modularDrawer/hooks/useRightBalanceNetwork.js +9 -4
  213. package/lib-es/modularDrawer/hooks/useRightBalanceNetwork.js.map +1 -1
  214. package/lib-es/modularDrawer/index.d.ts +4 -0
  215. package/lib-es/modularDrawer/index.d.ts.map +1 -0
  216. package/lib-es/modularDrawer/index.js +4 -0
  217. package/lib-es/modularDrawer/index.js.map +1 -0
  218. package/lib-es/modularDrawer/types/detailedAccount.d.ts +46 -0
  219. package/lib-es/modularDrawer/types/detailedAccount.d.ts.map +1 -0
  220. package/lib-es/modularDrawer/types/detailedAccount.js +2 -0
  221. package/lib-es/modularDrawer/types/detailedAccount.js.map +1 -0
  222. package/lib-es/modularDrawer/types/index.d.ts +2 -0
  223. package/lib-es/modularDrawer/types/index.d.ts.map +1 -0
  224. package/lib-es/modularDrawer/types/index.js +2 -0
  225. package/lib-es/modularDrawer/types/index.js.map +1 -0
  226. package/lib-es/modularDrawer/utils/__tests__/sortAccountsByFiatValue.test.d.ts +2 -0
  227. package/lib-es/modularDrawer/utils/__tests__/sortAccountsByFiatValue.test.d.ts.map +1 -0
  228. package/lib-es/modularDrawer/utils/__tests__/sortAccountsByFiatValue.test.js +101 -0
  229. package/lib-es/modularDrawer/utils/__tests__/sortAccountsByFiatValue.test.js.map +1 -0
  230. package/lib-es/modularDrawer/utils/getBalanceAndFiatValueByAssets.d.ts +3 -4
  231. package/lib-es/modularDrawer/utils/getBalanceAndFiatValueByAssets.d.ts.map +1 -1
  232. package/lib-es/modularDrawer/utils/getBalanceAndFiatValueByAssets.js +4 -0
  233. package/lib-es/modularDrawer/utils/getBalanceAndFiatValueByAssets.js.map +1 -1
  234. package/lib-es/modularDrawer/utils/index.d.ts +1 -0
  235. package/lib-es/modularDrawer/utils/index.d.ts.map +1 -1
  236. package/lib-es/modularDrawer/utils/index.js +1 -0
  237. package/lib-es/modularDrawer/utils/index.js.map +1 -1
  238. package/lib-es/modularDrawer/utils/sortAccountsByFiatValue.d.ts +8 -0
  239. package/lib-es/modularDrawer/utils/sortAccountsByFiatValue.d.ts.map +1 -0
  240. package/lib-es/modularDrawer/utils/sortAccountsByFiatValue.js +13 -0
  241. package/lib-es/modularDrawer/utils/sortAccountsByFiatValue.js.map +1 -0
  242. package/lib-es/modularDrawer/utils/type.d.ts +2 -2
  243. package/lib-es/modularDrawer/utils/type.d.ts.map +1 -1
  244. package/lib-es/platform/providers/RemoteLiveAppProvider/api/mock.json +3 -3
  245. package/lib-es/wallet-api/useDappLogic.js +2 -2
  246. package/lib-es/wallet-api/useDappLogic.js.map +1 -1
  247. package/package.json +51 -51
  248. package/src/bridge/crypto-assets/index.test.ts +0 -4
  249. package/src/bridge/crypto-assets/index.ts +0 -2
  250. package/src/currencies/index.ts +1 -2
  251. package/src/currencies/sortByMarketcap.test.ts +1 -3
  252. package/src/e2e/enum/Account.ts +31 -0
  253. package/src/e2e/enum/AppInfos.ts +2 -0
  254. package/src/e2e/enum/Currency.ts +11 -0
  255. package/src/e2e/enum/Network.ts +1 -0
  256. package/src/e2e/enum/TokenType.ts +1 -0
  257. package/src/e2e/enum/TransactionStatus.ts +3 -0
  258. package/src/e2e/families/sui.ts +7 -0
  259. package/src/e2e/speculos.ts +23 -0
  260. package/src/exchange/providers/swap.ts +4 -4
  261. package/src/exchange/swap/api/v5/__mocks__/fetchRates.mocks.ts +1 -2
  262. package/src/exchange/swap/mock.ts +1 -1
  263. package/src/featureFlags/defaultFeatures.ts +5 -0
  264. package/src/hooks/useManifestWithSessionId.test.ts +105 -0
  265. package/src/hooks/useManifestWithSessionId.ts +83 -0
  266. package/src/market/utils/index.ts +3 -0
  267. package/src/modularDrawer/hooks/__tests__/useDetailedAccountsCore.test.ts +472 -0
  268. package/src/modularDrawer/hooks/index.ts +1 -0
  269. package/src/modularDrawer/hooks/useDetailedAccountsCore.ts +146 -0
  270. package/src/modularDrawer/hooks/useRightBalanceAsset.tsx +5 -1
  271. package/src/modularDrawer/hooks/useRightBalanceNetwork.tsx +10 -4
  272. package/src/modularDrawer/index.ts +3 -0
  273. package/src/modularDrawer/types/detailedAccount.ts +49 -0
  274. package/src/modularDrawer/types/index.ts +1 -0
  275. package/src/modularDrawer/utils/__tests__/sortAccountsByFiatValue.test.ts +117 -0
  276. package/src/modularDrawer/utils/getBalanceAndFiatValueByAssets.ts +6 -3
  277. package/src/modularDrawer/utils/index.ts +1 -0
  278. package/src/modularDrawer/utils/sortAccountsByFiatValue.ts +14 -0
  279. package/src/modularDrawer/utils/type.ts +3 -2
  280. package/src/platform/providers/RemoteLiveAppProvider/api/mock.json +3 -3
  281. package/src/wallet-api/useDappLogic.ts +3 -3
@@ -0,0 +1,472 @@
1
+ /**
2
+ * @jest-environment jsdom
3
+ */
4
+ import { renderHook } from "@testing-library/react";
5
+ import { useDetailedAccountsCore } from "../useDetailedAccountsCore";
6
+ import { CounterValuesState } from "@ledgerhq/live-countervalues/types";
7
+ import { Currency } from "@ledgerhq/types-cryptoassets";
8
+ import { Account, TokenAccount } from "@ledgerhq/types-live";
9
+ import BigNumber from "bignumber.js";
10
+
11
+ // Mock the calculate function
12
+ jest.mock("@ledgerhq/live-countervalues/logic", () => ({
13
+ calculate: jest.fn(),
14
+ }));
15
+
16
+ // Mock the derivation function
17
+ jest.mock("@ledgerhq/coin-framework/derivation", () => ({
18
+ getTagDerivationMode: jest.fn(() => "native_segwit"),
19
+ }));
20
+
21
+ // Import the mocked functions
22
+ import { calculate } from "@ledgerhq/live-countervalues/logic";
23
+ import { getTagDerivationMode } from "@ledgerhq/coin-framework/derivation";
24
+ const mockCalculate = calculate as jest.MockedFunction<typeof calculate>;
25
+ const mockGetTagDerivationMode = getTagDerivationMode as jest.MockedFunction<
26
+ typeof getTagDerivationMode
27
+ >;
28
+
29
+ describe("useDetailedAccountsCore", () => {
30
+ const mockCounterValuesState = {} as CounterValuesState;
31
+ const mockCounterValueCurrency = {
32
+ id: "usd",
33
+ ticker: "USD",
34
+ units: [{ name: "USD", code: "USD", magnitude: 2 }],
35
+ } as Currency;
36
+
37
+ const mockAccount = {
38
+ id: "account1",
39
+ type: "Account",
40
+ currency: {
41
+ id: "ethereum",
42
+ ticker: "ETH",
43
+ name: "Ethereum",
44
+ units: [{ name: "Ethereum", code: "ETH", magnitude: 18 }],
45
+ },
46
+ balance: new BigNumber("1000000000000000000"), // 1 ETH
47
+ freshAddress: "0x123...abc",
48
+ derivationMode: "ethM",
49
+ } as Account;
50
+
51
+ const mockTokenAccount = {
52
+ id: "token1",
53
+ type: "TokenAccount",
54
+ parentId: "account1",
55
+ token: {
56
+ id: "usdc",
57
+ ticker: "USDC",
58
+ name: "USD Coin",
59
+ units: [{ name: "USD Coin", code: "USDC", magnitude: 6 }],
60
+ parentCurrency: mockAccount.currency,
61
+ },
62
+ balance: new BigNumber("1000000"), // 1 USDC
63
+ } as TokenAccount;
64
+
65
+ beforeEach(() => {
66
+ mockCalculate.mockClear();
67
+ });
68
+
69
+ it("should calculate fiat value correctly", () => {
70
+ mockCalculate.mockReturnValue(2500); // Mock fiat value
71
+
72
+ const { result } = renderHook(() =>
73
+ useDetailedAccountsCore(mockCounterValuesState, mockCounterValueCurrency),
74
+ );
75
+
76
+ const fiatValue = result.current.calculateFiatValue(mockAccount);
77
+
78
+ expect(mockCalculate).toHaveBeenCalledWith(mockCounterValuesState, {
79
+ from: mockAccount.currency,
80
+ to: mockCounterValueCurrency,
81
+ value: mockAccount.balance.toNumber(),
82
+ });
83
+ expect(fiatValue).toBe(2500);
84
+ });
85
+
86
+ it("should return 0 when mockCalculate returns null", () => {
87
+ mockCalculate.mockReturnValue(null);
88
+
89
+ const { result } = renderHook(() =>
90
+ useDetailedAccountsCore(mockCounterValuesState, mockCounterValueCurrency),
91
+ );
92
+
93
+ const fiatValue = result.current.calculateFiatValue(mockAccount);
94
+ expect(fiatValue).toBe(0);
95
+ });
96
+
97
+ it("should create base detailed accounts for regular accounts", () => {
98
+ mockCalculate.mockReturnValue(2500);
99
+
100
+ const { result } = renderHook(() =>
101
+ useDetailedAccountsCore(mockCounterValuesState, mockCounterValueCurrency),
102
+ );
103
+
104
+ const accountTuples = [{ account: mockAccount, subAccount: null }];
105
+ const accountNameMap = { account1: "My Ethereum Account" };
106
+
107
+ const detailedAccounts = result.current.createBaseDetailedAccounts({
108
+ asset: mockAccount.currency,
109
+ accountTuples,
110
+ accountNameMap,
111
+ isTokenCurrency: false,
112
+ });
113
+
114
+ expect(detailedAccounts).toHaveLength(1);
115
+ expect(detailedAccounts[0]).toEqual({
116
+ id: "account1",
117
+ name: "My Ethereum Account",
118
+ ticker: "ETH",
119
+ balance: mockAccount.balance,
120
+ balanceUnit: mockAccount.currency.units[0],
121
+ fiatValue: 2500,
122
+ address: "0x123...abc",
123
+ cryptoId: "ethereum",
124
+ });
125
+ });
126
+
127
+ it("should create base detailed accounts for token accounts", () => {
128
+ mockCalculate.mockReturnValue(1); // 1 USD for USDC
129
+
130
+ const { result } = renderHook(() =>
131
+ useDetailedAccountsCore(mockCounterValuesState, mockCounterValueCurrency),
132
+ );
133
+
134
+ const accountTuples = [{ account: mockAccount, subAccount: mockTokenAccount }];
135
+ const accountNameMap = { account1: "My Ethereum Account" };
136
+
137
+ const detailedAccounts = result.current.createBaseDetailedAccounts({
138
+ asset: mockTokenAccount.token,
139
+ accountTuples,
140
+ accountNameMap,
141
+ isTokenCurrency: true,
142
+ });
143
+
144
+ expect(detailedAccounts).toHaveLength(1);
145
+ expect(detailedAccounts[0]).toEqual({
146
+ id: "token1",
147
+ name: "My Ethereum Account",
148
+ ticker: "USDC",
149
+ balance: mockTokenAccount.balance,
150
+ balanceUnit: mockTokenAccount.token.units[0],
151
+ fiatValue: 1,
152
+ address: "0x123...abc",
153
+ cryptoId: "usdc",
154
+ parentId: "ethereum",
155
+ });
156
+ });
157
+
158
+ it("should create extended detailed accounts with account references", () => {
159
+ mockCalculate.mockReturnValue(2500);
160
+
161
+ const { result } = renderHook(() =>
162
+ useDetailedAccountsCore(mockCounterValuesState, mockCounterValueCurrency),
163
+ );
164
+
165
+ const accountTuples = [{ account: mockAccount, subAccount: null }];
166
+ const accountNameMap = { account1: "My Ethereum Account" };
167
+
168
+ const detailedAccounts = result.current.createExtendedDetailedAccounts({
169
+ asset: mockAccount.currency,
170
+ accountTuples,
171
+ accountNameMap,
172
+ isTokenCurrency: false,
173
+ });
174
+
175
+ expect(detailedAccounts).toHaveLength(1);
176
+ expect(detailedAccounts[0]).toEqual({
177
+ id: "account1",
178
+ name: "My Ethereum Account",
179
+ ticker: "ETH",
180
+ balance: mockAccount.balance,
181
+ balanceUnit: mockAccount.currency.units[0],
182
+ fiatValue: 2500,
183
+ address: "0x123...abc",
184
+ cryptoId: "ethereum",
185
+ account: mockAccount,
186
+ protocol: "native_segwit",
187
+ });
188
+ });
189
+
190
+ it("should sort accounts by fiat value in descending order", () => {
191
+ const { result } = renderHook(() =>
192
+ useDetailedAccountsCore(mockCounterValuesState, mockCounterValueCurrency),
193
+ );
194
+
195
+ const mockAccount2 = { ...mockAccount, id: "account2" };
196
+
197
+ // Mock different fiat values for different accounts
198
+ mockCalculate
199
+ .mockReturnValueOnce(1000) // First account
200
+ .mockReturnValueOnce(5000); // Second account
201
+
202
+ const accountTuples = [
203
+ { account: mockAccount, subAccount: null },
204
+ { account: mockAccount2, subAccount: null },
205
+ ];
206
+ const accountNameMap = {
207
+ account1: "Account 1",
208
+ account2: "Account 2",
209
+ };
210
+
211
+ const detailedAccounts = result.current.createBaseDetailedAccounts({
212
+ asset: mockAccount.currency,
213
+ accountTuples,
214
+ accountNameMap,
215
+ isTokenCurrency: false,
216
+ });
217
+
218
+ expect(detailedAccounts).toHaveLength(2);
219
+ expect(detailedAccounts[0].id).toBe("account2"); // Higher fiat value (5000)
220
+ expect(detailedAccounts[1].id).toBe("account1"); // Lower fiat value (1000)
221
+ });
222
+
223
+ it("should use fallback name when account name is not in map", () => {
224
+ mockCalculate.mockReturnValue(2500);
225
+
226
+ const { result } = renderHook(() =>
227
+ useDetailedAccountsCore(mockCounterValuesState, mockCounterValueCurrency),
228
+ );
229
+
230
+ const accountTuples = [{ account: mockAccount, subAccount: null }];
231
+ const accountNameMap = {}; // Empty map
232
+
233
+ const detailedAccounts = result.current.createBaseDetailedAccounts({
234
+ asset: mockAccount.currency,
235
+ accountTuples,
236
+ accountNameMap,
237
+ isTokenCurrency: false,
238
+ });
239
+
240
+ expect(detailedAccounts[0].name).toBe("Ethereum"); // Falls back to currency name
241
+ });
242
+
243
+ it("should handle token accounts with extended detailed accounts", () => {
244
+ mockCalculate.mockReturnValue(1); // 1 USD for USDC
245
+
246
+ const { result } = renderHook(() =>
247
+ useDetailedAccountsCore(mockCounterValuesState, mockCounterValueCurrency),
248
+ );
249
+
250
+ const accountTuples = [{ account: mockAccount, subAccount: mockTokenAccount }];
251
+ const accountNameMap = { account1: "My Ethereum Account" };
252
+
253
+ const detailedAccounts = result.current.createExtendedDetailedAccounts({
254
+ asset: mockTokenAccount.token,
255
+ accountTuples,
256
+ accountNameMap,
257
+ isTokenCurrency: true,
258
+ });
259
+
260
+ expect(detailedAccounts).toHaveLength(1);
261
+ expect(detailedAccounts[0]).toEqual({
262
+ id: "token1",
263
+ name: "My Ethereum Account",
264
+ ticker: "USDC",
265
+ balance: mockTokenAccount.balance,
266
+ balanceUnit: mockTokenAccount.token.units[0],
267
+ fiatValue: 1,
268
+ address: "0x123...abc",
269
+ cryptoId: "usdc",
270
+ parentId: "ethereum",
271
+ account: mockTokenAccount,
272
+ parentAccount: mockAccount,
273
+ });
274
+ });
275
+
276
+ it("should handle multiple accounts with mixed fiat values including zero", () => {
277
+ const { result } = renderHook(() =>
278
+ useDetailedAccountsCore(mockCounterValuesState, mockCounterValueCurrency),
279
+ );
280
+
281
+ const mockAccount2 = { ...mockAccount, id: "account2" };
282
+ const mockAccount3 = { ...mockAccount, id: "account3" };
283
+
284
+ // Mock different fiat values including zero
285
+ mockCalculate
286
+ .mockReturnValueOnce(0) // First account - zero value
287
+ .mockReturnValueOnce(5000) // Second account - high value
288
+ .mockReturnValueOnce(100); // Third account - low value
289
+
290
+ const accountTuples = [
291
+ { account: mockAccount, subAccount: null },
292
+ { account: mockAccount2, subAccount: null },
293
+ { account: mockAccount3, subAccount: null },
294
+ ];
295
+ const accountNameMap = {
296
+ account1: "Account 1",
297
+ account2: "Account 2",
298
+ account3: "Account 3",
299
+ };
300
+
301
+ const detailedAccounts = result.current.createBaseDetailedAccounts({
302
+ asset: mockAccount.currency,
303
+ accountTuples,
304
+ accountNameMap,
305
+ isTokenCurrency: false,
306
+ });
307
+
308
+ expect(detailedAccounts).toHaveLength(3);
309
+ // Should be sorted by fiat value descending: 5000, 100, 0
310
+ expect(detailedAccounts[0].id).toBe("account2"); // 5000
311
+ expect(detailedAccounts[1].id).toBe("account3"); // 100
312
+ expect(detailedAccounts[2].id).toBe("account1"); // 0
313
+ expect(detailedAccounts[2].fiatValue).toBe(0);
314
+ });
315
+
316
+ it("should handle token account fiat value calculation correctly", () => {
317
+ mockCalculate.mockReturnValue(50); // Mock fiat value for token
318
+
319
+ const { result } = renderHook(() =>
320
+ useDetailedAccountsCore(mockCounterValuesState, mockCounterValueCurrency),
321
+ );
322
+
323
+ const fiatValue = result.current.calculateFiatValue(mockTokenAccount);
324
+
325
+ expect(mockCalculate).toHaveBeenCalledWith(mockCounterValuesState, {
326
+ from: mockTokenAccount.token,
327
+ to: mockCounterValueCurrency,
328
+ value: mockTokenAccount.balance.toNumber(),
329
+ });
330
+ expect(fiatValue).toBe(50);
331
+ });
332
+
333
+ it("should handle empty account tuples", () => {
334
+ const { result } = renderHook(() =>
335
+ useDetailedAccountsCore(mockCounterValuesState, mockCounterValueCurrency),
336
+ );
337
+
338
+ const accountTuples: Array<{ account: Account; subAccount: TokenAccount | null }> = [];
339
+ const accountNameMap = {};
340
+
341
+ const detailedAccounts = result.current.createBaseDetailedAccounts({
342
+ asset: mockAccount.currency,
343
+ accountTuples,
344
+ accountNameMap,
345
+ isTokenCurrency: false,
346
+ });
347
+
348
+ expect(detailedAccounts).toHaveLength(0);
349
+ });
350
+
351
+ it("should handle accounts with undefined fiat values", () => {
352
+ mockCalculate.mockReturnValue(undefined); // Simulate undefined return
353
+
354
+ const { result } = renderHook(() =>
355
+ useDetailedAccountsCore(mockCounterValuesState, mockCounterValueCurrency),
356
+ );
357
+
358
+ const fiatValue = result.current.calculateFiatValue(mockAccount);
359
+ expect(fiatValue).toBe(0); // Should default to 0
360
+ });
361
+
362
+ it("should preserve account properties in extended detailed accounts", () => {
363
+ mockCalculate.mockReturnValue(1500);
364
+
365
+ const { result } = renderHook(() =>
366
+ useDetailedAccountsCore(mockCounterValuesState, mockCounterValueCurrency),
367
+ );
368
+
369
+ const accountTuples = [{ account: mockAccount, subAccount: null }];
370
+ const accountNameMap = { account1: "Custom Account Name" };
371
+
372
+ const detailedAccounts = result.current.createExtendedDetailedAccounts({
373
+ asset: mockAccount.currency,
374
+ accountTuples,
375
+ accountNameMap,
376
+ isTokenCurrency: false,
377
+ });
378
+
379
+ expect(detailedAccounts[0].account).toBe(mockAccount);
380
+ expect(detailedAccounts[0].protocol).toBe("native_segwit");
381
+ expect(detailedAccounts[0].parentAccount).toBeUndefined();
382
+ });
383
+
384
+ it("should use fallback name when parent account name is not in map for token accounts", () => {
385
+ mockCalculate.mockReturnValue(1);
386
+
387
+ const { result } = renderHook(() =>
388
+ useDetailedAccountsCore(mockCounterValuesState, mockCounterValueCurrency),
389
+ );
390
+
391
+ const accountTuples = [{ account: mockAccount, subAccount: mockTokenAccount }];
392
+ const accountNameMap = {}; // Empty map - no parent account name
393
+
394
+ const detailedAccounts = result.current.createBaseDetailedAccounts({
395
+ asset: mockTokenAccount.token,
396
+ accountTuples,
397
+ accountNameMap,
398
+ isTokenCurrency: true,
399
+ });
400
+
401
+ expect(detailedAccounts[0].name).toBe("USD Coin"); // Falls back to token name
402
+ });
403
+
404
+ it("should use fallback name when parent account name is not in map for extended token accounts", () => {
405
+ mockCalculate.mockReturnValue(1);
406
+
407
+ const { result } = renderHook(() =>
408
+ useDetailedAccountsCore(mockCounterValuesState, mockCounterValueCurrency),
409
+ );
410
+
411
+ const accountTuples = [{ account: mockAccount, subAccount: mockTokenAccount }];
412
+ const accountNameMap = {}; // Empty map - no parent account name
413
+
414
+ const detailedAccounts = result.current.createExtendedDetailedAccounts({
415
+ asset: mockTokenAccount.token,
416
+ accountTuples,
417
+ accountNameMap,
418
+ isTokenCurrency: true,
419
+ });
420
+
421
+ expect(detailedAccounts[0].name).toBe("USD Coin"); // Falls back to token name
422
+ expect(detailedAccounts[0].account).toBe(mockTokenAccount);
423
+ expect(detailedAccounts[0].parentAccount).toBe(mockAccount);
424
+ });
425
+
426
+ it("should handle null derivation mode in extended detailed accounts", () => {
427
+ // Mock getTagDerivationMode to return null
428
+ mockGetTagDerivationMode.mockReturnValue(null);
429
+
430
+ mockCalculate.mockReturnValue(2500);
431
+
432
+ const { result } = renderHook(() =>
433
+ useDetailedAccountsCore(mockCounterValuesState, mockCounterValueCurrency),
434
+ );
435
+
436
+ const accountTuples = [{ account: mockAccount, subAccount: null }];
437
+ const accountNameMap = { account1: "My Account" };
438
+
439
+ const detailedAccounts = result.current.createExtendedDetailedAccounts({
440
+ asset: mockAccount.currency,
441
+ accountTuples,
442
+ accountNameMap,
443
+ isTokenCurrency: false,
444
+ });
445
+
446
+ expect(detailedAccounts[0].protocol).toBe(""); // Should fallback to empty string
447
+
448
+ // Reset mock for other tests
449
+ mockGetTagDerivationMode.mockReturnValue("native_segwit");
450
+ });
451
+
452
+ it("should use fallback name when account name is not in map for extended accounts", () => {
453
+ mockCalculate.mockReturnValue(2500);
454
+
455
+ const { result } = renderHook(() =>
456
+ useDetailedAccountsCore(mockCounterValuesState, mockCounterValueCurrency),
457
+ );
458
+
459
+ const accountTuples = [{ account: mockAccount, subAccount: null }];
460
+ const accountNameMap = {}; // Empty map - no account name
461
+
462
+ const detailedAccounts = result.current.createExtendedDetailedAccounts({
463
+ asset: mockAccount.currency,
464
+ accountTuples,
465
+ accountNameMap,
466
+ isTokenCurrency: false,
467
+ });
468
+
469
+ expect(detailedAccounts[0].name).toBe("Ethereum"); // Falls back to currency name
470
+ expect(detailedAccounts[0].account).toBe(mockAccount);
471
+ });
472
+ });
@@ -0,0 +1 @@
1
+ export { useDetailedAccountsCore } from "./useDetailedAccountsCore";
@@ -0,0 +1,146 @@
1
+ import { useCallback } from "react";
2
+ import { AccountLike } from "@ledgerhq/types-live";
3
+ import { Currency } from "@ledgerhq/types-cryptoassets";
4
+ import { CounterValuesState } from "@ledgerhq/live-countervalues/types";
5
+ import { calculate } from "@ledgerhq/live-countervalues/logic";
6
+ import { getTagDerivationMode } from "@ledgerhq/coin-framework/derivation";
7
+ import {
8
+ BaseRawDetailedAccount,
9
+ ExtendedRawDetailedAccount,
10
+ CreateDetailedAccountsParams,
11
+ } from "../types/detailedAccount";
12
+ import { sortAccountsByFiatValue } from "../utils/sortAccountsByFiatValue";
13
+
14
+ /**
15
+ * Core hook for creating detailed accounts with shared logic
16
+ * This contains the business logic that can be reused across platforms
17
+ */
18
+ export function useDetailedAccountsCore(
19
+ counterValuesState: CounterValuesState,
20
+ counterValueCurrency: Currency,
21
+ ) {
22
+ /**
23
+ * Calculate fiat value for an account using counter values
24
+ */
25
+ const calculateFiatValue = useCallback(
26
+ (account: AccountLike): number => {
27
+ const currency = account.type === "Account" ? account.currency : account.token;
28
+ const fiatValue = calculate(counterValuesState, {
29
+ from: currency,
30
+ to: counterValueCurrency,
31
+ value: account.balance.toNumber(),
32
+ });
33
+ return fiatValue || 0;
34
+ },
35
+ [counterValuesState, counterValueCurrency],
36
+ );
37
+
38
+ /**
39
+ * Create base detailed accounts from account tuples
40
+ * This is the core transformation logic shared between platforms
41
+ */
42
+ const createBaseDetailedAccounts = useCallback(
43
+ (params: CreateDetailedAccountsParams): BaseRawDetailedAccount[] => {
44
+ const { accountTuples, accountNameMap, isTokenCurrency } = params;
45
+
46
+ const baseAccounts = accountTuples.map(tuple => {
47
+ const { account, subAccount } = tuple;
48
+ const address = account.freshAddress;
49
+
50
+ if (isTokenCurrency && subAccount) {
51
+ const parentAccountName = accountNameMap[account.id];
52
+ const details = subAccount.token;
53
+
54
+ return {
55
+ id: subAccount.id,
56
+ name: parentAccountName ?? details.name,
57
+ ticker: details.ticker,
58
+ balance: subAccount.balance,
59
+ balanceUnit: subAccount.token.units[0],
60
+ fiatValue: calculateFiatValue(subAccount),
61
+ address,
62
+ cryptoId: details.id,
63
+ parentId: details.parentCurrency.id,
64
+ };
65
+ } else {
66
+ const accountName = accountNameMap[account.id];
67
+ const details = account.currency;
68
+
69
+ return {
70
+ id: account.id,
71
+ name: accountName ?? details.name,
72
+ ticker: details.ticker,
73
+ balance: account.balance,
74
+ balanceUnit: account.currency.units[0],
75
+ fiatValue: calculateFiatValue(account),
76
+ address,
77
+ cryptoId: details.id,
78
+ };
79
+ }
80
+ });
81
+
82
+ return sortAccountsByFiatValue(baseAccounts);
83
+ },
84
+ [calculateFiatValue],
85
+ );
86
+
87
+ /**
88
+ * Create extended detailed accounts that include account references
89
+ * Used by mobile implementation that needs access to the full account objects
90
+ */
91
+ const createExtendedDetailedAccounts = useCallback(
92
+ (params: CreateDetailedAccountsParams): ExtendedRawDetailedAccount[] => {
93
+ const { accountTuples, accountNameMap, isTokenCurrency } = params;
94
+
95
+ const extendedAccounts = accountTuples.map(tuple => {
96
+ const { account, subAccount } = tuple;
97
+ const protocol = getTagDerivationMode(account.currency, account.derivationMode) ?? "";
98
+ const address = account.freshAddress;
99
+
100
+ if (isTokenCurrency && subAccount) {
101
+ const parentAccountName = accountNameMap[account.id];
102
+ const details = subAccount.token;
103
+
104
+ return {
105
+ id: subAccount.id,
106
+ name: parentAccountName ?? details.name,
107
+ ticker: details.ticker,
108
+ balance: subAccount.balance,
109
+ balanceUnit: subAccount.token.units[0],
110
+ fiatValue: calculateFiatValue(subAccount),
111
+ address,
112
+ cryptoId: details.id,
113
+ parentId: details.parentCurrency.id,
114
+ account: subAccount,
115
+ parentAccount: account,
116
+ };
117
+ } else {
118
+ const accountName = accountNameMap[account.id];
119
+ const details = account.currency;
120
+
121
+ return {
122
+ id: account.id,
123
+ name: accountName ?? details.name,
124
+ ticker: details.ticker,
125
+ balance: account.balance,
126
+ balanceUnit: account.currency.units[0],
127
+ fiatValue: calculateFiatValue(account),
128
+ address,
129
+ cryptoId: details.id,
130
+ account,
131
+ protocol,
132
+ };
133
+ }
134
+ });
135
+
136
+ return sortAccountsByFiatValue(extendedAccounts);
137
+ },
138
+ [calculateFiatValue],
139
+ );
140
+
141
+ return {
142
+ calculateFiatValue,
143
+ createBaseDetailedAccounts,
144
+ createExtendedDetailedAccounts,
145
+ };
146
+ }
@@ -53,7 +53,11 @@ export function createUseRightBalanceAsset({ useBalanceDeps, balanceItem, assets
53
53
  }
54
54
 
55
55
  const assetsWithBalanceData = assets.map(asset => {
56
- const balanceData = balanceMap.get(asset.id) || {};
56
+ const balanceData = balanceMap.get(asset.id) || {
57
+ currency: asset,
58
+ balance: new BigNumber(0),
59
+ fiatValue: 0,
60
+ };
57
61
  return {
58
62
  ...asset,
59
63
  balanceData,
@@ -1,6 +1,7 @@
1
1
  import type { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
2
2
  import { UseBalanceDeps, CreateBalanceItem } from "../utils/type";
3
3
  import { getBalanceAndFiatValueByAssets } from "../utils/getBalanceAndFiatValueByAssets";
4
+ import BigNumber from "bignumber.js";
4
5
 
5
6
  export type NetworkDeps = {
6
7
  balanceItem: CreateBalanceItem;
@@ -25,12 +26,17 @@ export function createUseRightBalanceNetwork({ useBalanceDeps, balanceItem }: Ne
25
26
  const balanceMap = new Map(networkBalanceData.map(b => [b.id, b]));
26
27
 
27
28
  return networks.map(network => {
28
- const balanceData = balanceMap.get(network.id) || {};
29
- const details = network.type === "TokenCurrency" ? network.parentCurrency : network;
29
+ const currency = network.type === "TokenCurrency" ? network.parentCurrency : network;
30
+ const balanceData = balanceMap.get(network.id) || {
31
+ currency,
32
+ balance: new BigNumber(0),
33
+ fiatValue: 0,
34
+ };
35
+
30
36
  return {
31
- ...details,
37
+ ...currency,
32
38
  rightElement: balanceItem(balanceData),
33
- balanceData: balanceData,
39
+ balanceData,
34
40
  };
35
41
  });
36
42
  };
@@ -0,0 +1,3 @@
1
+ export * from "./hooks";
2
+ export * from "./types";
3
+ export * from "./utils";