@ledgerhq/live-common 34.53.0-nightly.20251118023800 → 34.53.0-nightly.20251119023741

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 (192) hide show
  1. package/lib/__tests__/test-helpers/bridge.d.ts.map +1 -1
  2. package/lib/__tests__/test-helpers/bridge.js +0 -4
  3. package/lib/__tests__/test-helpers/bridge.js.map +1 -1
  4. package/lib/bridge/generic-alpaca/getAccountShape.d.ts.map +1 -1
  5. package/lib/bridge/generic-alpaca/getAccountShape.js +12 -10
  6. package/lib/bridge/generic-alpaca/getAccountShape.js.map +1 -1
  7. package/lib/deposit/type.d.ts +0 -17
  8. package/lib/deposit/type.d.ts.map +1 -1
  9. package/lib/deposit/type.js.map +1 -1
  10. package/lib/deviceSDK/tasks/core.d.ts +1 -1
  11. package/lib/deviceSDK/tasks/core.d.ts.map +1 -1
  12. package/lib/deviceSDK/tasks/core.js +1 -1
  13. package/lib/deviceSDK/tasks/core.js.map +1 -1
  14. package/lib/e2e/enum/Account.d.ts +0 -1
  15. package/lib/e2e/enum/Account.d.ts.map +1 -1
  16. package/lib/e2e/enum/Account.js +0 -1
  17. package/lib/e2e/enum/Account.js.map +1 -1
  18. package/lib/e2e/enum/Currency.d.ts +0 -1
  19. package/lib/e2e/enum/Currency.d.ts.map +1 -1
  20. package/lib/e2e/enum/Currency.js +1 -5
  21. package/lib/e2e/enum/Currency.js.map +1 -1
  22. package/lib/e2e/enum/ReceiveFundsOptions.d.ts +6 -0
  23. package/lib/e2e/enum/ReceiveFundsOptions.d.ts.map +1 -0
  24. package/lib/e2e/enum/ReceiveFundsOptions.js +8 -0
  25. package/lib/e2e/enum/ReceiveFundsOptions.js.map +1 -0
  26. package/lib/exchange/providers/swap.d.ts +1 -0
  27. package/lib/exchange/providers/swap.d.ts.map +1 -1
  28. package/lib/exchange/providers/swap.js +5 -1
  29. package/lib/exchange/providers/swap.js.map +1 -1
  30. package/lib/exchange/swap/hooks/v5/useFetchCurrencyAll.d.ts.map +1 -1
  31. package/lib/exchange/swap/hooks/v5/useFetchCurrencyAll.js +2 -3
  32. package/lib/exchange/swap/hooks/v5/useFetchCurrencyAll.js.map +1 -1
  33. package/lib/exchange/swap/hooks/v5/useFilteredProviders.d.ts.map +1 -1
  34. package/lib/exchange/swap/hooks/v5/useFilteredProviders.js +15 -10
  35. package/lib/exchange/swap/hooks/v5/useFilteredProviders.js.map +1 -1
  36. package/lib/market/hooks/useMarketDataProvider.js +1 -0
  37. package/lib/market/hooks/useMarketDataProvider.js.map +1 -1
  38. package/lib/market/utils/types.d.ts +1 -0
  39. package/lib/market/utils/types.d.ts.map +1 -1
  40. package/lib/market/utils/types.js.map +1 -1
  41. package/lib/modularDrawer/utils/{groupCurrenciesByProvider.d.ts → groupCurrenciesByAsset.d.ts} +2 -2
  42. package/lib/modularDrawer/utils/groupCurrenciesByAsset.d.ts.map +1 -0
  43. package/lib/modularDrawer/utils/{groupCurrenciesByProvider.js → groupCurrenciesByAsset.js} +7 -7
  44. package/lib/modularDrawer/utils/groupCurrenciesByAsset.js.map +1 -0
  45. package/lib/modularDrawer/utils/index.d.ts +1 -1
  46. package/lib/modularDrawer/utils/index.d.ts.map +1 -1
  47. package/lib/modularDrawer/utils/index.js +3 -3
  48. package/lib/modularDrawer/utils/index.js.map +1 -1
  49. package/lib/wallet-api/types.d.ts +3 -0
  50. package/lib/wallet-api/types.d.ts.map +1 -1
  51. package/lib/wallet-api/utils/deriveAccountIdForManifest.d.ts +6 -0
  52. package/lib/wallet-api/utils/deriveAccountIdForManifest.d.ts.map +1 -1
  53. package/lib/wallet-api/utils/deriveAccountIdForManifest.js +13 -3
  54. package/lib/wallet-api/utils/deriveAccountIdForManifest.js.map +1 -1
  55. package/lib-es/__tests__/test-helpers/bridge.d.ts.map +1 -1
  56. package/lib-es/__tests__/test-helpers/bridge.js +0 -4
  57. package/lib-es/__tests__/test-helpers/bridge.js.map +1 -1
  58. package/lib-es/bridge/generic-alpaca/getAccountShape.d.ts.map +1 -1
  59. package/lib-es/bridge/generic-alpaca/getAccountShape.js +13 -11
  60. package/lib-es/bridge/generic-alpaca/getAccountShape.js.map +1 -1
  61. package/lib-es/deposit/type.d.ts +0 -17
  62. package/lib-es/deposit/type.d.ts.map +1 -1
  63. package/lib-es/deposit/type.js.map +1 -1
  64. package/lib-es/deviceSDK/tasks/core.d.ts +1 -1
  65. package/lib-es/deviceSDK/tasks/core.d.ts.map +1 -1
  66. package/lib-es/deviceSDK/tasks/core.js +1 -1
  67. package/lib-es/deviceSDK/tasks/core.js.map +1 -1
  68. package/lib-es/e2e/enum/Account.d.ts +0 -1
  69. package/lib-es/e2e/enum/Account.d.ts.map +1 -1
  70. package/lib-es/e2e/enum/Account.js +0 -1
  71. package/lib-es/e2e/enum/Account.js.map +1 -1
  72. package/lib-es/e2e/enum/Currency.d.ts +0 -1
  73. package/lib-es/e2e/enum/Currency.d.ts.map +1 -1
  74. package/lib-es/e2e/enum/Currency.js +1 -5
  75. package/lib-es/e2e/enum/Currency.js.map +1 -1
  76. package/lib-es/e2e/enum/ReceiveFundsOptions.d.ts +6 -0
  77. package/lib-es/e2e/enum/ReceiveFundsOptions.d.ts.map +1 -0
  78. package/lib-es/e2e/enum/ReceiveFundsOptions.js +5 -0
  79. package/lib-es/e2e/enum/ReceiveFundsOptions.js.map +1 -0
  80. package/lib-es/exchange/providers/swap.d.ts +1 -0
  81. package/lib-es/exchange/providers/swap.d.ts.map +1 -1
  82. package/lib-es/exchange/providers/swap.js +3 -0
  83. package/lib-es/exchange/providers/swap.js.map +1 -1
  84. package/lib-es/exchange/swap/hooks/v5/useFetchCurrencyAll.d.ts.map +1 -1
  85. package/lib-es/exchange/swap/hooks/v5/useFetchCurrencyAll.js +2 -3
  86. package/lib-es/exchange/swap/hooks/v5/useFetchCurrencyAll.js.map +1 -1
  87. package/lib-es/exchange/swap/hooks/v5/useFilteredProviders.d.ts.map +1 -1
  88. package/lib-es/exchange/swap/hooks/v5/useFilteredProviders.js +17 -12
  89. package/lib-es/exchange/swap/hooks/v5/useFilteredProviders.js.map +1 -1
  90. package/lib-es/market/hooks/useMarketDataProvider.js +1 -0
  91. package/lib-es/market/hooks/useMarketDataProvider.js.map +1 -1
  92. package/lib-es/market/utils/types.d.ts +1 -0
  93. package/lib-es/market/utils/types.d.ts.map +1 -1
  94. package/lib-es/market/utils/types.js.map +1 -1
  95. package/lib-es/modularDrawer/utils/{groupCurrenciesByProvider.d.ts → groupCurrenciesByAsset.d.ts} +2 -2
  96. package/lib-es/modularDrawer/utils/groupCurrenciesByAsset.d.ts.map +1 -0
  97. package/lib-es/modularDrawer/utils/{groupCurrenciesByProvider.js → groupCurrenciesByAsset.js} +5 -5
  98. package/lib-es/modularDrawer/utils/groupCurrenciesByAsset.js.map +1 -0
  99. package/lib-es/modularDrawer/utils/index.d.ts +1 -1
  100. package/lib-es/modularDrawer/utils/index.d.ts.map +1 -1
  101. package/lib-es/modularDrawer/utils/index.js +1 -1
  102. package/lib-es/modularDrawer/utils/index.js.map +1 -1
  103. package/lib-es/wallet-api/types.d.ts +3 -0
  104. package/lib-es/wallet-api/types.d.ts.map +1 -1
  105. package/lib-es/wallet-api/utils/deriveAccountIdForManifest.d.ts +6 -0
  106. package/lib-es/wallet-api/utils/deriveAccountIdForManifest.d.ts.map +1 -1
  107. package/lib-es/wallet-api/utils/deriveAccountIdForManifest.js +11 -2
  108. package/lib-es/wallet-api/utils/deriveAccountIdForManifest.js.map +1 -1
  109. package/package.json +54 -54
  110. package/src/__tests__/test-helpers/bridge.ts +0 -2
  111. package/src/bridge/generic-alpaca/getAccountShape.ts +15 -12
  112. package/src/bridge/generic-alpaca/tests/getAccountShape.test.ts +142 -101
  113. package/src/deposit/type.ts +0 -21
  114. package/src/deviceSDK/tasks/core.test.ts +20 -0
  115. package/src/deviceSDK/tasks/core.ts +2 -1
  116. package/src/e2e/enum/Account.ts +0 -6
  117. package/src/e2e/enum/Currency.ts +1 -5
  118. package/src/e2e/enum/ReceiveFundsOptions.ts +7 -0
  119. package/src/exchange/providers/swap.ts +4 -0
  120. package/src/exchange/swap/hooks/v5/useFetchCurrencyAll.ts +2 -3
  121. package/src/exchange/swap/hooks/v5/useFilteredProviders.ts +37 -12
  122. package/src/families/stellar/__snapshots__/bridge.integration.test.ts.snap +84 -12
  123. package/src/market/hooks/useMarketDataProvider.ts +1 -0
  124. package/src/market/utils/types.ts +1 -0
  125. package/src/modularDrawer/modules/__test__/createAssetConfiguration.test.tsx +2 -2
  126. package/src/modularDrawer/utils/__tests__/{groupCurrenciesByProvider.test.ts → groupCurrenciesByAsset.test.ts} +6 -6
  127. package/src/modularDrawer/utils/{groupCurrenciesByProvider.ts → groupCurrenciesByAsset.ts} +4 -4
  128. package/src/modularDrawer/utils/index.ts +1 -1
  129. package/src/wallet-api/types.ts +5 -0
  130. package/src/wallet-api/utils/deriveAccountIdForManifest.ts +14 -2
  131. package/lib/deposit/helper.d.ts +0 -8
  132. package/lib/deposit/helper.d.ts.map +0 -1
  133. package/lib/deposit/helper.js +0 -125
  134. package/lib/deposit/helper.js.map +0 -1
  135. package/lib/deposit/index.d.ts +0 -3
  136. package/lib/deposit/index.d.ts.map +0 -1
  137. package/lib/deposit/index.js +0 -6
  138. package/lib/deposit/index.js.map +0 -1
  139. package/lib/deposit/mock.d.ts +0 -75
  140. package/lib/deposit/mock.d.ts.map +0 -1
  141. package/lib/deposit/mock.js +0 -15111
  142. package/lib/deposit/mock.js.map +0 -1
  143. package/lib/deposit/useGroupedCurrenciesByProvider.hook.d.ts +0 -3
  144. package/lib/deposit/useGroupedCurrenciesByProvider.hook.d.ts.map +0 -1
  145. package/lib/deposit/useGroupedCurrenciesByProvider.hook.js +0 -40
  146. package/lib/deposit/useGroupedCurrenciesByProvider.hook.js.map +0 -1
  147. package/lib/modularDrawer/__mocks__/useGroupedCurrenciesByProvider.mock.d.ts +0 -22
  148. package/lib/modularDrawer/__mocks__/useGroupedCurrenciesByProvider.mock.d.ts.map +0 -1
  149. package/lib/modularDrawer/__mocks__/useGroupedCurrenciesByProvider.mock.js +0 -41
  150. package/lib/modularDrawer/__mocks__/useGroupedCurrenciesByProvider.mock.js.map +0 -1
  151. package/lib/modularDrawer/utils/currencyUtils.d.ts +0 -10
  152. package/lib/modularDrawer/utils/currencyUtils.d.ts.map +0 -1
  153. package/lib/modularDrawer/utils/currencyUtils.js +0 -74
  154. package/lib/modularDrawer/utils/currencyUtils.js.map +0 -1
  155. package/lib/modularDrawer/utils/groupCurrenciesByProvider.d.ts.map +0 -1
  156. package/lib/modularDrawer/utils/groupCurrenciesByProvider.js.map +0 -1
  157. package/lib-es/deposit/helper.d.ts +0 -8
  158. package/lib-es/deposit/helper.d.ts.map +0 -1
  159. package/lib-es/deposit/helper.js +0 -117
  160. package/lib-es/deposit/helper.js.map +0 -1
  161. package/lib-es/deposit/index.d.ts +0 -3
  162. package/lib-es/deposit/index.d.ts.map +0 -1
  163. package/lib-es/deposit/index.js +0 -3
  164. package/lib-es/deposit/index.js.map +0 -1
  165. package/lib-es/deposit/mock.d.ts +0 -75
  166. package/lib-es/deposit/mock.d.ts.map +0 -1
  167. package/lib-es/deposit/mock.js +0 -15108
  168. package/lib-es/deposit/mock.js.map +0 -1
  169. package/lib-es/deposit/useGroupedCurrenciesByProvider.hook.d.ts +0 -3
  170. package/lib-es/deposit/useGroupedCurrenciesByProvider.hook.d.ts.map +0 -1
  171. package/lib-es/deposit/useGroupedCurrenciesByProvider.hook.js +0 -36
  172. package/lib-es/deposit/useGroupedCurrenciesByProvider.hook.js.map +0 -1
  173. package/lib-es/modularDrawer/__mocks__/useGroupedCurrenciesByProvider.mock.d.ts +0 -22
  174. package/lib-es/modularDrawer/__mocks__/useGroupedCurrenciesByProvider.mock.d.ts.map +0 -1
  175. package/lib-es/modularDrawer/__mocks__/useGroupedCurrenciesByProvider.mock.js +0 -38
  176. package/lib-es/modularDrawer/__mocks__/useGroupedCurrenciesByProvider.mock.js.map +0 -1
  177. package/lib-es/modularDrawer/utils/currencyUtils.d.ts +0 -10
  178. package/lib-es/modularDrawer/utils/currencyUtils.d.ts.map +0 -1
  179. package/lib-es/modularDrawer/utils/currencyUtils.js +0 -65
  180. package/lib-es/modularDrawer/utils/currencyUtils.js.map +0 -1
  181. package/lib-es/modularDrawer/utils/groupCurrenciesByProvider.d.ts.map +0 -1
  182. package/lib-es/modularDrawer/utils/groupCurrenciesByProvider.js.map +0 -1
  183. package/src/deposit/deposit.integration.test.ts +0 -88
  184. package/src/deposit/deposit.test.ts +0 -684
  185. package/src/deposit/helper.ts +0 -143
  186. package/src/deposit/index.ts +0 -3
  187. package/src/deposit/mock.ts +0 -15112
  188. package/src/deposit/useGroupedCurrenciesByProvider.hook.ts +0 -46
  189. package/src/modularDrawer/__mocks__/useGroupedCurrenciesByProvider.mock.ts +0 -49
  190. package/src/modularDrawer/modules/__test__/createNetworkConfiguration.test.ts +0 -342
  191. package/src/modularDrawer/utils/__tests__/currencyUtils.test.ts +0 -126
  192. package/src/modularDrawer/utils/currencyUtils.ts +0 -95
@@ -1,6 +1,12 @@
1
1
  import { Account as WalletAPIAccount } from "@ledgerhq/wallet-api-core";
2
2
  import { TokenAccount, Account, AccountLike } from "@ledgerhq/types-live";
3
3
  import { LiveAppManifest } from "../../platform/types";
4
+ /**
5
+ * Determines if a manifest uses (Ledger Live) account ID format or UUID (Wallet API) format.
6
+ * @param manifest - The live app manifest to check
7
+ * @returns true if the manifest uses encoded format (v3+ dapp), false otherwise
8
+ */
9
+ export declare function usesEncodedAccountIdFormat(manifest: LiveAppManifest): boolean;
4
10
  /** The dapp connector "v3" uses the ledger live account ID to find the correct account. Live app and dapp browser manifests require wallet API ID. */
5
11
  export declare function deriveAccountIdForManifest(accountId: Account["id"] | TokenAccount["id"] | AccountLike["id"], walletApiAccountId: WalletAPIAccount["id"] | string, manifest: LiveAppManifest): string;
6
12
  //# sourceMappingURL=deriveAccountIdForManifest.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"deriveAccountIdForManifest.d.ts","sourceRoot":"","sources":["../../../src/wallet-api/utils/deriveAccountIdForManifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAExE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGvD,wJAAwJ;AACxJ,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,EACjE,kBAAkB,EAAE,gBAAgB,CAAC,IAAI,CAAC,GAAG,MAAM,EACnD,QAAQ,EAAE,eAAe,UAQ1B"}
1
+ {"version":3,"file":"deriveAccountIdForManifest.d.ts","sourceRoot":"","sources":["../../../src/wallet-api/utils/deriveAccountIdForManifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAExE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGvD;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAM7E;AAED,wJAAwJ;AACxJ,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,EACjE,kBAAkB,EAAE,gBAAgB,CAAC,IAAI,CAAC,GAAG,MAAM,EACnD,QAAQ,EAAE,eAAe,UAO1B"}
@@ -1,9 +1,18 @@
1
1
  import { WALLET_API_VERSION } from "../../wallet-api/constants";
2
2
  import semver from "semver";
3
+ /**
4
+ * Determines if a manifest uses (Ledger Live) account ID format or UUID (Wallet API) format.
5
+ * @param manifest - The live app manifest to check
6
+ * @returns true if the manifest uses encoded format (v3+ dapp), false otherwise
7
+ */
8
+ export function usesEncodedAccountIdFormat(manifest) {
9
+ return ("dapp" in manifest &&
10
+ !!manifest.apiVersion &&
11
+ semver.satisfies(WALLET_API_VERSION, manifest.apiVersion));
12
+ }
3
13
  /** The dapp connector "v3" uses the ledger live account ID to find the correct account. Live app and dapp browser manifests require wallet API ID. */
4
14
  export function deriveAccountIdForManifest(accountId, walletApiAccountId, manifest) {
5
- const isDapp = "dapp" in manifest;
6
- if (isDapp && manifest.apiVersion && semver.satisfies(WALLET_API_VERSION, manifest.apiVersion)) {
15
+ if (usesEncodedAccountIdFormat(manifest)) {
7
16
  return accountId;
8
17
  }
9
18
  /** Assume dapp browser <=v2 or live app, fallback to wallet ID. */
@@ -1 +1 @@
1
- {"version":3,"file":"deriveAccountIdForManifest.js","sourceRoot":"","sources":["../../../src/wallet-api/utils/deriveAccountIdForManifest.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAGhE,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,wJAAwJ;AACxJ,MAAM,UAAU,0BAA0B,CACxC,SAAiE,EACjE,kBAAmD,EACnD,QAAyB;IAEzB,MAAM,MAAM,GAAG,MAAM,IAAI,QAAQ,CAAC;IAClC,IAAI,MAAM,IAAI,QAAQ,CAAC,UAAU,IAAI,MAAM,CAAC,SAAS,CAAC,kBAAkB,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE;QAC9F,OAAO,SAAS,CAAC;KAClB;IACD,qEAAqE;IACrE,OAAO,kBAAkB,CAAC;AAC5B,CAAC"}
1
+ {"version":3,"file":"deriveAccountIdForManifest.js","sourceRoot":"","sources":["../../../src/wallet-api/utils/deriveAccountIdForManifest.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAGhE,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CAAC,QAAyB;IAClE,OAAO,CACL,MAAM,IAAI,QAAQ;QAClB,CAAC,CAAC,QAAQ,CAAC,UAAU;QACrB,MAAM,CAAC,SAAS,CAAC,kBAAkB,EAAE,QAAQ,CAAC,UAAU,CAAC,CAC1D,CAAC;AACJ,CAAC;AAED,wJAAwJ;AACxJ,MAAM,UAAU,0BAA0B,CACxC,SAAiE,EACjE,kBAAmD,EACnD,QAAyB;IAEzB,IAAI,0BAA0B,CAAC,QAAQ,CAAC,EAAE;QACxC,OAAO,SAAS,CAAC;KAClB;IACD,qEAAqE;IACrE,OAAO,kBAAkB,CAAC;AAC5B,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ledgerhq/live-common",
3
3
  "description": "Common ground for the Ledger Live apps",
4
- "version": "34.53.0-nightly.20251118023800",
4
+ "version": "34.53.0-nightly.20251119023741",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/LedgerHQ/ledger-live.git"
@@ -168,79 +168,79 @@
168
168
  "xstate": "^5.19.2",
169
169
  "yargs": "^17.0.0",
170
170
  "zod": "^3.22.4",
171
- "@ledgerhq/coin-algorand": "^0.13.0-nightly.20251118023800",
172
- "@ledgerhq/coin-aptos": "^3.6.0-nightly.20251118023800",
173
- "@ledgerhq/coin-bitcoin": "^0.25.0-nightly.20251118023800",
174
- "@ledgerhq/coin-cardano": "^0.15.0-nightly.20251118023800",
175
- "@ledgerhq/coin-canton": "^0.10.0-nightly.20251118023800",
176
- "@ledgerhq/coin-casper": "^2.3.1-nightly.20251118023800",
177
- "@ledgerhq/coin-celo": "^1.7.1-nightly.20251118023800",
178
- "@ledgerhq/coin-cosmos": "^0.20.0-nightly.20251118023800",
179
- "@ledgerhq/coin-evm": "^2.35.0-nightly.20251118023800",
180
- "@ledgerhq/coin-filecoin": "^1.15.0-nightly.20251118023800",
181
- "@ledgerhq/coin-framework": "^6.9.0-nightly.20251118023800",
182
- "@ledgerhq/coin-hedera": "^1.14.0-nightly.20251118023800",
183
- "@ledgerhq/coin-icon": "^0.15.0-nightly.20251118023800",
184
- "@ledgerhq/coin-internet_computer": "^1.10.1-nightly.20251118023800",
185
- "@ledgerhq/coin-kaspa": "^1.4.1-nightly.20251118023800",
186
- "@ledgerhq/coin-mina": "^1.4.1-nightly.20251118023800",
187
- "@ledgerhq/coin-multiversx": "^0.8.0-nightly.20251118023800",
188
- "@ledgerhq/coin-near": "^0.16.0-nightly.20251118023800",
189
- "@ledgerhq/coin-polkadot": "^6.13.0-nightly.20251118023800",
190
- "@ledgerhq/coin-solana": "^0.37.0-nightly.20251118023800",
191
- "@ledgerhq/coin-stacks": "^0.12.0-nightly.20251118023800",
192
- "@ledgerhq/coin-stellar": "^6.7.0-nightly.20251118023800",
193
- "@ledgerhq/coin-sui": "^0.18.0-nightly.20251118023800",
194
- "@ledgerhq/coin-tezos": "^6.9.0-nightly.20251118023800",
195
- "@ledgerhq/coin-ton": "^0.17.0-nightly.20251118023800",
196
- "@ledgerhq/coin-vechain": "^2.12.1-nightly.20251118023800",
197
- "@ledgerhq/coin-tron": "^5.7.0-nightly.20251118023800",
198
- "@ledgerhq/crypto-icons-ui": "^1.23.0-nightly.20251118023800",
199
- "@ledgerhq/coin-xrp": "^7.8.0-nightly.20251118023800",
200
- "@ledgerhq/cryptoassets": "^13.33.0-nightly.20251118023800",
201
- "@ledgerhq/device-core": "^0.6.8-nightly.20251118023800",
171
+ "@ledgerhq/coin-algorand": "^0.13.0-nightly.20251119023741",
172
+ "@ledgerhq/coin-aptos": "^3.6.0-nightly.20251119023741",
173
+ "@ledgerhq/coin-bitcoin": "^0.25.0-nightly.20251119023741",
174
+ "@ledgerhq/coin-canton": "^0.10.0-nightly.20251119023741",
175
+ "@ledgerhq/coin-cardano": "^0.15.0-nightly.20251119023741",
176
+ "@ledgerhq/coin-casper": "^2.3.1-nightly.20251119023741",
177
+ "@ledgerhq/coin-celo": "^1.7.1-nightly.20251119023741",
178
+ "@ledgerhq/coin-cosmos": "^0.20.0-nightly.20251119023741",
179
+ "@ledgerhq/coin-evm": "^2.35.0-nightly.20251119023741",
180
+ "@ledgerhq/coin-filecoin": "^1.15.0-nightly.20251119023741",
181
+ "@ledgerhq/coin-framework": "^6.9.0-nightly.20251119023741",
182
+ "@ledgerhq/coin-hedera": "^1.14.0-nightly.20251119023741",
183
+ "@ledgerhq/coin-icon": "^0.15.0-nightly.20251119023741",
184
+ "@ledgerhq/coin-internet_computer": "^1.10.1-nightly.20251119023741",
185
+ "@ledgerhq/coin-kaspa": "^1.4.1-nightly.20251119023741",
186
+ "@ledgerhq/coin-mina": "^1.4.1-nightly.20251119023741",
187
+ "@ledgerhq/coin-multiversx": "^0.8.0-nightly.20251119023741",
188
+ "@ledgerhq/coin-near": "^0.16.0-nightly.20251119023741",
189
+ "@ledgerhq/coin-polkadot": "^6.13.0-nightly.20251119023741",
190
+ "@ledgerhq/coin-solana": "^0.37.0-nightly.20251119023741",
191
+ "@ledgerhq/coin-stacks": "^0.12.0-nightly.20251119023741",
192
+ "@ledgerhq/coin-stellar": "^6.7.0-nightly.20251119023741",
193
+ "@ledgerhq/coin-sui": "^0.18.0-nightly.20251119023741",
194
+ "@ledgerhq/coin-tezos": "^6.9.0-nightly.20251119023741",
195
+ "@ledgerhq/coin-ton": "^0.17.0-nightly.20251119023741",
196
+ "@ledgerhq/coin-tron": "^5.7.0-nightly.20251119023741",
197
+ "@ledgerhq/coin-vechain": "^2.12.1-nightly.20251119023741",
198
+ "@ledgerhq/coin-xrp": "^7.8.0-nightly.20251119023741",
199
+ "@ledgerhq/crypto-icons-ui": "^1.23.0-nightly.20251119023741",
200
+ "@ledgerhq/cryptoassets": "^13.33.0-nightly.20251119023741",
201
+ "@ledgerhq/device-core": "^0.6.8-nightly.20251119023741",
202
202
  "@ledgerhq/devices": "8.7.0",
203
203
  "@ledgerhq/errors": "^6.27.0",
204
204
  "@ledgerhq/hw-app-algorand": "^6.31.9",
205
205
  "@ledgerhq/hw-app-aptos": "^6.34.9",
206
206
  "@ledgerhq/hw-app-btc": "^10.12.0",
207
- "@ledgerhq/hw-app-celo": "^6.35.3-nightly.20251118023800",
208
- "@ledgerhq/hw-app-eth": "^6.47.1-nightly.20251118023800",
207
+ "@ledgerhq/hw-app-celo": "^6.35.3-nightly.20251119023741",
209
208
  "@ledgerhq/hw-app-cosmos": "^6.32.9",
209
+ "@ledgerhq/hw-app-eth": "^6.47.1-nightly.20251119023741",
210
210
  "@ledgerhq/hw-app-exchange": "^0.17.0",
211
211
  "@ledgerhq/hw-app-hedera": "^1.2.9",
212
- "@ledgerhq/hw-app-kaspa": "^1.3.2",
213
212
  "@ledgerhq/hw-app-icon": "^1.3.9",
213
+ "@ledgerhq/hw-app-kaspa": "^1.3.2",
214
214
  "@ledgerhq/hw-app-multiversx": "^6.26.0",
215
215
  "@ledgerhq/hw-app-near": "^6.31.9",
216
216
  "@ledgerhq/hw-app-polkadot": "^6.34.9",
217
217
  "@ledgerhq/hw-app-str": "^7.2.9",
218
- "@ledgerhq/hw-app-tezos": "^6.31.9",
219
218
  "@ledgerhq/hw-app-sui": "^1.4.0",
219
+ "@ledgerhq/hw-app-tezos": "^6.31.9",
220
220
  "@ledgerhq/hw-app-trx": "^6.31.9",
221
- "@ledgerhq/hw-app-vet": "^0.7.0",
221
+ "@ledgerhq/hw-app-vet": "^0.8.0-nightly.20251119023741",
222
222
  "@ledgerhq/hw-app-xrp": "^6.32.7",
223
223
  "@ledgerhq/hw-bolos": "^6.32.9",
224
224
  "@ledgerhq/hw-transport": "6.31.13",
225
225
  "@ledgerhq/hw-transport-mocker": "^6.29.13",
226
- "@ledgerhq/ledger-trust-service": "^0.4.2-nightly.20251118023800",
226
+ "@ledgerhq/ledger-cal-service": "^1.9.0-nightly.20251119023741",
227
+ "@ledgerhq/ledger-trust-service": "^0.4.2-nightly.20251119023741",
227
228
  "@ledgerhq/live-config": "^3.2.0",
228
- "@ledgerhq/live-countervalues": "^0.10.0-nightly.20251118023800",
229
- "@ledgerhq/live-countervalues-react": "^0.7.2-nightly.20251118023800",
230
- "@ledgerhq/ledger-cal-service": "^1.9.0-nightly.20251118023800",
229
+ "@ledgerhq/live-countervalues": "^0.10.0-nightly.20251119023741",
230
+ "@ledgerhq/live-countervalues-react": "^0.7.2-nightly.20251119023741",
231
231
  "@ledgerhq/live-dmk-shared": "^0.15.0",
232
- "@ledgerhq/live-env": "^2.21.0-nightly.20251118023800",
232
+ "@ledgerhq/live-env": "^2.21.0-nightly.20251119023741",
233
233
  "@ledgerhq/live-hooks": "0.2.0",
234
- "@ledgerhq/live-network": "^2.1.1-nightly.20251118023800",
234
+ "@ledgerhq/live-network": "^2.1.1-nightly.20251119023741",
235
235
  "@ledgerhq/live-promise": "^0.1.1",
236
- "@ledgerhq/live-signer-canton": "^0.5.1-nightly.20251118023800",
237
- "@ledgerhq/live-signer-evm": "^0.10.1-nightly.20251118023800",
238
- "@ledgerhq/live-signer-solana": "^0.6.1-nightly.20251118023800",
239
- "@ledgerhq/live-wallet": "^0.16.0-nightly.20251118023800",
236
+ "@ledgerhq/live-signer-canton": "^0.5.1-nightly.20251119023741",
237
+ "@ledgerhq/live-signer-evm": "^0.10.1-nightly.20251119023741",
238
+ "@ledgerhq/live-signer-solana": "^0.6.1-nightly.20251119023741",
239
+ "@ledgerhq/live-wallet": "^0.16.0-nightly.20251119023741",
240
240
  "@ledgerhq/logs": "^6.13.0",
241
- "@ledgerhq/speculos-transport": "^0.2.15-nightly.20251118023800",
242
- "@ledgerhq/wallet-api-acre-module": "^0.10.0-nightly.20251118023800",
243
- "@ledgerhq/wallet-api-exchange-module": "^0.19.0-nightly.20251118023800"
241
+ "@ledgerhq/speculos-transport": "^0.2.15-nightly.20251119023741",
242
+ "@ledgerhq/wallet-api-acre-module": "^0.10.0-nightly.20251119023741",
243
+ "@ledgerhq/wallet-api-exchange-module": "^0.19.0-nightly.20251119023741"
244
244
  },
245
245
  "devDependencies": {
246
246
  "@solana/web3.js": "1.95.4",
@@ -277,8 +277,8 @@
277
277
  "nock": "^13.0.5",
278
278
  "react": "18.3.1",
279
279
  "react-dom": "18.3.1",
280
- "react-native": "0.77.2",
281
- "react-native-svg": "15.11.2",
280
+ "react-native": "0.77.3",
281
+ "react-native-svg": "15.12.1",
282
282
  "react-test-renderer": "18.3.1",
283
283
  "redux-actions": "2.6.5",
284
284
  "timemachine": "^0.3.2",
@@ -288,10 +288,10 @@
288
288
  "undici": "6.19.2",
289
289
  "uuid": "^8.3.2",
290
290
  "ws": "7",
291
- "@ledgerhq/device-react": "^0.3.2-nightly.20251118023800",
291
+ "@ledgerhq/device-react": "^0.3.2-nightly.20251119023741",
292
292
  "@ledgerhq/types-cryptoassets": "^7.30.0",
293
293
  "@ledgerhq/types-devices": "^6.27.0",
294
- "@ledgerhq/types-live": "^6.89.0-nightly.20251118023800"
294
+ "@ledgerhq/types-live": "^6.89.0-nightly.20251119023741"
295
295
  },
296
296
  "scripts": {
297
297
  "build": "zx ./scripts/build-ts.mjs",
@@ -468,7 +468,6 @@ export function testBridge<T extends TransactionCommon>(data: DatasetTest<T>): v
468
468
  };
469
469
  const bridge = await getBridge();
470
470
  const synced = await syncAccount(bridge, copy);
471
- if (initialAccountId.includes("ripple")) return; // ripple wont work because of the current implementation of pagination
472
471
  expect(synced.operations.length).toBe(account.operations.length);
473
472
  // same ops are restored
474
473
  expect(synced.operations).toEqual(account.operations);
@@ -481,7 +480,6 @@ export function testBridge<T extends TransactionCommon>(data: DatasetTest<T>): v
481
480
  });
482
481
  makeTest("pendingOperations are cleaned up", async () => {
483
482
  const account = await getSynced();
484
- if (initialAccountId.includes("ripple")) return; // ripple wont work because of the current implementation of pagination
485
483
 
486
484
  if (account.operations.length) {
487
485
  const operations = account.operations.slice(1);
@@ -1,4 +1,4 @@
1
- import { encodeAccountId } from "@ledgerhq/coin-framework/account/index";
1
+ import { encodeAccountId, getSyncHash } from "@ledgerhq/coin-framework/account/index";
2
2
  import { GetAccountShape, mergeOps } from "@ledgerhq/coin-framework/bridge/jsHelpers";
3
3
  import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
4
4
  import BigNumber from "bignumber.js";
@@ -8,6 +8,7 @@ import { inferSubOperations } from "@ledgerhq/coin-framework/serialization";
8
8
  import { buildSubAccounts, mergeSubAccounts } from "./buildSubAccounts";
9
9
  import type { Operation, Pagination } from "@ledgerhq/coin-framework/api/types";
10
10
  import type { OperationCommon } from "./types";
11
+ import type { Account } from "@ledgerhq/types-live";
11
12
 
12
13
  function isNftCoreOp(operation: Operation): boolean {
13
14
  return (
@@ -52,14 +53,13 @@ export function genericGetAccountShape(network: string, kind: string): GetAccoun
52
53
  : { ...op, accountId, id: encodeOperationId(accountId, op.hash, op.type) },
53
54
  );
54
55
  const lastPagingToken = oldOps[0]?.extra?.pagingToken || "";
56
+ const syncHash = await getSyncHash(currency.id, syncConfig.blacklistedTokenIds);
57
+ const syncFromScratch = !initialAccount?.blockHeight || initialAccount?.syncHash !== syncHash;
55
58
 
56
59
  // Calculate minHeight for pagination
57
- let minHeight: number = 0;
58
- if (oldOps.length > 0 && initialAccount?.blockHeight !== 0) {
59
- minHeight = (oldOps[0].blockHeight ?? 0) + 1;
60
- }
60
+ const minHeight = syncFromScratch ? 0 : (oldOps[0]?.blockHeight ?? 0) + 1;
61
61
  const paginationParams: Pagination = { minHeight, order: "asc" };
62
- if (lastPagingToken) {
62
+ if (lastPagingToken && !syncFromScratch) {
63
63
  paginationParams.lastPagingToken = lastPagingToken;
64
64
  }
65
65
 
@@ -81,7 +81,9 @@ export function genericGetAccountShape(network: string, kind: string): GetAccoun
81
81
  operations: newAssetOperations,
82
82
  getTokenFromAsset: alpacaApi.getTokenFromAsset,
83
83
  });
84
- const subAccounts = mergeSubAccounts(initialAccount?.subAccounts ?? [], newSubAccounts);
84
+ const subAccounts = syncFromScratch
85
+ ? newSubAccounts
86
+ : mergeSubAccounts(initialAccount?.subAccounts ?? [], newSubAccounts);
85
87
 
86
88
  const newOpsWithSubs = newOps.map(op => {
87
89
  const subOperations = inferSubOperations(op.hash, newSubAccounts);
@@ -95,12 +97,12 @@ export function genericGetAccountShape(network: string, kind: string): GetAccoun
95
97
  alpacaApi.refreshOperations && initialAccount?.pendingOperations.length
96
98
  ? await alpacaApi.refreshOperations(initialAccount.pendingOperations)
97
99
  : [];
98
- const operations = mergeOps(oldOps, [
99
- ...confirmedOperations,
100
- ...newOpsWithSubs,
101
- ]) as OperationCommon[];
100
+ const newOperations = [...confirmedOperations, ...newOpsWithSubs];
101
+ const operations = syncFromScratch
102
+ ? newOperations
103
+ : (mergeOps(oldOps, newOperations) as OperationCommon[]);
102
104
 
103
- const res = {
105
+ const res: Partial<Account> = {
104
106
  id: accountId,
105
107
  xpub: address,
106
108
  blockHeight: operations.length === 0 ? 0 : blockInfo.height || initialAccount?.blockHeight,
@@ -109,6 +111,7 @@ export function genericGetAccountShape(network: string, kind: string): GetAccoun
109
111
  operations,
110
112
  subAccounts,
111
113
  operationsCount: operations.length,
114
+ syncHash,
112
115
  };
113
116
  return res;
114
117
  };
@@ -1,8 +1,10 @@
1
1
  import BigNumber from "bignumber.js";
2
2
  import { genericGetAccountShape } from "../getAccountShape";
3
3
 
4
+ const getSyncHashMock = jest.fn();
4
5
  jest.mock("@ledgerhq/coin-framework/account/index", () => ({
5
6
  encodeAccountId: jest.fn(() => "accId"),
7
+ getSyncHash: (...args: any[]) => getSyncHashMock(...args),
6
8
  }));
7
9
 
8
10
  const mergeOpsMock = jest.fn();
@@ -63,105 +65,16 @@ describe("genericGetAccountShape", () => {
63
65
  });
64
66
 
65
67
  describe.each(chains)("$currency.id", ({ currency, network }) => {
66
- test("builds account shape with existing operations, pagination and sub accounts", async () => {
67
- const oldOp = {
68
- hash: "h1",
69
- blockHeight: 10,
70
- type: "OPT_IN",
71
- extra: { pagingToken: "pt1", assetReference: "ar1", assetOwner: "ow1" },
72
- };
73
- const pendingOp = {
74
- hash: "h0",
75
- blockHeight: 10,
76
- type: "OUT",
77
- };
78
- const initialAccount = {
79
- operations: [oldOp],
80
- pendingOperations: [pendingOp],
81
- blockHeight: 10,
82
- };
83
-
84
- extractBalanceMock.mockReturnValue({ value: "1000", locked: "300" });
85
- getBalanceMock.mockResolvedValue([
86
- { asset: { type: "native" }, value: "1000", locked: "300" },
87
- { asset: { type: "token", symbol: "TOK1" }, value: "42" },
88
- { asset: { type: "token", symbol: "TOK_IGNORE" }, value: "5" },
89
- ]);
90
-
91
- getTokenFromAssetMock.mockImplementation(asset =>
92
- asset.symbol === "TOK1" ? { id: `${currency.id}_token1` } : null,
93
- );
94
-
95
- const coreOp = { hash: "h2", height: 12 };
96
- listOperationsMock.mockResolvedValue([[coreOp]]);
97
- refreshOperationsMock.mockImplementation(ops => {
98
- const op = ops[0];
99
- if (op?.hash === "h0") {
100
- return [{ ...op, blockHeight: 12 }];
101
- }
102
- return [];
103
- });
104
-
105
- adaptCoreOperationToLiveOperationMock.mockImplementation((_accId, op) => ({
106
- hash: op.hash,
107
- type: "IN",
108
- blockHeight: 12,
109
- extra: { assetReference: "ar2", assetOwner: "ow2" },
110
- }));
111
-
112
- mergeOpsMock.mockImplementation((oldOps, newOps) => [...newOps, ...oldOps]);
113
- cleanedOperationMock.mockImplementation(operation => operation);
114
- mergeSubAccountsMock.mockImplementation((oldSubAccounts, newSubAccounts) => [
115
- ...newSubAccounts,
116
- ...oldSubAccounts,
117
- ]);
118
-
119
- buildSubAccountsMock.mockReturnValue([
120
- { id: `${currency.id}_subAcc1`, type: "TokenAccount" },
121
- ]);
122
-
123
- inferSubOperationsMock.mockImplementation(hash =>
124
- hash === "h2" ? [{ id: `${currency.id}_subOp1` }] : [],
125
- );
126
-
127
- lastBlockMock.mockResolvedValue({ height: 123 });
128
-
129
- const getShape = genericGetAccountShape(network, currency.id);
130
- const result = await getShape(
68
+ test.each([
69
+ [
70
+ "an up-to-date sync hash",
71
+ "sync-hash",
131
72
  {
132
- address: `${currency.id}_addr1`,
133
- initialAccount,
134
- currency,
135
- derivationMode: "",
136
- } as any,
137
- { paginationConfig: {} as any },
138
- );
139
-
140
- expect(chainSpecificGetAccountShapeMock).toHaveBeenCalledWith(`${currency.id}_addr1`);
141
-
142
- expect(listOperationsMock).toHaveBeenCalledWith(`${currency.id}_addr1`, {
143
- minHeight: 11,
144
- order: "asc",
145
- lastPagingToken: "pt1",
146
- });
147
-
148
- const assetsBalancePassed = buildSubAccountsMock.mock.calls[0][0].allTokenAssetsBalances;
149
- expect(assetsBalancePassed).toEqual([
150
- { asset: { symbol: "TOK1", type: "token" }, value: "42" },
151
- { asset: { symbol: "TOK_IGNORE", type: "token" }, value: "5" },
152
- ]);
153
-
154
- const assetOpsPassed = buildSubAccountsMock.mock.calls[0][0].operations;
155
- expect(assetOpsPassed).toHaveLength(1);
156
- expect(assetOpsPassed[0].hash).toBe("h2");
157
-
158
- expect(result).toMatchObject({
159
- balance: new BigNumber(1000),
160
- spendableBalance: new BigNumber(700),
161
- blockHeight: 123,
162
- operationsCount: 3,
163
- subAccounts: [{ id: `${currency.id}_subAcc1`, type: "TokenAccount" }],
164
- operations: [
73
+ minHeight: 11,
74
+ order: "asc",
75
+ lastPagingToken: "pt1",
76
+ },
77
+ [
165
78
  {
166
79
  hash: "h0",
167
80
  type: "OUT",
@@ -174,10 +87,138 @@ describe("genericGetAccountShape", () => {
174
87
  subOperations: [{ id: `${currency.id}_subOp1` }],
175
88
  extra: { assetReference: "ar2", assetOwner: "ow2" },
176
89
  },
177
- oldOp,
90
+ {
91
+ hash: "h1",
92
+ blockHeight: 10,
93
+ type: "OPT_IN",
94
+ extra: { pagingToken: "pt1", assetReference: "ar1", assetOwner: "ow1" },
95
+ },
178
96
  ],
179
- });
180
- });
97
+ ],
98
+ [
99
+ "an outdated sync hash",
100
+ "outdated-sync-hash",
101
+ {
102
+ minHeight: 0,
103
+ order: "asc",
104
+ },
105
+ [
106
+ {
107
+ hash: "h0",
108
+ type: "OUT",
109
+ blockHeight: 12,
110
+ },
111
+ {
112
+ hash: "h2",
113
+ type: "IN",
114
+ blockHeight: 12,
115
+ subOperations: [{ id: `${currency.id}_subOp1` }],
116
+ extra: { assetReference: "ar2", assetOwner: "ow2" },
117
+ },
118
+ ],
119
+ ],
120
+ ])(
121
+ "builds account shape with existing operations, pagination and sub accounts from %s",
122
+ async (_s, syncHash, expectedPagination, expectedOperations) => {
123
+ const oldOp = {
124
+ hash: "h1",
125
+ blockHeight: 10,
126
+ type: "OPT_IN",
127
+ extra: { pagingToken: "pt1", assetReference: "ar1", assetOwner: "ow1" },
128
+ };
129
+ const pendingOp = {
130
+ hash: "h0",
131
+ blockHeight: 10,
132
+ type: "OUT",
133
+ };
134
+ const initialAccount = {
135
+ operations: [oldOp],
136
+ pendingOperations: [pendingOp],
137
+ blockHeight: 10,
138
+ syncHash,
139
+ };
140
+
141
+ getSyncHashMock.mockReturnValue("sync-hash");
142
+ extractBalanceMock.mockReturnValue({ value: "1000", locked: "300" });
143
+ getBalanceMock.mockResolvedValue([
144
+ { asset: { type: "native" }, value: "1000", locked: "300" },
145
+ { asset: { type: "token", symbol: "TOK1" }, value: "42" },
146
+ { asset: { type: "token", symbol: "TOK_IGNORE" }, value: "5" },
147
+ ]);
148
+
149
+ getTokenFromAssetMock.mockImplementation(asset =>
150
+ asset.symbol === "TOK1" ? { id: `${currency.id}_token1` } : null,
151
+ );
152
+
153
+ const coreOp = { hash: "h2", height: 12 };
154
+ listOperationsMock.mockResolvedValue([[coreOp]]);
155
+ refreshOperationsMock.mockImplementation(ops => {
156
+ const op = ops[0];
157
+ if (op?.hash === "h0") {
158
+ return [{ ...op, blockHeight: 12 }];
159
+ }
160
+ return [];
161
+ });
162
+
163
+ adaptCoreOperationToLiveOperationMock.mockImplementation((_accId, op) => ({
164
+ hash: op.hash,
165
+ type: "IN",
166
+ blockHeight: 12,
167
+ extra: { assetReference: "ar2", assetOwner: "ow2" },
168
+ }));
169
+
170
+ mergeOpsMock.mockImplementation((oldOps, newOps) => [...newOps, ...oldOps]);
171
+ cleanedOperationMock.mockImplementation(operation => operation);
172
+ mergeSubAccountsMock.mockImplementation((oldSubAccounts, newSubAccounts) => [
173
+ ...newSubAccounts,
174
+ ...oldSubAccounts,
175
+ ]);
176
+
177
+ buildSubAccountsMock.mockReturnValue([
178
+ { id: `${currency.id}_subAcc1`, type: "TokenAccount" },
179
+ ]);
180
+
181
+ inferSubOperationsMock.mockImplementation(hash =>
182
+ hash === "h2" ? [{ id: `${currency.id}_subOp1` }] : [],
183
+ );
184
+
185
+ lastBlockMock.mockResolvedValue({ height: 123 });
186
+
187
+ const getShape = genericGetAccountShape(network, currency.id);
188
+ const result = await getShape(
189
+ {
190
+ address: `${currency.id}_addr1`,
191
+ initialAccount,
192
+ currency,
193
+ derivationMode: "",
194
+ } as any,
195
+ { paginationConfig: {} as any },
196
+ );
197
+
198
+ expect(chainSpecificGetAccountShapeMock).toHaveBeenCalledWith(`${currency.id}_addr1`);
199
+
200
+ expect(listOperationsMock).toHaveBeenCalledWith(`${currency.id}_addr1`, expectedPagination);
201
+
202
+ const assetsBalancePassed = buildSubAccountsMock.mock.calls[0][0].allTokenAssetsBalances;
203
+ expect(assetsBalancePassed).toEqual([
204
+ { asset: { symbol: "TOK1", type: "token" }, value: "42" },
205
+ { asset: { symbol: "TOK_IGNORE", type: "token" }, value: "5" },
206
+ ]);
207
+
208
+ const assetOpsPassed = buildSubAccountsMock.mock.calls[0][0].operations;
209
+ expect(assetOpsPassed).toHaveLength(1);
210
+ expect(assetOpsPassed[0].hash).toBe("h2");
211
+
212
+ expect(result).toMatchObject({
213
+ balance: new BigNumber(1000),
214
+ spendableBalance: new BigNumber(700),
215
+ blockHeight: 123,
216
+ operationsCount: expectedOperations.length,
217
+ subAccounts: [{ id: `${currency.id}_subAcc1`, type: "TokenAccount" }],
218
+ operations: expectedOperations,
219
+ });
220
+ },
221
+ );
181
222
 
182
223
  test("handles empty operations (no old ops, no new ops) and blockHeight=0", async () => {
183
224
  getBalanceMock.mockResolvedValue([{ asset: { type: "native" }, value: "0", locked: "0" }]);
@@ -17,30 +17,9 @@ export type MappedAsset = {
17
17
  ledgerCurrency?: CryptoOrTokenCurrency;
18
18
  };
19
19
 
20
- export type GroupedCurrency = {
21
- providerId: string;
22
- currenciesByNetwork: MappedAsset[];
23
- };
24
-
25
- export type CurrenciesByProviderId = {
26
- currenciesByNetwork: CryptoOrTokenCurrency[];
27
- providerId: string;
28
- metaCurrencyId?: string;
29
- };
30
-
31
- export type GroupedCurrencies = {
32
- currenciesByProvider: CurrenciesByProviderId[];
33
- sortedCryptoCurrencies: CryptoOrTokenCurrency[];
34
- };
35
-
36
20
  export enum LoadingStatus {
37
21
  Idle = "idle",
38
22
  Pending = "pending",
39
23
  Success = "success",
40
24
  Error = "error",
41
25
  }
42
-
43
- export type LoadingBasedGroupedCurrencies = {
44
- result: GroupedCurrencies;
45
- loadingStatus: LoadingStatus;
46
- };
@@ -1,9 +1,11 @@
1
1
  import { of, throwError } from "rxjs";
2
2
  import { retryOnErrorsCommandWrapper, sharedLogicTaskWrapper } from "./core";
3
3
  import { DisconnectedDevice, LockedDeviceError } from "@ledgerhq/errors";
4
+ import { DeviceBusyError } from "@ledgerhq/device-management-kit";
4
5
  import { concatMap } from "rxjs/operators";
5
6
  import { TransportRef } from "../transports/core";
6
7
  import { aTransportRefBuilder } from "../mocks/aTransportRef";
8
+ import { isDmkError } from "./core";
7
9
 
8
10
  // Needs to mock the timer from rxjs used in the retry mechanism
9
11
  jest.mock("rxjs", () => {
@@ -330,4 +332,22 @@ describe("retryOnErrorsCommandWrapper", () => {
330
332
  });
331
333
  });
332
334
  });
335
+
336
+ describe("isDmkError (deviceSDK/tasks/core)", () => {
337
+ it("returns true for a DMK error instance", () => {
338
+ expect(isDmkError(new DeviceBusyError())).toBe(true);
339
+ });
340
+
341
+ it("returns false for a regular Error instance", () => {
342
+ expect(isDmkError(new Error("error"))).toBe(false);
343
+ });
344
+
345
+ it("returns false for a string error (e.g. 'Invalid extension provided')", () => {
346
+ expect(isDmkError("Invalid extension provided")).toBe(false);
347
+ });
348
+
349
+ it("returns false for undefined", () => {
350
+ expect(isDmkError(undefined)).toBe(false);
351
+ });
352
+ });
333
353
  });
@@ -79,7 +79,8 @@ type ErrorClass = CustomErrorClassType | TransportStatusErrorClassType;
79
79
  // To be able to retry a command, the command needs to take an object containing a transport as its argument
80
80
  type CommandTransportArgs = { transport: Transport };
81
81
 
82
- export const isDmkError = (error: any): error is DmkError => error && "_tag" in error;
82
+ export const isDmkError = (error: unknown): error is DmkError =>
83
+ !!error && typeof error === "object" && error !== null && "_tag" in error;
83
84
 
84
85
  /**
85
86
  * Calls a command and retries it on given errors. The transport is refreshed before each retry.
@@ -108,12 +108,6 @@ export class Account {
108
108
  "0xa1baa625c5E6A9304cB7AcD86d2fee6B710eC3eB",
109
109
  1,
110
110
  );
111
- static readonly BSC_SHIBA = new Account(
112
- Currency.BSC_SHIBA,
113
- "BNB Chain 1",
114
- "0x4BE2E2B8872AA298D6d123b9211B53E41f611566",
115
- 0,
116
- );
117
111
 
118
112
  static readonly BTC_LEGACY_1 = new Account(
119
113
  Currency.BTC,