diff --git a/components/brave_wallet_ui/common/async/balanceUpdater.ts b/components/brave_wallet_ui/common/async/balanceUpdater.ts new file mode 100644 index 000000000000..b8e558e1bca4 --- /dev/null +++ b/components/brave_wallet_ui/common/async/balanceUpdater.ts @@ -0,0 +1,22 @@ +// Copyright (c) 2021 The Brave Authors. All rights reserved. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// you can obtain one at http://mozilla.org/MPL/2.0/. + +export default class BalanceUpdater { + private intervalId: ReturnType | undefined + + beginUpdatingBalances (timeMs: number, onUpdateBalances: () => unknown) { + this.intervalId = setInterval( + () => { + onUpdateBalances() + }, timeMs) + } + + stopUpdatingBalances () { + if (this.intervalId) { + clearTimeout(this.intervalId) + this.intervalId = undefined + } + } +} diff --git a/components/brave_wallet_ui/common/async/handlers.ts b/components/brave_wallet_ui/common/async/handlers.ts index a803e7501c85..0203217f40b9 100644 --- a/components/brave_wallet_ui/common/async/handlers.ts +++ b/components/brave_wallet_ui/common/async/handlers.ts @@ -45,14 +45,17 @@ import { refreshSitePermissions, refreshTransactionHistory, refreshBalances, + refreshVisibleTokenInfo, refreshPrices } from './lib' import { Store } from './types' import InteractionNotifier from './interactionNotifier' +import BalanceUpdater from './balanceUpdater' const handler = new AsyncActionHandler() const interactionNotifier = new InteractionNotifier() +const balanceUpdater = new BalanceUpdater() function getWalletState (store: Store): WalletState { return store.getState().wallet @@ -60,7 +63,8 @@ function getWalletState (store: Store): WalletState { async function refreshBalancesPricesAndHistory (store: Store) { const state = getWalletState(store) - await store.dispatch(refreshBalances(state.selectedNetwork)) + await store.dispatch(refreshVisibleTokenInfo(state.selectedNetwork)) + await store.dispatch(refreshBalances()) await store.dispatch(refreshPrices()) await store.dispatch(refreshTokenPriceHistory(state.selectedPortfolioTimeline)) } @@ -101,7 +105,8 @@ async function updateAccountInfo (store: Store) { handler.on(WalletActions.refreshBalancesAndPrices.getType(), async (store: Store) => { const state = getWalletState(store) - await store.dispatch(refreshBalances(state.selectedNetwork)) + await store.dispatch(refreshVisibleTokenInfo(state.selectedNetwork)) + await store.dispatch(refreshBalances()) await store.dispatch(refreshPrices()) }) @@ -131,6 +136,7 @@ handler.on(WalletActions.keyringReset.getType(), async (store) => { handler.on(WalletActions.locked.getType(), async (store) => { interactionNotifier.stopWatchingForInteraction() + balanceUpdater.stopUpdatingBalances() await refreshWalletInfo(store) }) @@ -219,7 +225,11 @@ handler.on(WalletActions.initialized.getType(), async (store: Store, payload: Wa // Fetch Balances and Prices if (!state.isWalletLocked && state.isWalletCreated) { const currentNetwork = await store.dispatch(refreshNetworkInfo()) - await store.dispatch(refreshBalances(currentNetwork)) + await store.dispatch(refreshVisibleTokenInfo(currentNetwork)) + await store.dispatch(refreshBalances()) + balanceUpdater.beginUpdatingBalances(15000, async () => { + await store.dispatch(refreshBalances()) + }) await store.dispatch(refreshPrices()) await store.dispatch(refreshTokenPriceHistory(state.selectedPortfolioTimeline)) } diff --git a/components/brave_wallet_ui/common/async/lib.ts b/components/brave_wallet_ui/common/async/lib.ts index 340418ca9b7b..13a94a4f7f05 100644 --- a/components/brave_wallet_ui/common/async/lib.ts +++ b/components/brave_wallet_ui/common/async/lib.ts @@ -161,12 +161,9 @@ export async function getIsSwapSupported (network: BraveWallet.EthereumChain): P return (await swapService.isSwapSupported(network.chainId)).result } -export function refreshBalances (currentNetwork: BraveWallet.EthereumChain) { - return async (dispatch: Dispatch, getState: () => State) => { - const { braveWalletService, jsonRpcService } = getAPIProxy() - const { wallet: { accounts } } = getState() - - const visibleTokensInfo = await braveWalletService.getUserAssets(currentNetwork.chainId) +export function refreshVisibleTokenInfo (currentNetwork: BraveWallet.EthereumChain) { + return async (dispatch: Dispatch) => { + const { braveWalletService } = getAPIProxy() // Selected Network's Native Asset const nativeAsset: BraveWallet.BlockchainToken = { @@ -182,6 +179,17 @@ export function refreshBalances (currentNetwork: BraveWallet.EthereumChain) { coingeckoId: '' } + const visibleTokensInfo = await braveWalletService.getUserAssets(currentNetwork.chainId) + const visibleAssets: BraveWallet.BlockchainToken[] = visibleTokensInfo.tokens.length === 0 ? [nativeAsset] : visibleTokensInfo.tokens + await dispatch(WalletActions.setVisibleTokensInfo(visibleAssets)) + } +} + +export function refreshBalances () { + return async (dispatch: Dispatch, getState: () => State) => { + const { jsonRpcService } = getAPIProxy() + const { wallet: { accounts, userVisibleTokensInfo } } = getState() + const getBalanceReturnInfos = await Promise.all(accounts.map(async (account) => { const balanceInfo = await jsonRpcService.getBalance(account.address, account.coin) return balanceInfo @@ -190,9 +198,7 @@ export function refreshBalances (currentNetwork: BraveWallet.EthereumChain) { balances: getBalanceReturnInfos })) - const visibleAssets: BraveWallet.BlockchainToken[] = visibleTokensInfo.tokens.length === 0 ? [nativeAsset] : visibleTokensInfo.tokens - await dispatch(WalletActions.setVisibleTokensInfo(visibleAssets)) - const visibleTokens = visibleAssets.filter(asset => asset.contractAddress !== '') + const visibleTokens = userVisibleTokensInfo.filter(asset => asset.contractAddress !== '') const getBlockchainTokenBalanceReturnInfos = await Promise.all(accounts.map(async (account) => { return Promise.all(visibleTokens.map(async (token) => { @@ -284,12 +290,12 @@ export function refreshTokenPriceHistory (selectedPortfolioTimeline: BraveWallet const balance = token.contractAddress ? account.tokenBalanceRegistry[token.contractAddress.toLowerCase()] : account.balance - return { - token, - balance: balance || '0', - history: priceHistory.find((t) => token.contractAddress === t.contractAddress)?.history ?? { success: true, values: [] } - } - }) + return { + token, + balance: balance || '0', + history: priceHistory.find((t) => token.contractAddress === t.contractAddress)?.history ?? { success: true, values: [] } + } + }) }) dispatch(WalletActions.portfolioPriceHistoryUpdated(priceHistoryWithBalances)) diff --git a/components/brave_wallet_ui/components/desktop/views/crypto/index.tsx b/components/brave_wallet_ui/components/desktop/views/crypto/index.tsx index 2817acf7372a..27d11b116de0 100644 --- a/components/brave_wallet_ui/components/desktop/views/crypto/index.tsx +++ b/components/brave_wallet_ui/components/desktop/views/crypto/index.tsx @@ -189,7 +189,7 @@ const CryptoView = (props: Props) => { setHideNav(false) } } - }, [id, userVisibleTokensInfo, category, accounts]) + }, [id, userVisibleTokensInfo, category]) const toggleNav = () => { setHideNav(!hideNav)