Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: cached safe overviews #4221

Merged
merged 7 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 25 additions & 16 deletions src/components/common/NetworkSelector/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,34 @@ import { useAllSafesGrouped } from '@/components/welcome/MyAccounts/useAllSafesG
import useSafeAddress from '@/hooks/useSafeAddress'
import { sameAddress } from '@/utils/addresses'
import uniq from 'lodash/uniq'
import useSafeOverviews from '@/components/welcome/MyAccounts/useSafeOverviews'
import { useCompatibleNetworks } from '@/features/multichain/hooks/useCompatibleNetworks'
import { useSafeCreationData } from '@/features/multichain/hooks/useSafeCreationData'
import { type ChainInfo } from '@safe-global/safe-gateway-typescript-sdk'
import PlusIcon from '@/public/images/common/plus.svg'
import useAddressBook from '@/hooks/useAddressBook'
import { CreateSafeOnSpecificChain } from '@/features/multichain/components/CreateSafeOnNewChain'
import { useGetSafeOverviewQuery } from '@/store/api/gateway'

const ChainIndicatorWithFiatBalance = ({
isSelected,
chain,
safeAddress,
}: {
isSelected: boolean
chain: ChainInfo
safeAddress: string
}) => {
const { data: safeOverview } = useGetSafeOverviewQuery({ safeAddress, chainId: chain.chainId })

return (
<ChainIndicator
responsive={isSelected}
chainId={chain.chainId}
fiatValue={safeOverview ? safeOverview.fiatTotal : undefined}
inline
/>
)
}

export const getNetworkLink = (router: NextRouter, safeAddress: string, networkShortName: string) => {
const isSafeOpened = safeAddress !== ''
Expand Down Expand Up @@ -272,12 +293,6 @@ const NetworkSelector = ({
[availableChainIds, configs],
)

const multiChainSafes = useMemo(
() => availableChainIds.map((chain) => ({ address: safeAddress, chainId: chain })),
[availableChainIds, safeAddress],
)
const [safeOverviews] = useSafeOverviews(multiChainSafes)

const onChange = (event: SelectChangeEvent) => {
event.preventDefault() // Prevent the link click

Expand All @@ -293,9 +308,8 @@ const NetworkSelector = ({

const renderMenuItem = useCallback(
(chainId: string, isSelected: boolean) => {
useChainId
const chain = chains.data.find((chain) => chain.chainId === chainId)
const safeOverview = safeOverviews?.find((overview) => chainId === overview.chainId)

if (!chain) return null

return (
Expand All @@ -305,17 +319,12 @@ const NetworkSelector = ({
onClick={onChainSelect}
className={css.item}
>
<ChainIndicator
responsive={isSelected}
chainId={chain.chainId}
fiatValue={safeOverview ? safeOverview.fiatTotal : undefined}
inline
/>
<ChainIndicatorWithFiatBalance chain={chain} safeAddress={safeAddress} isSelected={isSelected} />
</Link>
</MenuItem>
)
},
[chains.data, onChainSelect, router, safeAddress, safeOverviews],
[chains.data, onChainSelect, router, safeAddress],
)

return configs.length ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import SafeTokenWidget from '..'
import { toBeHex } from 'ethers'
import { AppRoutes } from '@/config/routes'
import useSafeTokenAllocation, { useSafeVotingPower } from '@/hooks/useSafeTokenAllocation'
import * as safePass from '@/store/safePass'
import type { CampaignLeaderboardEntry } from '@/store/safePass'
import * as safePass from '@/store/api/safePass'
import type { CampaignLeaderboardEntry } from '@/store/api/safePass'

jest.mock('@/hooks/useChainId')

Expand Down
2 changes: 1 addition & 1 deletion src/components/common/SafeTokenWidget/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import css from './styles.module.css'
import useSafeAddress from '@/hooks/useSafeAddress'
import { skipToken } from '@reduxjs/toolkit/query/react'
import { useDarkMode } from '@/hooks/useDarkMode'
import { useGetOwnGlobalCampaignRankQuery } from '@/store/safePass'
import { useGetOwnGlobalCampaignRankQuery } from '@/store/api/safePass'
import { formatAmount } from '@/utils/formatNumber'

const TOKEN_DECIMALS = 18
Expand Down
2 changes: 1 addition & 1 deletion src/components/transactions/SingleTx/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import ExpandableTransactionItem, {
} from '@/components/transactions/TxListItem/ExpandableTransactionItem'
import GroupLabel from '../GroupLabel'
import { isMultisigDetailedExecutionInfo } from '@/utils/transaction-guards'
import { useGetTransactionDetailsQuery } from '@/store/gateway'
import { useGetTransactionDetailsQuery } from '@/store/api/gateway'
import { skipToken } from '@reduxjs/toolkit/query/react'
import { asError } from '@/services/exceptions/utils'

Expand Down
2 changes: 1 addition & 1 deletion src/components/transactions/TxDetails/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import useIsPending from '@/hooks/useIsPending'
import { isImitation, isTrustedTx } from '@/utils/transactions'
import { useHasFeature } from '@/hooks/useChains'
import { FEATURES } from '@/utils/chains'
import { useGetTransactionDetailsQuery } from '@/store/gateway'
import { useGetTransactionDetailsQuery } from '@/store/api/gateway'
import { asError } from '@/services/exceptions/utils'
import { POLLING_INTERVAL } from '@/config/constants'

Expand Down
2 changes: 1 addition & 1 deletion src/components/tx-flow/flows/ExecuteBatch/ReviewBatch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import WalletRejectionError from '@/components/tx/SignOrExecuteForm/WalletReject
import useUserNonce from '@/components/tx/AdvancedParams/useUserNonce'
import { getLatestSafeVersion } from '@/utils/chains'
import { HexEncodedData } from '@/components/transactions/HexEncodedData'
import { useGetMultipleTransactionDetailsQuery } from '@/store/gateway'
import { useGetMultipleTransactionDetailsQuery } from '@/store/api/gateway'
import { skipToken } from '@reduxjs/toolkit/query/react'
import NetworkWarning from '@/components/new-safe/create/NetworkWarning'

Expand Down
2 changes: 1 addition & 1 deletion src/components/tx/DecodedTx/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
import DecodedData from '@/components/transactions/TxDetails/TxData/DecodedData'
import accordionCss from '@/styles/accordion.module.css'
import HelpToolTip from './HelpTooltip'
import { useGetTransactionDetailsQuery } from '@/store/gateway'
import { useGetTransactionDetailsQuery } from '@/store/api/gateway'
import { skipToken } from '@reduxjs/toolkit/query/react'
import { asError } from '@/services/exceptions/utils'

Expand Down
2 changes: 1 addition & 1 deletion src/components/tx/SignOrExecuteForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import { MigrateToL2Information } from './MigrateToL2Information'
import { extractMigrationL2MasterCopyAddress } from '@/utils/transactions'

import type { TransactionDetails } from '@safe-global/safe-gateway-typescript-sdk'
import { useGetTransactionDetailsQuery, useLazyGetTransactionDetailsQuery } from '@/store/gateway'
import { useGetTransactionDetailsQuery, useLazyGetTransactionDetailsQuery } from '@/store/api/gateway'
import { skipToken } from '@reduxjs/toolkit/query/react'
import NetworkWarning from '@/components/new-safe/create/NetworkWarning'

Expand Down
16 changes: 15 additions & 1 deletion src/components/welcome/MyAccounts/AccountItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,17 @@ import FiatValue from '@/components/common/FiatValue'
import QueueActions from './QueueActions'
import { useGetHref } from './useGetHref'
import { extractCounterfactualSafeSetup, isPredictedSafeProps } from '@/features/counterfactual/utils'
import { useGetSafeOverviewQuery } from '@/store/api/gateway'
import useWallet from '@/hooks/wallets/useWallet'
import { skipToken } from '@reduxjs/toolkit/query'

type AccountItemProps = {
safeItem: SafeItem
safeOverview?: SafeOverview
onLinkClick?: () => void
}

const AccountItem = ({ onLinkClick, safeItem, safeOverview }: AccountItemProps) => {
const AccountItem = ({ onLinkClick, safeItem }: AccountItemProps) => {
const { chainId, address } = safeItem
const chain = useAppSelector((state) => selectChainById(state, chainId))
const undeployedSafe = useAppSelector((state) => selectUndeployedSafe(state, chainId, address))
Expand All @@ -42,6 +45,7 @@ const AccountItem = ({ onLinkClick, safeItem, safeOverview }: AccountItemProps)
const router = useRouter()
const isCurrentSafe = chainId === currChainId && sameAddress(safeAddress, address)
const isWelcomePage = router.pathname === AppRoutes.welcome.accounts
const { address: walletAddress } = useWallet() ?? {}

const trackingLabel = isWelcomePage ? OVERVIEW_LABELS.login_page : OVERVIEW_LABELS.sidebar

Expand All @@ -61,6 +65,16 @@ const AccountItem = ({ onLinkClick, safeItem, safeOverview }: AccountItemProps)

const isReplayable = !safeItem.isWatchlist && (!undeployedSafe || !isPredictedSafeProps(undeployedSafe.props))

const { data: safeOverview } = useGetSafeOverviewQuery(
undeployedSafe
? skipToken
: {
chainId: safeItem.chainId,
safeAddress: safeItem.address,
walletAddress,
},
)

return (
<ListItemButton
data-testid="safe-list-item"
Expand Down
28 changes: 21 additions & 7 deletions src/components/welcome/MyAccounts/MultiAccountItem.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { selectUndeployedSafes } from '@/features/counterfactual/store/undeployedSafesSlice'
import type { SafeOverview } from '@safe-global/safe-gateway-typescript-sdk'
import { useMemo, useState } from 'react'
import { useCallback, useMemo, useState } from 'react'
import {
ListItemButton,
Box,
Expand Down Expand Up @@ -33,6 +33,9 @@ import { AddNetworkButton } from './AddNetworkButton'
import { isPredictedSafeProps } from '@/features/counterfactual/utils'
import ChainIndicator from '@/components/common/ChainIndicator'
import MultiAccountContextMenu from '@/components/sidebar/SafeListContextMenu/MultiAccountContextMenu'
import { useGetMultipleSafeOverviewsQuery } from '@/store/api/gateway'
import useWallet from '@/hooks/wallets/useWallet'
import { selectCurrency } from '@/store/settingsSlice'

type MultiAccountItemProps = {
multiSafeAccountItem: MultiChainSafeItem
Expand Down Expand Up @@ -62,7 +65,7 @@ const MultichainIndicator = ({ safes }: { safes: SafeItem[] }) => {
)
}

const MultiAccountItem = ({ onLinkClick, multiSafeAccountItem, safeOverviews }: MultiAccountItemProps) => {
const MultiAccountItem = ({ onLinkClick, multiSafeAccountItem }: MultiAccountItemProps) => {
const { address, safes } = multiSafeAccountItem
const undeployedSafes = useAppSelector(selectUndeployedSafes)
const safeAddress = useSafeAddress()
Expand Down Expand Up @@ -90,6 +93,14 @@ const MultiAccountItem = ({ onLinkClick, multiSafeAccountItem, safeOverviews }:
return Object.values(allAddressBooks).find((ab) => ab[address] !== undefined)?.[address]
}, [address, allAddressBooks])

const currency = useAppSelector(selectCurrency)
const { address: walletAddress } = useWallet() ?? {}
const deployedSafes = useMemo(
() => safes.filter((safe) => undeployedSafes[safe.chainId]?.[safe.address] === undefined),
[safes, undeployedSafes],
)
const { data: safeOverviews } = useGetMultipleSafeOverviewsQuery({ currency, walletAddress, safes: deployedSafes })

const safeSetups = useMemo(
() => getSafeSetups(safes, safeOverviews ?? [], undeployedSafes),
[safeOverviews, safes, undeployedSafes],
Expand All @@ -111,11 +122,14 @@ const MultiAccountItem = ({ onLinkClick, multiSafeAccountItem, safeOverviews }:
[safes, undeployedSafes],
)

const findOverview = (item: SafeItem) => {
return safeOverviews?.find(
(overview) => item.chainId === overview.chainId && sameAddress(overview.address.value, item.address),
)
}
const findOverview = useCallback(
(item: SafeItem) => {
return safeOverviews?.find(
(overview) => item.chainId === overview.chainId && sameAddress(overview.address.value, item.address),
)
},
[safeOverviews],
)

return (
<ListItemButton
Expand Down
28 changes: 2 additions & 26 deletions src/components/welcome/MyAccounts/PaginatedSafeList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import { Paper, Typography } from '@mui/material'
import AccountItem from './AccountItem'
import { type SafeItem } from './useAllSafes'
import css from './styles.module.css'
import useSafeOverviews from './useSafeOverviews'
import { sameAddress } from '@/utils/addresses'
import InfiniteScroll from '@/components/common/InfiniteScroll'
import { type MultiChainSafeItem } from './useAllSafesGrouped'
import MultiAccountItem from './MultiAccountItem'
Expand All @@ -26,35 +24,13 @@ type SafeListPageProps = {
const DEFAULT_PAGE_SIZE = 10

export const SafeListPage = ({ safes, onLinkClick }: SafeListPageProps) => {
const flattenedSafes = useMemo(
() => safes.flatMap((safe) => (isMultiChainSafeItem(safe) ? safe.safes : safe)),
[safes],
)
const [overviews] = useSafeOverviews(flattenedSafes)

const findOverview = (item: SafeItem) => {
return overviews?.find(
(overview) => item.chainId === overview.chainId && sameAddress(overview.address.value, item.address),
)
}

return (
<>
{safes.map((item) =>
isMultiChainSafeItem(item) ? (
<MultiAccountItem
onLinkClick={onLinkClick}
key={item.address}
multiSafeAccountItem={item}
safeOverviews={overviews?.filter((overview) => sameAddress(overview.address.value, item.address))}
/>
<MultiAccountItem onLinkClick={onLinkClick} key={item.address} multiSafeAccountItem={item} />
) : (
<AccountItem
onLinkClick={onLinkClick}
safeItem={item}
safeOverview={findOverview(item)}
key={item.chainId + item.address}
/>
<AccountItem onLinkClick={onLinkClick} safeItem={item} key={item.chainId + item.address} />
),
)}
</>
Expand Down

This file was deleted.

Loading
Loading