From 206dc965faf7de2bc47a2d05a847d3defc74520b Mon Sep 17 00:00:00 2001
From: Ostap Piatkovskyi <44294945+ost-ptk@users.noreply.github.com>
Date: Thu, 14 Nov 2024 20:00:09 +0200
Subject: [PATCH] fix: fix account balances fetching (#1068)
* update account balances fetching
* fix issues with balances and update playwright
---
package-lock.json | 62 ++++----
package.json | 4 +-
src/apps/onboarding/index.tsx | 10 +-
.../select-accounts-to-recover/content.tsx | 36 +----
.../select-accounts-to-recover/index.tsx | 95 +++++--------
src/apps/popup/pages/all-accounts/content.tsx | 14 ++
src/apps/popup/pages/buy-cspr/country.tsx | 12 +-
.../components/account-list-item.tsx | 38 +++--
.../pages/download-account-keys/download.tsx | 31 +++-
.../components/account-balance/amount-bar.tsx | 29 ++--
.../components/account-balance/amount-row.tsx | 45 ++----
.../home/components/account-balance/index.tsx | 42 +++---
.../connected-ledger.tsx | 69 +++------
.../pages/import-account-from-ledger/types.ts | 4 +-
src/apps/popup/pages/receive/content.tsx | 14 +-
src/apps/popup/pages/stakes/amount-step.tsx | 32 ++---
src/apps/popup/pages/stakes/confirm-step.tsx | 16 ++-
src/apps/popup/pages/stakes/index.tsx | 10 +-
src/apps/popup/pages/transfer-nft/index.tsx | 11 +-
.../popup/pages/transfer-nft/review-step.tsx | 8 +-
src/apps/popup/pages/transfer/amount-step.tsx | 29 ++--
.../popup/pages/transfer/confirm-step.tsx | 25 ++--
src/apps/popup/pages/transfer/index.tsx | 2 +-
src/apps/popup/pages/transfer/token-step.tsx | 4 +-
src/background/index.ts | 62 --------
.../redux/account-balances/actions.ts | 11 --
.../redux/account-balances/reducer.ts | 13 --
.../redux/account-balances/selectors.ts | 4 -
.../redux/account-balances/types.ts | 3 -
src/background/redux/account-info/actions.ts | 9 --
src/background/redux/account-info/reducer.ts | 21 ---
.../redux/account-info/selectors.ts | 6 -
src/background/redux/account-info/types.ts | 3 -
src/background/redux/get-main-store.ts | 1 -
src/background/redux/redux-action.ts | 2 -
src/background/redux/root-reducer.ts | 2 -
src/background/redux/sagas/vault-sagas.ts | 2 -
src/background/redux/types.d.ts | 2 -
src/background/redux/vault/selectors.ts | 64 +++------
src/background/service-message.ts | 20 ---
src/background/wallet-repositories.ts | 5 +-
src/fixtures/initial-state-for-popup-tests.ts | 9 --
src/hooks/use-casper-token.ts | 42 ++----
src/hooks/use-fetch-account-balances.ts | 60 --------
src/hooks/use-fetch-active-account-balance.ts | 93 ------------
.../layout/header/header-data-updater.tsx | 7 +-
.../header/header-submenu-bar-nav-link.tsx | 28 ++--
.../balance-service/balance-service.ts | 132 ------------------
.../services/balance-service/constants.ts | 28 +---
src/libs/services/balance-service/index.ts | 5 +-
src/libs/services/balance-service/queries.ts | 68 +++++++++
src/libs/services/balance-service/types.ts | 25 ----
.../use-fetch-accounts-balances.ts | 28 ++++
.../use-fetch-wallet-balance.ts | 123 ++++++++++++++++
src/libs/services/deployer-service/index.ts | 8 +-
src/libs/types/account.ts | 8 +-
.../account-list/account-list-item.tsx | 19 +--
.../components/account-list/account-list.tsx | 8 ++
src/libs/ui/components/account-list/utils.ts | 4 +-
.../active-account-plate.tsx | 8 +-
.../dynamic-accounts-list-with-select.tsx | 28 ++--
.../components/my-accounts-list.tsx | 4 +-
.../transaction-fee-plate.tsx | 8 +-
src/libs/ui/forms/create-account.ts | 4 +-
src/libs/ui/forms/form-validation-rules.ts | 25 ++--
src/libs/ui/forms/stakes-form.ts | 2 +-
src/libs/ui/forms/transfer-nft.ts | 2 +-
src/libs/ui/forms/transfer.ts | 2 +-
68 files changed, 636 insertions(+), 1014 deletions(-)
delete mode 100644 src/background/redux/account-balances/actions.ts
delete mode 100644 src/background/redux/account-balances/reducer.ts
delete mode 100644 src/background/redux/account-balances/selectors.ts
delete mode 100644 src/background/redux/account-balances/types.ts
delete mode 100644 src/hooks/use-fetch-account-balances.ts
delete mode 100644 src/hooks/use-fetch-active-account-balance.ts
delete mode 100644 src/libs/services/balance-service/balance-service.ts
create mode 100644 src/libs/services/balance-service/queries.ts
delete mode 100644 src/libs/services/balance-service/types.ts
create mode 100644 src/libs/services/balance-service/use-fetch-accounts-balances.ts
create mode 100644 src/libs/services/balance-service/use-fetch-wallet-balance.ts
diff --git a/package-lock.json b/package-lock.json
index b06431668..e59c9331c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -28,7 +28,7 @@
"big.js": "^6.2.1",
"casper-cep18-js-client": "1.0.2",
"casper-js-sdk": "2.15.4",
- "casper-wallet-core": "git+ssh://git@github.com:make-software/casper-wallet-core.git#v0.9.5",
+ "casper-wallet-core": "git+ssh://git@github.com:make-software/casper-wallet-core.git#v0.9.6",
"date-fns": "^2.30.0",
"i18next": "^23.11.0",
"i18next-browser-languagedetector": "^7.2.1",
@@ -66,7 +66,7 @@
"@babel/preset-env": "7.23.2",
"@babel/preset-react": "7.18.6",
"@babel/preset-typescript": "^7.23.3",
- "@playwright/test": "^1.39.0",
+ "@playwright/test": "^1.47.2",
"@redux-devtools/cli": "^4.0.0",
"@redux-devtools/remote": "^0.9.3",
"@testing-library/dom": "9.3.4",
@@ -4996,18 +4996,18 @@
"dev": true
},
"node_modules/@playwright/test": {
- "version": "1.39.0",
- "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.39.0.tgz",
- "integrity": "sha512-3u1iFqgzl7zr004bGPYiN/5EZpRUSFddQBra8Rqll5N0/vfpqlP9I9EXqAoGacuAbX6c9Ulg/Cjqglp5VkK6UQ==",
+ "version": "1.47.2",
+ "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.47.2.tgz",
+ "integrity": "sha512-jTXRsoSPONAs8Za9QEQdyjFn+0ZQFjCiIztAIF6bi1HqhBzG9Ma7g1WotyiGqFSBRZjIEqMdT8RUlbk1QVhzCQ==",
"dev": true,
"dependencies": {
- "playwright": "1.39.0"
+ "playwright": "1.47.2"
},
"bin": {
"playwright": "cli.js"
},
"engines": {
- "node": ">=16"
+ "node": ">=18"
}
},
"node_modules/@pnpm/network.ca-file": {
@@ -10601,8 +10601,8 @@
},
"node_modules/casper-wallet-core": {
"name": "CasperWalletCore",
- "version": "0.9.5",
- "resolved": "git+ssh://git@github.com/make-software/casper-wallet-core.git#9d91ccbec58b1bd5c94a6d5dd658503a2fa1ce4c",
+ "version": "0.9.6",
+ "resolved": "git+ssh://git@github.com/make-software/casper-wallet-core.git#cef8e4ffb029396095993f020d19d472db3c4d02",
"dependencies": {
"@make-software/ces-js-parser": "^1.3.3",
"@react-native/typescript-config": "0.74.83",
@@ -23711,33 +23711,33 @@
}
},
"node_modules/playwright": {
- "version": "1.39.0",
- "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.39.0.tgz",
- "integrity": "sha512-naE5QT11uC/Oiq0BwZ50gDmy8c8WLPRTEWuSSFVG2egBka/1qMoSqYQcROMT9zLwJ86oPofcTH2jBY/5wWOgIw==",
+ "version": "1.47.2",
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.47.2.tgz",
+ "integrity": "sha512-nx1cLMmQWqmA3UsnjaaokyoUpdVaaDhJhMoxX2qj3McpjnsqFHs516QAKYhqHAgOP+oCFTEOCOAaD1RgD/RQfA==",
"dev": true,
"dependencies": {
- "playwright-core": "1.39.0"
+ "playwright-core": "1.47.2"
},
"bin": {
"playwright": "cli.js"
},
"engines": {
- "node": ">=16"
+ "node": ">=18"
},
"optionalDependencies": {
"fsevents": "2.3.2"
}
},
"node_modules/playwright-core": {
- "version": "1.39.0",
- "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.39.0.tgz",
- "integrity": "sha512-+k4pdZgs1qiM+OUkSjx96YiKsXsmb59evFoqv8SKO067qBA+Z2s/dCzJij/ZhdQcs2zlTAgRKfeiiLm8PQ2qvw==",
+ "version": "1.47.2",
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.47.2.tgz",
+ "integrity": "sha512-3JvMfF+9LJfe16l7AbSmU555PaTl2tPyQsVInqm3id16pdDfvZ8TTZ/pyzmkbDrZTQefyzU7AIHlZqQnxpqHVQ==",
"dev": true,
"bin": {
"playwright-core": "cli.js"
},
"engines": {
- "node": ">=16"
+ "node": ">=18"
}
},
"node_modules/possible-typed-array-names": {
@@ -33328,12 +33328,12 @@
}
},
"@playwright/test": {
- "version": "1.39.0",
- "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.39.0.tgz",
- "integrity": "sha512-3u1iFqgzl7zr004bGPYiN/5EZpRUSFddQBra8Rqll5N0/vfpqlP9I9EXqAoGacuAbX6c9Ulg/Cjqglp5VkK6UQ==",
+ "version": "1.47.2",
+ "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.47.2.tgz",
+ "integrity": "sha512-jTXRsoSPONAs8Za9QEQdyjFn+0ZQFjCiIztAIF6bi1HqhBzG9Ma7g1WotyiGqFSBRZjIEqMdT8RUlbk1QVhzCQ==",
"dev": true,
"requires": {
- "playwright": "1.39.0"
+ "playwright": "1.47.2"
}
},
"@pnpm/network.ca-file": {
@@ -37770,8 +37770,8 @@
}
},
"casper-wallet-core": {
- "version": "git+ssh://git@github.com/make-software/casper-wallet-core.git#9d91ccbec58b1bd5c94a6d5dd658503a2fa1ce4c",
- "from": "casper-wallet-core@git+ssh://git@github.com:make-software/casper-wallet-core.git#v0.9.5",
+ "version": "git+ssh://git@github.com/make-software/casper-wallet-core.git#cef8e4ffb029396095993f020d19d472db3c4d02",
+ "from": "casper-wallet-core@git+ssh://git@github.com:make-software/casper-wallet-core.git#v0.9.6",
"requires": {
"@make-software/ces-js-parser": "^1.3.3",
"@react-native/typescript-config": "0.74.83",
@@ -47536,19 +47536,19 @@
}
},
"playwright": {
- "version": "1.39.0",
- "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.39.0.tgz",
- "integrity": "sha512-naE5QT11uC/Oiq0BwZ50gDmy8c8WLPRTEWuSSFVG2egBka/1qMoSqYQcROMT9zLwJ86oPofcTH2jBY/5wWOgIw==",
+ "version": "1.47.2",
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.47.2.tgz",
+ "integrity": "sha512-nx1cLMmQWqmA3UsnjaaokyoUpdVaaDhJhMoxX2qj3McpjnsqFHs516QAKYhqHAgOP+oCFTEOCOAaD1RgD/RQfA==",
"dev": true,
"requires": {
"fsevents": "2.3.2",
- "playwright-core": "1.39.0"
+ "playwright-core": "1.47.2"
}
},
"playwright-core": {
- "version": "1.39.0",
- "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.39.0.tgz",
- "integrity": "sha512-+k4pdZgs1qiM+OUkSjx96YiKsXsmb59evFoqv8SKO067qBA+Z2s/dCzJij/ZhdQcs2zlTAgRKfeiiLm8PQ2qvw==",
+ "version": "1.47.2",
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.47.2.tgz",
+ "integrity": "sha512-3JvMfF+9LJfe16l7AbSmU555PaTl2tPyQsVInqm3id16pdDfvZ8TTZ/pyzmkbDrZTQefyzU7AIHlZqQnxpqHVQ==",
"dev": true
},
"possible-typed-array-names": {
diff --git a/package.json b/package.json
index a65352a24..54646437b 100644
--- a/package.json
+++ b/package.json
@@ -72,7 +72,7 @@
"big.js": "^6.2.1",
"casper-cep18-js-client": "1.0.2",
"casper-js-sdk": "2.15.4",
- "casper-wallet-core": "git+ssh://git@github.com:make-software/casper-wallet-core.git#v0.9.5",
+ "casper-wallet-core": "git+ssh://git@github.com:make-software/casper-wallet-core.git#v0.9.6",
"date-fns": "^2.30.0",
"i18next": "^23.11.0",
"i18next-browser-languagedetector": "^7.2.1",
@@ -110,7 +110,7 @@
"@babel/preset-env": "7.23.2",
"@babel/preset-react": "7.18.6",
"@babel/preset-typescript": "^7.23.3",
- "@playwright/test": "^1.39.0",
+ "@playwright/test": "^1.47.2",
"@redux-devtools/cli": "^4.0.0",
"@redux-devtools/remote": "^0.9.3",
"@testing-library/dom": "9.3.4",
diff --git a/src/apps/onboarding/index.tsx b/src/apps/onboarding/index.tsx
index a245e07ac..6775baf4f 100644
--- a/src/apps/onboarding/index.tsx
+++ b/src/apps/onboarding/index.tsx
@@ -1,3 +1,4 @@
+import { QueryClientProvider } from '@tanstack/react-query';
import React, { Suspense, useState } from 'react';
import { createRoot } from 'react-dom/client';
import { Provider as ReduxProvider } from 'react-redux';
@@ -14,6 +15,7 @@ import { onboardingAppInit } from '@background/redux/windowManagement/actions';
import '@libs/i18n/i18n';
import { ErrorBoundary } from '@libs/layout';
+import { newQueryClient } from '@libs/services/query-client';
import { GlobalStyle, lightTheme } from '@libs/ui';
const Tree = () => {
@@ -37,9 +39,11 @@ const Tree = () => {
-
-
-
+
+
+
+
+
diff --git a/src/apps/onboarding/pages/select-accounts-to-recover/content.tsx b/src/apps/onboarding/pages/select-accounts-to-recover/content.tsx
index d80b0b79b..d0384d4de 100644
--- a/src/apps/onboarding/pages/select-accounts-to-recover/content.tsx
+++ b/src/apps/onboarding/pages/select-accounts-to-recover/content.tsx
@@ -1,5 +1,5 @@
import { Player } from '@lottiefiles/react-lottie-player';
-import React, { SetStateAction } from 'react';
+import React from 'react';
import { Trans, useTranslation } from 'react-i18next';
import styled from 'styled-components';
@@ -13,12 +13,7 @@ import {
TabPageContainer,
VerticalSpaceContainer
} from '@libs/layout';
-import { AccountListRows } from '@libs/types/account';
-import {
- DynamicAccountsListWithSelect,
- Tile,
- Typography
-} from '@libs/ui/components';
+import { Tile, Typography } from '@libs/ui/components';
const AnimationContainer = styled(CenteredFlexColumn)`
padding: 106px 16px;
@@ -26,24 +21,12 @@ const AnimationContainer = styled(CenteredFlexColumn)`
interface SelectAccountsToRecoverContentProps {
isLoading: boolean;
- derivedAccountsWithBalance: AccountListRows[];
- isLoadingMore: boolean;
- onLoadMore: () => void;
- maxItemsToRender: number;
- setSelectedAccounts: React.Dispatch>;
- selectedAccounts: AccountListRows[];
- setIsButtonDisabled: React.Dispatch>;
+ children: React.ReactNode;
}
export const SelectAccountsToRecoverContent = ({
isLoading,
- isLoadingMore,
- onLoadMore,
- derivedAccountsWithBalance,
- maxItemsToRender,
- setSelectedAccounts,
- selectedAccounts,
- setIsButtonDisabled
+ children
}: SelectAccountsToRecoverContentProps) => {
const { t } = useTranslation();
const isDarkMode = useIsDarkMode();
@@ -90,16 +73,7 @@ export const SelectAccountsToRecoverContent = ({
) : (
-
+ children
)}
);
diff --git a/src/apps/onboarding/pages/select-accounts-to-recover/index.tsx b/src/apps/onboarding/pages/select-accounts-to-recover/index.tsx
index ea1250ca7..12f364066 100644
--- a/src/apps/onboarding/pages/select-accounts-to-recover/index.tsx
+++ b/src/apps/onboarding/pages/select-accounts-to-recover/index.tsx
@@ -1,8 +1,5 @@
import React, { useEffect, useState } from 'react';
import { Trans, useTranslation } from 'react-i18next';
-import { useSelector } from 'react-redux';
-
-import { isEqualCaseInsensitive } from '@src/utils';
import { Stepper } from '@onboarding/components/stepper';
import { SelectAccountsToRecoverContent } from '@onboarding/pages/select-accounts-to-recover/content';
@@ -15,7 +12,6 @@ import {
import { closeActiveTab } from '@onboarding/utils/close-active-tab';
import { recoverVault } from '@background/redux/sagas/actions';
-import { selectApiConfigBasedOnActiveNetwork } from '@background/redux/settings/selectors';
import { dispatchToMainStore } from '@background/redux/utils';
import { getAccountHashFromPublicKey } from '@libs/entities/Account';
@@ -25,9 +21,9 @@ import {
TabFooterContainer,
TabHeaderContainer
} from '@libs/layout';
-import { dispatchFetchAccountBalances } from '@libs/services/balance-service';
+import { useFetchAccountsBalances } from '@libs/services/balance-service';
import { Account, AccountListRows, KeyPair } from '@libs/types/account';
-import { Button } from '@libs/ui/components';
+import { Button, DynamicAccountsListWithSelect } from '@libs/ui/components';
export const SelectAccountsToRecoverPage = () => {
const [derivedAccounts, setDerivedAccounts] = useState([]);
@@ -47,10 +43,6 @@ export const SelectAccountsToRecoverPage = () => {
const { t } = useTranslation();
const location = useTypedLocation();
- const { casperWalletApiUrl } = useSelector(
- selectApiConfigBasedOnActiveNetwork
- );
-
useEffect(() => {
if (location.state?.secretPhrase) {
const keyPairs = getKeyPairList({
@@ -63,49 +55,31 @@ export const SelectAccountsToRecoverPage = () => {
}
}, [location.state?.secretPhrase, setDerivedAccounts]);
- useEffect(() => {
- if (!derivedAccounts.length) return;
+ const accountHashes = derivedAccounts.map(account =>
+ getAccountHashFromPublicKey(account.publicKey)
+ );
- const hashes = derivedAccounts.reduce(
- (previousValue, currentValue, currentIndex) => {
- const hash = getAccountHashFromPublicKey(currentValue.publicKey);
+ const { accountsBalances, isLoadingBalances } =
+ useFetchAccountsBalances(accountHashes);
- return derivedAccounts.length === currentIndex + 1
- ? previousValue + `${hash}`
- : previousValue + `${hash},`;
- },
- ''
+ useEffect(() => {
+ if (!derivedAccounts.length || isLoadingBalances) return;
+
+ const derivedAccountsWithBalance: AccountListRows[] = derivedAccounts.map(
+ (account, index) => ({
+ ...account,
+ id: account.publicKey,
+ hidden: false,
+ derivationIndex: index,
+ name: ''
+ })
);
- dispatchFetchAccountBalances(hashes)
- .then(({ payload }) => {
- if ('data' in payload) {
- const derivedAccountsWithBalance: AccountListRows[] =
- derivedAccounts.map((account, index) => {
- const accountWithBalance = payload.data.find(ac =>
- isEqualCaseInsensitive(ac.public_key, account.publicKey)
- );
-
- return {
- ...account,
- id: account.publicKey,
- hidden: false,
- derivationIndex: index,
- name: '',
- balance: {
- liquidMotes: `${accountWithBalance?.balance ?? '0'}`
- }
- };
- });
-
- setDerivedAccountsWithBalance(derivedAccountsWithBalance);
- }
- })
- .finally(() => {
- setIsLoading(false);
- setIsLoadingMore(false);
- });
- }, [derivedAccounts, casperWalletApiUrl]);
+ setDerivedAccountsWithBalance(derivedAccountsWithBalance);
+
+ setIsLoading(false);
+ setIsLoadingMore(false);
+ }, [accountsBalances, derivedAccounts, isLoadingBalances]);
const onLoadMore = () => {
try {
@@ -156,16 +130,19 @@ export const SelectAccountsToRecoverPage = () => {
)}
renderContent={() => (
-
+
+
+
)}
renderFooter={() => (
diff --git a/src/apps/popup/pages/all-accounts/content.tsx b/src/apps/popup/pages/all-accounts/content.tsx
index 9898508c8..6155aa316 100644
--- a/src/apps/popup/pages/all-accounts/content.tsx
+++ b/src/apps/popup/pages/all-accounts/content.tsx
@@ -13,6 +13,7 @@ import {
import { getAccountHashFromPublicKey } from '@libs/entities/Account';
import { ContentContainer, SpacingSize } from '@libs/layout';
import { useFetchAccountsInfo } from '@libs/services/account-info';
+import { useFetchWalletBalance } from '@libs/services/balance-service';
import {
AccountListRowWithAccountHash,
AccountListRows
@@ -39,6 +40,7 @@ export const AllAccountsContent = () => {
const accountsPublicKeys = useSelector(selectVaultAccountsPublicKeys);
const accountsInfo = useFetchAccountsInfo(accountsPublicKeys);
+ const { accountsBalances, isLoadingBalance } = useFetchWalletBalance();
useEffect(() => {
const visibleAccountListRows = sortAccounts(
@@ -79,6 +81,10 @@ export const AllAccountsContent = () => {
const isConnected = connectedAccountNames.includes(account.name);
const isActiveAccount = activeAccountName === account.name;
+ const accountLiquidBalance =
+ accountsBalances &&
+ accountsBalances[account.accountHash]?.liquidBalance;
+
return (
{
isConnected={isConnected}
showHideAccountItem
accountsInfo={accountsInfo}
+ accountLiquidBalance={accountLiquidBalance}
+ isLoadingBalance={isLoadingBalance}
/>
);
}}
@@ -100,6 +108,10 @@ export const AllAccountsContent = () => {
renderRow={account => {
const isConnected = connectedAccountNames.includes(account.name);
+ const accountLiquidBalance =
+ accountsBalances &&
+ accountsBalances[account.accountHash]?.liquidBalance;
+
return (
{
isConnected={isConnected}
showHideAccountItem
accountsInfo={accountsInfo}
+ accountLiquidBalance={accountLiquidBalance}
+ isLoadingBalance={isLoadingBalance}
/>
);
}}
diff --git a/src/apps/popup/pages/buy-cspr/country.tsx b/src/apps/popup/pages/buy-cspr/country.tsx
index 7bf564501..87cb8c7d1 100644
--- a/src/apps/popup/pages/buy-cspr/country.tsx
+++ b/src/apps/popup/pages/buy-cspr/country.tsx
@@ -1,9 +1,6 @@
import React, { useEffect, useState } from 'react';
import { useForm, useWatch } from 'react-hook-form';
import { Trans, useTranslation } from 'react-i18next';
-import { useSelector } from 'react-redux';
-
-import { selectAccountBalance } from '@background/redux/account-info/selectors';
import {
ContentContainer,
@@ -11,6 +8,7 @@ import {
ParagraphContainer,
SpacingSize
} from '@libs/layout';
+import { useFetchWalletBalance } from '@libs/services/balance-service';
import { ResponseCountryPropsWithId } from '@libs/services/buy-cspr-service/types';
import {
ActiveAccountPlate,
@@ -21,7 +19,6 @@ import {
SvgIcon,
Typography
} from '@libs/ui/components';
-import { motesToCSPR } from '@libs/ui/utils';
import { CountryRow } from './components/country-row';
import { ListRow } from './components/list-row';
@@ -45,10 +42,7 @@ export const Country = ({
>([]);
const { t } = useTranslation();
- const csprBalance = useSelector(selectAccountBalance);
-
- const balance =
- csprBalance.liquidMotes && motesToCSPR(csprBalance.liquidMotes);
+ const { accountBalance } = useFetchWalletBalance();
const { register, control, setValue } = useForm();
@@ -79,7 +73,7 @@ export const Country = ({
diff --git a/src/apps/popup/pages/download-account-keys/components/account-list-item.tsx b/src/apps/popup/pages/download-account-keys/components/account-list-item.tsx
index 39ea860d3..29300b1e3 100644
--- a/src/apps/popup/pages/download-account-keys/components/account-list-item.tsx
+++ b/src/apps/popup/pages/download-account-keys/components/account-list-item.tsx
@@ -1,3 +1,4 @@
+import { IAccountInfo } from 'casper-wallet-core/src/domain/accountInfo';
import React from 'react';
import styled from 'styled-components';
@@ -6,7 +7,11 @@ import {
FlexColumn,
SpacingSize
} from '@libs/layout';
-import { AccountListRows, HardwareWalletType } from '@libs/types/account';
+import {
+ AccountListRowWithAccountHash,
+ AccountListRows,
+ HardwareWalletType
+} from '@libs/types/account';
import {
Avatar,
Checkbox,
@@ -37,11 +42,13 @@ const AccountName = styled(Typography)`
`;
interface AccountListItemProps {
- account: AccountListRows;
+ account: AccountListRowWithAccountHash;
onClick: (event: React.MouseEvent) => void;
isConnected: boolean;
isActiveAccount: boolean;
isSelected?: boolean;
+ accountsInfo: Record | undefined;
+ accountLiquidBalance: string | undefined;
}
export const AccountListItem = ({
@@ -49,14 +56,19 @@ export const AccountListItem = ({
onClick,
isActiveAccount,
isConnected,
- isSelected
+ isSelected,
+ accountsInfo,
+ accountLiquidBalance
}: AccountListItemProps) => {
- const accountBalance =
- account.balance?.liquidMotes != null
- ? formatNumber(motesToCSPR(account.balance.liquidMotes), {
- precision: { max: 0 }
- })
- : '-';
+ const accountBalance = accountLiquidBalance
+ ? formatNumber(motesToCSPR(accountLiquidBalance), {
+ precision: { max: 0 }
+ })
+ : '0';
+
+ const csprName = accountsInfo && accountsInfo[account.accountHash]?.csprName;
+ const brandingLogo =
+ accountsInfo && accountsInfo[account.accountHash]?.brandingLogo;
return (
@@ -68,23 +80,21 @@ export const AccountListItem = ({
isConnected={isConnected}
displayContext="accountList"
isActiveAccount={isActiveAccount}
+ brandingLogo={brandingLogo}
/>
{account.name}
-
+
{accountBalance}
{
- const [accountsWithId, setAccountsWithId] = useState([]);
+ const [accountsWithId, setAccountsWithId] = useState<
+ AccountListRowWithAccountHash[]
+ >([]);
const { t } = useTranslation();
- // TODO: update this when the ledger feature is ready, to not allow the download of the ledger accounts
- const accounts = useSelector(selectVaultAccountsWithBalances);
+ const accounts = useSelector(selectVaultAccountsExceptLedgersAccounts);
const connectedAccountNames =
useSelector(selectConnectedAccountNamesWithActiveOrigin) || [];
const activeAccountName = useSelector(selectVaultActiveAccountName);
+ const accountsPublicKeys = useSelector(selectVaultAccountsPublicKeys);
+
+ const accountsInfo = useFetchAccountsInfo(accountsPublicKeys);
+ const { accountsBalances } = useFetchWalletBalance();
useEffect(() => {
const accountsWithId = accounts.map(account => ({
...account,
- id: account.name
+ id: account.name,
+ accountHash: getAccountHashFromPublicKey(account.publicKey)
}));
setAccountsWithId(accountsWithId);
@@ -99,6 +112,10 @@ export const Download = ({
const isSelected =
selectedAccounts.findIndex(acc => acc.id === account.id) !== -1;
+ const accountLiquidBalance =
+ accountsBalances &&
+ accountsBalances[account.accountHash]?.liquidBalance;
+
return (
toggleAccount(account)}
isSelected={isSelected}
+ accountLiquidBalance={accountLiquidBalance}
+ accountsInfo={accountsInfo}
/>
);
}}
diff --git a/src/apps/popup/pages/home/components/account-balance/amount-bar.tsx b/src/apps/popup/pages/home/components/account-balance/amount-bar.tsx
index 63b859651..a0c557062 100644
--- a/src/apps/popup/pages/home/components/account-balance/amount-bar.tsx
+++ b/src/apps/popup/pages/home/components/account-balance/amount-bar.tsx
@@ -1,10 +1,8 @@
import React, { useMemo } from 'react';
-import { useSelector } from 'react-redux';
import styled from 'styled-components';
-import { selectAccountBalance } from '@background/redux/account-info/selectors';
-
import { FlexRow, SpacingSize } from '@libs/layout';
+import { useFetchWalletBalance } from '@libs/services/balance-service';
import { ContentColor, getColorFromTheme, motesToCSPR } from '@libs/ui/utils';
const Container = styled(FlexRow)`
@@ -20,8 +18,8 @@ const Filled = styled.div<{ filledWidth: number; color: ContentColor }>`
`;
function calculateLiquidPercentage(
- amountMotes: string | null,
- fullBalanceMotes: string | null
+ amountMotes: string | undefined,
+ fullBalanceMotes: string | undefined
) {
if (amountMotes != null && fullBalanceMotes != null) {
const current = Number(motesToCSPR(amountMotes));
@@ -34,28 +32,31 @@ function calculateLiquidPercentage(
}
export const AmountBar = () => {
- const balance = useSelector(selectAccountBalance);
+ const { accountBalance } = useFetchWalletBalance();
const liquidPercentage = useMemo(
() =>
- calculateLiquidPercentage(balance.liquidMotes, balance.totalBalanceMotes),
- [balance.liquidMotes, balance.totalBalanceMotes]
+ calculateLiquidPercentage(
+ accountBalance.liquidBalance,
+ accountBalance.totalBalance
+ ),
+ [accountBalance.liquidBalance, accountBalance.totalBalance]
);
const delegatedPercentage = useMemo(
() =>
calculateLiquidPercentage(
- balance.delegatedMotes,
- balance.totalBalanceMotes
+ accountBalance.delegatedBalance,
+ accountBalance.totalBalance
),
- [balance.delegatedMotes, balance.totalBalanceMotes]
+ [accountBalance.delegatedBalance, accountBalance.totalBalance]
);
const undelegatingPercentage = useMemo(
() =>
calculateLiquidPercentage(
- balance.undelegatingMotes,
- balance.totalBalanceMotes
+ accountBalance.undelegatingBalance,
+ accountBalance.totalBalance
),
- [balance.undelegatingMotes, balance.totalBalanceMotes]
+ [accountBalance.undelegatingBalance, accountBalance.totalBalance]
);
return (
diff --git a/src/apps/popup/pages/home/components/account-balance/amount-row.tsx b/src/apps/popup/pages/home/components/account-balance/amount-row.tsx
index 9160dbb50..410c4afeb 100644
--- a/src/apps/popup/pages/home/components/account-balance/amount-row.tsx
+++ b/src/apps/popup/pages/home/components/account-balance/amount-row.tsx
@@ -1,61 +1,42 @@
import React from 'react';
import { Trans, useTranslation } from 'react-i18next';
-import { useSelector } from 'react-redux';
-
-import { selectAccountCurrencyRate } from '@background/redux/account-info/selectors';
import { AlignedSpaceBetweenFlexRow, FlexRow, SpacingSize } from '@libs/layout';
import { Typography } from '@libs/ui/components';
-import {
- ContentColor,
- formatCurrency,
- formatNumber,
- motesToCSPR,
- motesToCurrency
-} from '@libs/ui/utils';
+import { ContentColor } from '@libs/ui/utils';
interface AmountRowProps {
text: string;
- amountMotes: string | null;
+ fiatAmount: string | undefined;
+ amountFormattedDecimalBalance: string | undefined;
color: ContentColor;
showFiatAmounts: boolean;
}
export const AmountRow = ({
text,
- amountMotes,
+ fiatAmount,
+ amountFormattedDecimalBalance,
color,
showFiatAmounts
}: AmountRowProps) => {
const { t } = useTranslation();
- const currencyRate = useSelector(selectAccountCurrencyRate);
-
- const fiatAmount =
- currencyRate != null && amountMotes != null
- ? formatCurrency(
- motesToCurrency(String(amountMotes), currencyRate),
- 'USD',
- {
- precision: 2
- }
- )
- : '';
-
return (
{text}
{showFiatAmounts ? (
- {fiatAmount}
+
+ {fiatAmount}
+
) : (
-
- {amountMotes == null
- ? '-'
- : formatNumber(motesToCSPR(amountMotes), {
- precision: { max: 5 }
- })}
+
+ {amountFormattedDecimalBalance}
CSPR
diff --git a/src/apps/popup/pages/home/components/account-balance/index.tsx b/src/apps/popup/pages/home/components/account-balance/index.tsx
index ddc5dd09a..89cdf5a1b 100644
--- a/src/apps/popup/pages/home/components/account-balance/index.tsx
+++ b/src/apps/popup/pages/home/components/account-balance/index.tsx
@@ -1,13 +1,10 @@
import React, { useState } from 'react';
import { Trans, useTranslation } from 'react-i18next';
-import { useSelector } from 'react-redux';
import styled from 'styled-components';
-import { selectAccountBalance } from '@background/redux/account-info/selectors';
-
import { FlexColumn, FlexRow, SpacingSize } from '@libs/layout';
+import { useFetchWalletBalance } from '@libs/services/balance-service';
import { Typography, getFontSizeBasedOnTextLength } from '@libs/ui/components';
-import { formatNumber, motesToCSPR } from '@libs/ui/utils';
import { AmountBar } from './amount-bar';
import { AmountRow } from './amount-row';
@@ -20,7 +17,7 @@ export const AccountBalance = () => {
const [showFiatAmounts, setShowFiatAmounts] = useState(false);
const { t } = useTranslation();
- const balance = useSelector(selectAccountBalance);
+ const { accountBalance } = useFetchWalletBalance();
return (
@@ -28,30 +25,26 @@ export const AccountBalance = () => {
Total balance ยท
- {balance.totalBalanceFiat}
+ {accountBalance.totalFormattedFiatBalance}
- {balance.totalBalanceMotes == null
- ? '-'
- : formatNumber(motesToCSPR(balance.totalBalanceMotes), {
- precision: { max: 5 }
- })}
+ {accountBalance?.totalFormattedDecimalBalance}
CSPR
@@ -67,21 +60,30 @@ export const AccountBalance = () => {
>
- {balance.undelegatingMotes !== '0' &&
- balance.undelegatingMotes != null && (
+ {accountBalance?.undelegatingBalance &&
+ accountBalance?.undelegatingBalance !== '0' && (
diff --git a/src/apps/popup/pages/import-account-from-ledger/connected-ledger.tsx b/src/apps/popup/pages/import-account-from-ledger/connected-ledger.tsx
index b08952d8a..2b83073be 100644
--- a/src/apps/popup/pages/import-account-from-ledger/connected-ledger.tsx
+++ b/src/apps/popup/pages/import-account-from-ledger/connected-ledger.tsx
@@ -1,14 +1,10 @@
import { Player } from '@lottiefiles/react-lottie-player';
import React, { useEffect, useState } from 'react';
import { Trans, useTranslation } from 'react-i18next';
-import { useSelector } from 'react-redux';
import styled from 'styled-components';
-import { isEqualCaseInsensitive } from '@src/utils';
-
import { RouterPath, useTypedNavigate } from '@popup/router';
-import { selectApiConfigBasedOnActiveNetwork } from '@background/redux/settings/selectors';
import { dispatchToMainStore } from '@background/redux/utils';
import { accountsImported } from '@background/redux/vault/actions';
@@ -28,7 +24,7 @@ import {
SpacingSize,
VerticalSpaceContainer
} from '@libs/layout';
-import { dispatchFetchAccountBalances } from '@libs/services/balance-service';
+import { useFetchAccountsBalances } from '@libs/services/balance-service';
import {
LedgerAccount,
LedgerEventStatus,
@@ -73,10 +69,6 @@ export const ConnectedLedger: React.FC = ({
const navigate = useTypedNavigate();
const isDarkMode = useIsDarkMode();
- const { casperWalletApiUrl } = useSelector(
- selectApiConfigBasedOnActiveNetwork
- );
-
useEffect(() => {
ledger.getAccountList({ size: 5, offset: 0 });
}, []);
@@ -93,48 +85,30 @@ export const ConnectedLedger: React.FC = ({
return () => sub.unsubscribe();
}, []);
- useEffect(() => {
- if (!accountsFromLedger.length) return;
+ const accountHashes = accountsFromLedger.map(account =>
+ getAccountHashFromPublicKey(account.publicKey)
+ );
- const hashes = accountsFromLedger.reduce(
- (previousValue, currentValue, currentIndex) => {
- const hash = getAccountHashFromPublicKey(currentValue.publicKey);
+ const { accountsBalances, isLoadingBalances } =
+ useFetchAccountsBalances(accountHashes);
- return accountsFromLedger.length === currentIndex + 1
- ? previousValue + `${hash}`
- : previousValue + `${hash},`;
- },
- ''
+ useEffect(() => {
+ if (!accountsFromLedger.length || isLoadingBalances) return;
+
+ const accountsWithBalance = accountsFromLedger.map(
+ account => ({
+ publicKey: account.publicKey,
+ derivationIndex: account.index,
+ name: '',
+ id: account.publicKey
+ })
);
- dispatchFetchAccountBalances(hashes)
- .then(({ payload }) => {
- if ('data' in payload) {
- const accountsWithBalance =
- accountsFromLedger.map(account => {
- const accountWithBalance = payload.data.find(ac =>
- isEqualCaseInsensitive(ac.public_key, account.publicKey)
- );
-
- return {
- publicKey: account.publicKey,
- derivationIndex: account.index,
- name: '',
- id: account.publicKey,
- balance: {
- liquidMotes: `${accountWithBalance?.balance ?? '0'}`
- }
- };
- });
-
- setLedgerAccountsWithBalance(accountsWithBalance);
- }
- })
- .finally(() => {
- setIsLoading(false);
- setIsLoadingMore(false);
- });
- }, [casperWalletApiUrl, accountsFromLedger]);
+ setLedgerAccountsWithBalance(accountsWithBalance);
+
+ setIsLoading(false);
+ setIsLoadingMore(false);
+ }, [accountsBalances, accountsFromLedger, isLoadingBalances]);
const onSubmit = () => {
const accounts: Account[] = selectedAccounts.map(account => ({
@@ -232,6 +206,7 @@ export const ConnectedLedger: React.FC = ({
onLoadMore={onLoadMore}
isLoadingMore={isLoadingMore}
namePrefix="Ledger account"
+ accountsBalances={accountsBalances}
/>
)}
diff --git a/src/apps/popup/pages/import-account-from-ledger/types.ts b/src/apps/popup/pages/import-account-from-ledger/types.ts
index bae38cb3e..9bf6d14d0 100644
--- a/src/apps/popup/pages/import-account-from-ledger/types.ts
+++ b/src/apps/popup/pages/import-account-from-ledger/types.ts
@@ -1,6 +1,6 @@
-import { AccountWithBalance } from '@libs/types/account';
+import { Account } from '@libs/types/account';
export type ILedgerAccountListItem = Omit<
- AccountWithBalance,
+ Account,
'hidden' | 'secretKey' | 'imported' | 'hardware'
> & { id: string };
diff --git a/src/apps/popup/pages/receive/content.tsx b/src/apps/popup/pages/receive/content.tsx
index 55bd830b9..1aa80318a 100644
--- a/src/apps/popup/pages/receive/content.tsx
+++ b/src/apps/popup/pages/receive/content.tsx
@@ -7,10 +7,7 @@ import styled from 'styled-components';
import { formatErc20TokenBalance } from '@popup/pages/home/components/tokens-list/utils';
import { useTypedLocation } from '@popup/router';
-import {
- selectAccountBalance,
- selectErc20Tokens
-} from '@background/redux/account-info/selectors';
+import { selectErc20Tokens } from '@background/redux/account-info/selectors';
import { selectVaultActiveAccount } from '@background/redux/vault/selectors';
import { useCopyToClipboard } from '@hooks/use-copy-to-clipboard';
@@ -22,6 +19,7 @@ import {
SpacingSize,
VerticalSpaceContainer
} from '@libs/layout';
+import { useFetchWalletBalance } from '@libs/services/balance-service';
import { ActiveAccountPlate, Tile, Typography } from '@libs/ui/components';
import { motesToCSPR } from '@libs/ui/utils';
@@ -57,13 +55,15 @@ export const ReceivePageContent = () => {
symbol: location?.state?.tokenData?.symbol ?? ''
});
- const csprBalance = useSelector(selectAccountBalance, shallowEqual);
const tokens = useSelector(selectErc20Tokens, shallowEqual);
+ const { accountBalance } = useFetchWalletBalance();
+
useEffect(() => {
if (tokenData?.symbol === 'CSPR') {
const balance =
- (csprBalance.liquidMotes && motesToCSPR(csprBalance.liquidMotes)) ||
+ (accountBalance.liquidBalance &&
+ motesToCSPR(accountBalance.liquidBalance)) ||
'0';
setTokenData(prev => ({ ...prev, balance }));
} else {
@@ -72,7 +72,7 @@ export const ReceivePageContent = () => {
erc20Tokens?.find(t => t?.symbol === tokenData?.symbol)?.amount ?? '0';
setTokenData(prev => ({ ...prev, balance }));
}
- }, [csprBalance.liquidMotes, tokenData?.symbol, tokens]);
+ }, [accountBalance.liquidBalance, tokenData?.symbol, tokens]);
return (
diff --git a/src/apps/popup/pages/stakes/amount-step.tsx b/src/apps/popup/pages/stakes/amount-step.tsx
index 204dbe3e7..5ae05f39d 100644
--- a/src/apps/popup/pages/stakes/amount-step.tsx
+++ b/src/apps/popup/pages/stakes/amount-step.tsx
@@ -2,7 +2,6 @@ import Big from 'big.js';
import React, { useEffect, useState } from 'react';
import { UseFormReturn, useWatch } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
-import { useSelector } from 'react-redux';
import styled from 'styled-components';
import {
@@ -11,17 +10,13 @@ import {
STAKE_COST_MOTES
} from '@src/constants';
-import {
- selectAccountBalance,
- selectAccountCurrencyRate
-} from '@background/redux/account-info/selectors';
-
import {
AlignedFlexRow,
ParagraphContainer,
SpacingSize,
VerticalSpaceContainer
} from '@libs/layout';
+import { useFetchWalletBalance } from '@libs/services/balance-service';
import { Error, Input, Typography } from '@libs/ui/components';
import { StakeAmountFormValues } from '@libs/ui/forms/stakes-form';
import {
@@ -54,22 +49,20 @@ export const AmountStep = ({
const { t } = useTranslation();
- const currencyRate = useSelector(selectAccountCurrencyRate);
- const csprBalance = useSelector(selectAccountBalance);
+ const { accountBalance, currencyRate } = useFetchWalletBalance();
useEffect(() => {
switch (stakeType) {
case AuctionManagerEntryPoint.delegate: {
- const maxAmountMotes: string =
- csprBalance.liquidMotes == null
- ? '0'
- : Big(csprBalance.liquidMotes).sub(STAKE_COST_MOTES).toFixed();
+ const maxAmountMotes: string = !accountBalance.liquidBalance
+ ? '0'
+ : Big(accountBalance.liquidBalance).sub(STAKE_COST_MOTES).toFixed();
const minAmount = Big(STAKE_COST_MOTES)
.add(DELEGATION_MIN_AMOUNT_MOTES)
.toFixed();
const hasEnoughBalance =
- csprBalance.liquidMotes != null &&
- Big(csprBalance.liquidMotes).gte(minAmount);
+ accountBalance.liquidBalance &&
+ Big(accountBalance.liquidBalance).gte(minAmount);
setDisabled(!hasEnoughBalance);
@@ -79,14 +72,14 @@ export const AmountStep = ({
case AuctionManagerEntryPoint.undelegate:
case AuctionManagerEntryPoint.redelegate: {
const hasEnoughBalance =
- csprBalance.liquidMotes != null &&
- Big(csprBalance.liquidMotes).gte(STAKE_COST_MOTES);
+ accountBalance.liquidBalance &&
+ Big(accountBalance.liquidBalance).gte(STAKE_COST_MOTES);
setDisabled(!hasEnoughBalance);
setMaxAmountMotes(stakeAmountMotes);
}
}
- }, [csprBalance.liquidMotes, stakeAmountMotes, stakeType]);
+ }, [accountBalance.liquidBalance, stakeAmountMotes, stakeType]);
const {
register,
@@ -103,7 +96,10 @@ export const AmountStep = ({
const amountLabel = t('Amount');
- const fiatAmount = formatFiatAmount(amount || '0', currencyRate);
+ const fiatAmount = formatFiatAmount(
+ amount || '0',
+ currencyRate?.rate || null
+ );
return (
<>
diff --git a/src/apps/popup/pages/stakes/confirm-step.tsx b/src/apps/popup/pages/stakes/confirm-step.tsx
index c2aad3e22..11497a18f 100644
--- a/src/apps/popup/pages/stakes/confirm-step.tsx
+++ b/src/apps/popup/pages/stakes/confirm-step.tsx
@@ -1,13 +1,10 @@
import Big from 'big.js';
import React from 'react';
import { useTranslation } from 'react-i18next';
-import { useSelector } from 'react-redux';
import styled from 'styled-components';
import { AuctionManagerEntryPoint } from '@src/constants';
-import { selectAccountCurrencyRate } from '@background/redux/account-info/selectors';
-
import {
AmountContainer,
ParagraphContainer,
@@ -15,6 +12,7 @@ import {
SpacingSize,
VerticalSpaceContainer
} from '@libs/layout';
+import { useFetchWalletBalance } from '@libs/services/balance-service';
import { getAuctionManagerDeployCost } from '@libs/services/deployer-service';
import { ValidatorResult } from '@libs/services/validators-service/types';
import { List, Typography, ValidatorPlate } from '@libs/ui/components';
@@ -40,7 +38,7 @@ export const ConfirmStep = ({
}: ConfirmStepProps) => {
const { t } = useTranslation();
- const currencyRate = useSelector(selectAccountCurrencyRate);
+ const { currencyRate } = useFetchWalletBalance();
const transferFeeMotes = getAuctionManagerDeployCost(stakeType);
@@ -58,14 +56,18 @@ export const ConfirmStep = ({
amount: formatNumber(inputAmountCSPR, {
precision: { max: 5 }
}),
- fiatPrice: formatFiatAmount(inputAmountCSPR, currencyRate),
+ fiatPrice: formatFiatAmount(inputAmountCSPR, currencyRate?.rate || null),
symbol: 'CSPR'
},
{
id: 2,
text: t('Transaction fee'),
amount: transferCostInCSPR,
- fiatPrice: formatFiatAmount(transferCostInCSPR, currencyRate, 3),
+ fiatPrice: formatFiatAmount(
+ transferCostInCSPR,
+ currencyRate?.rate || null,
+ 3
+ ),
symbol: 'CSPR'
},
{
@@ -74,7 +76,7 @@ export const ConfirmStep = ({
amount: formatNumber(totalCSPR, {
precision: { max: 5 }
}),
- fiatPrice: formatFiatAmount(totalCSPR, currencyRate),
+ fiatPrice: formatFiatAmount(totalCSPR, currencyRate?.rate || null),
symbol: 'CSPR',
bold: true
}
diff --git a/src/apps/popup/pages/stakes/index.tsx b/src/apps/popup/pages/stakes/index.tsx
index bb1b32d65..3b485048f 100644
--- a/src/apps/popup/pages/stakes/index.tsx
+++ b/src/apps/popup/pages/stakes/index.tsx
@@ -24,7 +24,6 @@ import { ValidatorDropdownInput } from '@popup/pages/stakes/validator-dropdown-i
import { RouterPath, useTypedNavigate } from '@popup/router';
import { accountPendingDeployHashesChanged } from '@background/redux/account-info/actions';
-import { selectAccountBalance } from '@background/redux/account-info/selectors';
import { ledgerDeployChanged } from '@background/redux/ledger/actions';
import {
selectAskForReviewAfter,
@@ -55,6 +54,7 @@ import {
VerticalSpaceContainer,
createErrorLocationState
} from '@libs/layout';
+import { useFetchWalletBalance } from '@libs/services/balance-service';
import {
makeAuctionManagerDeploy,
sendSignDeploy,
@@ -111,13 +111,14 @@ export const StakesPage = () => {
const { networkName, nodeUrl, auctionManagerContractHash } = useSelector(
selectApiConfigBasedOnActiveNetwork
);
- const csprBalance = useSelector(selectAccountBalance);
const ratedInStore = useSelector(selectRatedInStore);
const askForReviewAfter = useSelector(selectAskForReviewAfter);
const { t } = useTranslation();
const navigate = useTypedNavigate();
+ const { accountBalance } = useFetchWalletBalance();
+
const { stakeType, validatorList, undelegateValidatorList, loading } =
useStakeType();
@@ -130,7 +131,7 @@ export const StakesPage = () => {
);
const { amountForm, validatorForm, newValidatorForm } = useStakesForm(
- csprBalance.liquidMotes,
+ accountBalance.liquidBalance,
stakeType,
stakeAmountMotes,
validator?.delegators_number,
@@ -538,7 +539,8 @@ export const StakesPage = () => {
if (
(stakeType === AuctionManagerEntryPoint.undelegate ||
stakeType === AuctionManagerEntryPoint.redelegate) &&
- (csprBalance.delegatedMotes == null || csprBalance.delegatedMotes === '0')
+ (!accountBalance.delegatedBalance ||
+ accountBalance.delegatedBalance === '0')
) {
return (
{
const { contractPackageHash, tokenId } = useParams();
const nftTokens = useSelector(selectAccountNftTokens);
- const csprBalance = useSelector(selectAccountBalance);
const activeAccount = useSelector(selectVaultActiveAccount);
const isActiveAccountFromLedger = useSelector(
selectIsActiveAccountFromLedger
@@ -99,6 +96,8 @@ export const TransferNftPage = () => {
const ratedInStore = useSelector(selectRatedInStore);
const askForReviewAfter = useSelector(selectAskForReviewAfter);
+ const { accountBalance } = useFetchWalletBalance();
+
const { t } = useTranslation();
const navigate = useTypedNavigate();
const location = useTypedLocation();
@@ -137,7 +136,7 @@ export const TransferNftPage = () => {
);
const { recipientForm, amountForm } = useTransferNftForm(
- csprBalance.liquidMotes,
+ accountBalance.liquidBalance,
defaultPaymentAmount
);
diff --git a/src/apps/popup/pages/transfer-nft/review-step.tsx b/src/apps/popup/pages/transfer-nft/review-step.tsx
index aa22224c0..3f6e2a6bd 100644
--- a/src/apps/popup/pages/transfer-nft/review-step.tsx
+++ b/src/apps/popup/pages/transfer-nft/review-step.tsx
@@ -1,9 +1,6 @@
import React from 'react';
import { UseFormReturn, useWatch } from 'react-hook-form';
import { Trans, useTranslation } from 'react-i18next';
-import { useSelector } from 'react-redux';
-
-import { selectAccountCurrencyRate } from '@background/redux/account-info/selectors';
import {
ContentContainer,
@@ -11,6 +8,7 @@ import {
SpacingSize,
VerticalSpaceContainer
} from '@libs/layout';
+import { useFetchWalletBalance } from '@libs/services/balance-service';
import { NFTTokenResult } from '@libs/services/nft-service';
import { Input, Typography } from '@libs/ui/components';
import { TransferNftAmountFormValues } from '@libs/ui/forms/transfer-nft';
@@ -34,7 +32,7 @@ export const ReviewStep = ({
}: ReviewStepProps) => {
const { t } = useTranslation();
- const currencyRate = useSelector(selectAccountCurrencyRate);
+ const { currencyRate } = useFetchWalletBalance();
const {
register,
@@ -49,7 +47,7 @@ export const ReviewStep = ({
const paymentFiatAmount = formatFiatAmount(
paymentAmount || '0',
- currencyRate
+ currencyRate?.rate || null
);
return (
diff --git a/src/apps/popup/pages/transfer/amount-step.tsx b/src/apps/popup/pages/transfer/amount-step.tsx
index f1d38627d..1a8c132b6 100644
--- a/src/apps/popup/pages/transfer/amount-step.tsx
+++ b/src/apps/popup/pages/transfer/amount-step.tsx
@@ -6,10 +6,6 @@ import { useSelector } from 'react-redux';
import { TRANSFER_COST_MOTES, TRANSFER_MIN_AMOUNT_MOTES } from '@src/constants';
-import {
- selectAccountBalance,
- selectAccountCurrencyRate
-} from '@background/redux/account-info/selectors';
import { selectApiConfigBasedOnActiveNetwork } from '@background/redux/settings/selectors';
import { selectVaultActiveAccount } from '@background/redux/vault/selectors';
@@ -21,6 +17,7 @@ import {
SpacingSize,
VerticalSpaceContainer
} from '@libs/layout';
+import { useFetchWalletBalance } from '@libs/services/balance-service';
import { Error, Input, Typography } from '@libs/ui/components';
import { TransactionFeePlate } from '@libs/ui/components/transaction-fee-plate/transaction-fee-plate';
import { calculateSubmitButtonDisabled } from '@libs/ui/forms/get-submit-button-state-from-validation';
@@ -56,11 +53,11 @@ export const AmountStep = ({
const { t } = useTranslation();
- const currencyRate = useSelector(selectAccountCurrencyRate);
- const csprBalance = useSelector(selectAccountBalance);
const activeAccount = useSelector(selectVaultActiveAccount);
const { networkName } = useSelector(selectApiConfigBasedOnActiveNetwork);
+ const { accountBalance, currencyRate } = useFetchWalletBalance();
+
const erc20Balance =
(selectedToken?.balance &&
divideErc20Balance(
@@ -72,22 +69,21 @@ export const AmountStep = ({
const amountForm = useTransferAmountForm(
erc20Balance,
isErc20Transfer,
- csprBalance.liquidMotes,
+ accountBalance.liquidBalance,
paymentAmount,
selectedToken?.decimals
);
useEffect(() => {
- const maxAmountMotes: string =
- csprBalance.liquidMotes == null
- ? '0'
- : Big(csprBalance.liquidMotes).sub(TRANSFER_COST_MOTES).toFixed();
+ const maxAmountMotes: string = !accountBalance.liquidBalance
+ ? '0'
+ : Big(accountBalance.liquidBalance).sub(TRANSFER_COST_MOTES).toFixed();
const hasEnoughBalance = Big(maxAmountMotes).gte(TRANSFER_MIN_AMOUNT_MOTES);
setMaxAmountMotes(maxAmountMotes);
setDisabled(!hasEnoughBalance);
- }, [csprBalance.liquidMotes]);
+ }, [accountBalance.liquidBalance]);
useEffect(() => {
if (!isErc20Transfer) {
@@ -109,7 +105,7 @@ export const AmountStep = ({
trigger,
formState.touchedFields.amount,
selectedToken?.amount,
- csprBalance.liquidMotes,
+ accountBalance.liquidBalance,
paymentAmount
]);
@@ -131,10 +127,13 @@ export const AmountStep = ({
const transferIdLabel = t('Transfer ID (memo)');
const paymentAmoutLabel = t('Set custom transaction fee');
const fiatAmount = !isErc20Transfer
- ? formatFiatAmount(amount || '0', currencyRate)
+ ? formatFiatAmount(amount || '0', currencyRate?.rate || null)
: undefined;
const paymentFiatAmount = isErc20Transfer
- ? formatFiatAmount(paymentAmountFieldValue || '0', currencyRate)
+ ? formatFiatAmount(
+ paymentAmountFieldValue || '0',
+ currencyRate?.rate || null
+ )
: undefined;
useEffect(() => {
diff --git a/src/apps/popup/pages/transfer/confirm-step.tsx b/src/apps/popup/pages/transfer/confirm-step.tsx
index 76543f2b8..5a2719c2c 100644
--- a/src/apps/popup/pages/transfer/confirm-step.tsx
+++ b/src/apps/popup/pages/transfer/confirm-step.tsx
@@ -1,13 +1,10 @@
import Big from 'big.js';
import React from 'react';
import { Trans, useTranslation } from 'react-i18next';
-import { useSelector } from 'react-redux';
import styled from 'styled-components';
import { TRANSFER_COST_MOTES } from '@src/constants';
-import { selectAccountCurrencyRate } from '@background/redux/account-info/selectors';
-
import { getAccountHashFromPublicKey } from '@libs/entities/Account';
import {
AmountContainer,
@@ -18,6 +15,7 @@ import {
VerticalSpaceContainer
} from '@libs/layout';
import { useFetchAccountsInfo } from '@libs/services/account-info';
+import { useFetchWalletBalance } from '@libs/services/balance-service';
import {
ActiveAccountPlate,
List,
@@ -33,7 +31,7 @@ const ListItemContainer = styled(SpaceBetweenFlexRow)`
interface ConfirmStepProps {
recipientPublicKey: string;
amount: string;
- balance: string | null;
+ balance: string | undefined;
symbol: string | null;
isErc20Transfer: boolean;
paymentAmount: string;
@@ -50,8 +48,7 @@ export const ConfirmStep = ({
}: ConfirmStepProps) => {
const { t } = useTranslation();
- const currencyRate = useSelector(selectAccountCurrencyRate);
-
+ const { currencyRate } = useFetchWalletBalance();
const accountsInfo = useFetchAccountsInfo([recipientPublicKey]);
const accountHash = getAccountHashFromPublicKey(recipientPublicKey);
@@ -74,14 +71,18 @@ export const ConfirmStep = ({
amount: formatNumber(amount, {
precision: { max: 5 }
}),
- fiatPrice: formatFiatAmount(amount, currencyRate),
+ fiatPrice: formatFiatAmount(amount, currencyRate?.rate || null),
symbol
},
{
id: 2,
text: t('Transaction fee'),
amount: transferCostInCSPR,
- fiatPrice: formatFiatAmount(transferCostInCSPR, currencyRate, 3),
+ fiatPrice: formatFiatAmount(
+ transferCostInCSPR,
+ currencyRate?.rate || null,
+ 3
+ ),
symbol
},
{
@@ -90,7 +91,7 @@ export const ConfirmStep = ({
amount: formatNumber(totalCSPR, {
precision: { max: 5 }
}),
- fiatPrice: formatFiatAmount(totalCSPR, currencyRate),
+ fiatPrice: formatFiatAmount(totalCSPR, currencyRate?.rate || null),
symbol,
bold: true
}
@@ -112,7 +113,11 @@ export const ConfirmStep = ({
amount: formatNumber(paymentAmount, {
precision: { max: 5 }
}),
- fiatPrice: formatFiatAmount(paymentAmount, currencyRate, 3),
+ fiatPrice: formatFiatAmount(
+ paymentAmount,
+ currencyRate?.rate || null,
+ 3
+ ),
symbol: 'CSPR'
}
];
diff --git a/src/apps/popup/pages/transfer/index.tsx b/src/apps/popup/pages/transfer/index.tsx
index 5ccb09ece..e8ab1827b 100644
--- a/src/apps/popup/pages/transfer/index.tsx
+++ b/src/apps/popup/pages/transfer/index.tsx
@@ -336,7 +336,7 @@ export const TransferPage = () => {
@@ -117,7 +117,7 @@ export const TokenStep = ({
diff --git a/src/background/index.ts b/src/background/index.ts
index e924f940b..efdeb037a 100644
--- a/src/background/index.ts
+++ b/src/background/index.ts
@@ -29,12 +29,6 @@ import {
openOnboardingUi
} from '@background/open-onboarding-flow';
import {
- accountBalancesChanged,
- accountBalancesReseted
-} from '@background/redux/account-balances/actions';
-import {
- accountBalanceChanged,
- accountCurrencyRateChanged,
accountErc20Changed,
accountInfoReset,
accountNftTokensAdded,
@@ -110,11 +104,6 @@ import { sdkEvent } from '@content/sdk-event';
import { SdkMethod, isSDKMethod, sdkMethod } from '@content/sdk-method';
import { fetchExtendedDeploysInfo } from '@libs/services/account-activity-service';
-import {
- fetchAccountBalance,
- fetchAccountBalances,
- fetchCurrencyRate
-} from '@libs/services/balance-service';
import {
fetchOnRampOptionGet,
fetchOnRampOptionPost,
@@ -608,8 +597,6 @@ runtime.onMessage.addListener(
case getType(loginRetryLockoutTimeSet):
case getType(recipientPublicKeyAdded):
case getType(recipientPublicKeyReseted):
- case getType(accountBalanceChanged):
- case getType(accountCurrencyRateChanged):
case getType(accountInfoReset):
case getType(accountPendingDeployHashesChanged):
case getType(accountPendingDeployHashesRemove):
@@ -626,8 +613,6 @@ runtime.onMessage.addListener(
case getType(contactsReseted):
case getType(ratedInStoreChanged):
case getType(askForReviewAfterChanged):
- case getType(accountBalancesChanged):
- case getType(accountBalancesReseted):
case getType(ledgerNewWindowIdChanged):
case getType(ledgerStateCleared):
case getType(ledgerDeployChanged):
@@ -642,53 +627,6 @@ runtime.onMessage.addListener(
return;
// SERVICE MESSAGE HANDLERS
- case getType(serviceMessage.fetchBalanceRequest): {
- const { casperWalletApiUrl, casperClarityApiUrl } =
- selectApiConfigBasedOnActiveNetwork(store.getState());
-
- try {
- const [accountData, rate] = await Promise.all([
- fetchAccountBalance({
- accountHash: action.payload.accountHash,
- casperWalletApiUrl
- }),
- fetchCurrencyRate({ casperClarityApiUrl })
- ]);
-
- return sendResponse(
- serviceMessage.fetchBalanceResponse({
- accountData: accountData?.data || null,
- currencyRate: rate?.data || null
- })
- );
- } catch (error) {
- console.error(error);
- }
-
- return;
- }
-
- case getType(serviceMessage.fetchAccountBalancesRequest): {
- const { casperWalletApiUrl } = selectApiConfigBasedOnActiveNetwork(
- store.getState()
- );
-
- try {
- const data = await fetchAccountBalances({
- accountHashes: action.payload.accountHashes,
- casperWalletApiUrl
- });
-
- return sendResponse(
- serviceMessage.fetchAccountBalancesResponse(data)
- );
- } catch (error) {
- console.error(error);
- }
-
- return;
- }
-
case getType(serviceMessage.fetchExtendedDeploysInfoRequest): {
const { casperClarityApiUrl } = selectApiConfigBasedOnActiveNetwork(
store.getState()
diff --git a/src/background/redux/account-balances/actions.ts b/src/background/redux/account-balances/actions.ts
deleted file mode 100644
index e4926b171..000000000
--- a/src/background/redux/account-balances/actions.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { createAction } from 'typesafe-actions';
-
-import { AccountData } from '@libs/services/balance-service/types';
-
-export const accountBalancesChanged = createAction('ACCOUNT_BALANCES_CHANGED')<
- AccountData[]
->();
-
-export const accountBalancesReseted = createAction(
- 'ACCOUNT_BALANCES_RESETED'
-)();
diff --git a/src/background/redux/account-balances/reducer.ts b/src/background/redux/account-balances/reducer.ts
deleted file mode 100644
index 044e2af70..000000000
--- a/src/background/redux/account-balances/reducer.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { createReducer } from 'typesafe-actions';
-
-import { accountBalancesChanged, accountBalancesReseted } from './actions';
-import { AccountBalancesState } from './types';
-
-const initialState = [] as AccountBalancesState;
-
-export const reducer = createReducer(initialState)
- .handleAction(accountBalancesReseted, () => initialState)
- .handleAction(
- accountBalancesChanged,
- (state, action: ReturnType) => action.payload
- );
diff --git a/src/background/redux/account-balances/selectors.ts b/src/background/redux/account-balances/selectors.ts
deleted file mode 100644
index fcd061275..000000000
--- a/src/background/redux/account-balances/selectors.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-import { RootState } from 'typesafe-actions';
-
-export const selectAccountBalances = (state: RootState) =>
- state.accountBalances;
diff --git a/src/background/redux/account-balances/types.ts b/src/background/redux/account-balances/types.ts
deleted file mode 100644
index f97a24ed1..000000000
--- a/src/background/redux/account-balances/types.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import { AccountData } from '@libs/services/balance-service/types';
-
-export type AccountBalancesState = AccountData[];
diff --git a/src/background/redux/account-info/actions.ts b/src/background/redux/account-info/actions.ts
index 8e7e3f6c0..c58b29a49 100644
--- a/src/background/redux/account-info/actions.ts
+++ b/src/background/redux/account-info/actions.ts
@@ -1,21 +1,12 @@
import { createAction } from 'typesafe-actions';
-import { AccountBalance } from '@libs/services/balance-service/types';
import { ContractPackageWithBalance } from '@libs/services/erc20-service/types';
import { NFTTokenResult } from '@libs/services/nft-service/types';
-export const accountBalanceChanged = createAction(
- 'ACCOUNT_BALANCE_CHANGED'
-)();
-
export const accountErc20Changed = createAction('ACCOUNT_ERC20_CHANGED')<
ContractPackageWithBalance[]
>();
-export const accountCurrencyRateChanged = createAction(
- 'ACCOUNT_CURRENCY_RATE_CHANGED'
-)();
-
export const accountInfoReset = createAction('ACCOUNT_INFO_RESET')();
export const accountPendingDeployHashesChanged = createAction(
diff --git a/src/background/redux/account-info/reducer.ts b/src/background/redux/account-info/reducer.ts
index 9eb129dee..888a13fb9 100644
--- a/src/background/redux/account-info/reducer.ts
+++ b/src/background/redux/account-info/reducer.ts
@@ -3,8 +3,6 @@ import { createReducer } from 'typesafe-actions';
import { isEqualCaseInsensitive } from '@src/utils';
import {
- accountBalanceChanged,
- accountCurrencyRateChanged,
accountErc20Changed,
accountInfoReset,
accountNftTokensAdded,
@@ -18,14 +16,6 @@ import {
import { AccountInfoState } from './types';
const initialState: AccountInfoState = {
- balance: {
- liquidMotes: null,
- delegatedMotes: null,
- undelegatingMotes: null,
- totalBalanceMotes: null,
- totalBalanceFiat: null
- },
- currencyRate: null,
pendingDeployHashes: [],
erc20Tokens: [],
accountNftTokens: [],
@@ -35,17 +25,6 @@ const initialState: AccountInfoState = {
export const reducer = createReducer(initialState)
.handleAction(accountInfoReset, () => initialState)
- .handleAction(accountBalanceChanged, (state, { payload }) => ({
- ...state,
- balance: payload
- }))
- .handleAction(
- accountCurrencyRateChanged,
- (state, { payload }): AccountInfoState => ({
- ...state,
- currencyRate: payload
- })
- )
.handleAction(
accountErc20Changed,
(state, { payload }): AccountInfoState => ({
diff --git a/src/background/redux/account-info/selectors.ts b/src/background/redux/account-info/selectors.ts
index 6008be84a..c1680794a 100644
--- a/src/background/redux/account-info/selectors.ts
+++ b/src/background/redux/account-info/selectors.ts
@@ -1,11 +1,5 @@
import { RootState } from 'typesafe-actions';
-export const selectAccountBalance = (state: RootState) =>
- state.accountInfo.balance;
-
-export const selectAccountCurrencyRate = (state: RootState) =>
- state.accountInfo.currencyRate;
-
export const selectPendingDeployHashes = (state: RootState) =>
state.accountInfo.pendingDeployHashes;
diff --git a/src/background/redux/account-info/types.ts b/src/background/redux/account-info/types.ts
index 6d0d3ab1f..b9586c51b 100644
--- a/src/background/redux/account-info/types.ts
+++ b/src/background/redux/account-info/types.ts
@@ -1,11 +1,8 @@
-import { AccountBalance } from '@libs/services/balance-service';
import { ContractPackageWithBalance } from '@libs/services/erc20-service';
import { NFTTokenResult } from '@libs/services/nft-service';
export interface AccountInfoState {
- balance: AccountBalance;
erc20Tokens: ContractPackageWithBalance[];
- currencyRate: number | null;
pendingDeployHashes: string[];
accountNftTokens: NFTTokenResult[] | null;
nftTokensCount: number;
diff --git a/src/background/redux/get-main-store.ts b/src/background/redux/get-main-store.ts
index f79f7c562..33e8eb8a5 100644
--- a/src/background/redux/get-main-store.ts
+++ b/src/background/redux/get-main-store.ts
@@ -58,7 +58,6 @@ export const selectPopupState = (state: RootState): PopupState => {
accountInfo: state.accountInfo,
contacts: state.contacts,
rateApp: state.rateApp,
- accountBalances: state.accountBalances,
ledger: state.ledger,
promotion: state.promotion
};
diff --git a/src/background/redux/redux-action.ts b/src/background/redux/redux-action.ts
index 7ddc20f6f..48a260502 100644
--- a/src/background/redux/redux-action.ts
+++ b/src/background/redux/redux-action.ts
@@ -1,6 +1,5 @@
import { ActionType } from 'typesafe-actions';
-import * as accountBalances from './account-balances/actions';
import * as accountInfo from './account-info/actions';
import * as activeOrigin from './active-origin/actions';
import * as contacts from './contacts/actions';
@@ -35,7 +34,6 @@ const reduxAction = {
accountInfo,
contacts,
rateApp,
- accountBalances,
ledger,
promotion
};
diff --git a/src/background/redux/root-reducer.ts b/src/background/redux/root-reducer.ts
index d3d6a3aa6..aea14de02 100644
--- a/src/background/redux/root-reducer.ts
+++ b/src/background/redux/root-reducer.ts
@@ -1,6 +1,5 @@
import { combineReducers } from 'redux';
-import { reducer as accountBalances } from './account-balances/reducer';
import { reducer as accountInfo } from './account-info/reducer';
import { reducer as activeOrigin } from './active-origin/reducer';
import { reducer as contacts } from './contacts/reducer';
@@ -33,7 +32,6 @@ const rootReducer = combineReducers({
accountInfo,
contacts,
rateApp,
- accountBalances,
ledger,
promotion
});
diff --git a/src/background/redux/sagas/vault-sagas.ts b/src/background/redux/sagas/vault-sagas.ts
index 15d8dcee4..567644534 100644
--- a/src/background/redux/sagas/vault-sagas.ts
+++ b/src/background/redux/sagas/vault-sagas.ts
@@ -8,7 +8,6 @@ import {
MapTimeoutDurationSettingToValue
} from '@popup/constants';
-import { accountBalancesReseted } from '@background/redux/account-balances/actions';
import {
loginRetryLockoutTimeReseted,
loginRetryLockoutTimeSet
@@ -120,7 +119,6 @@ function* lockVaultSaga() {
yield put(vaultReseted());
yield put(deploysReseted());
yield put(accountInfoReset());
- yield put(accountBalancesReseted());
emitSdkEventToActiveTabs(() => {
return sdkEvent.lockedEvent({
diff --git a/src/background/redux/types.d.ts b/src/background/redux/types.d.ts
index efc28c05e..a708694cc 100644
--- a/src/background/redux/types.d.ts
+++ b/src/background/redux/types.d.ts
@@ -1,6 +1,5 @@
import { ActionType, StateType } from 'typesafe-actions';
-import { AccountBalancesState } from '@background/redux/account-balances/types';
import { AccountInfoState } from '@background/redux/account-info/types';
import { ActiveOriginState } from '@background/redux/active-origin/types';
import { ContactsState } from '@background/redux/contacts/types';
@@ -50,7 +49,6 @@ export type PopupState = {
accountInfo: AccountInfoState;
contacts: ContactsState;
rateApp: RateAppState;
- accountBalances: AccountBalancesState;
ledger: LedgerState;
promotion: PromotionState;
};
diff --git a/src/background/redux/vault/selectors.ts b/src/background/redux/vault/selectors.ts
index 1fb369709..09506eade 100644
--- a/src/background/redux/vault/selectors.ts
+++ b/src/background/redux/vault/selectors.ts
@@ -1,15 +1,10 @@
import { createSelector } from 'reselect';
import { RootState } from 'typesafe-actions';
-import { selectAccountBalances } from '@background/redux/account-balances/selectors';
import { VaultState } from '@background/redux/vault/types';
import { SecretPhrase } from '@libs/crypto';
-import {
- Account,
- AccountWithBalance,
- HardwareWalletType
-} from '@libs/types/account';
+import { Account, HardwareWalletType } from '@libs/types/account';
import { selectActiveOrigin } from '../active-origin/selectors';
@@ -27,35 +22,12 @@ export const selectVaultAccounts = (state: RootState): Account[] =>
export const selectVaultAccountsPublicKeys = (state: RootState): string[] =>
state.vault.accounts.map(key => key.publicKey);
-export const selectVaultAccountsWithBalances = createSelector(
- selectVaultAccounts,
- selectAccountBalances,
- (accounts, accountBalances): AccountWithBalance[] =>
- accounts.map(account => {
- if (!accountBalances.length) {
- return {
- ...account,
- balance: {
- liquidMotes: null
- }
- };
- }
-
- const accountBalance = accountBalances.find(
- ac => ac.public_key === account.publicKey
- );
-
- return {
- ...account,
- balance: {
- liquidMotes: String(accountBalance?.balance || '0')
- }
- };
- })
-);
+export const selectVaultAccountsExceptLedgersAccounts = (
+ state: RootState
+): Account[] => state.vault.accounts.filter(account => !account.hardware);
export const selectVaultCountsOfAccounts = createSelector(
- selectVaultAccountsWithBalances,
+ selectVaultAccounts,
accounts => accounts.length
);
@@ -63,12 +35,12 @@ export const selectVaultHasAccounts = (state: RootState): boolean =>
state.vault.accounts.length > 0;
export const selectVaultAccountsNames = createSelector(
- selectVaultAccountsWithBalances,
+ selectVaultAccounts,
accounts => accounts.map(account => account.name)
);
export const selectVaultImportedAccounts = createSelector(
- selectVaultAccountsWithBalances,
+ selectVaultAccounts,
accounts => accounts.filter(account => account.imported)
);
@@ -78,12 +50,12 @@ export const selectVaultImportedAccountNames = createSelector(
);
export const selectVaultVisibleAccounts = createSelector(
- selectVaultAccountsWithBalances,
+ selectVaultAccounts,
accounts => accounts.filter(account => !account.hidden)
);
export const selectVaultHiddenAccounts = createSelector(
- selectVaultAccountsWithBalances,
+ selectVaultAccounts,
accounts => accounts.filter(account => account.hidden)
);
@@ -98,12 +70,12 @@ export const selectVaultHasImportedAccount = createSelector(
);
export const selectVaultDerivedAccounts = createSelector(
- selectVaultAccountsWithBalances,
+ selectVaultAccounts,
accounts => accounts.filter(account => !account.imported && !account.hardware)
);
export const selectVaultLedgerAccounts = createSelector(
- selectVaultAccountsWithBalances,
+ selectVaultAccounts,
accounts =>
accounts.filter(account => account.hardware === HardwareWalletType.Ledger)
);
@@ -114,12 +86,12 @@ export const selectVaultLedgerAccountNames = createSelector(
);
export const selectVaultAccountsSecretKeysBase64 = createSelector(
- selectVaultAccountsWithBalances,
+ selectVaultAccounts,
accounts => accounts.map(account => account.secretKey)
);
export const selectVaultAccount = createSelector(
- selectVaultAccountsWithBalances,
+ selectVaultAccounts,
(_: RootState, accountName: string) => accountName,
(accounts, accountName) =>
accounts.find(account => account.name === accountName)
@@ -129,7 +101,7 @@ export const selectVaultActiveAccountName = (state: RootState) =>
state.vault.activeAccountName;
export const selectVaultActiveAccount = createSelector(
- selectVaultAccountsWithBalances,
+ selectVaultAccounts,
selectVaultActiveAccountName,
(accounts, activeAccountName) => {
return accounts.find(account => account.name === activeAccountName);
@@ -222,19 +194,19 @@ export const selectConnectedAccountNamesWithActiveOrigin = createSelector(
export const selectConnectedAccountsWithActiveOrigin = createSelector(
selectActiveOrigin,
- selectVaultAccountsWithBalances,
+ selectVaultAccounts,
selectConnectedAccountNamesWithActiveOrigin,
- (origin, accounts, connectedAccountNamesWithOrigin): AccountWithBalance[] => {
+ (origin, accounts, connectedAccountNamesWithOrigin): Account[] => {
return (connectedAccountNamesWithOrigin || [])
.map(accountName =>
accounts.find(account => account.name === accountName)
)
- .filter((account): account is AccountWithBalance => !!account);
+ .filter((account): account is Account => !!account);
}
);
export const selectUnconnectedAccountsWithActiveOrigin = createSelector(
- selectVaultAccountsWithBalances,
+ selectVaultAccounts,
selectConnectedAccountsWithActiveOrigin,
(accounts, connectedAccountsToActiveTab) =>
accounts.filter(
diff --git a/src/background/service-message.ts b/src/background/service-message.ts
index e91c66159..c09f251a8 100644
--- a/src/background/service-message.ts
+++ b/src/background/service-message.ts
@@ -1,10 +1,6 @@
import { IDeploy } from 'casper-wallet-core';
import { ActionType, createAction } from 'typesafe-actions';
-import {
- AccountData,
- FetchBalanceResponse
-} from '@libs/services/balance-service/types';
import {
GetOnRampResponse,
OptionsPostRequestData,
@@ -23,22 +19,6 @@ import {
type Meta = void;
export const serviceMessage = {
- fetchBalanceRequest: createAction('FETCH_ACCOUNT_BALANCE')<
- { accountHash: string },
- Meta
- >(),
- fetchBalanceResponse: createAction('FETCH_ACCOUNT_BALANCE_RESPONSE')<
- FetchBalanceResponse,
- Meta
- >(),
- fetchAccountBalancesRequest: createAction('FETCH_ACCOUNT_BALANCES')<
- { accountHashes: string },
- Meta
- >(),
- fetchAccountBalancesResponse: createAction('FETCH_ACCOUNT_BALANCES_RESPONSE')<
- PaginatedResponse | ErrorResponse,
- Meta
- >(),
fetchExtendedDeploysInfoRequest: createAction('FETCH_EXTENDED_DEPLOYS_INFO')<
{ deployHash: string; publicKey: string },
Meta
diff --git a/src/background/wallet-repositories.ts b/src/background/wallet-repositories.ts
index ea4e8b05d..901479d47 100644
--- a/src/background/wallet-repositories.ts
+++ b/src/background/wallet-repositories.ts
@@ -1,5 +1,6 @@
import { setupRepositories } from 'casper-wallet-core';
-const { deploysRepository, accountInfoRepository } = setupRepositories();
+const { deploysRepository, accountInfoRepository, tokensRepository } =
+ setupRepositories();
-export { deploysRepository, accountInfoRepository };
+export { deploysRepository, accountInfoRepository, tokensRepository };
diff --git a/src/fixtures/initial-state-for-popup-tests.ts b/src/fixtures/initial-state-for-popup-tests.ts
index 35b1094ad..212a71697 100644
--- a/src/fixtures/initial-state-for-popup-tests.ts
+++ b/src/fixtures/initial-state-for-popup-tests.ts
@@ -91,14 +91,6 @@ export const initialStateForPopupTests: RootState = {
},
recentRecipientPublicKeys: [],
accountInfo: {
- balance: {
- liquidMotes: null,
- delegatedMotes: null,
- undelegatingMotes: null,
- totalBalanceMotes: null,
- totalBalanceFiat: null
- },
- currencyRate: null,
pendingDeployHashes: [],
erc20Tokens: [],
accountNftTokens: [],
@@ -113,7 +105,6 @@ export const initialStateForPopupTests: RootState = {
ratedInStore: false,
askForReviewAfter: null
},
- accountBalances: [],
promotion: {
showCSPRNamePromotion: true
}
diff --git a/src/hooks/use-casper-token.ts b/src/hooks/use-casper-token.ts
index d5f8ad23e..b36313704 100644
--- a/src/hooks/use-casper-token.ts
+++ b/src/hooks/use-casper-token.ts
@@ -1,17 +1,6 @@
import { useEffect, useState } from 'react';
-import { useSelector } from 'react-redux';
-import {
- selectAccountBalance,
- selectAccountCurrencyRate
-} from '@background/redux/account-info/selectors';
-
-import {
- formatCurrency,
- formatNumber,
- motesToCSPR,
- motesToCurrency
-} from '@libs/ui/utils';
+import { useFetchWalletBalance } from '@libs/services/balance-service';
export type TokenType = {
id: string;
@@ -28,37 +17,22 @@ export type TokenType = {
export const useCasperToken = () => {
const [casperToken, setCasperToken] = useState(null);
- const balance = useSelector(selectAccountBalance);
- const currencyRate = useSelector(selectAccountCurrencyRate);
-
- const amount =
- balance?.liquidMotes == null
- ? '-'
- : formatNumber(motesToCSPR(balance.liquidMotes), {
- precision: { max: 5 }
- });
- const amountFiat =
- currencyRate != null && balance?.liquidMotes != null
- ? formatCurrency(
- motesToCurrency(String(balance.liquidMotes), currencyRate),
- 'USD',
- {
- precision: 2
- }
- )
- : '';
+ const { accountBalance } = useFetchWalletBalance();
useEffect(() => {
setCasperToken({
id: 'Casper',
contractHash: undefined,
name: 'Casper',
- amount,
- amountFiat: amountFiat,
+ amount: accountBalance.liquidFormattedDecimalBalance || '-',
+ amountFiat: accountBalance.liquidFormattedFiatBalance,
symbol: 'CSPR',
icon: '/assets/icons/casper.svg'
});
- }, [amount, amountFiat]);
+ }, [
+ accountBalance.liquidFormattedDecimalBalance,
+ accountBalance.liquidFormattedFiatBalance
+ ]);
return casperToken;
};
diff --git a/src/hooks/use-fetch-account-balances.ts b/src/hooks/use-fetch-account-balances.ts
deleted file mode 100644
index 0500c8d28..000000000
--- a/src/hooks/use-fetch-account-balances.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import { useEffect, useRef } from 'react';
-import { useTranslation } from 'react-i18next';
-import { useSelector } from 'react-redux';
-
-import { BALANCE_REFRESH_RATE } from '@src/constants';
-
-import { useForceUpdate } from '@popup/hooks/use-force-update';
-
-import { accountBalancesChanged } from '@background/redux/account-balances/actions';
-import { selectApiConfigBasedOnActiveNetwork } from '@background/redux/settings/selectors';
-import { dispatchToMainStore } from '@background/redux/utils';
-import { selectVaultAccounts } from '@background/redux/vault/selectors';
-
-import { getAccountHashFromPublicKey } from '@libs/entities/Account';
-import { dispatchFetchAccountBalances } from '@libs/services/balance-service';
-
-export const useFetchAccountBalances = () => {
- const effectTimeoutRef = useRef();
- const forceUpdate = useForceUpdate();
- const { t } = useTranslation();
-
- const { casperClarityApiUrl } = useSelector(
- selectApiConfigBasedOnActiveNetwork
- );
- const accounts = useSelector(selectVaultAccounts);
-
- const hashes = accounts.reduce(
- (previousValue, currentValue, currentIndex) => {
- const hash = getAccountHashFromPublicKey(currentValue.publicKey);
-
- return accounts.length === currentIndex + 1
- ? previousValue + `${hash}`
- : previousValue + `${hash},`;
- },
- ''
- );
-
- useEffect(() => {
- dispatchFetchAccountBalances(hashes)
- .then(({ payload }) => {
- if ('data' in payload) {
- dispatchToMainStore(accountBalancesChanged(payload.data));
- } else {
- dispatchToMainStore(accountBalancesChanged([]));
- }
- })
- .catch(error => {
- console.error(t('Failed to fetch accounts balance'), error);
- });
-
- // will cause effect to run again after timeout
- effectTimeoutRef.current = setTimeout(() => {
- forceUpdate();
- }, BALANCE_REFRESH_RATE + 1);
-
- return () => {
- clearTimeout(effectTimeoutRef.current);
- };
- }, [casperClarityApiUrl, forceUpdate, t, hashes]);
-};
diff --git a/src/hooks/use-fetch-active-account-balance.ts b/src/hooks/use-fetch-active-account-balance.ts
deleted file mode 100644
index 3968d437d..000000000
--- a/src/hooks/use-fetch-active-account-balance.ts
+++ /dev/null
@@ -1,93 +0,0 @@
-import { useEffect, useRef } from 'react';
-import { useTranslation } from 'react-i18next';
-import { useSelector } from 'react-redux';
-
-import { BALANCE_REFRESH_RATE } from '@src/constants';
-
-import { useForceUpdate } from '@popup/hooks/use-force-update';
-
-import {
- accountBalanceChanged,
- accountCurrencyRateChanged
-} from '@background/redux/account-info/actions';
-import { selectApiConfigBasedOnActiveNetwork } from '@background/redux/settings/selectors';
-import { dispatchToMainStore } from '@background/redux/utils';
-import { selectVaultActiveAccount } from '@background/redux/vault/selectors';
-
-import { getAccountHashFromPublicKey } from '@libs/entities/Account';
-import { dispatchFetchActiveAccountBalance } from '@libs/services/balance-service';
-import { formatCurrency, motesToCurrency } from '@libs/ui/utils';
-
-export const useFetchActiveAccountBalance = () => {
- const effectTimeoutRef = useRef();
- const forceUpdate = useForceUpdate();
- const { t } = useTranslation();
-
- const activeAccount = useSelector(selectVaultActiveAccount);
- const { casperClarityApiUrl } = useSelector(
- selectApiConfigBasedOnActiveNetwork
- );
-
- useEffect(() => {
- if (!activeAccount?.publicKey) return;
-
- const accountHash = getAccountHashFromPublicKey(activeAccount.publicKey);
-
- dispatchFetchActiveAccountBalance(accountHash)
- .then(({ payload: { accountData, currencyRate } }) => {
- if (accountData != null) {
- const liquidBalance = accountData?.balance || 0;
- const delegatedBalance = accountData?.delegated_balance || 0;
- const undelegatingBalance = accountData?.undelegating_balance || 0;
-
- const totalAmountMotes =
- liquidBalance + delegatedBalance + undelegatingBalance;
- const totalBalanceFiat =
- currencyRate != null
- ? formatCurrency(
- motesToCurrency(String(totalAmountMotes), currencyRate),
- 'USD',
- {
- precision: 2
- }
- )
- : t('Currency service is offline...');
-
- dispatchToMainStore(accountCurrencyRateChanged(currencyRate));
- dispatchToMainStore(
- accountBalanceChanged({
- liquidMotes: String(liquidBalance),
- delegatedMotes: String(delegatedBalance),
- undelegatingMotes: String(undelegatingBalance),
- totalBalanceMotes: String(totalAmountMotes),
- totalBalanceFiat: totalBalanceFiat
- })
- );
- } else {
- dispatchToMainStore(accountCurrencyRateChanged(currencyRate));
- dispatchToMainStore(
- accountBalanceChanged({
- liquidMotes: null,
- undelegatingMotes: null,
- delegatedMotes: null,
- totalBalanceMotes: null,
- totalBalanceFiat: null
- })
- );
- }
- })
- .catch(error => {
- console.error('Balance request failed:', error);
- });
-
- // will cause effect to run again after timeout
- effectTimeoutRef.current = setTimeout(() => {
- forceUpdate();
- }, BALANCE_REFRESH_RATE + 1);
-
- return () => {
- clearTimeout(effectTimeoutRef.current);
- };
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [activeAccount?.publicKey, casperClarityApiUrl, t, forceUpdate]);
-};
diff --git a/src/libs/layout/header/header-data-updater.tsx b/src/libs/layout/header/header-data-updater.tsx
index 76a57ef3a..5c243c723 100644
--- a/src/libs/layout/header/header-data-updater.tsx
+++ b/src/libs/layout/header/header-data-updater.tsx
@@ -1,13 +1,12 @@
import React from 'react';
-import { useFetchAccountBalances } from '@hooks/use-fetch-account-balances';
-import { useFetchActiveAccountBalance } from '@hooks/use-fetch-active-account-balance';
import { useFetchErc20Tokens } from '@hooks/use-fetch-erc20-tokens';
+import { useFetchWalletBalance } from '@libs/services/balance-service';
+
export const HeaderDataUpdater: React.FC = () => {
- useFetchActiveAccountBalance();
useFetchErc20Tokens();
- useFetchAccountBalances();
+ useFetchWalletBalance();
return null;
};
diff --git a/src/libs/layout/header/header-submenu-bar-nav-link.tsx b/src/libs/layout/header/header-submenu-bar-nav-link.tsx
index 8108ffeea..e5c44e825 100644
--- a/src/libs/layout/header/header-submenu-bar-nav-link.tsx
+++ b/src/libs/layout/header/header-submenu-bar-nav-link.tsx
@@ -1,17 +1,15 @@
import React from 'react';
import { Trans, useTranslation } from 'react-i18next';
-import { useSelector } from 'react-redux';
import styled from 'styled-components';
import { RouterPath } from '@popup/router/paths';
import { useTypedNavigate } from '@popup/router/use-typed-navigate';
import { closeCurrentWindow } from '@background/close-current-window';
-import { selectAccountBalance } from '@background/redux/account-info/selectors';
import { AlignedFlexRow, SpacingSize } from '@libs/layout';
+import { useFetchWalletBalance } from '@libs/services/balance-service';
import { Link, SvgIcon, Typography } from '@libs/ui/components';
-import { formatNumber, motesToCSPR } from '@libs/ui/utils/formatters';
const LinkWithIconContainer = styled.div`
display: flex;
@@ -40,11 +38,7 @@ export function HeaderSubmenuBarNavLink({
const { t } = useTranslation();
const navigate = useTypedNavigate();
- const balance = useSelector(selectAccountBalance);
-
- const formattedBalance = formatNumber(
- (balance.liquidMotes && motesToCSPR(balance.liquidMotes)) || ''
- );
+ const { accountBalance } = useFetchWalletBalance();
switch (linkType) {
case 'close':
@@ -81,14 +75,16 @@ export function HeaderSubmenuBarNavLink({
}}
withLeftChevronIcon
/>
-
-
- Balance:
-
-
- {`${formattedBalance} CSPR`}
-
-
+ {accountBalance.liquidFormattedDecimalBalance && (
+
+
+ Balance:
+
+
+ {`${accountBalance.liquidFormattedDecimalBalance} CSPR`}
+
+
+ )}
>
) : (
=>
- fetch(getCurrencyRateUrl(casperClarityApiUrl), { signal })
- .then(toJson)
- .catch(handleError);
-
-export const accountBalanceRequest = (
- accountHash: string,
- casperWalletApiUrl: string,
- signal?: AbortSignal
-): Promise => {
- if (!accountHash) {
- throw Error('Missing account hash');
- }
-
- return fetch(getAccountBalanceUrl({ accountHash, casperWalletApiUrl }), {
- signal
- })
- .then(res => {
- if (res.status === 404) {
- return {
- data: {
- balance: 0
- } as AccountData
- };
- }
-
- return toJson(res);
- })
- .catch(handleError);
-};
-
-export const accountBalancesRequest = (
- accountHashes: string,
- casperWalletApiUrl: string,
- signal?: AbortSignal
-): Promise | ErrorResponse> =>
- fetch(
- getAccountBalancesUrl({
- accountHashes,
- casperWalletApiUrl
- }),
- {
- signal
- }
- )
- .then(toJson)
- .catch(handleError);
-
-export const dispatchFetchActiveAccountBalance = (
- accountHash = ''
-): Promise> =>
- dispatchToMainStore(serviceMessage.fetchBalanceRequest({ accountHash }));
-
-export const dispatchFetchAccountBalances = (
- accountHashes = ''
-): Promise | ErrorResponse>> =>
- dispatchToMainStore(
- serviceMessage.fetchAccountBalancesRequest({ accountHashes })
- );
-
-export const fetchAccountBalance = ({
- accountHash,
- casperWalletApiUrl
-}: {
- accountHash: string;
- casperWalletApiUrl: string;
-}): Promise> =>
- queryClient.fetchQuery(
- ['getAccountBalanceRequest', accountHash, casperWalletApiUrl],
- ({ signal }) =>
- accountBalanceRequest(accountHash, casperWalletApiUrl, signal),
- {
- staleTime: BALANCE_REFRESH_RATE
- }
- );
-
-export const fetchCurrencyRate = ({
- casperClarityApiUrl
-}: {
- casperClarityApiUrl: string;
-}) =>
- queryClient.fetchQuery(
- 'getCurrencyRateRequest',
- ({ signal }) => currencyRateRequest(casperClarityApiUrl, signal),
- {
- staleTime: CURRENCY_REFRESH_RATE
- }
- );
-
-export const fetchAccountBalances = ({
- accountHashes,
- casperWalletApiUrl
-}: {
- accountHashes: string;
- casperWalletApiUrl: string;
-}) =>
- queryClient.fetchQuery(
- ['getAccountBalancesRequest', accountHashes, casperWalletApiUrl],
- ({ signal }) =>
- accountBalancesRequest(accountHashes, casperWalletApiUrl, signal),
- {
- staleTime: BALANCE_REFRESH_RATE
- }
- );
diff --git a/src/libs/services/balance-service/constants.ts b/src/libs/services/balance-service/constants.ts
index 44cc59b0a..33bf11a9f 100644
--- a/src/libs/services/balance-service/constants.ts
+++ b/src/libs/services/balance-service/constants.ts
@@ -1,24 +1,8 @@
-interface GetAccountBalanceUrl {
- accountHash: string;
- casperWalletApiUrl: string;
-}
-
-interface GetAccountBalancesUrl {
- accountHashes: string;
- casperWalletApiUrl: string;
-}
+import { ICsprBalance } from 'casper-wallet-core/src/domain/tokens';
-export const getCurrencyRateUrl = (casperClarityApiUrl: string) =>
- `${casperClarityApiUrl}/rates/1/amount`;
+type AccountsBalances = Record | undefined;
-export const getAccountBalanceUrl = ({
- accountHash,
- casperWalletApiUrl
-}: GetAccountBalanceUrl) =>
- `${casperWalletApiUrl}/accounts/${accountHash}?includes=delegated_balance,undelegating_balance`;
-
-export const getAccountBalancesUrl = ({
- accountHashes,
- casperWalletApiUrl
-}: GetAccountBalancesUrl) =>
- `${casperWalletApiUrl}/accounts?account_hash=${accountHashes}&page=1&page_size=100&includes=delegated_balance,undelegating_balance`;
+export interface UseFetchAccountsBalances {
+ accountsBalances: AccountsBalances;
+ isLoadingBalances: boolean;
+}
diff --git a/src/libs/services/balance-service/index.ts b/src/libs/services/balance-service/index.ts
index b7d524836..f929e3a8f 100644
--- a/src/libs/services/balance-service/index.ts
+++ b/src/libs/services/balance-service/index.ts
@@ -1,3 +1,2 @@
-export * from './balance-service';
-export * from './types';
-export * from './constants';
+export * from './use-fetch-accounts-balances';
+export * from './use-fetch-wallet-balance';
diff --git a/src/libs/services/balance-service/queries.ts b/src/libs/services/balance-service/queries.ts
new file mode 100644
index 000000000..56a00a91c
--- /dev/null
+++ b/src/libs/services/balance-service/queries.ts
@@ -0,0 +1,68 @@
+import { CasperNetwork } from 'casper-wallet-core/src/domain/common/common';
+
+import {
+ BALANCE_REFRESH_RATE,
+ CURRENCY_REFRESH_RATE,
+ NetworkSetting
+} from '@src/constants';
+
+import {
+ accountInfoRepository,
+ tokensRepository
+} from '@background/wallet-repositories';
+
+import { Account } from '@libs/types/account';
+
+interface AccountBalanceQueryProps {
+ network: NetworkSetting;
+ activeAccount: Account | undefined;
+}
+
+interface CurrencyRateQueryProps {
+ network: NetworkSetting;
+}
+
+interface AccountBalancesQueryProps {
+ accountHashesString: string;
+ network: NetworkSetting;
+ accountHashes: string[];
+}
+
+export const accountBalanceQuery = ({
+ network,
+ activeAccount
+}: AccountBalanceQueryProps) => ({
+ queryKey: ['ACCOUNT_BALANCE', network, activeAccount?.publicKey],
+ queryFn: () =>
+ tokensRepository.getCsprBalance({
+ publicKey: activeAccount?.publicKey || '',
+ network: network.toLowerCase() as CasperNetwork
+ }),
+ refetchInterval: BALANCE_REFRESH_RATE,
+ staleTime: BALANCE_REFRESH_RATE
+});
+
+export const currencyRateQuery = ({ network }: CurrencyRateQueryProps) => ({
+ queryKey: ['CURRENCY_RATE', network],
+ queryFn: () =>
+ tokensRepository.getCsprFiatCurrencyRate({
+ network: network.toLowerCase() as CasperNetwork
+ }),
+ refetchInterval: CURRENCY_REFRESH_RATE,
+ staleTime: CURRENCY_REFRESH_RATE
+});
+
+export const accountsBalancesQuery = ({
+ accountHashesString,
+ network,
+ accountHashes
+}: AccountBalancesQueryProps) => ({
+ queryKey: ['ACCOUNTS_BALANCES', accountHashesString, network],
+ queryFn: async () =>
+ accountInfoRepository.getAccountsBalances({
+ accountHashes: accountHashes,
+ network: network.toLowerCase() as CasperNetwork
+ }),
+ refetchInterval: BALANCE_REFRESH_RATE,
+ staleTime: BALANCE_REFRESH_RATE
+});
diff --git a/src/libs/services/balance-service/types.ts b/src/libs/services/balance-service/types.ts
deleted file mode 100644
index 867c1a87e..000000000
--- a/src/libs/services/balance-service/types.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-export interface GetCurrencyRateRequestResponse {
- data: number;
-}
-
-export interface AccountData {
- account_hash: string;
- balance: number;
- delegated_balance?: number;
- main_purse_uref: string;
- public_key: string;
- undelegating_balance?: number;
-}
-
-export interface FetchBalanceResponse {
- currencyRate: number | null;
- accountData: AccountData | null;
-}
-
-export interface AccountBalance {
- liquidMotes: string | null;
- delegatedMotes: string | null;
- undelegatingMotes: string | null;
- totalBalanceMotes: string | null;
- totalBalanceFiat: string | null;
-}
diff --git a/src/libs/services/balance-service/use-fetch-accounts-balances.ts b/src/libs/services/balance-service/use-fetch-accounts-balances.ts
new file mode 100644
index 000000000..8270a4e26
--- /dev/null
+++ b/src/libs/services/balance-service/use-fetch-accounts-balances.ts
@@ -0,0 +1,28 @@
+import { useQuery } from '@tanstack/react-query';
+import { useSelector } from 'react-redux';
+
+import { selectActiveNetworkSetting } from '@background/redux/settings/selectors';
+
+import { UseFetchAccountsBalances } from '@libs/services/balance-service/constants';
+import { accountsBalancesQuery } from '@libs/services/balance-service/queries';
+
+export const useFetchAccountsBalances = (
+ accountHashes: string[]
+): UseFetchAccountsBalances => {
+ const network = useSelector(selectActiveNetworkSetting);
+
+ const accountHashesString = accountHashes.toString();
+
+ const { data: accountsBalances, isFetching: isLoadingBalances } = useQuery(
+ accountsBalancesQuery({
+ network,
+ accountHashes,
+ accountHashesString
+ })
+ );
+
+ return {
+ accountsBalances,
+ isLoadingBalances
+ };
+};
diff --git a/src/libs/services/balance-service/use-fetch-wallet-balance.ts b/src/libs/services/balance-service/use-fetch-wallet-balance.ts
new file mode 100644
index 000000000..76da2ee4f
--- /dev/null
+++ b/src/libs/services/balance-service/use-fetch-wallet-balance.ts
@@ -0,0 +1,123 @@
+import { useQueries } from '@tanstack/react-query';
+import { useSelector } from 'react-redux';
+
+import { selectActiveNetworkSetting } from '@background/redux/settings/selectors';
+import {
+ selectVaultAccounts,
+ selectVaultActiveAccount
+} from '@background/redux/vault/selectors';
+
+import { getAccountHashFromPublicKey } from '@libs/entities/Account';
+import {
+ accountBalanceQuery,
+ accountsBalancesQuery,
+ currencyRateQuery
+} from '@libs/services/balance-service/queries';
+import { formatCurrency, motesToCurrency } from '@libs/ui/utils';
+
+export const useFetchWalletBalance = () => {
+ const activeAccount = useSelector(selectVaultActiveAccount);
+ const network = useSelector(selectActiveNetworkSetting);
+ const accounts = useSelector(selectVaultAccounts);
+
+ const accountHashes = accounts.map(account =>
+ getAccountHashFromPublicKey(account.publicKey)
+ );
+
+ const accountHashesString = accountHashes.toString();
+
+ const {
+ accountBalance,
+ isLoadingBalance,
+ currencyRate,
+ accountsBalances,
+ isLoadingBalances
+ } = useQueries({
+ queries: [
+ accountBalanceQuery({
+ network,
+ activeAccount
+ }),
+ currencyRateQuery({
+ network
+ }),
+ accountsBalancesQuery({
+ accountHashesString,
+ network,
+ accountHashes
+ })
+ ],
+ combine: results => {
+ const accountBalance = results[0].data;
+ const totalBalance = results[0].data?.totalBalance;
+ const liquidBalance = results[0].data?.liquidBalance;
+ const delegatedBalance = results[0].data?.delegatedBalance;
+ const undelegatingBalance = results[0].data?.undelegatingBalance;
+ const currencyRate = results[1].data?.rate;
+ const accountsBalances = results[2].data;
+
+ const totalFormattedFiatBalance =
+ currencyRate && totalBalance
+ ? formatCurrency(
+ motesToCurrency(String(totalBalance), currencyRate),
+ 'USD',
+ {
+ precision: 2
+ }
+ )
+ : '';
+ const liquidFormattedFiatBalance =
+ currencyRate && liquidBalance
+ ? formatCurrency(
+ motesToCurrency(String(liquidBalance), currencyRate),
+ 'USD',
+ {
+ precision: 2
+ }
+ )
+ : '';
+ const delegatedFormattedFiatBalance =
+ currencyRate && delegatedBalance
+ ? formatCurrency(
+ motesToCurrency(String(delegatedBalance), currencyRate),
+ 'USD',
+ {
+ precision: 2
+ }
+ )
+ : '';
+ const undelegatedFormattedFiatBalance =
+ currencyRate && undelegatingBalance
+ ? formatCurrency(
+ motesToCurrency(String(undelegatingBalance), currencyRate),
+ 'USD',
+ {
+ precision: 2
+ }
+ )
+ : '';
+
+ return {
+ accountBalance: {
+ ...accountBalance,
+ totalFormattedFiatBalance,
+ liquidFormattedFiatBalance,
+ delegatedFormattedFiatBalance,
+ undelegatedFormattedFiatBalance
+ },
+ isLoadingBalance: results[0].isLoading,
+ currencyRate: results[1].data,
+ accountsBalances,
+ isLoadingBalances: results[2].isLoading
+ };
+ }
+ });
+
+ return {
+ accountBalance,
+ isLoadingBalance,
+ currencyRate,
+ accountsBalances,
+ isLoadingBalances
+ };
+};
diff --git a/src/libs/services/deployer-service/index.ts b/src/libs/services/deployer-service/index.ts
index 3f622926d..6dbe61b04 100644
--- a/src/libs/services/deployer-service/index.ts
+++ b/src/libs/services/deployer-service/index.ts
@@ -20,11 +20,7 @@ import {
import { getRawPublicKey } from '@libs/entities/Account';
import { toJson } from '@libs/services/utils';
-import {
- Account,
- AccountWithBalance,
- HardwareWalletType
-} from '@libs/types/account';
+import { Account, HardwareWalletType } from '@libs/types/account';
import { CSPRtoMotes, multiplyErc20Balance } from '@libs/ui/utils';
import { ledger } from '../ledger';
@@ -119,7 +115,7 @@ export const makeAuctionManagerDeploy = async (
};
export const makeNativeTransferDeploy = async (
- activeAccount: AccountWithBalance,
+ activeAccount: Account,
recipientPublicKeyHex: string,
amountMotes: string,
networkName: NetworkName,
diff --git a/src/libs/types/account.ts b/src/libs/types/account.ts
index f5f6a57d0..82a5883a6 100644
--- a/src/libs/types/account.ts
+++ b/src/libs/types/account.ts
@@ -14,13 +14,7 @@ export enum HardwareWalletType {
Ledger = 'Ledger'
}
-export interface AccountWithBalance extends Account {
- balance: {
- liquidMotes: string | null;
- };
-}
-
-export interface AccountListRows extends AccountWithBalance {
+export interface AccountListRows extends Account {
id: string;
}
diff --git a/src/libs/ui/components/account-list/account-list-item.tsx b/src/libs/ui/components/account-list/account-list-item.tsx
index d90ed69b0..d7f7b9e80 100644
--- a/src/libs/ui/components/account-list/account-list-item.tsx
+++ b/src/libs/ui/components/account-list/account-list-item.tsx
@@ -56,6 +56,8 @@ interface AccountListItemProps {
showHideAccountItem?: boolean;
closeModal?: (e: React.MouseEvent) => void;
accountsInfo: Record | undefined;
+ accountLiquidBalance: string | undefined;
+ isLoadingBalance: boolean;
}
export const AccountListItem = ({
@@ -65,14 +67,15 @@ export const AccountListItem = ({
isConnected,
showHideAccountItem,
closeModal,
- accountsInfo
+ accountsInfo,
+ accountLiquidBalance,
+ isLoadingBalance
}: AccountListItemProps) => {
- const accountBalance =
- account.balance?.liquidMotes != null
- ? formatNumber(motesToCSPR(account.balance.liquidMotes), {
- precision: { max: 0 }
- })
- : '-';
+ const accountBalance = accountLiquidBalance
+ ? formatNumber(motesToCSPR(accountLiquidBalance), {
+ precision: { max: 0 }
+ })
+ : '0';
const csprName = accountsInfo && accountsInfo[account.accountHash]?.csprName;
const brandingLogo =
@@ -106,7 +109,7 @@ export const AccountListItem = ({
{accountBalance}
diff --git a/src/libs/ui/components/account-list/account-list.tsx b/src/libs/ui/components/account-list/account-list.tsx
index d76c669d4..89921ff01 100644
--- a/src/libs/ui/components/account-list/account-list.tsx
+++ b/src/libs/ui/components/account-list/account-list.tsx
@@ -21,6 +21,7 @@ import { useWindowManager } from '@hooks/use-window-manager';
import { getAccountHashFromPublicKey } from '@libs/entities/Account';
import { FlexColumn, SpacingSize } from '@libs/layout';
import { useFetchAccountsInfo } from '@libs/services/account-info';
+import { useFetchWalletBalance } from '@libs/services/balance-service';
import {
AccountListRowWithAccountHash,
AccountListRows
@@ -56,6 +57,7 @@ export const AccountList = ({ closeModal }: AccountListProps) => {
const accountsPublicKeys = useSelector(selectVaultAccountsPublicKeys);
const accountsInfo = useFetchAccountsInfo(accountsPublicKeys);
+ const { accountsBalances, isLoadingBalance } = useFetchWalletBalance();
useEffect(() => {
const accountListRows = sortAccounts(
@@ -82,6 +84,10 @@ export const AccountList = ({ closeModal }: AccountListProps) => {
const isConnected = connectedAccountNames.includes(account.name);
const isActiveAccount = activeAccountName === account.name;
+ const accountLiquidBalance =
+ accountsBalances &&
+ accountsBalances[account.accountHash]?.liquidBalance;
+
return (
{
changeActiveAccount(account.name);
closeModal(event);
}}
+ accountLiquidBalance={accountLiquidBalance}
accountsInfo={accountsInfo}
+ isLoadingBalance={isLoadingBalance}
/>
);
}}
diff --git a/src/libs/ui/components/account-list/utils.ts b/src/libs/ui/components/account-list/utils.ts
index d794b7637..7b777e8fb 100644
--- a/src/libs/ui/components/account-list/utils.ts
+++ b/src/libs/ui/components/account-list/utils.ts
@@ -1,7 +1,7 @@
-import { Account, AccountWithBalance } from '@libs/types/account';
+import { Account } from '@libs/types/account';
export function sortAccounts(
- accounts: AccountWithBalance[],
+ accounts: Account[],
activeAccountName: string | null,
connectedAccountNames: string[]
) {
diff --git a/src/libs/ui/components/active-account-plate/active-account-plate.tsx b/src/libs/ui/components/active-account-plate/active-account-plate.tsx
index aba7d66cc..439e6327c 100644
--- a/src/libs/ui/components/active-account-plate/active-account-plate.tsx
+++ b/src/libs/ui/components/active-account-plate/active-account-plate.tsx
@@ -42,7 +42,7 @@ const Container = styled(TileContainer)`
interface ActiveAccountPlateProps {
label: string;
- balance: string | null;
+ balance: string | undefined;
symbol: string | null;
top?: SpacingSize;
}
@@ -107,15 +107,13 @@ export const ActiveAccountPlate = ({
9 ? balance : undefined
- }
+ title={balance && balance?.length > 9 ? balance : undefined}
placement="topLeft"
overflowWrap
fullWidth
>
- {balance == null ? '-' : balance}
+ {balance || '-'}
diff --git a/src/libs/ui/components/dynamic-accounts-list-with-select/dynamic-accounts-list-with-select.tsx b/src/libs/ui/components/dynamic-accounts-list-with-select/dynamic-accounts-list-with-select.tsx
index 7e4dba9b7..b15cecf37 100644
--- a/src/libs/ui/components/dynamic-accounts-list-with-select/dynamic-accounts-list-with-select.tsx
+++ b/src/libs/ui/components/dynamic-accounts-list-with-select/dynamic-accounts-list-with-select.tsx
@@ -1,4 +1,5 @@
import { Player } from '@lottiefiles/react-lottie-player';
+import { ICsprBalance } from 'casper-wallet-core/src/domain/tokens';
import React, { useEffect, useState } from 'react';
import {
Controller,
@@ -23,6 +24,7 @@ import { useIsDarkMode } from '@hooks/use-is-dark-mode';
import dotsDarkModeAnimation from '@libs/animations/dots_dark_mode.json';
import dotsLightModeAnimation from '@libs/animations/dots_light_mode.json';
+import { getAccountHashFromPublicKey } from '@libs/entities/Account';
import {
CenteredFlexRow,
FlexColumn,
@@ -68,6 +70,7 @@ interface ListProps {
onLoadMore: () => void;
isLoadingMore: boolean;
namePrefix: string;
+ accountsBalances: Record | undefined;
}
type FormFields = FieldValues & {
@@ -83,7 +86,8 @@ export const DynamicAccountsListWithSelect = ({
maxItemsToRender,
onLoadMore,
isLoadingMore,
- namePrefix
+ namePrefix,
+ accountsBalances
}: ListProps) => {
const [accountNames, setAccountNames] = useState<{ name: string }[]>([]);
const [checkboxes, setCheckboxes] = useState([]);
@@ -152,12 +156,16 @@ export const DynamicAccountsListWithSelect = ({
renderRow={(account, index) => {
const inputFieldName = `accountNames.${index}.name`;
const checkBoxFieldName = `checkbox.${index}`;
- const balance = formatNumber(
- motesToCSPR(String(account.balance.liquidMotes)),
- {
- precision: { max: 0 }
- }
- );
+ const accountHash = getAccountHashFromPublicKey(account.publicKey);
+
+ const accountLiquidBalance =
+ accountsBalances && accountsBalances[accountHash]?.liquidBalance;
+
+ const accountBalance = accountLiquidBalance
+ ? formatNumber(motesToCSPR(accountLiquidBalance), {
+ precision: { max: 0 }
+ })
+ : '0';
const isAlreadyConnected = alreadyConnectedLedgerAccounts.some(
alreadyConnectedAccount =>
@@ -232,7 +240,9 @@ export const DynamicAccountsListWithSelect = ({
9 ? balance : undefined}
+ title={
+ accountBalance.length > 9 ? accountBalance : undefined
+ }
placement="topLeft"
overflowWrap
fullWidth
@@ -242,7 +252,7 @@ export const DynamicAccountsListWithSelect = ({
style={{ textAlign: 'right' }}
ellipsis
>
- {balance}
+ {accountBalance}
{
diff --git a/src/libs/ui/components/transaction-fee-plate/transaction-fee-plate.tsx b/src/libs/ui/components/transaction-fee-plate/transaction-fee-plate.tsx
index 111e1afe6..da8dd3d73 100644
--- a/src/libs/ui/components/transaction-fee-plate/transaction-fee-plate.tsx
+++ b/src/libs/ui/components/transaction-fee-plate/transaction-fee-plate.tsx
@@ -1,16 +1,14 @@
import React from 'react';
import { Trans, useTranslation } from 'react-i18next';
-import { useSelector } from 'react-redux';
import styled from 'styled-components';
import { TRANSFER_COST_MOTES } from '@src/constants';
-import { selectAccountCurrencyRate } from '@background/redux/account-info/selectors';
-
import {
AlignedSpaceBetweenFlexRow,
RightAlignedFlexColumn
} from '@libs/layout';
+import { useFetchWalletBalance } from '@libs/services/balance-service';
import { Tile, Typography } from '@libs/ui/components';
import { formatFiatAmount, formatNumber, motesToCSPR } from '@libs/ui/utils';
@@ -27,7 +25,7 @@ export const TransactionFeePlate = ({
}: TransactionFeePlateProps) => {
const { t } = useTranslation();
- const currencyRate = useSelector(selectAccountCurrencyRate);
+ const { currencyRate } = useFetchWalletBalance();
return (
@@ -45,7 +43,7 @@ export const TransactionFeePlate = ({
{formatFiatAmount(
motesToCSPR(TRANSFER_COST_MOTES) || '0',
- currencyRate,
+ currencyRate?.rate || null,
3
)}
diff --git a/src/libs/ui/forms/create-account.ts b/src/libs/ui/forms/create-account.ts
index 382166e93..e633ec467 100644
--- a/src/libs/ui/forms/create-account.ts
+++ b/src/libs/ui/forms/create-account.ts
@@ -3,7 +3,7 @@ import { yupResolver } from '@hookform/resolvers/yup/dist/yup';
import { UseFormProps, useForm } from 'react-hook-form';
import { SecretPhrase, deriveKeyPair } from '@libs/crypto';
-import { AccountWithBalance } from '@libs/types/account';
+import { Account } from '@libs/types/account';
import { useAccountNameRule } from './form-validation-rules';
@@ -34,7 +34,7 @@ export function useCreateAccountForm(
export function getDefaultName(
existingAccountNames: string[],
- derivedAccounts: AccountWithBalance[],
+ derivedAccounts: Account[],
secretPhrase: SecretPhrase | null
) {
const accountString = 'Account';
diff --git a/src/libs/ui/forms/form-validation-rules.ts b/src/libs/ui/forms/form-validation-rules.ts
index 0a7789715..09ca5a2aa 100644
--- a/src/libs/ui/forms/form-validation-rules.ts
+++ b/src/libs/ui/forms/form-validation-rules.ts
@@ -141,13 +141,12 @@ export const useRecipientPublicKeyRule = () => {
});
};
-export const useCSPRTransferAmountRule = (amountMotes: string | null) => {
+export const useCSPRTransferAmountRule = (amountMotes: string | undefined) => {
const { t } = useTranslation();
- const maxAmountMotes: string =
- amountMotes == null
- ? '0'
- : Big(amountMotes).sub(TRANSFER_COST_MOTES).toFixed();
+ const maxAmountMotes: string = !amountMotes
+ ? '0'
+ : Big(amountMotes).sub(TRANSFER_COST_MOTES).toFixed();
return Yup.string()
.required(t('Amount is required'))
@@ -269,11 +268,12 @@ export const useErc20AmountRule = (
});
};
-export const usePaymentAmountRule = (csprBalance: string | null) => {
+export const usePaymentAmountRule = (csprBalance: string | undefined) => {
const { t } = useTranslation();
- const maxAmountMotes: string =
- csprBalance == null ? '0' : Big(csprBalance).toFixed();
+ const maxAmountMotes: string = !csprBalance
+ ? '0'
+ : Big(csprBalance).toFixed();
return Yup.string()
.required(t('Payment amount is required'))
@@ -315,7 +315,7 @@ export const usePaymentAmountRule = (csprBalance: string | null) => {
};
export const useCSPRStakeAmountRule = (
- amountMotes: string | null,
+ amountMotes: string | undefined,
mode: AuctionManagerEntryPoint,
stakeAmountMotes: string
) => {
@@ -337,10 +337,9 @@ export const useCSPRStakeAmountRule = (
}
};
- const maxAmountMotes: string =
- amountMotes == null
- ? '0'
- : Big(amountMotes).sub(STAKE_COST_MOTES).toFixed();
+ const maxAmountMotes: string = !amountMotes
+ ? '0'
+ : Big(amountMotes).sub(STAKE_COST_MOTES).toFixed();
return Yup.string()
.required({
diff --git a/src/libs/ui/forms/stakes-form.ts b/src/libs/ui/forms/stakes-form.ts
index 4b40c5660..2b57b78cf 100644
--- a/src/libs/ui/forms/stakes-form.ts
+++ b/src/libs/ui/forms/stakes-form.ts
@@ -23,7 +23,7 @@ export type StakeAmountFormValues = {
};
export const useStakesForm = (
- amountMotes: string | null,
+ amountMotes: string | undefined,
stakeType: AuctionManagerEntryPoint,
stakeAmountMotes: string,
delegatorsNumber?: number,
diff --git a/src/libs/ui/forms/transfer-nft.ts b/src/libs/ui/forms/transfer-nft.ts
index e0fc37bbd..b7225cfe2 100644
--- a/src/libs/ui/forms/transfer-nft.ts
+++ b/src/libs/ui/forms/transfer-nft.ts
@@ -16,7 +16,7 @@ export type TransferNftRecipientFormValues = {
};
export const useTransferNftForm = (
- amountMotes: string | null,
+ amountMotes: string | undefined,
paymentAmount: string
) => {
const recipientFormSchema = Yup.object().shape({
diff --git a/src/libs/ui/forms/transfer.ts b/src/libs/ui/forms/transfer.ts
index 6d6fe9aaf..1006fddf0 100644
--- a/src/libs/ui/forms/transfer.ts
+++ b/src/libs/ui/forms/transfer.ts
@@ -41,7 +41,7 @@ export const useTransferRecipientForm = () => {
export const useTransferAmountForm = (
erc20Balance: string | null,
isErc20: boolean,
- amountMotes: string | null,
+ amountMotes: string | undefined,
paymentAmount: string,
decimals: number | undefined
) => {