@ledgerhq/live-common 34.47.0-nightly.9 → 34.48.0-nightly.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/lib/e2e/enum/DeviceLabels.d.ts +6 -5
  2. package/lib/e2e/enum/DeviceLabels.d.ts.map +1 -1
  3. package/lib/e2e/enum/DeviceLabels.js +6 -5
  4. package/lib/e2e/enum/DeviceLabels.js.map +1 -1
  5. package/lib/e2e/speculos.d.ts +1 -1
  6. package/lib/e2e/speculos.d.ts.map +1 -1
  7. package/lib/e2e/speculos.js +13 -15
  8. package/lib/e2e/speculos.js.map +1 -1
  9. package/lib/modularDrawer/hooks/modules/useLeftApyModule.d.ts.map +1 -1
  10. package/lib/modularDrawer/hooks/modules/useLeftApyModule.js +4 -20
  11. package/lib/modularDrawer/hooks/modules/useLeftApyModule.js.map +1 -1
  12. package/lib/modularDrawer/hooks/useInterestRatesByCurrencies.d.ts +3 -0
  13. package/lib/modularDrawer/hooks/useInterestRatesByCurrencies.d.ts.map +1 -0
  14. package/lib/modularDrawer/hooks/useInterestRatesByCurrencies.js +23 -0
  15. package/lib/modularDrawer/hooks/useInterestRatesByCurrencies.js.map +1 -0
  16. package/lib/modularDrawer/hooks/useLeftAccountsApy.d.ts +2 -4
  17. package/lib/modularDrawer/hooks/useLeftAccountsApy.d.ts.map +1 -1
  18. package/lib/modularDrawer/hooks/useLeftAccountsApy.js +23 -12
  19. package/lib/modularDrawer/hooks/useLeftAccountsApy.js.map +1 -1
  20. package/lib/modularDrawer/modules/createAssetConfiguration.d.ts.map +1 -1
  21. package/lib/modularDrawer/modules/createAssetConfiguration.js +8 -8
  22. package/lib/modularDrawer/modules/createAssetConfiguration.js.map +1 -1
  23. package/lib/modularDrawer/modules/createNetworkConfiguration.d.ts +3 -3
  24. package/lib/modularDrawer/modules/createNetworkConfiguration.d.ts.map +1 -1
  25. package/lib/modularDrawer/modules/createNetworkConfiguration.js +12 -14
  26. package/lib/modularDrawer/modules/createNetworkConfiguration.js.map +1 -1
  27. package/lib/modularDrawer/utils/__tests__/getInterestRateForAsset.test.d.ts +2 -0
  28. package/lib/modularDrawer/utils/__tests__/getInterestRateForAsset.test.d.ts.map +1 -0
  29. package/lib/modularDrawer/utils/__tests__/getInterestRateForAsset.test.js +36 -0
  30. package/lib/modularDrawer/utils/__tests__/getInterestRateForAsset.test.js.map +1 -0
  31. package/lib/modularDrawer/utils/getInterestRateForAsset.d.ts +13 -0
  32. package/lib/modularDrawer/utils/getInterestRateForAsset.d.ts.map +1 -0
  33. package/lib/modularDrawer/utils/getInterestRateForAsset.js +20 -0
  34. package/lib/modularDrawer/utils/getInterestRateForAsset.js.map +1 -0
  35. package/lib/modularDrawer/utils/type.d.ts +4 -3
  36. package/lib/modularDrawer/utils/type.d.ts.map +1 -1
  37. package/lib/wallet-api/ModularDrawer/types.d.ts +6 -6
  38. package/lib/wallet-api/ModularDrawer/types.d.ts.map +1 -1
  39. package/lib/wallet-api/ModularDrawer/types.js +1 -1
  40. package/lib/wallet-api/ModularDrawer/types.js.map +1 -1
  41. package/lib-es/e2e/enum/DeviceLabels.d.ts +6 -5
  42. package/lib-es/e2e/enum/DeviceLabels.d.ts.map +1 -1
  43. package/lib-es/e2e/enum/DeviceLabels.js +6 -5
  44. package/lib-es/e2e/enum/DeviceLabels.js.map +1 -1
  45. package/lib-es/e2e/speculos.d.ts +1 -1
  46. package/lib-es/e2e/speculos.d.ts.map +1 -1
  47. package/lib-es/e2e/speculos.js +13 -15
  48. package/lib-es/e2e/speculos.js.map +1 -1
  49. package/lib-es/modularDrawer/hooks/modules/useLeftApyModule.d.ts.map +1 -1
  50. package/lib-es/modularDrawer/hooks/modules/useLeftApyModule.js +4 -20
  51. package/lib-es/modularDrawer/hooks/modules/useLeftApyModule.js.map +1 -1
  52. package/lib-es/modularDrawer/hooks/useInterestRatesByCurrencies.d.ts +3 -0
  53. package/lib-es/modularDrawer/hooks/useInterestRatesByCurrencies.d.ts.map +1 -0
  54. package/lib-es/modularDrawer/hooks/useInterestRatesByCurrencies.js +19 -0
  55. package/lib-es/modularDrawer/hooks/useInterestRatesByCurrencies.js.map +1 -0
  56. package/lib-es/modularDrawer/hooks/useLeftAccountsApy.d.ts +2 -4
  57. package/lib-es/modularDrawer/hooks/useLeftAccountsApy.d.ts.map +1 -1
  58. package/lib-es/modularDrawer/hooks/useLeftAccountsApy.js +21 -10
  59. package/lib-es/modularDrawer/hooks/useLeftAccountsApy.js.map +1 -1
  60. package/lib-es/modularDrawer/modules/createAssetConfiguration.d.ts.map +1 -1
  61. package/lib-es/modularDrawer/modules/createAssetConfiguration.js +8 -8
  62. package/lib-es/modularDrawer/modules/createAssetConfiguration.js.map +1 -1
  63. package/lib-es/modularDrawer/modules/createNetworkConfiguration.d.ts +3 -3
  64. package/lib-es/modularDrawer/modules/createNetworkConfiguration.d.ts.map +1 -1
  65. package/lib-es/modularDrawer/modules/createNetworkConfiguration.js +13 -15
  66. package/lib-es/modularDrawer/modules/createNetworkConfiguration.js.map +1 -1
  67. package/lib-es/modularDrawer/utils/__tests__/getInterestRateForAsset.test.d.ts +2 -0
  68. package/lib-es/modularDrawer/utils/__tests__/getInterestRateForAsset.test.d.ts.map +1 -0
  69. package/lib-es/modularDrawer/utils/__tests__/getInterestRateForAsset.test.js +34 -0
  70. package/lib-es/modularDrawer/utils/__tests__/getInterestRateForAsset.test.js.map +1 -0
  71. package/lib-es/modularDrawer/utils/getInterestRateForAsset.d.ts +13 -0
  72. package/lib-es/modularDrawer/utils/getInterestRateForAsset.d.ts.map +1 -0
  73. package/lib-es/modularDrawer/utils/getInterestRateForAsset.js +16 -0
  74. package/lib-es/modularDrawer/utils/getInterestRateForAsset.js.map +1 -0
  75. package/lib-es/modularDrawer/utils/type.d.ts +4 -3
  76. package/lib-es/modularDrawer/utils/type.d.ts.map +1 -1
  77. package/lib-es/wallet-api/ModularDrawer/types.d.ts +6 -6
  78. package/lib-es/wallet-api/ModularDrawer/types.d.ts.map +1 -1
  79. package/lib-es/wallet-api/ModularDrawer/types.js +1 -1
  80. package/lib-es/wallet-api/ModularDrawer/types.js.map +1 -1
  81. package/package.json +71 -71
  82. package/src/e2e/enum/DeviceLabels.ts +6 -5
  83. package/src/e2e/speculos.ts +13 -16
  84. package/src/families/hedera/__snapshots__/bridge.integration.test.ts.snap +27 -7
  85. package/src/modularDrawer/hooks/modules/useLeftApyModule.tsx +7 -22
  86. package/src/modularDrawer/hooks/useInterestRatesByCurrencies.ts +23 -0
  87. package/src/modularDrawer/hooks/useLeftAccountsApy.tsx +32 -16
  88. package/src/modularDrawer/modules/createAssetConfiguration.ts +11 -10
  89. package/src/modularDrawer/modules/createNetworkConfiguration.ts +25 -17
  90. package/src/modularDrawer/utils/__tests__/getInterestRateForAsset.test.ts +58 -0
  91. package/src/modularDrawer/utils/getInterestRateForAsset.ts +32 -0
  92. package/src/modularDrawer/utils/type.ts +4 -3
  93. package/src/wallet-api/ModularDrawer/types.ts +1 -1
  94. package/lib/modularDrawer/hooks/useLeftApy.d.ts +0 -54
  95. package/lib/modularDrawer/hooks/useLeftApy.d.ts.map +0 -1
  96. package/lib/modularDrawer/hooks/useLeftApy.js +0 -15
  97. package/lib/modularDrawer/hooks/useLeftApy.js.map +0 -1
  98. package/lib-es/modularDrawer/hooks/useLeftApy.d.ts +0 -54
  99. package/lib-es/modularDrawer/hooks/useLeftApy.d.ts.map +0 -1
  100. package/lib-es/modularDrawer/hooks/useLeftApy.js +0 -11
  101. package/lib-es/modularDrawer/hooks/useLeftApy.js.map +0 -1
  102. package/src/modularDrawer/hooks/useLeftApy.tsx +0 -19
@@ -491,14 +491,14 @@ export async function pressBoth() {
491
491
 
492
492
  export async function pressUntilTextFound(
493
493
  targetText: string,
494
- maxAttempts: number = 15,
494
+ strictMatch: boolean = false,
495
495
  ): Promise<string[]> {
496
+ const maxAttempts = 15;
496
497
  const speculosApiPort = getEnv("SPECULOS_API_PORT");
497
498
 
498
499
  for (let attempts = 0; attempts < maxAttempts; attempts++) {
499
500
  const texts = await fetchCurrentScreenTexts(speculosApiPort);
500
-
501
- if (texts.includes(targetText)) {
501
+ if (strictMatch ? texts === targetText : texts.includes(targetText)) {
502
502
  return await fetchAllEvents(speculosApiPort);
503
503
  }
504
504
 
@@ -575,28 +575,25 @@ export async function waitForTimeOut(ms: number) {
575
575
  }
576
576
 
577
577
  export async function removeMemberLedgerSync() {
578
- await waitFor(DeviceLabels.CONNECT_WITH);
579
- await pressUntilTextFound(DeviceLabels.MAKE_SURE_TO_USE);
580
- await pressUntilTextFound(DeviceLabels.CONNECT_WITH);
578
+ await waitFor(DeviceLabels.CONNECT_TO);
579
+ await pressUntilTextFound(DeviceLabels.CONNECT, true);
581
580
  await pressBoth();
582
- await waitFor(DeviceLabels.REMOVE_PHONE_OR_COMPUTER);
583
- await pressUntilTextFound(DeviceLabels.AFTER_REMOVING);
584
- await pressUntilTextFound(DeviceLabels.REMOVE_PHONE_OR_COMPUTER);
581
+ await waitFor(DeviceLabels.REMOVE_FROM_LEDGER_SYNC);
582
+ await pressUntilTextFound(DeviceLabels.REMOVE, true);
585
583
  await pressBoth();
586
584
  await waitFor(DeviceLabels.TURN_ON_SYNC);
587
- await pressUntilTextFound(DeviceLabels.YOUR_CRYPTO_ACCOUNTS);
588
- await pressUntilTextFound(DeviceLabels.TURN_ON_SYNC);
585
+ await pressUntilTextFound(DeviceLabels.LEDGER_LIVE_WILL_BE);
586
+ await pressUntilTextFound(DeviceLabels.TURN_ON_SYNC2);
589
587
  await pressBoth();
590
588
  }
591
589
 
592
590
  export async function activateLedgerSync() {
593
- await waitFor(DeviceLabels.CONNECT_WITH);
594
- await pressUntilTextFound(DeviceLabels.MAKE_SURE_TO_USE);
595
- await pressUntilTextFound(DeviceLabels.CONNECT_WITH);
591
+ await waitFor(DeviceLabels.CONNECT_TO);
592
+ await pressUntilTextFound(DeviceLabels.CONNECT, true);
596
593
  await pressBoth();
597
594
  await waitFor(DeviceLabels.TURN_ON_SYNC);
598
- await pressUntilTextFound(DeviceLabels.YOUR_CRYPTO_ACCOUNTS);
599
- await pressUntilTextFound(DeviceLabels.TURN_ON_SYNC);
595
+ await pressUntilTextFound(DeviceLabels.LEDGER_LIVE_WILL_BE);
596
+ await pressUntilTextFound(DeviceLabels.TURN_ON_SYNC2);
600
597
  await pressBoth();
601
598
  }
602
599
 
@@ -3,7 +3,7 @@
3
3
  exports[`hedera currency bridge scanAccounts hedera seed 1 1`] = `
4
4
  [
5
5
  {
6
- "balance": "942529312",
6
+ "balance": "942076781",
7
7
  "currencyId": "hedera",
8
8
  "derivationMode": "hederaBip44",
9
9
  "freshAddress": "0.0.1040977",
@@ -14,22 +14,22 @@ exports[`hedera currency bridge scanAccounts hedera seed 1 1`] = `
14
14
  },
15
15
  "id": "js:2:hedera:0.0.1040977:hederaBip44",
16
16
  "index": 0,
17
- "operationsCount": 40,
17
+ "operationsCount": 41,
18
18
  "pendingOperations": [],
19
19
  "seedIdentifier": "9e92a312233d5fd6b5a723875aeea2cea81a8e48ffc00341cff6dffcfd3ab7f2",
20
- "spendableBalance": "942529312",
20
+ "spendableBalance": "942076781",
21
21
  "subAccounts": [],
22
22
  "swapHistory": [],
23
23
  "syncHash": "0x30c71e3f",
24
24
  "used": true,
25
25
  },
26
26
  {
27
- "balance": "30000000",
27
+ "balance": "20000000",
28
28
  "id": "js:2:hedera:0.0.1040977:hederaBip44+hedera%2Fhts%2Ftune~!underscore!~fm~!underscore!~0.0.127877",
29
29
  "operationsCount": 0,
30
30
  "parentId": "js:2:hedera:0.0.1040977:hederaBip44",
31
31
  "pendingOperations": [],
32
- "spendableBalance": "30000000",
32
+ "spendableBalance": "20000000",
33
33
  "swapHistory": [],
34
34
  "tokenId": "hedera/hts/tune_fm_0.0.127877",
35
35
  "type": "TokenAccountRaw",
@@ -141,12 +141,12 @@ exports[`hedera currency bridge scanAccounts hedera seed 1 1`] = `
141
141
  "used": true,
142
142
  },
143
143
  {
144
- "balance": "328000000",
144
+ "balance": "338000000",
145
145
  "id": "js:2:hedera:0.0.8313485:hederaBip44+hedera%2Fhts%2Ftune~!underscore!~fm~!underscore!~0.0.127877",
146
146
  "operationsCount": 0,
147
147
  "parentId": "js:2:hedera:0.0.8313485:hederaBip44",
148
148
  "pendingOperations": [],
149
- "spendableBalance": "328000000",
149
+ "spendableBalance": "338000000",
150
150
  "swapHistory": [],
151
151
  "tokenId": "hedera/hts/tune_fm_0.0.127877",
152
152
  "type": "TokenAccountRaw",
@@ -724,6 +724,26 @@ exports[`hedera currency bridge scanAccounts hedera seed 1 2`] = `
724
724
  "type": "OUT",
725
725
  "value": "1000054816",
726
726
  },
727
+ {
728
+ "accountId": "js:2:hedera:0.0.1040977:hederaBip44",
729
+ "blockHash": null,
730
+ "blockHeight": 5,
731
+ "extra": {
732
+ "consensusTimestamp": "1756718310.549818000",
733
+ },
734
+ "fee": "452531",
735
+ "hasFailed": false,
736
+ "hash": "QDUwQqgrOgB4aPkMprRe3yiux277A7_PJVfpbv-P4GBMT33ahyXp8NQXbblLDA0c",
737
+ "id": "js:2:hedera:0.0.1040977:hederaBip44-QDUwQqgrOgB4aPkMprRe3yiux277A7_PJVfpbv-P4GBMT33ahyXp8NQXbblLDA0c-FEES",
738
+ "recipients": [
739
+ "0.0.8313485",
740
+ ],
741
+ "senders": [
742
+ "0.0.1040977",
743
+ ],
744
+ "type": "FEES",
745
+ "value": "452531",
746
+ },
727
747
  {
728
748
  "accountId": "js:2:hedera:0.0.1040977:hederaBip44",
729
749
  "blockHash": null,
@@ -1,11 +1,8 @@
1
1
  import React, { useMemo } from "react";
2
- import { useSelector } from "react-redux";
3
2
  import { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
4
- import { selectInterestRateByCurrency } from "../../data/entities/interestRateSelectors";
5
3
  import { ApyType } from "../../utils/type";
6
-
7
- const isValidApyType = (type: string): type is ApyType =>
8
- type === "NRR" || type === "APY" || type === "APR";
4
+ import { useInterestRatesByCurrencies } from "../useInterestRatesByCurrencies";
5
+ import { getInterestRateForAsset } from "../../utils/getInterestRateForAsset";
9
6
 
10
7
  const createApyItem = ({
11
8
  value,
@@ -21,26 +18,14 @@ export const useLeftApyModule = (
21
18
  currencies: CryptoOrTokenCurrency[],
22
19
  ApyIndicator: React.ComponentType<{ value: number; type: ApyType }>,
23
20
  ) => {
24
- const interestRates = useSelector(state => {
25
- const rates: Record<string, { value: number; type: ApyType } | undefined> = {};
26
- currencies.forEach(currency => {
27
- const apiRate = selectInterestRateByCurrency(state, currency.id);
28
- if (apiRate && isValidApyType(apiRate.type)) {
29
- rates[currency.id] = {
30
- value: apiRate.rate,
31
- type: apiRate.type,
32
- };
33
- }
34
- });
35
- return rates;
36
- });
21
+ const interestRates = useInterestRatesByCurrencies(currencies);
37
22
 
38
23
  return useMemo(() => {
39
24
  return currencies.map(currency => {
40
- const interestRate = interestRates[currency.id];
41
- const interestRatePercentageRounded = interestRate
42
- ? Math.round(interestRate.value * 100 * 100) / 100
43
- : 0;
25
+ const { interestRate, interestRatePercentageRounded } = getInterestRateForAsset(
26
+ currency,
27
+ interestRates,
28
+ );
44
29
 
45
30
  if (!interestRate || interestRatePercentageRounded <= 0) {
46
31
  return currency;
@@ -0,0 +1,23 @@
1
+ import { useSelector } from "react-redux";
2
+ import { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
3
+ import { selectInterestRateByCurrency } from "../data/entities/interestRateSelectors";
4
+ import { ApyType } from "../utils/type";
5
+
6
+ const isValidApyType = (type: string): type is ApyType =>
7
+ type === "NRR" || type === "APY" || type === "APR";
8
+
9
+ export const useInterestRatesByCurrencies = (currencies: CryptoOrTokenCurrency[]) => {
10
+ return useSelector(state => {
11
+ const rates: Record<string, { value: number; type: ApyType } | undefined> = {};
12
+ currencies.forEach(currency => {
13
+ const apiRate = selectInterestRateByCurrency(state, currency.id);
14
+ if (apiRate && isValidApyType(apiRate.type)) {
15
+ rates[currency.id] = {
16
+ value: apiRate.rate,
17
+ type: apiRate.type,
18
+ };
19
+ }
20
+ });
21
+ return rates;
22
+ });
23
+ };
@@ -4,25 +4,41 @@ import {
4
4
  CreateAccountsCountAndApy,
5
5
  NetworkWithCount,
6
6
  } from "../utils/type";
7
+ import { useInterestRatesByCurrencies } from "../hooks/useInterestRatesByCurrencies";
8
+ import { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
9
+ import { getInterestRateForAsset } from "../utils/getInterestRateForAsset";
7
10
 
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);
11
+ export function useLeftAccountsApyModule(
12
+ params: AccountModuleParams,
13
+ useAccountData: (params: AccountModuleParams) => AccountDataItem[],
14
+ accountsCountAndApy: CreateAccountsCountAndApy,
15
+ networks: CryptoOrTokenCurrency[],
16
+ ): NetworkWithCount[] {
17
+ const accountData = useAccountData(params);
18
+ const interestRates = useInterestRatesByCurrencies(networks);
17
19
 
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
20
+ // Map each account to its APY info using the shared utility
21
+ return accountData.map(({ asset, label, count }) => {
22
+ const { interestRate, interestRatePercentageRounded } = getInterestRateForAsset(
23
+ asset,
24
+ interestRates,
25
+ networks,
26
+ );
27
+
28
+ if ((!interestRate || interestRatePercentageRounded <= 0) && count <= 0) {
21
29
  return {
22
30
  ...asset,
23
- leftElement: count > 0 ? accountsCountAndApy({ label, value, type }) : undefined,
24
31
  count,
25
32
  };
26
- });
27
- };
28
- };
33
+ }
34
+ return {
35
+ ...asset,
36
+ leftElement: accountsCountAndApy({
37
+ label: count > 0 ? label : undefined,
38
+ value: interestRatePercentageRounded,
39
+ type: interestRate?.type,
40
+ }),
41
+ count,
42
+ };
43
+ });
44
+ }
@@ -2,30 +2,31 @@ import type { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
2
2
  import { AssetType, CreateAssetConfigurationHook, AssetConfigurationDeps } from "../utils/type";
3
3
  import { CurrenciesByProviderId } from "../../deposit/type";
4
4
  import { composeHooks } from "../../utils/composeHooks";
5
- import { createUseLeftApyModule } from "../hooks/useLeftApy";
5
+ import { useLeftApyModule } from "../hooks/modules/useLeftApyModule";
6
6
  import { createUseRightBalanceAsset } from "../hooks/useRightBalanceAsset";
7
7
 
8
8
  const getRightElement =
9
- (AssetConfigurationDeps: AssetConfigurationDeps) => (rightElement: string) => {
9
+ (AssetConfigurationDeps: AssetConfigurationDeps) => (rightElement?: string) => {
10
10
  switch (rightElement) {
11
+ case "undefined":
12
+ return undefined;
13
+ case "marketTrend":
11
14
  case "balance":
15
+ default:
12
16
  return createUseRightBalanceAsset({
13
17
  useBalanceDeps: AssetConfigurationDeps.useBalanceDeps,
14
18
  balanceItem: AssetConfigurationDeps.balanceItem,
15
19
  });
16
- case "marketTrend":
17
- case "undefined":
18
- default:
19
- return undefined;
20
20
  }
21
21
  };
22
22
 
23
23
  const getLeftElement =
24
- (AssetConfigurationDeps: AssetConfigurationDeps) => (leftElement: string) => {
24
+ (AssetConfigurationDeps: AssetConfigurationDeps) => (leftElement?: string) => {
25
25
  switch (leftElement) {
26
26
  case "apy":
27
- return createUseLeftApyModule({ ApyIndicator: AssetConfigurationDeps.ApyIndicator });
28
- case "priceVariation":
27
+ return (assets: CryptoOrTokenCurrency[]) =>
28
+ useLeftApyModule(assets, AssetConfigurationDeps.ApyIndicator);
29
+ case "marketTrend":
29
30
  case "undefined":
30
31
  default:
31
32
  return undefined;
@@ -35,7 +36,7 @@ const getLeftElement =
35
36
  const createAssetConfigurationHook: CreateAssetConfigurationHook =
36
37
  deps =>
37
38
  ({ assetsConfiguration, currenciesByProvider }) => {
38
- const { rightElement = "undefined", leftElement = "undefined" } = assetsConfiguration ?? {};
39
+ const { rightElement, leftElement } = assetsConfiguration ?? {};
39
40
 
40
41
  const rightHook = getRightElement(deps)(rightElement);
41
42
  const leftHook = getLeftElement(deps)(leftElement);
@@ -1,6 +1,6 @@
1
1
  import type { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
2
2
  import { createUseLeftAccountsModule } from "../hooks/useLeftAccounts";
3
- import { createUseLeftAccountsApyModule } from "../hooks/useLeftAccountsApy";
3
+ import { useLeftAccountsApyModule } from "../hooks/useLeftAccountsApy";
4
4
  import { createUseRightBalanceNetwork } from "../hooks/useRightBalanceNetwork";
5
5
  import {
6
6
  CreateNetworkConfigurationHookProps,
@@ -9,41 +9,45 @@ import {
9
9
  Network,
10
10
  NetworkHook,
11
11
  RightElementKind,
12
+ AccountModuleParams,
12
13
  } from "../utils/type";
13
14
  import { composeHooks } from "../../utils/composeHooks";
14
15
 
15
16
  export const getLeftElement =
16
17
  (NetworkConfigurationDeps: NetworkConfigurationDeps) =>
17
- (leftElement: LeftElementKind): NetworkHook | undefined => {
18
+ (leftElement?: LeftElementKind): NetworkHook | undefined => {
18
19
  switch (leftElement) {
20
+ case "undefined":
21
+ return undefined;
22
+ case "numberOfAccountsAndApy":
23
+ return (params: AccountModuleParams & { networks: CryptoOrTokenCurrency[] }) =>
24
+ useLeftAccountsApyModule(
25
+ params,
26
+ NetworkConfigurationDeps.useAccountData,
27
+ NetworkConfigurationDeps.accountsCountAndApy,
28
+ params.networks,
29
+ );
19
30
  case "numberOfAccounts":
31
+ default:
20
32
  return createUseLeftAccountsModule({
21
33
  useAccountData: NetworkConfigurationDeps.useAccountData,
22
34
  accountsCount: NetworkConfigurationDeps.accountsCount,
23
35
  });
24
- case "numberOfAccountsAndApy":
25
- return createUseLeftAccountsApyModule({
26
- useAccountData: NetworkConfigurationDeps.useAccountData,
27
- accountsCountAndApy: NetworkConfigurationDeps.accountsCountAndApy,
28
- });
29
- case "undefined":
30
- default:
31
- return undefined;
32
36
  }
33
37
  };
34
38
 
35
39
  export const getRightElement =
36
40
  (NetworkConfigurationDeps: NetworkConfigurationDeps) =>
37
- (rightElement: RightElementKind): NetworkHook | undefined => {
41
+ (rightElement?: RightElementKind): NetworkHook | undefined => {
38
42
  switch (rightElement) {
43
+ case "undefined":
44
+ return undefined;
39
45
  case "balance":
46
+ default:
40
47
  return createUseRightBalanceNetwork({
41
48
  useBalanceDeps: NetworkConfigurationDeps.useBalanceDeps,
42
49
  balanceItem: NetworkConfigurationDeps.balanceItem,
43
50
  });
44
- case "undefined":
45
- default:
46
- return undefined;
47
51
  }
48
52
  };
49
53
 
@@ -55,22 +59,26 @@ export const createNetworkConfigurationHook =
55
59
  currenciesByProvider,
56
60
  accounts$,
57
61
  }: CreateNetworkConfigurationHookProps) => {
58
- const { leftElement = "undefined", rightElement = "undefined" } = networksConfig ?? {};
62
+ const { leftElement, rightElement } = networksConfig ?? {};
59
63
  const leftHook = getLeftElement(NetworkConfigurationDeps)(leftElement);
60
64
  const rightHook = getRightElement(NetworkConfigurationDeps)(rightElement);
61
65
 
62
66
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
63
67
  const hooks = [rightHook, leftHook].filter(Boolean) as NetworkHook[];
64
68
 
65
- return (assets: CryptoOrTokenCurrency[]): Array<CryptoOrTokenCurrency & Network> => {
69
+ return (
70
+ assets: CryptoOrTokenCurrency[],
71
+ networks: CryptoOrTokenCurrency[],
72
+ ): Array<CryptoOrTokenCurrency & Network> => {
66
73
  const composedHook = composeHooks<CryptoOrTokenCurrency, Network>(
67
74
  ...hooks.map(
68
- hook => (assets: CryptoOrTokenCurrency[]) =>
75
+ hook => () =>
69
76
  hook({
70
77
  assets,
71
78
  selectedAssetId,
72
79
  currenciesByProvider: currenciesByProvider || [],
73
80
  accounts$,
81
+ networks,
74
82
  }),
75
83
  ),
76
84
  );
@@ -0,0 +1,58 @@
1
+ import { getInterestRateForAsset } from "../getInterestRateForAsset";
2
+ import {
3
+ mockEthCryptoCurrency,
4
+ mockScrollCryptoCurrency,
5
+ usdcToken,
6
+ } from "../../__mocks__/currencies.mock";
7
+ import { ApyType } from "../type";
8
+
9
+ describe("getInterestRateForAsset", () => {
10
+ const networks = [mockEthCryptoCurrency, usdcToken];
11
+ const interestRates: Record<string, { value: number; type: ApyType }> = {
12
+ [mockEthCryptoCurrency.id]: { value: 0.05, type: "APY" },
13
+ [usdcToken.id]: { value: 0.042927, type: "NRR" },
14
+ };
15
+
16
+ it("returns correct rate for CryptoCurrency asset", () => {
17
+ const { interestRate, interestRatePercentageRounded } = getInterestRateForAsset(
18
+ mockEthCryptoCurrency,
19
+ interestRates,
20
+ );
21
+ expect(interestRate).toEqual({ value: 0.05, type: "APY" });
22
+ expect(interestRatePercentageRounded).toBe(5);
23
+ });
24
+
25
+ it("returns correct rate for TokenCurrency (parentCurrency) asset", () => {
26
+ const { interestRate, interestRatePercentageRounded } = getInterestRateForAsset(
27
+ usdcToken,
28
+ interestRates,
29
+ networks,
30
+ );
31
+ expect(interestRate).toEqual({ value: 0.042927, type: "NRR" });
32
+ expect(interestRatePercentageRounded).toBeCloseTo(4.29, 2);
33
+ });
34
+
35
+ it("returns undefined and 0 if no rate found", () => {
36
+ const { interestRate, interestRatePercentageRounded } = getInterestRateForAsset(
37
+ mockScrollCryptoCurrency,
38
+ interestRates,
39
+ networks,
40
+ );
41
+ expect(interestRate).toBeUndefined();
42
+ expect(interestRatePercentageRounded).toBe(0);
43
+ });
44
+
45
+ it("returns 0 if rate is 0", () => {
46
+ const zeroNetworks = [mockEthCryptoCurrency];
47
+ const zeroRates: Record<string, { value: number; type: ApyType }> = {
48
+ ethereum: { value: 0, type: "APY" },
49
+ };
50
+ const { interestRate, interestRatePercentageRounded } = getInterestRateForAsset(
51
+ mockEthCryptoCurrency,
52
+ zeroRates,
53
+ zeroNetworks,
54
+ );
55
+ expect(interestRate).toEqual({ value: 0, type: "APY" });
56
+ expect(interestRatePercentageRounded).toBe(0);
57
+ });
58
+ });
@@ -0,0 +1,32 @@
1
+ import { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
2
+ import { ApyType } from "./type";
3
+
4
+ type InterestRate = { value: number; type: ApyType };
5
+ type InterestRateResult = {
6
+ interestRate: InterestRate | undefined;
7
+ interestRatePercentageRounded: number;
8
+ };
9
+
10
+ const roundPercentage = (value: number, decimals = 2): number => {
11
+ const factor = 10 ** decimals;
12
+ return Math.round(value * 100 * factor) / factor;
13
+ };
14
+
15
+ export function getInterestRateForAsset(
16
+ asset: CryptoOrTokenCurrency,
17
+ interestRates: Record<string, InterestRate | undefined>,
18
+ networks: CryptoOrTokenCurrency[] = [],
19
+ ): InterestRateResult {
20
+ const currencyId =
21
+ asset.type === "TokenCurrency"
22
+ ? asset.id
23
+ : networks.find(n => n.type === "TokenCurrency" && n.parentCurrency?.id === asset.id)?.id ??
24
+ asset.id;
25
+
26
+ const interestRate = interestRates[currencyId] ?? undefined;
27
+
28
+ return {
29
+ interestRate,
30
+ interestRatePercentageRounded: interestRate ? roundPercentage(interestRate.value) : 0,
31
+ };
32
+ }
@@ -44,9 +44,9 @@ export type BalanceUI = { balance?: string; fiatValue?: string };
44
44
  export type CreateBalanceItem = (x: BalanceUI) => React.ReactNode;
45
45
 
46
46
  export type CreateAccountsCountAndApy = (args: {
47
- label: string;
48
- value: number;
49
- type: ApyType;
47
+ label?: string;
48
+ value?: number;
49
+ type?: ApyType;
50
50
  }) => ReactNode;
51
51
 
52
52
  export type NetworkWithCount = CryptoOrTokenCurrency & {
@@ -71,6 +71,7 @@ export type UseAccountData = (params: AccountModuleParams) => AccountDataItem[];
71
71
 
72
72
  export type NetworkHookParams = {
73
73
  assets: CryptoOrTokenCurrency[];
74
+ networks: CryptoOrTokenCurrency[];
74
75
  selectedAssetId: string;
75
76
  currenciesByProvider: CurrenciesByProviderId[];
76
77
  accounts$?: Observable<WalletAPIAccount[]>;
@@ -13,7 +13,7 @@ export type ModularDrawerConfiguration = {
13
13
  };
14
14
 
15
15
  export const filterOptions = ["topNetworks", "undefined"] as const;
16
- export const assetsLeftElementOptions = ["apy", "priceVariation", "undefined"] as const;
16
+ export const assetsLeftElementOptions = ["apy", "marketTrend", "undefined"] as const;
17
17
  export const assetsRightElementOptions = ["balance", "marketTrend", "undefined"] as const;
18
18
  export const networksLeftElementOptions = [
19
19
  "numberOfAccounts",
@@ -1,54 +0,0 @@
1
- import type { CryptoOrTokenCurrency } from "@ledgerhq/types-cryptoassets";
2
- import { ReactNode } from "react";
3
- import { ApyType } from "../utils/type";
4
- export declare const createUseLeftApyModule: ({ ApyIndicator, }: {
5
- ApyIndicator: (args: {
6
- value: number;
7
- type: ApyType;
8
- }) => ReactNode;
9
- }) => (assets: CryptoOrTokenCurrency[]) => ({
10
- leftElement: ReactNode;
11
- name: string;
12
- ticker: string;
13
- units: import("@ledgerhq/types-cryptoassets").Unit[];
14
- symbol?: string | undefined;
15
- disableCountervalue?: boolean | undefined;
16
- delisted?: boolean | undefined;
17
- keywords?: string[] | undefined;
18
- type: "CryptoCurrency";
19
- id: import("@ledgerhq/types-cryptoassets").CryptoCurrencyId | "LBRY" | "groestcoin" | "osmo";
20
- forkedFrom?: string | undefined;
21
- managerAppName: string;
22
- coinType: import("@ledgerhq/types-cryptoassets").CoinType;
23
- scheme: string;
24
- color: string;
25
- family: string;
26
- blockAvgTime?: number | undefined;
27
- supportsSegwit?: boolean | undefined;
28
- supportsNativeSegwit?: boolean | undefined;
29
- isTestnetFor?: string | undefined;
30
- bitcoinLikeInfo?: import("@ledgerhq/types-cryptoassets").BitcoinLikeInfo | undefined;
31
- ethereumLikeInfo?: import("@ledgerhq/types-cryptoassets").EthereumLikeInfo | undefined;
32
- explorerViews: import("@ledgerhq/types-cryptoassets").ExplorerView[];
33
- terminated?: {
34
- link: string;
35
- } | undefined;
36
- deviceTicker?: string | undefined;
37
- explorerId?: import("@ledgerhq/types-cryptoassets").LedgerExplorerId | undefined;
38
- } | {
39
- leftElement: ReactNode;
40
- name: string;
41
- ticker: string;
42
- units: import("@ledgerhq/types-cryptoassets").Unit[];
43
- symbol?: string | undefined;
44
- disableCountervalue?: boolean | undefined;
45
- delisted?: boolean | undefined;
46
- keywords?: string[] | undefined;
47
- type: "TokenCurrency";
48
- id: string;
49
- ledgerSignature?: string | undefined;
50
- contractAddress: string;
51
- parentCurrency: import("@ledgerhq/types-cryptoassets").CryptoCurrency;
52
- tokenType: string;
53
- })[];
54
- //# sourceMappingURL=useLeftApy.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useLeftApy.d.ts","sourceRoot":"","sources":["../../../src/modularDrawer/hooks/useLeftApy.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,eAAO,MAAM,sBAAsB;yBAGZ;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,KAAK,SAAS;eAEnD,qBAAqB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IASxC,CAAC"}
@@ -1,15 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createUseLeftApyModule = void 0;
4
- const createUseLeftApyModule = ({ ApyIndicator, }) => {
5
- return (assets) => {
6
- const value = 5.11; // TODO: fetch DADA
7
- const type = "APY"; // TODO: fetch DADA
8
- return assets.map(asset => ({
9
- ...asset,
10
- leftElement: ApyIndicator({ value, type }),
11
- }));
12
- };
13
- };
14
- exports.createUseLeftApyModule = createUseLeftApyModule;
15
- //# sourceMappingURL=useLeftApy.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useLeftApy.js","sourceRoot":"","sources":["../../../src/modularDrawer/hooks/useLeftApy.tsx"],"names":[],"mappings":";;;AAIO,MAAM,sBAAsB,GAAG,CAAC,EACrC,YAAY,GAGb,EAAE,EAAE;IACH,OAAO,CAAC,MAA+B,EAAE,EAAE;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,mBAAmB;QACvC,MAAM,IAAI,GAAY,KAAK,CAAC,CAAC,mBAAmB;QAEhD,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC1B,GAAG,KAAK;YACR,WAAW,EAAE,YAAY,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;SAC3C,CAAC,CAAC,CAAC;IACN,CAAC,CAAC;AACJ,CAAC,CAAC;AAdW,QAAA,sBAAsB,0BAcjC"}