@ledgerhq/live-common 34.50.0-nightly.1 → 34.50.0-nightly.2

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 (221) hide show
  1. package/lib/bridge/generic-alpaca/buildSubAccounts.d.ts +4 -4
  2. package/lib/bridge/generic-alpaca/buildSubAccounts.d.ts.map +1 -1
  3. package/lib/bridge/generic-alpaca/buildSubAccounts.js +7 -9
  4. package/lib/bridge/generic-alpaca/buildSubAccounts.js.map +1 -1
  5. package/lib/bridge/generic-alpaca/getAccountShape.d.ts.map +1 -1
  6. package/lib/bridge/generic-alpaca/getAccountShape.js +4 -6
  7. package/lib/bridge/generic-alpaca/getAccountShape.js.map +1 -1
  8. package/lib/bridge/generic-alpaca/tests/getAccountShape.test.js +5 -3
  9. package/lib/bridge/generic-alpaca/tests/getAccountShape.test.js.map +1 -1
  10. package/lib/e2e/enum/Account.d.ts +2 -0
  11. package/lib/e2e/enum/Account.d.ts.map +1 -1
  12. package/lib/e2e/enum/Account.js +4 -0
  13. package/lib/e2e/enum/Account.js.map +1 -1
  14. package/lib/e2e/enum/AppInfos.d.ts +1 -0
  15. package/lib/e2e/enum/AppInfos.d.ts.map +1 -1
  16. package/lib/e2e/enum/AppInfos.js +1 -0
  17. package/lib/e2e/enum/AppInfos.js.map +1 -1
  18. package/lib/e2e/enum/Currency.d.ts +2 -0
  19. package/lib/e2e/enum/Currency.d.ts.map +1 -1
  20. package/lib/e2e/enum/Currency.js +4 -0
  21. package/lib/e2e/enum/Currency.js.map +1 -1
  22. package/lib/e2e/enum/Network.d.ts +2 -1
  23. package/lib/e2e/enum/Network.d.ts.map +1 -1
  24. package/lib/e2e/enum/Network.js +1 -0
  25. package/lib/e2e/enum/Network.js.map +1 -1
  26. package/lib/e2e/families/hedera.d.ts +2 -0
  27. package/lib/e2e/families/hedera.d.ts.map +1 -0
  28. package/lib/e2e/families/hedera.js +11 -0
  29. package/lib/e2e/families/hedera.js.map +1 -0
  30. package/lib/e2e/speculos.d.ts.map +1 -1
  31. package/lib/e2e/speculos.js +12 -0
  32. package/lib/e2e/speculos.js.map +1 -1
  33. package/lib/exchange/platform/types.d.ts +2 -0
  34. package/lib/exchange/platform/types.d.ts.map +1 -1
  35. package/lib/exchange/swap/completeExchange.d.ts.map +1 -1
  36. package/lib/exchange/swap/completeExchange.js +22 -1
  37. package/lib/exchange/swap/completeExchange.js.map +1 -1
  38. package/lib/exchange/swap/getIncompatibleCurrencyKeys.d.ts.map +1 -1
  39. package/lib/exchange/swap/getIncompatibleCurrencyKeys.js +4 -0
  40. package/lib/exchange/swap/getIncompatibleCurrencyKeys.js.map +1 -1
  41. package/lib/families/hedera/exchange.d.ts +9 -0
  42. package/lib/families/hedera/exchange.d.ts.map +1 -0
  43. package/lib/families/hedera/exchange.js +36 -0
  44. package/lib/families/hedera/exchange.js.map +1 -0
  45. package/lib/hw/actions/completeExchange.d.ts +2 -0
  46. package/lib/hw/actions/completeExchange.d.ts.map +1 -1
  47. package/lib/hw/actions/completeExchange.js +1 -0
  48. package/lib/hw/actions/completeExchange.js.map +1 -1
  49. package/lib/modularDrawer/hooks/useRightBalanceAsset.d.ts +4 -3
  50. package/lib/modularDrawer/hooks/useRightBalanceAsset.d.ts.map +1 -1
  51. package/lib/modularDrawer/hooks/useRightBalanceAsset.js +13 -47
  52. package/lib/modularDrawer/hooks/useRightBalanceAsset.js.map +1 -1
  53. package/lib/modularDrawer/hooks/useRightBalanceNetwork.d.ts +1 -5
  54. package/lib/modularDrawer/hooks/useRightBalanceNetwork.d.ts.map +1 -1
  55. package/lib/modularDrawer/hooks/useRightBalanceNetwork.js +15 -55
  56. package/lib/modularDrawer/hooks/useRightBalanceNetwork.js.map +1 -1
  57. package/lib/modularDrawer/modules/createAssetConfiguration.d.ts.map +1 -1
  58. package/lib/modularDrawer/modules/createAssetConfiguration.js +2 -2
  59. package/lib/modularDrawer/modules/createAssetConfiguration.js.map +1 -1
  60. package/lib/modularDrawer/modules/createNetworkConfiguration.d.ts +1 -1
  61. package/lib/modularDrawer/modules/createNetworkConfiguration.d.ts.map +1 -1
  62. package/lib/modularDrawer/modules/createNetworkConfiguration.js +1 -3
  63. package/lib/modularDrawer/modules/createNetworkConfiguration.js.map +1 -1
  64. package/lib/modularDrawer/utils/__tests__/haveOneCommonAsset.test.d.ts +2 -0
  65. package/lib/modularDrawer/utils/__tests__/haveOneCommonAsset.test.d.ts.map +1 -0
  66. package/lib/modularDrawer/utils/__tests__/haveOneCommonAsset.test.js +46 -0
  67. package/lib/modularDrawer/utils/__tests__/haveOneCommonAsset.test.js.map +1 -0
  68. package/lib/modularDrawer/utils/currencyUtils.d.ts.map +1 -1
  69. package/lib/modularDrawer/utils/currencyUtils.js.map +1 -1
  70. package/lib/modularDrawer/utils/{haveOneCommonProvider.d.ts → haveOneCommonAsset.d.ts} +3 -3
  71. package/lib/modularDrawer/utils/haveOneCommonAsset.d.ts.map +1 -0
  72. package/lib/modularDrawer/utils/{haveOneCommonProvider.js → haveOneCommonAsset.js} +6 -6
  73. package/lib/modularDrawer/utils/haveOneCommonAsset.js.map +1 -0
  74. package/lib/modularDrawer/utils/index.d.ts +2 -4
  75. package/lib/modularDrawer/utils/index.d.ts.map +1 -1
  76. package/lib/modularDrawer/utils/index.js +3 -10
  77. package/lib/modularDrawer/utils/index.js.map +1 -1
  78. package/lib/modularDrawer/utils/index.test.js +0 -26
  79. package/lib/modularDrawer/utils/index.test.js.map +1 -1
  80. package/lib/modularDrawer/utils/type.d.ts +0 -6
  81. package/lib/modularDrawer/utils/type.d.ts.map +1 -1
  82. package/lib-es/bridge/generic-alpaca/buildSubAccounts.d.ts +4 -4
  83. package/lib-es/bridge/generic-alpaca/buildSubAccounts.d.ts.map +1 -1
  84. package/lib-es/bridge/generic-alpaca/buildSubAccounts.js +7 -9
  85. package/lib-es/bridge/generic-alpaca/buildSubAccounts.js.map +1 -1
  86. package/lib-es/bridge/generic-alpaca/getAccountShape.d.ts.map +1 -1
  87. package/lib-es/bridge/generic-alpaca/getAccountShape.js +4 -6
  88. package/lib-es/bridge/generic-alpaca/getAccountShape.js.map +1 -1
  89. package/lib-es/bridge/generic-alpaca/tests/getAccountShape.test.js +5 -3
  90. package/lib-es/bridge/generic-alpaca/tests/getAccountShape.test.js.map +1 -1
  91. package/lib-es/e2e/enum/Account.d.ts +2 -0
  92. package/lib-es/e2e/enum/Account.d.ts.map +1 -1
  93. package/lib-es/e2e/enum/Account.js +4 -0
  94. package/lib-es/e2e/enum/Account.js.map +1 -1
  95. package/lib-es/e2e/enum/AppInfos.d.ts +1 -0
  96. package/lib-es/e2e/enum/AppInfos.d.ts.map +1 -1
  97. package/lib-es/e2e/enum/AppInfos.js +1 -0
  98. package/lib-es/e2e/enum/AppInfos.js.map +1 -1
  99. package/lib-es/e2e/enum/Currency.d.ts +2 -0
  100. package/lib-es/e2e/enum/Currency.d.ts.map +1 -1
  101. package/lib-es/e2e/enum/Currency.js +4 -0
  102. package/lib-es/e2e/enum/Currency.js.map +1 -1
  103. package/lib-es/e2e/enum/Network.d.ts +2 -1
  104. package/lib-es/e2e/enum/Network.d.ts.map +1 -1
  105. package/lib-es/e2e/enum/Network.js +1 -0
  106. package/lib-es/e2e/enum/Network.js.map +1 -1
  107. package/lib-es/e2e/families/hedera.d.ts +2 -0
  108. package/lib-es/e2e/families/hedera.d.ts.map +1 -0
  109. package/lib-es/e2e/families/hedera.js +7 -0
  110. package/lib-es/e2e/families/hedera.js.map +1 -0
  111. package/lib-es/e2e/speculos.d.ts.map +1 -1
  112. package/lib-es/e2e/speculos.js +12 -0
  113. package/lib-es/e2e/speculos.js.map +1 -1
  114. package/lib-es/exchange/platform/types.d.ts +2 -0
  115. package/lib-es/exchange/platform/types.d.ts.map +1 -1
  116. package/lib-es/exchange/swap/completeExchange.d.ts.map +1 -1
  117. package/lib-es/exchange/swap/completeExchange.js +22 -1
  118. package/lib-es/exchange/swap/completeExchange.js.map +1 -1
  119. package/lib-es/exchange/swap/getIncompatibleCurrencyKeys.d.ts.map +1 -1
  120. package/lib-es/exchange/swap/getIncompatibleCurrencyKeys.js +4 -0
  121. package/lib-es/exchange/swap/getIncompatibleCurrencyKeys.js.map +1 -1
  122. package/lib-es/families/hedera/exchange.d.ts +9 -0
  123. package/lib-es/families/hedera/exchange.d.ts.map +1 -0
  124. package/lib-es/families/hedera/exchange.js +29 -0
  125. package/lib-es/families/hedera/exchange.js.map +1 -0
  126. package/lib-es/hw/actions/completeExchange.d.ts +2 -0
  127. package/lib-es/hw/actions/completeExchange.d.ts.map +1 -1
  128. package/lib-es/hw/actions/completeExchange.js +1 -0
  129. package/lib-es/hw/actions/completeExchange.js.map +1 -1
  130. package/lib-es/modularDrawer/hooks/useRightBalanceAsset.d.ts +4 -3
  131. package/lib-es/modularDrawer/hooks/useRightBalanceAsset.d.ts.map +1 -1
  132. package/lib-es/modularDrawer/hooks/useRightBalanceAsset.js +13 -47
  133. package/lib-es/modularDrawer/hooks/useRightBalanceAsset.js.map +1 -1
  134. package/lib-es/modularDrawer/hooks/useRightBalanceNetwork.d.ts +1 -5
  135. package/lib-es/modularDrawer/hooks/useRightBalanceNetwork.d.ts.map +1 -1
  136. package/lib-es/modularDrawer/hooks/useRightBalanceNetwork.js +15 -55
  137. package/lib-es/modularDrawer/hooks/useRightBalanceNetwork.js.map +1 -1
  138. package/lib-es/modularDrawer/modules/createAssetConfiguration.d.ts.map +1 -1
  139. package/lib-es/modularDrawer/modules/createAssetConfiguration.js +2 -2
  140. package/lib-es/modularDrawer/modules/createAssetConfiguration.js.map +1 -1
  141. package/lib-es/modularDrawer/modules/createNetworkConfiguration.d.ts +1 -1
  142. package/lib-es/modularDrawer/modules/createNetworkConfiguration.d.ts.map +1 -1
  143. package/lib-es/modularDrawer/modules/createNetworkConfiguration.js +1 -3
  144. package/lib-es/modularDrawer/modules/createNetworkConfiguration.js.map +1 -1
  145. package/lib-es/modularDrawer/utils/__tests__/currencyUtils.test.js +1 -1
  146. package/lib-es/modularDrawer/utils/__tests__/currencyUtils.test.js.map +1 -1
  147. package/lib-es/modularDrawer/utils/__tests__/haveOneCommonAsset.test.d.ts +2 -0
  148. package/lib-es/modularDrawer/utils/__tests__/haveOneCommonAsset.test.d.ts.map +1 -0
  149. package/lib-es/modularDrawer/utils/__tests__/haveOneCommonAsset.test.js +44 -0
  150. package/lib-es/modularDrawer/utils/__tests__/haveOneCommonAsset.test.js.map +1 -0
  151. package/lib-es/modularDrawer/utils/currencyUtils.d.ts.map +1 -1
  152. package/lib-es/modularDrawer/utils/currencyUtils.js.map +1 -1
  153. package/lib-es/modularDrawer/utils/{haveOneCommonProvider.d.ts → haveOneCommonAsset.d.ts} +3 -3
  154. package/lib-es/modularDrawer/utils/haveOneCommonAsset.d.ts.map +1 -0
  155. package/lib-es/modularDrawer/utils/{haveOneCommonProvider.js → haveOneCommonAsset.js} +4 -4
  156. package/lib-es/modularDrawer/utils/haveOneCommonAsset.js.map +1 -0
  157. package/lib-es/modularDrawer/utils/index.d.ts +2 -4
  158. package/lib-es/modularDrawer/utils/index.d.ts.map +1 -1
  159. package/lib-es/modularDrawer/utils/index.js +2 -8
  160. package/lib-es/modularDrawer/utils/index.js.map +1 -1
  161. package/lib-es/modularDrawer/utils/index.test.js +1 -27
  162. package/lib-es/modularDrawer/utils/index.test.js.map +1 -1
  163. package/lib-es/modularDrawer/utils/type.d.ts +0 -6
  164. package/lib-es/modularDrawer/utils/type.d.ts.map +1 -1
  165. package/package.json +39 -37
  166. package/src/bridge/generic-alpaca/buildSubAccounts.ts +28 -28
  167. package/src/bridge/generic-alpaca/getAccountShape.ts +9 -12
  168. package/src/bridge/generic-alpaca/tests/getAccountShape.test.ts +5 -3
  169. package/src/e2e/enum/Account.ts +10 -0
  170. package/src/e2e/enum/AppInfos.ts +2 -0
  171. package/src/e2e/enum/Currency.ts +11 -0
  172. package/src/e2e/enum/Network.ts +1 -0
  173. package/src/e2e/families/hedera.ts +7 -0
  174. package/src/e2e/speculos.ts +12 -0
  175. package/src/exchange/platform/types.ts +2 -0
  176. package/src/exchange/swap/completeExchange.ts +32 -2
  177. package/src/exchange/swap/getIncompatibleCurrencyKeys.ts +4 -0
  178. package/src/families/hedera/exchange.ts +48 -0
  179. package/src/hw/actions/completeExchange.ts +3 -0
  180. package/src/modularDrawer/hooks/useRightBalanceAsset.tsx +16 -76
  181. package/src/modularDrawer/hooks/useRightBalanceNetwork.tsx +25 -95
  182. package/src/modularDrawer/modules/createAssetConfiguration.ts +3 -11
  183. package/src/modularDrawer/modules/createNetworkConfiguration.ts +1 -8
  184. package/src/modularDrawer/utils/__tests__/currencyUtils.test.ts +1 -1
  185. package/src/modularDrawer/utils/__tests__/haveOneCommonAsset.test.ts +49 -0
  186. package/src/modularDrawer/utils/currencyUtils.ts +0 -1
  187. package/src/modularDrawer/utils/{haveOneCommonProvider.ts → haveOneCommonAsset.ts} +6 -5
  188. package/src/modularDrawer/utils/index.test.ts +1 -32
  189. package/src/modularDrawer/utils/index.ts +2 -16
  190. package/src/modularDrawer/utils/type.ts +0 -6
  191. package/lib/modularDrawer/utils/__tests__/haveOneCommonProvider.test.d.ts +0 -2
  192. package/lib/modularDrawer/utils/__tests__/haveOneCommonProvider.test.d.ts.map +0 -1
  193. package/lib/modularDrawer/utils/__tests__/haveOneCommonProvider.test.js +0 -28
  194. package/lib/modularDrawer/utils/__tests__/haveOneCommonProvider.test.js.map +0 -1
  195. package/lib/modularDrawer/utils/buildProviderCurrenciesMap.d.ts +0 -9
  196. package/lib/modularDrawer/utils/buildProviderCurrenciesMap.d.ts.map +0 -1
  197. package/lib/modularDrawer/utils/buildProviderCurrenciesMap.js +0 -17
  198. package/lib/modularDrawer/utils/buildProviderCurrenciesMap.js.map +0 -1
  199. package/lib/modularDrawer/utils/getProviderCurrency.d.ts +0 -3
  200. package/lib/modularDrawer/utils/getProviderCurrency.d.ts.map +0 -1
  201. package/lib/modularDrawer/utils/getProviderCurrency.js +0 -14
  202. package/lib/modularDrawer/utils/getProviderCurrency.js.map +0 -1
  203. package/lib/modularDrawer/utils/haveOneCommonProvider.d.ts.map +0 -1
  204. package/lib/modularDrawer/utils/haveOneCommonProvider.js.map +0 -1
  205. package/lib-es/modularDrawer/utils/__tests__/haveOneCommonProvider.test.d.ts +0 -2
  206. package/lib-es/modularDrawer/utils/__tests__/haveOneCommonProvider.test.d.ts.map +0 -1
  207. package/lib-es/modularDrawer/utils/__tests__/haveOneCommonProvider.test.js +0 -26
  208. package/lib-es/modularDrawer/utils/__tests__/haveOneCommonProvider.test.js.map +0 -1
  209. package/lib-es/modularDrawer/utils/buildProviderCurrenciesMap.d.ts +0 -9
  210. package/lib-es/modularDrawer/utils/buildProviderCurrenciesMap.d.ts.map +0 -1
  211. package/lib-es/modularDrawer/utils/buildProviderCurrenciesMap.js +0 -13
  212. package/lib-es/modularDrawer/utils/buildProviderCurrenciesMap.js.map +0 -1
  213. package/lib-es/modularDrawer/utils/getProviderCurrency.d.ts +0 -3
  214. package/lib-es/modularDrawer/utils/getProviderCurrency.d.ts.map +0 -1
  215. package/lib-es/modularDrawer/utils/getProviderCurrency.js +0 -10
  216. package/lib-es/modularDrawer/utils/getProviderCurrency.js.map +0 -1
  217. package/lib-es/modularDrawer/utils/haveOneCommonProvider.d.ts.map +0 -1
  218. package/lib-es/modularDrawer/utils/haveOneCommonProvider.js.map +0 -1
  219. package/src/modularDrawer/utils/__tests__/haveOneCommonProvider.test.ts +0 -34
  220. package/src/modularDrawer/utils/buildProviderCurrenciesMap.tsx +0 -25
  221. package/src/modularDrawer/utils/getProviderCurrency.ts +0 -13
@@ -28,6 +28,7 @@ import { sendStellar } from "./families/stellar";
28
28
  import { delegateCardano, sendCardano } from "./families/cardano";
29
29
  import { sendXRP } from "./families/xrp";
30
30
  import { delegateAptos, sendAptos } from "./families/aptos";
31
+ import { sendHedera } from "./families/hedera";
31
32
  import { delegateNear } from "./families/near";
32
33
  import { delegateCosmos, sendCosmos } from "./families/cosmos";
33
34
  import { sendKaspa } from "./families/kaspa";
@@ -335,6 +336,14 @@ export const specs: Specs = {
335
336
  },
336
337
  dependency: "",
337
338
  },
339
+ Hedera: {
340
+ currency: getCryptoCurrencyById("hedera"),
341
+ appQuery: {
342
+ model: getSpeculosModel(),
343
+ appName: "Hedera",
344
+ },
345
+ dependency: "",
346
+ },
338
347
  };
339
348
 
340
349
  export async function startSpeculos(
@@ -709,6 +718,9 @@ export async function signSendTransaction(tx: Transaction) {
709
718
  case Currency.KAS:
710
719
  await sendKaspa();
711
720
  break;
721
+ case Currency.HBAR:
722
+ await sendHedera();
723
+ break;
712
724
  default:
713
725
  throw new Error(`Unsupported currency: ${currencyName.ticker}`);
714
726
  }
@@ -1,3 +1,4 @@
1
+ import type { DeviceModelId } from "@ledgerhq/devices";
1
2
  import { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
2
3
  import type { Account, AccountLike, AccountRaw, AccountRawLike } from "@ledgerhq/types-live";
3
4
  import type { ExchangeTypes, RateTypes } from "@ledgerhq/hw-app-exchange";
@@ -42,6 +43,7 @@ export type StartExchangeInput = {
42
43
 
43
44
  interface CompleteExchangeInputCommon {
44
45
  rateType?: RateTypes;
46
+ deviceModelId?: DeviceModelId;
45
47
  deviceId?: string;
46
48
  provider: string;
47
49
  binaryPayload: string;
@@ -1,3 +1,4 @@
1
+ import type { Account } from "@ledgerhq/types-live";
1
2
  import {
2
3
  DisconnectedDeviceDuringOperation,
3
4
  TransportStatusError,
@@ -13,12 +14,14 @@ import {
13
14
  import { getDefaultAccountName } from "@ledgerhq/live-wallet/accountName";
14
15
  import { log } from "@ledgerhq/logs";
15
16
  import BigNumber from "bignumber.js";
17
+ import invariant from "invariant";
16
18
  import { Observable } from "rxjs";
17
19
  import { secp256k1 } from "@noble/curves/secp256k1";
18
20
  import { getCurrencyExchangeConfig } from "../";
19
21
  import { getAccountCurrency, getMainAccount } from "../../account";
20
22
  import { getAccountBridge } from "../../bridge";
21
23
  import { TransactionRefusedOnDevice } from "../../errors";
24
+ import { handleHederaTrustedFlow } from "../../families/hedera/exchange";
22
25
  import { withDevicePromise } from "../../hw/deviceAccess";
23
26
  import { delay } from "../../promise";
24
27
  import { CompleteExchangeStep, convertTransportError } from "../error";
@@ -27,6 +30,7 @@ import { convertToAppExchangePartnerKey, getSwapProvider } from "../providers";
27
30
  import { CEXProviderConfig } from "../providers/swap";
28
31
  import { isAddressSanctioned } from "@ledgerhq/coin-framework/sanction/index";
29
32
  import { AddressesSanctionedError } from "@ledgerhq/coin-framework/sanction/errors";
33
+ import { getCryptoCurrencyById } from "../../currencies";
30
34
 
31
35
  const COMPLETE_EXCHANGE_LOG = "SWAP-CompleteExchange";
32
36
 
@@ -34,8 +38,16 @@ const completeExchange = (
34
38
  input: CompleteExchangeInputSwap,
35
39
  ): Observable<CompleteExchangeRequestEvent> => {
36
40
  let { transaction } = input; // TODO build a tx from the data
37
-
38
- const { deviceId, exchange, provider, binaryPayload, signature, rateType, exchangeType } = input;
41
+ const {
42
+ deviceId,
43
+ deviceModelId,
44
+ exchange,
45
+ provider,
46
+ binaryPayload,
47
+ signature,
48
+ rateType,
49
+ exchangeType,
50
+ } = input;
39
51
 
40
52
  const { fromAccount, fromParentAccount } = exchange;
41
53
  const { toAccount, toParentAccount } = exchange;
@@ -152,6 +164,24 @@ const completeExchange = (
152
164
  await exchange.checkTransactionSignature(goodSign);
153
165
  if (unsubscribed) return;
154
166
 
167
+ // Hedera swap payload is filled with user account address,
168
+ // but the device app requires the related public key for verification.
169
+ // Since this key is stored on-chain, we use the TrustedService
170
+ // to fetch a signed descriptor linking the address to its public key.
171
+ const hederaCurrency = getCryptoCurrencyById("hedera");
172
+ let hederaAccount: Account | null = null;
173
+ if (payoutAccount.currency.family === hederaCurrency.family) {
174
+ hederaAccount = payoutAccount;
175
+ } else if (refundAccount.currency.family === hederaCurrency.family) {
176
+ hederaAccount = refundAccount;
177
+ }
178
+
179
+ if (hederaAccount) {
180
+ invariant(deviceModelId, "hedera: deviceModelId is not available");
181
+ await handleHederaTrustedFlow({ exchange, hederaAccount, deviceModelId });
182
+ if (unsubscribed) return;
183
+ }
184
+
155
185
  const payoutAddressParameters = payoutAccountBridge.getSerializedAddressParameters(
156
186
  payoutAccount,
157
187
  mainPayoutCurrency.id,
@@ -59,6 +59,10 @@ const INCOMPATIBLE_NANO_S_CURRENCY_KEYS: Keys = {
59
59
  title: "swap.incompatibility.cosmos_title",
60
60
  description: "swap.incompatibility.cosmos_description",
61
61
  },
62
+ hedera: {
63
+ title: "swap.incompatibility.hedera_title",
64
+ description: "swap.incompatibility.hedera_description",
65
+ },
62
66
  osmo: {
63
67
  title: "swap.incompatibility.osmo_title",
64
68
  description: "swap.incompatibility.osmo_description",
@@ -0,0 +1,48 @@
1
+ import { LatestFirmwareVersionRequired, TransportStatusError } from "@ledgerhq/errors";
2
+ import Exchange from "@ledgerhq/hw-app-exchange";
3
+ import { loadPKI } from "@ledgerhq/hw-bolos";
4
+ import calService from "@ledgerhq/ledger-cal-service";
5
+ import trustService from "@ledgerhq/ledger-trust-service";
6
+ import { getEnv } from "@ledgerhq/live-env";
7
+ import { DeviceModelId } from "@ledgerhq/types-devices";
8
+ import { Account } from "@ledgerhq/types-live";
9
+
10
+ function isPKIUnsupportedError(err: unknown): err is TransportStatusError {
11
+ return err instanceof TransportStatusError && err.message.includes("0x6a81");
12
+ }
13
+
14
+ export async function handleHederaTrustedFlow({
15
+ exchange,
16
+ hederaAccount,
17
+ deviceModelId,
18
+ }: {
19
+ exchange: Exchange;
20
+ hederaAccount: Account;
21
+ deviceModelId: DeviceModelId;
22
+ }) {
23
+ const serviceEnv = getEnv("MOCK_EXCHANGE_TEST_CONFIG") ? "test" : "prod";
24
+
25
+ const cert = await calService.getCertificate(deviceModelId, "trusted_name", "latest", {
26
+ env: serviceEnv,
27
+ signatureKind: serviceEnv,
28
+ });
29
+
30
+ try {
31
+ await loadPKI(exchange.transport, "TRUSTED_NAME", cert.descriptor, cert.signature);
32
+ } catch (err) {
33
+ if (isPKIUnsupportedError(err)) {
34
+ throw new LatestFirmwareVersionRequired("LatestFirmwareVersionRequired");
35
+ }
36
+ }
37
+
38
+ const challenge = await exchange.getChallenge();
39
+ const hexChallenge = challenge.toString(16);
40
+
41
+ const trustServiceResult = await trustService.hedera.getPublicKey(
42
+ hederaAccount.freshAddress,
43
+ hexChallenge,
44
+ );
45
+ const signedDescriptorBuffer = Buffer.from(trustServiceResult.signedDescriptor, "hex");
46
+
47
+ await exchange.sendTrustedDescriptor(signedDescriptorBuffer);
48
+ }
@@ -3,6 +3,7 @@ import { scan, tap } from "rxjs/operators";
3
3
  import { useEffect, useState } from "react";
4
4
  import type { Action, Device } from "./types";
5
5
  import type { AppState } from "./app";
6
+ import type { DeviceModelId } from "@ledgerhq/devices";
6
7
  import { log } from "@ledgerhq/logs";
7
8
  import { Exchange } from "../../exchange/types";
8
9
  import { Transaction } from "../../generated/types";
@@ -18,6 +19,7 @@ type State = {
18
19
 
19
20
  type CompleteExchangeState = AppState & State;
20
21
  type CompleteExchangeRequest = {
22
+ deviceModelId?: DeviceModelId;
21
23
  deviceId?: string;
22
24
  provider: string;
23
25
  transaction: Transaction;
@@ -130,6 +132,7 @@ export const createAction = (
130
132
  }),
131
133
  completeExchangeExec({
132
134
  deviceId: reduxDeviceFrozen?.deviceId,
135
+ deviceModelId: reduxDeviceFrozen?.modelId,
133
136
  provider,
134
137
  transaction,
135
138
  binaryPayload,
@@ -1,15 +1,11 @@
1
- import { useMemo } from "react";
2
- import type { ReactNode } from "react";
1
+ import { useMemo, type ReactNode } from "react";
3
2
  import type { CryptoOrTokenCurrency, Currency } from "@ledgerhq/types-cryptoassets";
4
3
  import { formatCurrencyUnit } from "@ledgerhq/coin-framework/currencies/formatCurrencyUnit";
5
4
  import BigNumber from "bignumber.js";
6
5
  import { counterValueFormatter } from "../utils/counterValueFormatter";
7
6
  import { compareByBalanceThenFiat } from "../utils/sortByBalance";
8
7
  import { UseBalanceDeps } from "../utils/type";
9
- import { buildProviderCurrenciesMap } from "../utils/buildProviderCurrenciesMap";
10
- import { CurrenciesByProviderId } from "../../deposit/type";
11
8
  import { calculateProviderTotals } from "../utils/calculateProviderTotal";
12
- import { getProviderCurrency } from "../utils/getProviderCurrency";
13
9
  import { groupAccountsByAsset } from "../utils/groupAccountsByAsset";
14
10
 
15
11
  export type AssetDeps = {
@@ -43,10 +39,7 @@ export function createUseRightBalanceAsset({ useBalanceDeps, balanceItem, assets
43
39
  return { balance, fiatValue };
44
40
  };
45
41
 
46
- return function useRightBalanceAsset(
47
- assets: CryptoOrTokenCurrency[],
48
- currenciesByProvider: CurrenciesByProviderId[],
49
- ) {
42
+ return function useRightBalanceAsset(assets: CryptoOrTokenCurrency[]) {
50
43
  const { flattenedAccounts, discreet, state, counterValueCurrency, locale } = useBalanceDeps();
51
44
 
52
45
  const grouped = useMemo(
@@ -54,92 +47,39 @@ export function createUseRightBalanceAsset({ useBalanceDeps, balanceItem, assets
54
47
  [flattenedAccounts, state, counterValueCurrency, discreet],
55
48
  );
56
49
 
57
- const providerMap = useMemo(
58
- () => buildProviderCurrenciesMap(currenciesByProvider),
59
- [currenciesByProvider],
60
- );
61
-
62
50
  return useMemo(() => {
63
- if (!providerMap) {
64
- const balanceMap = new Map();
65
-
66
- for (const [, { currencies, mainCurrency }] of assetsMap) {
67
- const { totalBalance, totalFiatValue } = calculateProviderTotals(currencies, grouped);
51
+ const balanceMap = new Map();
68
52
 
69
- const { balance, fiatValue } = formatProviderResult(
70
- mainCurrency,
71
- totalBalance,
72
- totalFiatValue,
73
- counterValueCurrency,
74
- locale,
75
- discreet,
76
- );
77
-
78
- balanceMap.set(mainCurrency.id, {
79
- balance: balance,
80
- fiatValue: fiatValue,
81
- });
82
- }
83
-
84
- const assetsWithBalanceData = assets.map(asset => {
85
- const balanceData = balanceMap.get(asset.id) || {};
86
- return {
87
- asset,
88
- balanceData,
89
- };
90
- });
91
-
92
- assetsWithBalanceData.sort((a, b) =>
93
- compareByBalanceThenFiat(a.balanceData, b.balanceData, discreet),
94
- );
95
-
96
- return assetsWithBalanceData.map(({ asset, balanceData }) => ({
97
- ...asset,
98
- rightElement: balanceItem(balanceData),
99
- }));
100
- }
101
-
102
- const assetsSet = new Set(assets.map(a => a.id));
103
- const providerResultsMap = new Map<string, { balance?: string; fiatValue?: string }>();
104
-
105
- for (const [, { currencies, mainCurrency }] of providerMap) {
106
- if (!assetsSet.has(mainCurrency.id)) continue;
107
- const providerCurrency = getProviderCurrency(mainCurrency, currencies);
108
- if (!providerCurrency) continue;
109
-
110
- const { totalBalance, totalFiatValue, hasAccounts } = calculateProviderTotals(
111
- currencies,
112
- grouped,
113
- );
114
- if (!hasAccounts) continue;
53
+ for (const [, { currencies, mainCurrency }] of assetsMap) {
54
+ const { totalBalance, totalFiatValue } = calculateProviderTotals(currencies, grouped);
115
55
 
116
56
  const { balance, fiatValue } = formatProviderResult(
117
- providerCurrency,
57
+ mainCurrency,
118
58
  totalBalance,
119
59
  totalFiatValue,
120
60
  counterValueCurrency,
121
61
  locale,
122
62
  discreet,
123
63
  );
124
- providerResultsMap.set(mainCurrency.id, { balance, fiatValue });
64
+
65
+ balanceMap.set(mainCurrency.id, {
66
+ balance: balance,
67
+ fiatValue: fiatValue,
68
+ });
125
69
  }
126
70
 
127
71
  const assetsWithBalanceData = assets.map(asset => {
128
- const balanceData = providerResultsMap.get(asset.id) || {};
72
+ const balanceData = balanceMap.get(asset.id) || {};
129
73
  return {
130
- asset,
74
+ ...asset,
131
75
  balanceData,
76
+ rightElement: balanceItem(balanceData),
132
77
  };
133
78
  });
134
79
 
135
- assetsWithBalanceData.sort((a, b) =>
80
+ return assetsWithBalanceData.sort((a, b) =>
136
81
  compareByBalanceThenFiat(a.balanceData, b.balanceData, discreet),
137
82
  );
138
-
139
- return assetsWithBalanceData.map(({ asset, balanceData }) => ({
140
- ...asset,
141
- rightElement: balanceItem(balanceData),
142
- }));
143
- }, [providerMap, assets, grouped, counterValueCurrency, locale, discreet]);
83
+ }, [assets, grouped, counterValueCurrency, locale, discreet]);
144
84
  };
145
85
  }
@@ -1,8 +1,7 @@
1
- import { useMemo, type ReactNode } from "react";
1
+ import { type ReactNode } from "react";
2
2
  import type { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
3
3
  import { compareByBalanceThenFiat } from "../utils/sortByBalance";
4
- import { BalanceUI, UseBalanceDeps } from "../utils/type";
5
- import { CurrenciesByProviderId } from "../../deposit/type";
4
+ import { UseBalanceDeps } from "../utils/type";
6
5
  import { getBalanceAndFiatValueByAssets } from "../utils/getBalanceAndFiatValueByAssets";
7
6
 
8
7
  export type NetworkDeps = {
@@ -11,108 +10,39 @@ export type NetworkDeps = {
11
10
  };
12
11
 
13
12
  type Params = {
14
- assets: CryptoOrTokenCurrency[];
15
13
  networks: CryptoOrTokenCurrency[];
16
- selectedAssetId: string;
17
- currenciesByProvider: CurrenciesByProviderId[];
18
14
  };
19
15
 
20
16
  export function createUseRightBalanceNetwork({ useBalanceDeps, balanceItem }: NetworkDeps) {
21
- return function useRightBalanceNetwork({
22
- assets: networks,
23
- selectedAssetId,
24
- currenciesByProvider,
25
- networks: actualNetworks,
26
- }: Params) {
17
+ return function useRightBalanceNetwork({ networks }: Params) {
27
18
  const { flattenedAccounts, discreet, state, counterValueCurrency, locale } = useBalanceDeps();
28
19
 
29
- return useMemo(() => {
30
- if (currenciesByProvider && currenciesByProvider.length > 0) {
31
- const providerOfSelectedAsset = currenciesByProvider.find(provider =>
32
- provider.currenciesByNetwork.some(currency => currency.id === selectedAssetId),
33
- );
34
-
35
- if (providerOfSelectedAsset) {
36
- const pairs = networks.map(network => ({
37
- network,
38
- asset: providerOfSelectedAsset.currenciesByNetwork.find(currency =>
39
- currency.type === "TokenCurrency"
40
- ? currency.parentCurrency.id === network.id
41
- : currency.id === network.id,
42
- ),
43
- }));
44
-
45
- const validAssets = pairs.filter(p => p.asset).map(p => p.asset!);
46
-
47
- const allBalanceData =
48
- validAssets.length > 0
49
- ? getBalanceAndFiatValueByAssets(
50
- flattenedAccounts,
51
- validAssets,
52
- state,
53
- counterValueCurrency,
54
- discreet,
55
- locale,
56
- )
57
- : [];
58
-
59
- const balanceMap = new Map(allBalanceData.map(b => [b.id, b]));
60
-
61
- const networkWithBalanceData = pairs.map(({ network, asset }) => {
62
- const balanceData: BalanceUI = asset ? balanceMap.get(asset.id) || {} : {};
63
- return {
64
- network,
65
- balanceData,
66
- };
67
- });
68
-
69
- networkWithBalanceData.sort((a, b) =>
70
- compareByBalanceThenFiat(a.balanceData, b.balanceData, discreet),
71
- );
72
-
73
- return networkWithBalanceData.map(({ network, balanceData }) => ({
74
- ...network,
75
- rightElement: balanceItem(balanceData),
76
- }));
77
- }
78
- }
79
-
80
- const networkBalanceData = getBalanceAndFiatValueByAssets(
81
- flattenedAccounts,
82
- actualNetworks,
83
- state,
84
- counterValueCurrency,
85
- discreet,
86
- locale,
87
- );
88
-
89
- const balanceMap = new Map(networkBalanceData.map(b => [b.id, b]));
90
-
91
- const networksWithBalance = actualNetworks.map(network => {
92
- const balanceData = balanceMap.get(network.id) || {};
93
- return {
94
- network,
95
- balanceData,
96
- };
97
- });
98
-
99
- networksWithBalance.sort((a, b) =>
100
- compareByBalanceThenFiat(a.balanceData, b.balanceData, discreet),
101
- );
102
-
103
- return networksWithBalance.map(({ network, balanceData }) => ({
104
- ...network,
105
- rightElement: balanceItem(balanceData),
106
- }));
107
- }, [
108
- networks,
109
- selectedAssetId,
110
- currenciesByProvider,
20
+ const networkBalanceData = getBalanceAndFiatValueByAssets(
111
21
  flattenedAccounts,
22
+ networks,
112
23
  state,
113
24
  counterValueCurrency,
114
25
  discreet,
115
26
  locale,
116
- ]);
27
+ );
28
+
29
+ const balanceMap = new Map(networkBalanceData.map(b => [b.id, b]));
30
+
31
+ const networksWithBalance = networks.map(network => {
32
+ const balanceData = balanceMap.get(network.id) || {};
33
+ return {
34
+ network,
35
+ balanceData,
36
+ };
37
+ });
38
+
39
+ networksWithBalance.sort((a, b) =>
40
+ compareByBalanceThenFiat(a.balanceData, b.balanceData, discreet),
41
+ );
42
+
43
+ return networksWithBalance.map(({ network, balanceData }) => ({
44
+ ...network,
45
+ rightElement: balanceItem(balanceData),
46
+ }));
117
47
  };
118
48
  }
@@ -1,6 +1,5 @@
1
1
  import type { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
2
2
  import { AssetType, CreateAssetConfigurationHook, AssetConfigurationDeps } from "../utils/type";
3
- import { CurrenciesByProviderId } from "../../deposit/type";
4
3
  import { composeHooks } from "../../utils/composeHooks";
5
4
  import { useLeftApyModule } from "../hooks/modules/useLeftApyModule";
6
5
  import { createUseRightBalanceAsset } from "../hooks/useRightBalanceAsset";
@@ -46,7 +45,7 @@ const getLeftElement =
46
45
 
47
46
  const createAssetConfigurationHook: CreateAssetConfigurationHook =
48
47
  deps =>
49
- ({ assetsConfiguration, currenciesByProvider }) => {
48
+ ({ assetsConfiguration }) => {
50
49
  const { rightElement, leftElement } = assetsConfiguration ?? {};
51
50
 
52
51
  const rightHook = getRightElement(deps)(rightElement);
@@ -54,18 +53,11 @@ const createAssetConfigurationHook: CreateAssetConfigurationHook =
54
53
 
55
54
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
56
55
  const hooks = [rightHook, leftHook].filter(Boolean) as Array<
57
- (
58
- assets: CryptoOrTokenCurrency[],
59
- currenciesByProvider?: CurrenciesByProviderId[],
60
- ) => AssetType[]
56
+ (assets: CryptoOrTokenCurrency[]) => AssetType[]
61
57
  >;
62
58
 
63
59
  return (assets: CryptoOrTokenCurrency[]) => {
64
- const composedHook = composeHooks<CryptoOrTokenCurrency, AssetType>(
65
- ...hooks.map(
66
- hook => (assets: CryptoOrTokenCurrency[]) => hook(assets, currenciesByProvider),
67
- ),
68
- );
60
+ const composedHook = composeHooks<CryptoOrTokenCurrency, AssetType>(...hooks);
69
61
  return composedHook(assets);
70
62
  };
71
63
  };
@@ -53,12 +53,7 @@ export const getRightElement =
53
53
 
54
54
  export const createNetworkConfigurationHook =
55
55
  (NetworkConfigurationDeps: NetworkConfigurationDeps) =>
56
- ({
57
- networksConfig,
58
- selectedAssetId,
59
- currenciesByProvider,
60
- accounts$,
61
- }: CreateNetworkConfigurationHookProps) => {
56
+ ({ networksConfig, accounts$ }: CreateNetworkConfigurationHookProps) => {
62
57
  const { leftElement, rightElement } = networksConfig ?? {};
63
58
  const leftHook = getLeftElement(NetworkConfigurationDeps)(leftElement);
64
59
  const rightHook = getRightElement(NetworkConfigurationDeps)(rightElement);
@@ -75,8 +70,6 @@ export const createNetworkConfigurationHook =
75
70
  hook => () =>
76
71
  hook({
77
72
  assets,
78
- selectedAssetId,
79
- currenciesByProvider: currenciesByProvider || [],
80
73
  accounts$,
81
74
  networks,
82
75
  }),
@@ -10,10 +10,10 @@ import {
10
10
  safeCurrencyLookup,
11
11
  } from "../currencyUtils";
12
12
  import {
13
- usdcToken,
14
13
  mockBaseCryptoCurrency,
15
14
  mockBtcCryptoCurrency,
16
15
  mockEthCryptoCurrency,
16
+ usdcToken,
17
17
  } from "../../__mocks__/currencies.mock";
18
18
 
19
19
  describe("safeCurrencyLookup", () => {
@@ -0,0 +1,49 @@
1
+ import { haveOneCommonAsset } from "../haveOneCommonAsset";
2
+ import { AssetData } from "../type";
3
+ import { getCryptoCurrencyById } from "@ledgerhq/cryptoassets/lib/currencies";
4
+
5
+ const MOCK_ASSETS_SORTED: AssetData[] = [
6
+ {
7
+ asset: {
8
+ id: "ethereum",
9
+ ticker: "ETH",
10
+ name: "Ethereum",
11
+ assetsIds: {
12
+ ethereum: "ethereum",
13
+ arbitrum: "arbitrum",
14
+ },
15
+ metaCurrencyId: "urn:crypto:meta-currency:ethereum",
16
+ },
17
+ networks: [getCryptoCurrencyById("ethereum"), getCryptoCurrencyById("arbitrum")],
18
+ },
19
+ {
20
+ asset: {
21
+ id: "bitcoin",
22
+ ticker: "BTC",
23
+ name: "Bitcoin",
24
+ assetsIds: {
25
+ bitcoin: "bitcoin",
26
+ },
27
+ metaCurrencyId: "bitcoin",
28
+ },
29
+ networks: [getCryptoCurrencyById("bitcoin")],
30
+ },
31
+ ];
32
+
33
+ describe("haveOneCommonAsset", () => {
34
+ it("should return false for an empty array", () => {
35
+ expect(haveOneCommonAsset([], [])).toBe(false);
36
+ });
37
+
38
+ it("should return true for a single currency with one provider", () => {
39
+ expect(haveOneCommonAsset(["bitcoin"], MOCK_ASSETS_SORTED)).toBe(true);
40
+ });
41
+
42
+ it("should return false for multiple currencies with different providers", () => {
43
+ expect(haveOneCommonAsset(["bitcoin", "ethereum"], MOCK_ASSETS_SORTED)).toBe(false);
44
+ });
45
+
46
+ it("should return true for multiple currencies with the same provider", () => {
47
+ expect(haveOneCommonAsset(["ethereum", "arbitrum"], MOCK_ASSETS_SORTED)).toBe(true);
48
+ });
49
+ });
@@ -4,7 +4,6 @@ import { isTokenCurrency } from "../../currencies";
4
4
  import { CurrenciesByProviderId } from "../../deposit/type";
5
5
 
6
6
  export type ProviderCoverageMap = Map<string, Set<string>>;
7
-
8
7
  export const safeCurrencyLookup = (id: string): CryptoOrTokenCurrency | null => {
9
8
  try {
10
9
  return getTokenOrCryptoCurrencyById(id);
@@ -1,4 +1,4 @@
1
- import { CurrenciesByProviderId } from "../../deposit/type";
1
+ import { AssetData } from "./type";
2
2
 
3
3
  /**
4
4
  * This function checks if all currencies in the provided array
@@ -8,9 +8,10 @@ import { CurrenciesByProviderId } from "../../deposit/type";
8
8
  * @param currenciesByProvider array of currencies grouped by provider
9
9
  * @returns boolean indicating whether all currencies in the array have one common provider
10
10
  */
11
- export const haveOneCommonProvider = (
11
+
12
+ export const haveOneCommonAsset = (
12
13
  currenciesIdsArray: string[],
13
- currenciesByProvider: CurrenciesByProviderId[],
14
+ currenciesByProvider: AssetData[],
14
15
  ): boolean => {
15
16
  if (currenciesIdsArray.length === 0) return false;
16
17
 
@@ -18,8 +19,8 @@ export const haveOneCommonProvider = (
18
19
 
19
20
  for (const currencyId of currenciesIdsArray) {
20
21
  for (const provider of currenciesByProvider) {
21
- if (provider.currenciesByNetwork.some(currency => currency.id === currencyId)) {
22
- providerIds.add(provider.providerId);
22
+ if (provider.networks.some(currency => currency.id === currencyId)) {
23
+ providerIds.add(provider.asset.id);
23
24
  if (providerIds.size > 1) {
24
25
  return false;
25
26
  }