@ledgerhq/live-common 34.47.0-nightly.6 → 34.47.0-nightly.8

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 (184) hide show
  1. package/lib/bridge/generic-alpaca/buildSubAccounts.d.ts.map +1 -1
  2. package/lib/bridge/generic-alpaca/buildSubAccounts.js +1 -2
  3. package/lib/bridge/generic-alpaca/buildSubAccounts.js.map +1 -1
  4. package/lib/bridge/generic-alpaca/getTransactionStatus.d.ts.map +1 -1
  5. package/lib/bridge/generic-alpaca/getTransactionStatus.js +0 -1
  6. package/lib/bridge/generic-alpaca/getTransactionStatus.js.map +1 -1
  7. package/lib/bridge/generic-alpaca/prepareTransaction.d.ts +14 -3
  8. package/lib/bridge/generic-alpaca/prepareTransaction.d.ts.map +1 -1
  9. package/lib/bridge/generic-alpaca/prepareTransaction.js +21 -5
  10. package/lib/bridge/generic-alpaca/prepareTransaction.js.map +1 -1
  11. package/lib/bridge/generic-alpaca/utils.d.ts.map +1 -1
  12. package/lib/bridge/generic-alpaca/utils.js +2 -4
  13. package/lib/bridge/generic-alpaca/utils.js.map +1 -1
  14. package/lib/bridge/generic-alpaca/utils.test.js +37 -0
  15. package/lib/bridge/generic-alpaca/utils.test.js.map +1 -1
  16. package/lib/e2e/enum/DeviceLabels.d.ts +2 -1
  17. package/lib/e2e/enum/DeviceLabels.d.ts.map +1 -1
  18. package/lib/e2e/enum/DeviceLabels.js +1 -0
  19. package/lib/e2e/enum/DeviceLabels.js.map +1 -1
  20. package/lib/e2e/index.d.ts +0 -2
  21. package/lib/e2e/index.d.ts.map +1 -1
  22. package/lib/e2e/speculos.d.ts +1 -0
  23. package/lib/e2e/speculos.d.ts.map +1 -1
  24. package/lib/e2e/speculos.js +10 -2
  25. package/lib/e2e/speculos.js.map +1 -1
  26. package/lib/featureFlags/defaultFeatures.d.ts.map +1 -1
  27. package/lib/featureFlags/defaultFeatures.js +0 -1
  28. package/lib/featureFlags/defaultFeatures.js.map +1 -1
  29. package/lib/featureFlags/useFeature.d.ts +1 -1
  30. package/lib/featureFlags/useFeature.d.ts.map +1 -1
  31. package/lib/modularDrawer/hooks/modules/useLeftApyModule.d.ts +1 -1
  32. package/lib/modularDrawer/hooks/modules/useLeftApyModule.d.ts.map +1 -1
  33. package/lib/modularDrawer/hooks/modules/useLeftApyModule.js.map +1 -1
  34. package/lib/modularDrawer/hooks/{modules/useAssetAccountCounts.d.ts → useAssetAccountCounts.d.ts} +1 -1
  35. package/lib/modularDrawer/hooks/useAssetAccountCounts.d.ts.map +1 -0
  36. package/lib/modularDrawer/hooks/{modules/useAssetAccountCounts.js → useAssetAccountCounts.js} +1 -1
  37. package/lib/modularDrawer/hooks/useAssetAccountCounts.js.map +1 -0
  38. package/lib/modularDrawer/hooks/useLeftAccounts.d.ts +13 -0
  39. package/lib/modularDrawer/hooks/useLeftAccounts.d.ts.map +1 -0
  40. package/lib/modularDrawer/hooks/useLeftAccounts.js +15 -0
  41. package/lib/modularDrawer/hooks/useLeftAccounts.js.map +1 -0
  42. package/lib/modularDrawer/hooks/useLeftAccountsApy.d.ts +6 -0
  43. package/lib/modularDrawer/hooks/useLeftAccountsApy.d.ts.map +1 -0
  44. package/lib/modularDrawer/hooks/useLeftAccountsApy.js +19 -0
  45. package/lib/modularDrawer/hooks/useLeftAccountsApy.js.map +1 -0
  46. package/lib/modularDrawer/hooks/useLeftApy.d.ts +54 -0
  47. package/lib/modularDrawer/hooks/useLeftApy.d.ts.map +1 -0
  48. package/lib/modularDrawer/hooks/useLeftApy.js +15 -0
  49. package/lib/modularDrawer/hooks/useLeftApy.js.map +1 -0
  50. package/lib/modularDrawer/hooks/useRightBalanceAsset.d.ts +57 -0
  51. package/lib/modularDrawer/hooks/useRightBalanceAsset.d.ts.map +1 -0
  52. package/lib/modularDrawer/hooks/useRightBalanceAsset.js +87 -0
  53. package/lib/modularDrawer/hooks/useRightBalanceAsset.js.map +1 -0
  54. package/lib/modularDrawer/hooks/useRightBalanceNetwork.d.ts +63 -0
  55. package/lib/modularDrawer/hooks/useRightBalanceNetwork.d.ts.map +1 -0
  56. package/lib/modularDrawer/hooks/useRightBalanceNetwork.js +66 -0
  57. package/lib/modularDrawer/hooks/useRightBalanceNetwork.js.map +1 -0
  58. package/lib/modularDrawer/modules/createAssetConfiguration.d.ts +4 -0
  59. package/lib/modularDrawer/modules/createAssetConfiguration.d.ts.map +1 -0
  60. package/lib/modularDrawer/modules/createAssetConfiguration.js +41 -0
  61. package/lib/modularDrawer/modules/createAssetConfiguration.js.map +1 -0
  62. package/lib/modularDrawer/modules/createNetworkConfiguration.d.ts +6 -0
  63. package/lib/modularDrawer/modules/createNetworkConfiguration.d.ts.map +1 -0
  64. package/lib/modularDrawer/modules/createNetworkConfiguration.js +56 -0
  65. package/lib/modularDrawer/modules/createNetworkConfiguration.js.map +1 -0
  66. package/lib/modularDrawer/utils/buildProviderCurrenciesMap.d.ts +9 -0
  67. package/lib/modularDrawer/utils/buildProviderCurrenciesMap.d.ts.map +1 -0
  68. package/lib/modularDrawer/utils/buildProviderCurrenciesMap.js +17 -0
  69. package/lib/modularDrawer/utils/buildProviderCurrenciesMap.js.map +1 -0
  70. package/lib/modularDrawer/utils/sortByBalance.d.ts +6 -0
  71. package/lib/modularDrawer/utils/sortByBalance.d.ts.map +1 -0
  72. package/lib/modularDrawer/utils/sortByBalance.js +32 -0
  73. package/lib/modularDrawer/utils/sortByBalance.js.map +1 -0
  74. package/lib/modularDrawer/utils/type.d.ts +89 -1
  75. package/lib/modularDrawer/utils/type.d.ts.map +1 -1
  76. package/lib-es/bridge/generic-alpaca/buildSubAccounts.d.ts.map +1 -1
  77. package/lib-es/bridge/generic-alpaca/buildSubAccounts.js +2 -3
  78. package/lib-es/bridge/generic-alpaca/buildSubAccounts.js.map +1 -1
  79. package/lib-es/bridge/generic-alpaca/getTransactionStatus.d.ts.map +1 -1
  80. package/lib-es/bridge/generic-alpaca/getTransactionStatus.js +0 -1
  81. package/lib-es/bridge/generic-alpaca/getTransactionStatus.js.map +1 -1
  82. package/lib-es/bridge/generic-alpaca/prepareTransaction.d.ts +14 -3
  83. package/lib-es/bridge/generic-alpaca/prepareTransaction.d.ts.map +1 -1
  84. package/lib-es/bridge/generic-alpaca/prepareTransaction.js +21 -5
  85. package/lib-es/bridge/generic-alpaca/prepareTransaction.js.map +1 -1
  86. package/lib-es/bridge/generic-alpaca/utils.d.ts.map +1 -1
  87. package/lib-es/bridge/generic-alpaca/utils.js +2 -4
  88. package/lib-es/bridge/generic-alpaca/utils.js.map +1 -1
  89. package/lib-es/bridge/generic-alpaca/utils.test.js +37 -0
  90. package/lib-es/bridge/generic-alpaca/utils.test.js.map +1 -1
  91. package/lib-es/e2e/enum/DeviceLabels.d.ts +2 -1
  92. package/lib-es/e2e/enum/DeviceLabels.d.ts.map +1 -1
  93. package/lib-es/e2e/enum/DeviceLabels.js +1 -0
  94. package/lib-es/e2e/enum/DeviceLabels.js.map +1 -1
  95. package/lib-es/e2e/index.d.ts +0 -2
  96. package/lib-es/e2e/index.d.ts.map +1 -1
  97. package/lib-es/e2e/speculos.d.ts +1 -0
  98. package/lib-es/e2e/speculos.d.ts.map +1 -1
  99. package/lib-es/e2e/speculos.js +8 -1
  100. package/lib-es/e2e/speculos.js.map +1 -1
  101. package/lib-es/featureFlags/defaultFeatures.d.ts.map +1 -1
  102. package/lib-es/featureFlags/defaultFeatures.js +0 -1
  103. package/lib-es/featureFlags/defaultFeatures.js.map +1 -1
  104. package/lib-es/featureFlags/useFeature.d.ts +1 -1
  105. package/lib-es/featureFlags/useFeature.d.ts.map +1 -1
  106. package/lib-es/modularDrawer/hooks/modules/useLeftApyModule.d.ts +1 -1
  107. package/lib-es/modularDrawer/hooks/modules/useLeftApyModule.d.ts.map +1 -1
  108. package/lib-es/modularDrawer/hooks/modules/useLeftApyModule.js.map +1 -1
  109. package/lib-es/modularDrawer/hooks/{modules/useAssetAccountCounts.d.ts → useAssetAccountCounts.d.ts} +1 -1
  110. package/lib-es/modularDrawer/hooks/useAssetAccountCounts.d.ts.map +1 -0
  111. package/lib-es/modularDrawer/hooks/{modules/useAssetAccountCounts.js → useAssetAccountCounts.js} +1 -1
  112. package/lib-es/modularDrawer/hooks/useAssetAccountCounts.js.map +1 -0
  113. package/lib-es/modularDrawer/hooks/useLeftAccounts.d.ts +13 -0
  114. package/lib-es/modularDrawer/hooks/useLeftAccounts.d.ts.map +1 -0
  115. package/lib-es/modularDrawer/hooks/useLeftAccounts.js +11 -0
  116. package/lib-es/modularDrawer/hooks/useLeftAccounts.js.map +1 -0
  117. package/lib-es/modularDrawer/hooks/useLeftAccountsApy.d.ts +6 -0
  118. package/lib-es/modularDrawer/hooks/useLeftAccountsApy.d.ts.map +1 -0
  119. package/lib-es/modularDrawer/hooks/useLeftAccountsApy.js +15 -0
  120. package/lib-es/modularDrawer/hooks/useLeftAccountsApy.js.map +1 -0
  121. package/lib-es/modularDrawer/hooks/useLeftApy.d.ts +54 -0
  122. package/lib-es/modularDrawer/hooks/useLeftApy.d.ts.map +1 -0
  123. package/lib-es/modularDrawer/hooks/useLeftApy.js +11 -0
  124. package/lib-es/modularDrawer/hooks/useLeftApy.js.map +1 -0
  125. package/lib-es/modularDrawer/hooks/useRightBalanceAsset.d.ts +57 -0
  126. package/lib-es/modularDrawer/hooks/useRightBalanceAsset.d.ts.map +1 -0
  127. package/lib-es/modularDrawer/hooks/useRightBalanceAsset.js +83 -0
  128. package/lib-es/modularDrawer/hooks/useRightBalanceAsset.js.map +1 -0
  129. package/lib-es/modularDrawer/hooks/useRightBalanceNetwork.d.ts +63 -0
  130. package/lib-es/modularDrawer/hooks/useRightBalanceNetwork.d.ts.map +1 -0
  131. package/lib-es/modularDrawer/hooks/useRightBalanceNetwork.js +62 -0
  132. package/lib-es/modularDrawer/hooks/useRightBalanceNetwork.js.map +1 -0
  133. package/lib-es/modularDrawer/modules/createAssetConfiguration.d.ts +4 -0
  134. package/lib-es/modularDrawer/modules/createAssetConfiguration.d.ts.map +1 -0
  135. package/lib-es/modularDrawer/modules/createAssetConfiguration.js +39 -0
  136. package/lib-es/modularDrawer/modules/createAssetConfiguration.js.map +1 -0
  137. package/lib-es/modularDrawer/modules/createNetworkConfiguration.d.ts +6 -0
  138. package/lib-es/modularDrawer/modules/createNetworkConfiguration.d.ts.map +1 -0
  139. package/lib-es/modularDrawer/modules/createNetworkConfiguration.js +50 -0
  140. package/lib-es/modularDrawer/modules/createNetworkConfiguration.js.map +1 -0
  141. package/lib-es/modularDrawer/utils/buildProviderCurrenciesMap.d.ts +9 -0
  142. package/lib-es/modularDrawer/utils/buildProviderCurrenciesMap.d.ts.map +1 -0
  143. package/lib-es/modularDrawer/utils/buildProviderCurrenciesMap.js +13 -0
  144. package/lib-es/modularDrawer/utils/buildProviderCurrenciesMap.js.map +1 -0
  145. package/lib-es/modularDrawer/utils/sortByBalance.d.ts +6 -0
  146. package/lib-es/modularDrawer/utils/sortByBalance.d.ts.map +1 -0
  147. package/lib-es/modularDrawer/utils/sortByBalance.js +25 -0
  148. package/lib-es/modularDrawer/utils/sortByBalance.js.map +1 -0
  149. package/lib-es/modularDrawer/utils/type.d.ts +89 -1
  150. package/lib-es/modularDrawer/utils/type.d.ts.map +1 -1
  151. package/package.json +40 -40
  152. package/src/bridge/generic-alpaca/buildSubAccounts.ts +2 -3
  153. package/src/bridge/generic-alpaca/getTransactionStatus.ts +0 -1
  154. package/src/bridge/generic-alpaca/prepareTransaction.ts +44 -17
  155. package/src/bridge/generic-alpaca/utils.test.ts +40 -0
  156. package/src/bridge/generic-alpaca/utils.ts +5 -6
  157. package/src/e2e/enum/DeviceLabels.ts +1 -0
  158. package/src/e2e/speculos.ts +9 -1
  159. package/src/featureFlags/defaultFeatures.ts +0 -1
  160. package/src/modularDrawer/hooks/modules/useLeftApyModule.tsx +1 -1
  161. package/src/modularDrawer/hooks/{modules/useAssetAccountCounts.tsx → useAssetAccountCounts.tsx} +2 -2
  162. package/src/modularDrawer/hooks/useLeftAccounts.tsx +23 -0
  163. package/src/modularDrawer/hooks/useLeftAccountsApy.tsx +28 -0
  164. package/src/modularDrawer/hooks/useLeftApy.tsx +19 -0
  165. package/src/modularDrawer/hooks/useRightBalanceAsset.tsx +140 -0
  166. package/src/modularDrawer/hooks/useRightBalanceNetwork.tsx +116 -0
  167. package/src/modularDrawer/modules/createAssetConfiguration.ts +61 -0
  168. package/src/modularDrawer/modules/createNetworkConfiguration.ts +79 -0
  169. package/src/modularDrawer/utils/buildProviderCurrenciesMap.tsx +25 -0
  170. package/src/modularDrawer/utils/sortByBalance.tsx +32 -0
  171. package/src/modularDrawer/utils/type.ts +97 -0
  172. package/lib/modularDrawer/hooks/modules/useAssetAccountCounts.d.ts.map +0 -1
  173. package/lib/modularDrawer/hooks/modules/useAssetAccountCounts.js.map +0 -1
  174. package/lib/modularDrawer/types.d.ts +0 -2
  175. package/lib/modularDrawer/types.d.ts.map +0 -1
  176. package/lib/modularDrawer/types.js +0 -3
  177. package/lib/modularDrawer/types.js.map +0 -1
  178. package/lib-es/modularDrawer/hooks/modules/useAssetAccountCounts.d.ts.map +0 -1
  179. package/lib-es/modularDrawer/hooks/modules/useAssetAccountCounts.js.map +0 -1
  180. package/lib-es/modularDrawer/types.d.ts +0 -2
  181. package/lib-es/modularDrawer/types.d.ts.map +0 -1
  182. package/lib-es/modularDrawer/types.js +0 -2
  183. package/lib-es/modularDrawer/types.js.map +0 -1
  184. package/src/modularDrawer/types.ts +0 -1
@@ -2,27 +2,41 @@ import { Account, AccountBridge, TransactionCommon } from "@ledgerhq/types-live"
2
2
  import { getAlpacaApi } from "./alpaca";
3
3
  import { transactionToIntent } from "./utils";
4
4
  import BigNumber from "bignumber.js";
5
- import { FeeEstimation } from "@ledgerhq/coin-framework/api/types";
5
+ import { AssetInfo, FeeEstimation } from "@ledgerhq/coin-framework/api/types";
6
+ import { decodeTokenAccountId } from "@ledgerhq/coin-framework/account/index";
7
+ import { TokenCurrency } from "@ledgerhq/types-cryptoassets";
6
8
 
7
9
  function bnEq(a: BigNumber | null | undefined, b: BigNumber | null | undefined): boolean {
8
10
  return !a && !b ? true : !a || !b ? false : a.eq(b);
9
11
  }
10
12
 
13
+ type TransactionParam = TransactionCommon & {
14
+ fees: BigNumber | null | undefined;
15
+ customFees?: FeeEstimation;
16
+ assetReference?: string;
17
+ assetOwner?: string;
18
+ subAccountId?: string;
19
+ };
20
+
21
+ function assetInfosFallback(transaction: TransactionParam): {
22
+ assetReference: string;
23
+ assetOwner: string;
24
+ } {
25
+ return {
26
+ assetReference: transaction.assetReference ?? "",
27
+ assetOwner: transaction.assetOwner ?? "",
28
+ };
29
+ }
30
+
11
31
  export function genericPrepareTransaction(
12
32
  network: string,
13
33
  kind,
14
34
  ): AccountBridge<TransactionCommon, Account, any, any>["prepareTransaction"] {
15
- return async (
16
- account,
17
- transaction: TransactionCommon & {
18
- fees: BigNumber | null | undefined;
19
- customFees?: FeeEstimation;
20
- assetReference?: string;
21
- assetOwner?: string;
22
- subAccountId?: string;
23
- },
24
- ) => {
25
- const [assetReference, assetOwner] = getAssetInfos(transaction);
35
+ return async (account, transaction: TransactionParam) => {
36
+ const { getAssetFromToken } = getAlpacaApi(network, kind);
37
+ const { assetReference, assetOwner } = getAssetFromToken
38
+ ? getAssetInfos(transaction, account.freshAddress, getAssetFromToken)
39
+ : assetInfosFallback(transaction);
26
40
 
27
41
  let fees = transaction.customFees?.parameters?.fees || null;
28
42
  if (fees === null) {
@@ -54,11 +68,24 @@ export function genericPrepareTransaction(
54
68
  }
55
69
 
56
70
  export function getAssetInfos(
57
- tr: TransactionCommon & { assetReference?: string; assetOwner?: string },
58
- ): string[] {
71
+ tr: TransactionParam,
72
+ owner: string,
73
+ getAssetFromToken: (token: TokenCurrency, owner: string) => AssetInfo,
74
+ ): {
75
+ assetReference: string;
76
+ assetOwner: string;
77
+ } {
59
78
  if (tr.subAccountId) {
60
- const assetString = tr.subAccountId.split("+")[1];
61
- return assetString.split(":");
79
+ const { token } = decodeTokenAccountId(tr.subAccountId);
80
+
81
+ if (!token) return assetInfosFallback(tr);
82
+
83
+ const asset = getAssetFromToken(token, owner);
84
+
85
+ return {
86
+ assetOwner: ("assetOwner" in asset && asset.assetOwner) || "",
87
+ assetReference: ("assetReference" in asset && asset.assetReference) || "",
88
+ };
62
89
  }
63
- return [tr.assetReference || "", tr.assetOwner || ""];
90
+ return assetInfosFallback(tr);
64
91
  }
@@ -43,6 +43,46 @@ describe("Alpaca utils", () => {
43
43
  recipients: ["recipient1"],
44
44
  };
45
45
 
46
+ it("does not include fees in non native asset value", () => {
47
+ expect(
48
+ adaptCoreOperationToLiveOperation("account", {
49
+ id: "operation",
50
+ asset: { type: "token", assetOwner: "owner", assetReference: "reference" },
51
+ type: "OUT",
52
+ value: BigInt(100),
53
+ tx: {
54
+ hash: "hash",
55
+ fees: BigInt(10),
56
+ block: {
57
+ hash: "block_hash",
58
+ height: 123456,
59
+ },
60
+ date: new Date("2025-08-29T12:00:00Z"),
61
+ },
62
+ senders: ["sender"],
63
+ recipients: ["recipient"],
64
+ }),
65
+ ).toEqual({
66
+ id: "account-hash-OUT",
67
+ hash: "hash",
68
+ accountId: "account",
69
+ type: "OUT",
70
+ value: new BigNumber(100), // value only
71
+ fee: new BigNumber(10),
72
+ extra: {
73
+ assetOwner: "owner",
74
+ assetReference: "reference",
75
+ },
76
+ blockHash: "block_hash",
77
+ blockHeight: 123456,
78
+ senders: ["sender"],
79
+ recipients: ["recipient"],
80
+ date: new Date("2025-08-29T12:00:00Z"),
81
+ transactionSequenceNumber: undefined,
82
+ hasFailed: false,
83
+ });
84
+ });
85
+
46
86
  it("adapts a basic OUT operation", () => {
47
87
  const result = adaptCoreOperationToLiveOperation(accountId, baseOp);
48
88
 
@@ -46,15 +46,14 @@ export function adaptCoreOperationToLiveOperation(accountId: string, op: CoreOpe
46
46
  }
47
47
  const bnFees = new BigNumber(op.tx.fees.toString());
48
48
  const res = {
49
- id: extra.ledgerOpType
50
- ? encodeOperationId(accountId, op.tx.hash, extra.ledgerOpType)
51
- : encodeOperationId(accountId, op.tx.hash, op.type),
49
+ id: encodeOperationId(accountId, op.tx.hash, op.type),
52
50
  hash: op.tx.hash,
53
51
  accountId,
54
52
  type: opType,
55
- value: ["OUT", "FEES"].includes(opType)
56
- ? new BigNumber(op.value.toString()).plus(bnFees)
57
- : new BigNumber(op.value.toString()),
53
+ value:
54
+ op.asset.type === "native" && ["OUT", "FEES"].includes(opType)
55
+ ? new BigNumber(op.value.toString()).plus(bnFees)
56
+ : new BigNumber(op.value.toString()),
58
57
  fee: bnFees,
59
58
  blockHash: op.tx.block.hash,
60
59
  blockHeight: op.tx.block.height,
@@ -55,4 +55,5 @@ export enum DeviceLabels {
55
55
  VERIFY_POLYGON = "Verify Polygon",
56
56
  VERIFY_SOLANA_ADDRESS = "Verify Solana address",
57
57
  REVIEW_TRANSACTION = "Review transaction",
58
+ I_UNDERSTAND = "I understand",
58
59
  }
@@ -460,7 +460,7 @@ async function retryAxiosRequest<T>(
460
460
  throw lastError!;
461
461
  }
462
462
 
463
- export async function waitFor(text: string, maxAttempts = 15): Promise<string[]> {
463
+ export async function waitFor(text: string, maxAttempts = 60): Promise<string[]> {
464
464
  const port = getEnv("SPECULOS_API_PORT");
465
465
  const address = getSpeculosAddress();
466
466
  const url = `${address}:${port}/events?stream=false&currentscreenonly=true`;
@@ -737,6 +737,14 @@ export async function verifyAmountsAndAcceptSwap(swap: Swap, amount: string) {
737
737
  await pressBoth();
738
738
  }
739
739
 
740
+ export async function verifyAmountsAndAcceptSwapForDifferentSeed(swap: Swap, amount: string) {
741
+ await pressUntilTextFound(DeviceLabels.I_UNDERSTAND);
742
+ await pressBoth();
743
+ const events = await pressUntilTextFound(DeviceLabels.SIGN_TRANSACTION);
744
+ await verifySwapData(swap, events, amount);
745
+ await pressBoth();
746
+ }
747
+
740
748
  export async function verifyAmountsAndRejectSwap(swap: Swap, amount: string) {
741
749
  await waitFor(DeviceLabels.REVIEW_TRANSACTION);
742
750
  const events = await pressUntilTextFound(DeviceLabels.REJECT);
@@ -625,7 +625,6 @@ export const DEFAULT_FEATURES: Features = {
625
625
  enableModularization: false,
626
626
  },
627
627
  },
628
- lldModularDrawerBackendData: DEFAULT_FEATURE,
629
628
  llmModularDrawer: {
630
629
  ...DEFAULT_FEATURE,
631
630
  params: {
@@ -1,8 +1,8 @@
1
1
  import React, { useMemo } from "react";
2
2
  import { useSelector } from "react-redux";
3
3
  import { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
4
- import { ApyType } from "../../types";
5
4
  import { selectInterestRateByCurrency } from "../../data/entities/interestRateSelectors";
5
+ import { ApyType } from "../../utils/type";
6
6
 
7
7
  const isValidApyType = (type: string): type is ApyType =>
8
8
  type === "NRR" || type === "APY" || type === "APR";
@@ -1,8 +1,8 @@
1
1
  import { Observable } from "rxjs";
2
2
  import { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
3
- import { getAccountTuplesForCurrency } from "../../../utils/getAccountTuplesForCurrency";
3
+ import { getAccountTuplesForCurrency } from "../../utils/getAccountTuplesForCurrency";
4
4
  import type { Account } from "@ledgerhq/types-live";
5
- import { WalletAPIAccount } from "../../../wallet-api/types";
5
+ import { WalletAPIAccount } from "../../wallet-api/types";
6
6
 
7
7
  type AccountModuleParams = {
8
8
  assets: CryptoOrTokenCurrency[];
@@ -0,0 +1,23 @@
1
+ import { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
2
+ import { ReactNode } from "react";
3
+ import { AccountModuleParams, AccountDataItem } from "../utils/type";
4
+
5
+ export const createUseLeftAccountsModule = ({
6
+ useAccountData,
7
+ accountsCount,
8
+ }: {
9
+ useAccountData: (params: AccountModuleParams) => AccountDataItem[];
10
+ accountsCount: (args: { label: string }) => ReactNode;
11
+ }) => {
12
+ return function useLeftAccountsModule(
13
+ params: AccountModuleParams,
14
+ ): Array<CryptoOrTokenCurrency & { leftElement?: ReactNode; count: number }> {
15
+ const accountData = useAccountData(params);
16
+
17
+ return accountData.map(({ asset, label, count }) => ({
18
+ ...asset,
19
+ leftElement: count > 0 ? accountsCount({ label }) : undefined,
20
+ count,
21
+ }));
22
+ };
23
+ };
@@ -0,0 +1,28 @@
1
+ import {
2
+ AccountDataItem,
3
+ AccountModuleParams,
4
+ CreateAccountsCountAndApy,
5
+ NetworkWithCount,
6
+ } from "../utils/type";
7
+
8
+ export const createUseLeftAccountsApyModule = ({
9
+ useAccountData,
10
+ accountsCountAndApy,
11
+ }: {
12
+ useAccountData: (params: AccountModuleParams) => AccountDataItem[];
13
+ accountsCountAndApy: CreateAccountsCountAndApy;
14
+ }) => {
15
+ return function useLeftAccountsApyModule(params: AccountModuleParams): NetworkWithCount[] {
16
+ const accountData = useAccountData(params);
17
+
18
+ return accountData.map(({ asset, label, count }) => {
19
+ const value = 5.11; // TODO to be retrieved from DADA
20
+ const type = "APY"; // TODO to be retrieved from DADA
21
+ return {
22
+ ...asset,
23
+ leftElement: count > 0 ? accountsCountAndApy({ label, value, type }) : undefined,
24
+ count,
25
+ };
26
+ });
27
+ };
28
+ };
@@ -0,0 +1,19 @@
1
+ import type { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
2
+ import { ReactNode } from "react";
3
+ import { ApyType } from "../utils/type";
4
+
5
+ export const createUseLeftApyModule = ({
6
+ ApyIndicator,
7
+ }: {
8
+ ApyIndicator: (args: { value: number; type: ApyType }) => ReactNode;
9
+ }) => {
10
+ return (assets: CryptoOrTokenCurrency[]) => {
11
+ const value = 5.11; // TODO: fetch DADA
12
+ const type: ApyType = "APY"; // TODO: fetch DADA
13
+
14
+ return assets.map(asset => ({
15
+ ...asset,
16
+ leftElement: ApyIndicator({ value, type }),
17
+ }));
18
+ };
19
+ };
@@ -0,0 +1,140 @@
1
+ import { useMemo } from "react";
2
+ import type { ReactNode } from "react";
3
+ import type { CryptoOrTokenCurrency, Currency } from "@ledgerhq/types-cryptoassets";
4
+ import { formatCurrencyUnit } from "@ledgerhq/coin-framework/currencies/formatCurrencyUnit";
5
+ import BigNumber from "bignumber.js";
6
+ import { counterValueFormatter } from "../utils/counterValueFormatter";
7
+ import { compareByBalanceThenFiat } from "../utils/sortByBalance";
8
+ import { UseBalanceDeps } from "../utils/type";
9
+ import { buildProviderCurrenciesMap } from "../utils/buildProviderCurrenciesMap";
10
+ import { CurrenciesByProviderId } from "../../deposit/type";
11
+ import { calculateProviderTotals } from "../utils/calculateProviderTotal";
12
+ import { getProviderCurrency } from "../utils/getProviderCurrency";
13
+ import { getBalanceAndFiatValueByAssets } from "../utils/getBalanceAndFiatValueByAssets";
14
+ import { groupAccountsByAsset } from "../utils/groupAccountsByAsset";
15
+
16
+ export type AssetDeps = {
17
+ useBalanceDeps: UseBalanceDeps;
18
+ balanceItem: (asset: { fiatValue?: string; balance?: string }) => ReactNode;
19
+ };
20
+
21
+ export function createUseRightBalanceAsset({ useBalanceDeps, balanceItem }: AssetDeps) {
22
+ const formatProviderResult = (
23
+ providerCurrency: CryptoOrTokenCurrency,
24
+ totalBalance: BigNumber,
25
+ totalFiatValue: BigNumber,
26
+ counterValueCurrency: Currency,
27
+ locale: string,
28
+ discreet: boolean,
29
+ ) => {
30
+ const unit = providerCurrency.units?.[0];
31
+ const balance = unit
32
+ ? formatCurrencyUnit(unit, totalBalance, { showCode: true, discreet })
33
+ : `${totalBalance.toFixed()} ${providerCurrency.ticker ?? providerCurrency.symbol}`;
34
+ const fiatValue = counterValueFormatter({
35
+ currency: counterValueCurrency.ticker,
36
+ value: totalFiatValue.toNumber(),
37
+ locale,
38
+ allowZeroValue: true,
39
+ });
40
+ return { balance, fiatValue };
41
+ };
42
+
43
+ return function useRightBalanceAsset(
44
+ assets: CryptoOrTokenCurrency[],
45
+ currenciesByProvider: CurrenciesByProviderId[],
46
+ ) {
47
+ const { flattenedAccounts, discreet, state, counterValueCurrency, locale } = useBalanceDeps();
48
+
49
+ const grouped = useMemo(
50
+ () => groupAccountsByAsset(flattenedAccounts, state, counterValueCurrency, discreet),
51
+ [flattenedAccounts, state, counterValueCurrency, discreet],
52
+ );
53
+
54
+ const providerMap = useMemo(
55
+ () => buildProviderCurrenciesMap(currenciesByProvider),
56
+ [currenciesByProvider],
57
+ );
58
+
59
+ return useMemo(() => {
60
+ if (!providerMap) {
61
+ const allBalance = getBalanceAndFiatValueByAssets(
62
+ flattenedAccounts,
63
+ assets,
64
+ state,
65
+ counterValueCurrency,
66
+ discreet,
67
+ locale,
68
+ );
69
+ const balanceMap = new Map(allBalance.map(b => [b.id, b]));
70
+ const assetsWithBalanceData = assets.map(asset => {
71
+ const balanceData = balanceMap.get(asset.id) || {};
72
+ return {
73
+ asset,
74
+ balanceData,
75
+ };
76
+ });
77
+
78
+ assetsWithBalanceData.sort((a, b) =>
79
+ compareByBalanceThenFiat(a.balanceData, b.balanceData, discreet),
80
+ );
81
+
82
+ return assetsWithBalanceData.map(({ asset, balanceData }) => ({
83
+ ...asset,
84
+ rightElement: balanceItem(balanceData),
85
+ }));
86
+ }
87
+
88
+ const assetsSet = new Set(assets.map(a => a.id));
89
+ const providerResultsMap = new Map<string, { balance?: string; fiatValue?: string }>();
90
+
91
+ for (const [, { currencies, mainCurrency }] of providerMap) {
92
+ if (!assetsSet.has(mainCurrency.id)) continue;
93
+ const providerCurrency = getProviderCurrency(mainCurrency, currencies);
94
+ if (!providerCurrency) continue;
95
+
96
+ const { totalBalance, totalFiatValue, hasAccounts } = calculateProviderTotals(
97
+ currencies,
98
+ grouped,
99
+ );
100
+ if (!hasAccounts) continue;
101
+
102
+ const { balance, fiatValue } = formatProviderResult(
103
+ providerCurrency,
104
+ totalBalance,
105
+ totalFiatValue,
106
+ counterValueCurrency,
107
+ locale,
108
+ discreet,
109
+ );
110
+ providerResultsMap.set(mainCurrency.id, { balance, fiatValue });
111
+ }
112
+
113
+ const assetsWithBalanceData = assets.map(asset => {
114
+ const balanceData = providerResultsMap.get(asset.id) || {};
115
+ return {
116
+ asset,
117
+ balanceData,
118
+ };
119
+ });
120
+
121
+ assetsWithBalanceData.sort((a, b) =>
122
+ compareByBalanceThenFiat(a.balanceData, b.balanceData, discreet),
123
+ );
124
+
125
+ return assetsWithBalanceData.map(({ asset, balanceData }) => ({
126
+ ...asset,
127
+ rightElement: balanceItem(balanceData),
128
+ }));
129
+ }, [
130
+ assets,
131
+ providerMap,
132
+ flattenedAccounts,
133
+ state,
134
+ counterValueCurrency,
135
+ discreet,
136
+ locale,
137
+ grouped,
138
+ ]);
139
+ };
140
+ }
@@ -0,0 +1,116 @@
1
+ import { useMemo, type ReactNode } from "react";
2
+ import type { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
3
+ import { compareByBalanceThenFiat } from "../utils/sortByBalance";
4
+ import { BalanceUI, UseBalanceDeps } from "../utils/type";
5
+ import { CurrenciesByProviderId } from "../../deposit/type";
6
+ import { getBalanceAndFiatValueByAssets } from "../utils/getBalanceAndFiatValueByAssets";
7
+
8
+ export type NetworkDeps = {
9
+ balanceItem: (asset: { fiatValue?: string; balance?: string }) => ReactNode;
10
+ useBalanceDeps: UseBalanceDeps;
11
+ };
12
+
13
+ type Params = {
14
+ assets: CryptoOrTokenCurrency[];
15
+ selectedAssetId: string;
16
+ currenciesByProvider: CurrenciesByProviderId[];
17
+ };
18
+
19
+ export function createUseRightBalanceNetwork({ useBalanceDeps, balanceItem }: NetworkDeps) {
20
+ return function useRightBalanceNetwork({
21
+ assets: networks,
22
+ selectedAssetId,
23
+ currenciesByProvider,
24
+ }: Params) {
25
+ const { flattenedAccounts, discreet, state, counterValueCurrency, locale } = useBalanceDeps();
26
+
27
+ return useMemo(() => {
28
+ if (currenciesByProvider && currenciesByProvider.length > 0) {
29
+ const providerOfSelectedAsset = currenciesByProvider.find(provider =>
30
+ provider.currenciesByNetwork.some(currency => currency.id === selectedAssetId),
31
+ );
32
+
33
+ if (providerOfSelectedAsset) {
34
+ const pairs = networks.map(network => ({
35
+ network,
36
+ asset: providerOfSelectedAsset.currenciesByNetwork.find(currency =>
37
+ currency.type === "TokenCurrency"
38
+ ? currency.parentCurrency.id === network.id
39
+ : currency.id === network.id,
40
+ ),
41
+ }));
42
+
43
+ const validAssets = pairs.filter(p => p.asset).map(p => p.asset!);
44
+
45
+ const allBalanceData =
46
+ validAssets.length > 0
47
+ ? getBalanceAndFiatValueByAssets(
48
+ flattenedAccounts,
49
+ validAssets,
50
+ state,
51
+ counterValueCurrency,
52
+ discreet,
53
+ locale,
54
+ )
55
+ : [];
56
+
57
+ const balanceMap = new Map(allBalanceData.map(b => [b.id, b]));
58
+
59
+ const networkWithBalanceData = pairs.map(({ network, asset }) => {
60
+ const balanceData: BalanceUI = asset ? balanceMap.get(asset.id) || {} : {};
61
+ return {
62
+ network,
63
+ balanceData,
64
+ };
65
+ });
66
+
67
+ networkWithBalanceData.sort((a, b) =>
68
+ compareByBalanceThenFiat(a.balanceData, b.balanceData, discreet),
69
+ );
70
+
71
+ return networkWithBalanceData.map(({ network, balanceData }) => ({
72
+ ...network,
73
+ rightElement: balanceItem(balanceData),
74
+ }));
75
+ }
76
+ }
77
+
78
+ const networkBalanceData = getBalanceAndFiatValueByAssets(
79
+ flattenedAccounts,
80
+ networks,
81
+ state,
82
+ counterValueCurrency,
83
+ discreet,
84
+ locale,
85
+ );
86
+
87
+ const balanceMap = new Map(networkBalanceData.map(b => [b.id, b]));
88
+
89
+ const networksWithBalance = networks.map(network => {
90
+ const balanceData = balanceMap.get(network.id) || {};
91
+ return {
92
+ network,
93
+ balanceData,
94
+ };
95
+ });
96
+
97
+ networksWithBalance.sort((a, b) =>
98
+ compareByBalanceThenFiat(a.balanceData, b.balanceData, discreet),
99
+ );
100
+
101
+ return networksWithBalance.map(({ network, balanceData }) => ({
102
+ ...network,
103
+ rightElement: balanceItem(balanceData),
104
+ }));
105
+ }, [
106
+ networks,
107
+ selectedAssetId,
108
+ currenciesByProvider,
109
+ flattenedAccounts,
110
+ state,
111
+ counterValueCurrency,
112
+ discreet,
113
+ locale,
114
+ ]);
115
+ };
116
+ }
@@ -0,0 +1,61 @@
1
+ import type { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
2
+ import { AssetType, CreateAssetConfigurationHook, AssetConfigurationDeps } from "../utils/type";
3
+ import { CurrenciesByProviderId } from "../../deposit/type";
4
+ import { composeHooks } from "../../utils/composeHooks";
5
+ import { createUseLeftApyModule } from "../hooks/useLeftApy";
6
+ import { createUseRightBalanceAsset } from "../hooks/useRightBalanceAsset";
7
+
8
+ const getRightElement =
9
+ (AssetConfigurationDeps: AssetConfigurationDeps) => (rightElement: string) => {
10
+ switch (rightElement) {
11
+ case "balance":
12
+ return createUseRightBalanceAsset({
13
+ useBalanceDeps: AssetConfigurationDeps.useBalanceDeps,
14
+ balanceItem: AssetConfigurationDeps.balanceItem,
15
+ });
16
+ case "marketTrend":
17
+ case "undefined":
18
+ default:
19
+ return undefined;
20
+ }
21
+ };
22
+
23
+ const getLeftElement =
24
+ (AssetConfigurationDeps: AssetConfigurationDeps) => (leftElement: string) => {
25
+ switch (leftElement) {
26
+ case "apy":
27
+ return createUseLeftApyModule({ ApyIndicator: AssetConfigurationDeps.ApyIndicator });
28
+ case "priceVariation":
29
+ case "undefined":
30
+ default:
31
+ return undefined;
32
+ }
33
+ };
34
+
35
+ const createAssetConfigurationHook: CreateAssetConfigurationHook =
36
+ deps =>
37
+ ({ assetsConfiguration, currenciesByProvider }) => {
38
+ const { rightElement = "undefined", leftElement = "undefined" } = assetsConfiguration ?? {};
39
+
40
+ const rightHook = getRightElement(deps)(rightElement);
41
+ const leftHook = getLeftElement(deps)(leftElement);
42
+
43
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
44
+ const hooks = [rightHook, leftHook].filter(Boolean) as Array<
45
+ (
46
+ assets: CryptoOrTokenCurrency[],
47
+ currenciesByProvider?: CurrenciesByProviderId[],
48
+ ) => AssetType[]
49
+ >;
50
+
51
+ return (assets: CryptoOrTokenCurrency[]) => {
52
+ const composedHook = composeHooks<CryptoOrTokenCurrency, AssetType>(
53
+ ...hooks.map(
54
+ hook => (assets: CryptoOrTokenCurrency[]) => hook(assets, currenciesByProvider),
55
+ ),
56
+ );
57
+ return composedHook(assets);
58
+ };
59
+ };
60
+
61
+ export default createAssetConfigurationHook;