From 12c4b3aedf1cbe57065e689aa99b5fc08815dbc2 Mon Sep 17 00:00:00 2001 From: Godwin JIbs <126525197+Jibz-Mysten@users.noreply.github.com> Date: Thu, 25 May 2023 10:07:09 -0400 Subject: [PATCH] move useGetAllBalance and useGetCoinBalance to core (#12164) ## Description - Move the useGetAllBalance and useGetCoinBalance to core - Fix the reordering issue on the Token --- apps/core/src/hooks/useGetAllBalances.ts | 23 +++++++++++++++ .../src}/hooks/useGetCoinBalance.ts | 15 ++++------ apps/core/src/index.ts | 2 ++ .../src/components/OwnedCoins/index.tsx | 2 +- apps/explorer/src/hooks/useGetAllBalances.ts | 15 ---------- .../components/active-coins-card/index.tsx | 13 +++++++-- .../components/ledger/LedgerAccountRow.tsx | 12 ++++++-- apps/wallet/src/ui/app/helpers/index.ts | 1 + .../ui/app/helpers/sortGetAllBalancesToken.ts | 14 +++++++++ apps/wallet/src/ui/app/hooks/index.ts | 3 +- .../ui/app/hooks/useCoinsReFetchingConfig.ts | 17 +++++++++++ .../src/ui/app/hooks/useGetAllBalances.ts | 29 ------------------- .../app/pages/home/tokens/TokensDetails.tsx | 25 +++++++++++++--- .../DelegationDetailCard.tsx | 8 +++-- .../src/ui/app/staking/stake/StakingCard.tsx | 16 ++++++++-- 15 files changed, 124 insertions(+), 71 deletions(-) create mode 100644 apps/core/src/hooks/useGetAllBalances.ts rename apps/{wallet/src/ui/app => core/src}/hooks/useGetCoinBalance.ts (58%) delete mode 100644 apps/explorer/src/hooks/useGetAllBalances.ts create mode 100644 apps/wallet/src/ui/app/helpers/sortGetAllBalancesToken.ts create mode 100644 apps/wallet/src/ui/app/hooks/useCoinsReFetchingConfig.ts delete mode 100644 apps/wallet/src/ui/app/hooks/useGetAllBalances.ts diff --git a/apps/core/src/hooks/useGetAllBalances.ts b/apps/core/src/hooks/useGetAllBalances.ts new file mode 100644 index 0000000000000..209637a806339 --- /dev/null +++ b/apps/core/src/hooks/useGetAllBalances.ts @@ -0,0 +1,23 @@ +// Copyright (c) Mysten Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 + +import { useRpcClient } from '../api/RpcClientContext'; +import { type SuiAddress, CoinBalance } from '@mysten/sui.js'; +import { useQuery } from '@tanstack/react-query'; + +export function useGetAllBalances( + address?: SuiAddress | null, + refetchInterval?: number, + staleTime?: number, + select?: (data: CoinBalance[]) => TResult +) { + const rpc = useRpcClient(); + return useQuery({ + queryKey: ['get-all-balance', address], + queryFn: () => rpc.getAllBalances({ owner: address! }), + enabled: !!address, + refetchInterval, + staleTime, + select, + }); +} diff --git a/apps/wallet/src/ui/app/hooks/useGetCoinBalance.ts b/apps/core/src/hooks/useGetCoinBalance.ts similarity index 58% rename from apps/wallet/src/ui/app/hooks/useGetCoinBalance.ts rename to apps/core/src/hooks/useGetCoinBalance.ts index fcab65756c8c1..a4e02bf638f9b 100644 --- a/apps/wallet/src/ui/app/hooks/useGetCoinBalance.ts +++ b/apps/core/src/hooks/useGetCoinBalance.ts @@ -1,28 +1,23 @@ // Copyright (c) Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 -import { useFeatureValue } from '@growthbook/growthbook-react'; -import { useRpcClient } from '@mysten/core'; +import { useRpcClient } from '../api/RpcClientContext'; import { type SuiAddress } from '@mysten/sui.js'; import { useQuery } from '@tanstack/react-query'; -import { FEATURES } from '_src/shared/experimentation/features'; - export function useGetCoinBalance( coinType: string, - address?: SuiAddress | null + address?: SuiAddress | null, + refetchInterval?: number, + staleTime?: number ) { const rpc = useRpcClient(); - const refetchInterval = useFeatureValue( - FEATURES.WALLET_BALANCE_REFETCH_INTERVAL, - 20_000 - ); return useQuery({ queryKey: ['coin-balance', address, coinType], queryFn: () => rpc.getBalance({ owner: address!, coinType }), enabled: !!address && !!coinType, refetchInterval, - staleTime: 5_000, + staleTime, }); } diff --git a/apps/core/src/index.ts b/apps/core/src/index.ts index 1e0d461518ad0..0859276bec093 100644 --- a/apps/core/src/index.ts +++ b/apps/core/src/index.ts @@ -30,3 +30,5 @@ export * from './hooks/useCopyToClipboard'; export * from './hooks/useGetOriginByteKioskContents'; export * from './hooks/useAppsBackend'; export * from './hooks/useGetCoins'; +export * from './hooks/useGetAllBalances'; +export * from './hooks/useGetCoinBalance'; diff --git a/apps/explorer/src/components/OwnedCoins/index.tsx b/apps/explorer/src/components/OwnedCoins/index.tsx index 0649d4e8472d1..c18f6832df439 100644 --- a/apps/explorer/src/components/OwnedCoins/index.tsx +++ b/apps/explorer/src/components/OwnedCoins/index.tsx @@ -1,11 +1,11 @@ // Copyright (c) Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 +import { useGetAllBalances } from '@mysten/core'; import { useState } from 'react'; import OwnedCoinView from './OwnedCoinView'; -import { useGetAllBalances } from '~/hooks/useGetAllBalances'; import { Heading } from '~/ui/Heading'; import { LoadingSpinner } from '~/ui/LoadingSpinner'; import { Pagination } from '~/ui/Pagination'; diff --git a/apps/explorer/src/hooks/useGetAllBalances.ts b/apps/explorer/src/hooks/useGetAllBalances.ts deleted file mode 100644 index 0e15eef469149..0000000000000 --- a/apps/explorer/src/hooks/useGetAllBalances.ts +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) Mysten Labs, Inc. -// SPDX-License-Identifier: Apache-2.0 - -import { useRpcClient } from '@mysten/core'; -import { type SuiAddress } from '@mysten/sui.js'; -import { useQuery } from '@tanstack/react-query'; - -export function useGetAllBalances(address?: SuiAddress | null) { - const rpc = useRpcClient(); - return useQuery({ - queryKey: ['get-all-balances', address], - queryFn: async () => await rpc.getAllBalances({ owner: address! }), - enabled: !!address, - }); -} diff --git a/apps/wallet/src/ui/app/components/active-coins-card/index.tsx b/apps/wallet/src/ui/app/components/active-coins-card/index.tsx index e6de3755147fe..7ae00391dea68 100644 --- a/apps/wallet/src/ui/app/components/active-coins-card/index.tsx +++ b/apps/wallet/src/ui/app/components/active-coins-card/index.tsx @@ -1,13 +1,15 @@ // Copyright (c) Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 +import { useGetAllBalances } from '@mysten/core'; import { SUI_TYPE_ARG } from '@mysten/sui.js'; import { Link } from 'react-router-dom'; import { CoinItem } from './CoinItem'; import { useActiveAddress } from '_app/hooks/useActiveAddress'; import Loading from '_components/loading'; -import { useGetAllBalances } from '_hooks'; +import { sortGetAllBalancesToken } from '_helpers'; +import { useCoinsReFetchingConfig } from '_hooks'; export function ActiveCoinsCard({ activeCoinType = SUI_TYPE_ARG, @@ -17,7 +19,14 @@ export function ActiveCoinsCard({ showActiveCoin?: boolean; }) { const selectedAddress = useActiveAddress(); - const { data: coins, isLoading } = useGetAllBalances(selectedAddress!); + + const { staleTime, refetchInterval } = useCoinsReFetchingConfig(); + const { data: coins, isLoading } = useGetAllBalances( + selectedAddress!, + refetchInterval, + staleTime, + sortGetAllBalancesToken + ); const activeCoin = coins?.find( ({ coinType }) => coinType === activeCoinType diff --git a/apps/wallet/src/ui/app/components/ledger/LedgerAccountRow.tsx b/apps/wallet/src/ui/app/components/ledger/LedgerAccountRow.tsx index 9ea6146a7d094..b9d154507cacc 100644 --- a/apps/wallet/src/ui/app/components/ledger/LedgerAccountRow.tsx +++ b/apps/wallet/src/ui/app/components/ledger/LedgerAccountRow.tsx @@ -1,12 +1,12 @@ // Copyright (c) Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 -import { useFormatCoin } from '@mysten/core'; +import { useFormatCoin, useGetCoinBalance } from '@mysten/core'; import { CheckFill16 } from '@mysten/icons'; import { formatAddress, type SuiAddress, SUI_TYPE_ARG } from '@mysten/sui.js'; import cl from 'classnames'; -import { useGetCoinBalance } from '../../hooks'; +import { useCoinsReFetchingConfig } from '../../hooks'; import { Text } from '_src/ui/app/shared/text'; type LedgerAccountRowProps = { @@ -18,7 +18,13 @@ export function LedgerAccountRow({ isSelected, address, }: LedgerAccountRowProps) { - const { data: coinBalance } = useGetCoinBalance(SUI_TYPE_ARG, address); + const { staleTime, refetchInterval } = useCoinsReFetchingConfig(); + const { data: coinBalance } = useGetCoinBalance( + SUI_TYPE_ARG, + address, + refetchInterval, + staleTime + ); const [totalAmount, totalAmountSymbol] = useFormatCoin( coinBalance?.totalBalance ?? 0, SUI_TYPE_ARG diff --git a/apps/wallet/src/ui/app/helpers/index.ts b/apps/wallet/src/ui/app/helpers/index.ts index 15cb91b915ea2..aecab553a555f 100644 --- a/apps/wallet/src/ui/app/helpers/index.ts +++ b/apps/wallet/src/ui/app/helpers/index.ts @@ -7,3 +7,4 @@ export { parseAmount } from './parseAmount'; // export { getEventsSummary } from './getEventsSummary'; export { getAmount } from './getAmount'; export { checkStakingTxn } from './checkStakingTxn'; +export { sortGetAllBalancesToken } from './sortGetAllBalancesToken'; diff --git a/apps/wallet/src/ui/app/helpers/sortGetAllBalancesToken.ts b/apps/wallet/src/ui/app/helpers/sortGetAllBalancesToken.ts new file mode 100644 index 0000000000000..67469ee80b9b7 --- /dev/null +++ b/apps/wallet/src/ui/app/helpers/sortGetAllBalancesToken.ts @@ -0,0 +1,14 @@ +// Copyright (c) Mysten Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 + +import { Coin, type CoinBalance } from '@mysten/sui.js'; + +// Sort tokens by symbol and total balance +// Move this to the API backend +export function sortGetAllBalancesToken(tokens: CoinBalance[]) { + return [...tokens].sort((a, b) => + (Coin.getCoinSymbol(a.coinType) + Number(a.totalBalance)).localeCompare( + Coin.getCoinSymbol(b.coinType) + Number(b.totalBalance) + ) + ); +} diff --git a/apps/wallet/src/ui/app/hooks/index.ts b/apps/wallet/src/ui/app/hooks/index.ts index ddd66d9ddff8b..8961b285b538c 100644 --- a/apps/wallet/src/ui/app/hooks/index.ts +++ b/apps/wallet/src/ui/app/hooks/index.ts @@ -15,10 +15,9 @@ export { useTransactionDryRun } from './useTransactionDryRun'; export { useGetTxnRecipientAddress } from './useGetTxnRecipientAddress'; export { useQueryTransactionsByAddress } from './useQueryTransactionsByAddress'; export { useGetTransferAmount } from './useGetTransferAmount'; -export { useGetCoinBalance } from './useGetCoinBalance'; -export { useGetAllBalances } from './useGetAllBalances'; export { useOwnedNFT } from './useOwnedNFT'; export * from './useSigner'; export * from './useTransactionData'; export * from './useActiveAddress'; export * from './useGetAllCoins'; +export * from './useCoinsReFetchingConfig'; diff --git a/apps/wallet/src/ui/app/hooks/useCoinsReFetchingConfig.ts b/apps/wallet/src/ui/app/hooks/useCoinsReFetchingConfig.ts new file mode 100644 index 0000000000000..a83e0b0ab5704 --- /dev/null +++ b/apps/wallet/src/ui/app/hooks/useCoinsReFetchingConfig.ts @@ -0,0 +1,17 @@ +// Copyright (c) Mysten Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 + +import { useFeatureValue } from '@growthbook/growthbook-react'; + +import { FEATURES } from '_src/shared/experimentation/features'; + +export function useCoinsReFetchingConfig() { + const refetchInterval = useFeatureValue( + FEATURES.WALLET_BALANCE_REFETCH_INTERVAL, + 20_000 + ); + return { + refetchInterval, + staleTime: 5_000, + }; +} diff --git a/apps/wallet/src/ui/app/hooks/useGetAllBalances.ts b/apps/wallet/src/ui/app/hooks/useGetAllBalances.ts deleted file mode 100644 index 2a4fda7c5d9d0..0000000000000 --- a/apps/wallet/src/ui/app/hooks/useGetAllBalances.ts +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) Mysten Labs, Inc. -// SPDX-License-Identifier: Apache-2.0 - -import { useFeatureValue } from '@growthbook/growthbook-react'; -import { useRpcClient } from '@mysten/core'; -import { Coin, type SuiAddress } from '@mysten/sui.js'; -import { useQuery } from '@tanstack/react-query'; - -import { FEATURES } from '_src/shared/experimentation/features'; - -export function useGetAllBalances(address?: SuiAddress | null) { - const rpc = useRpcClient(); - const refetchInterval = useFeatureValue( - FEATURES.WALLET_BALANCE_REFETCH_INTERVAL, - 20_000 - ); - - return useQuery({ - queryKey: ['get-all-balance', address], - queryFn: async () => await rpc.getAllBalances({ owner: address! }), - select: (data) => - [...data].sort(({ coinType: a }, { coinType: b }) => - Coin.getCoinSymbol(a).localeCompare(Coin.getCoinSymbol(b)) - ), - enabled: !!address, - refetchInterval, - staleTime: 5_000, - }); -} diff --git a/apps/wallet/src/ui/app/pages/home/tokens/TokensDetails.tsx b/apps/wallet/src/ui/app/pages/home/tokens/TokensDetails.tsx index dabd53ebed413..dda14e272e77d 100644 --- a/apps/wallet/src/ui/app/pages/home/tokens/TokensDetails.tsx +++ b/apps/wallet/src/ui/app/pages/home/tokens/TokensDetails.tsx @@ -1,7 +1,11 @@ // Copyright (c) Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 -import { useAppsBackend } from '@mysten/core'; +import { + useAppsBackend, + useGetCoinBalance, + useGetAllBalances, +} from '@mysten/core'; import { Info12, WalletActionBuy24, @@ -29,7 +33,8 @@ import { LargeButton } from '_app/shared/LargeButton'; import { Text } from '_app/shared/text'; import Alert from '_components/alert'; import Loading from '_components/loading'; -import { useAppSelector, useGetAllBalances, useGetCoinBalance } from '_hooks'; +import { sortGetAllBalancesToken } from '_helpers'; +import { useAppSelector, useCoinsReFetchingConfig } from '_hooks'; import { API_ENV } from '_src/shared/api-env'; import { AccountSelector } from '_src/ui/app/components/AccountSelector'; import { useLedgerNotification } from '_src/ui/app/hooks/useLedgerNotification'; @@ -68,7 +73,13 @@ function PinButton({ function MyTokens() { const accountAddress = useActiveAddress(); const apiEnv = useAppSelector(({ app }) => app.apiEnv); - const { data, isLoading, isFetched } = useGetAllBalances(accountAddress); + const { staleTime, refetchInterval } = useCoinsReFetchingConfig(); + const { data, isLoading, isFetched } = useGetAllBalances( + accountAddress, + staleTime, + refetchInterval, + sortGetAllBalancesToken + ); const recognizedPackages = useRecognizedPackages(); const [pinnedCoinTypes, { pinCoinType, unpinCoinType }] = @@ -178,12 +189,18 @@ function MyTokens() { function TokenDetails({ coinType }: TokenDetailsProps) { const activeCoinType = coinType || SUI_TYPE_ARG; const accountAddress = useActiveAddress(); + const { staleTime, refetchInterval } = useCoinsReFetchingConfig(); const { data: coinBalance, isError, isLoading, isFetched, - } = useGetCoinBalance(activeCoinType, accountAddress); + } = useGetCoinBalance( + activeCoinType, + accountAddress, + refetchInterval, + staleTime + ); const { apiEnv } = useAppSelector((state) => state.app); const { request } = useAppsBackend(); const { data } = useQuery({ diff --git a/apps/wallet/src/ui/app/staking/delegation-detail/DelegationDetailCard.tsx b/apps/wallet/src/ui/app/staking/delegation-detail/DelegationDetailCard.tsx index c6ea314b77680..11d42439f5140 100644 --- a/apps/wallet/src/ui/app/staking/delegation-detail/DelegationDetailCard.tsx +++ b/apps/wallet/src/ui/app/staking/delegation-detail/DelegationDetailCard.tsx @@ -6,6 +6,7 @@ import { useGetValidatorsApy, useGetSystemState, useCoinMetadata, + useGetCoinBalance, } from '@mysten/core'; import { ArrowLeft16, StakeAdd16, StakeRemove16 } from '@mysten/icons'; import { SUI_TYPE_ARG } from '@mysten/sui.js'; @@ -25,7 +26,7 @@ import { Text } from '_app/shared/text'; import { IconTooltip } from '_app/shared/tooltip'; import Alert from '_components/alert'; import LoadingIndicator from '_components/loading/LoadingIndicator'; -import { useAppSelector, useGetCoinBalance } from '_hooks'; +import { useAppSelector, useCoinsReFetchingConfig } from '_hooks'; import { API_ENV } from '_src/shared/api-env'; import { MIN_NUMBER_SUI_TO_STAKE } from '_src/shared/constants'; import { FEATURES } from '_src/shared/experimentation/features'; @@ -55,9 +56,12 @@ export function DelegationDetailCard({ } = useGetDelegatedStake(accountAddress || ''); const apiEnv = useAppSelector(({ app }) => app.apiEnv); + const { staleTime, refetchInterval } = useCoinsReFetchingConfig(); const { data: suiCoinBalance } = useGetCoinBalance( SUI_TYPE_ARG, - accountAddress + accountAddress, + refetchInterval, + staleTime ); const { data: metadata } = useCoinMetadata(SUI_TYPE_ARG); // set minimum stake amount to 1 SUI diff --git a/apps/wallet/src/ui/app/staking/stake/StakingCard.tsx b/apps/wallet/src/ui/app/staking/stake/StakingCard.tsx index b2507c624f223..b2598b944d23f 100644 --- a/apps/wallet/src/ui/app/staking/stake/StakingCard.tsx +++ b/apps/wallet/src/ui/app/staking/stake/StakingCard.tsx @@ -2,7 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 import { useFeatureIsOn } from '@growthbook/growthbook-react'; -import { useCoinMetadata, useGetSystemState } from '@mysten/core'; +import { + useCoinMetadata, + useGetSystemState, + useGetCoinBalance, +} from '@mysten/core'; import { ArrowLeft16 } from '@mysten/icons'; import { getTransactionDigest, @@ -41,7 +45,7 @@ import { Collapse } from '_app/shared/collapse'; import { Text } from '_app/shared/text'; import Loading from '_components/loading'; import { parseAmount } from '_helpers'; -import { useSigner, useGetCoinBalance } from '_hooks'; +import { useSigner, useCoinsReFetchingConfig } from '_hooks'; import { Coin } from '_redux/slices/sui-objects/Coin'; import { MIN_NUMBER_SUI_TO_STAKE } from '_src/shared/constants'; import { FEATURES } from '_src/shared/experimentation/features'; @@ -58,8 +62,14 @@ export type FormValues = typeof initialValues; function StakingCard() { const coinType = SUI_TYPE_ARG; const accountAddress = useActiveAddress(); + const { staleTime, refetchInterval } = useCoinsReFetchingConfig(); const { data: suiBalance, isLoading: loadingSuiBalances } = - useGetCoinBalance(SUI_TYPE_ARG, accountAddress); + useGetCoinBalance( + SUI_TYPE_ARG, + accountAddress, + refetchInterval, + staleTime + ); const coinBalance = BigInt(suiBalance?.totalBalance || 0); const [searchParams] = useSearchParams(); const validatorAddress = searchParams.get('address');