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

refactor: use useSWR in useUpdateUsdcBalances #2164

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import { warningToast } from '../common/atoms/Toast'
import { CommonAddress } from '../../util/CommonAddressUtils'
import { ArbOneNativeUSDC } from '../../util/L2NativeUtils'
import { getNetworkName, isNetwork } from '../../util/networks'
import { useUpdateUSDCBalances } from '../../hooks/CCTP/useUpdateUSDCBalances'
import { useUpdateUsdcBalances } from '../../hooks/CCTP/useUpdateUsdcBalances'
import { useAccountType } from '../../hooks/useAccountType'
import { useNativeCurrency } from '../../hooks/useNativeCurrency'
import { SearchPanelTable } from '../common/SearchPanel/SearchPanelTable'
Expand Down Expand Up @@ -538,7 +538,7 @@ export function TokenSearch({
parentChainProvider,
isTeleportMode
} = useNetworksRelationship(networks)
const { updateUSDCBalances } = useUpdateUSDCBalances({ walletAddress })
const { updateUsdcBalances } = useUpdateUsdcBalances({ walletAddress })
const { isLoading: isLoadingAccountType } = useAccountType()
const { openDialog: openTransferDisabledDialog } =
useTransferDisabledDialogStore()
Expand Down Expand Up @@ -574,7 +574,7 @@ export function TokenSearch({
return
}

await updateUSDCBalances()
updateUsdcBalances()

// if an Orbit chain is selected we need to fetch its USDC address
let childChainUsdcAddress
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
isTokenSepoliaUSDC,
isTokenMainnetUSDC
} from '../../util/TokenUtils'
import { useUpdateUSDCBalances } from '../../hooks/CCTP/useUpdateUSDCBalances'
import { useUpdateUsdcBalances } from '../../hooks/CCTP/useUpdateUsdcBalances'
import { useNativeCurrency } from '../../hooks/useNativeCurrency'
import { useNetworks } from '../../hooks/useNetworks'
import { useNetworksRelationship } from '../../hooks/useNetworksRelationship'
Expand Down Expand Up @@ -236,7 +236,7 @@ export function TransferPanelMain() {

const { updateErc20ParentBalances, updateErc20ChildBalances } = useBalances()

const { updateUSDCBalances } = useUpdateUSDCBalances({
const { updateUsdcBalances } = useUpdateUsdcBalances({
walletAddress: destinationAddressOrWalletAddress
})

Expand All @@ -262,7 +262,7 @@ export function TransferPanelMain() {
isTokenArbitrumOneNativeUSDC(selectedToken.address) ||
isTokenArbitrumSepoliaNativeUSDC(selectedToken.address))
) {
updateUSDCBalances()
updateUsdcBalances()
return
}

Expand All @@ -275,7 +275,7 @@ export function TransferPanelMain() {
updateErc20ParentBalances,
updateErc20ChildBalances,
destinationAddressOrWalletAddress,
updateUSDCBalances,
updateUsdcBalances,
isTeleportMode
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { useInterval, useLatest } from 'react-use'
import { useAccount } from 'wagmi'

import { useAppState } from '../../state'
import { useUpdateUSDCBalances } from '../../hooks/CCTP/useUpdateUSDCBalances'
import { useUpdateUsdcBalances } from '../../hooks/CCTP/useUpdateUsdcBalances'
import { isTokenNativeUSDC } from '../../util/TokenUtils'

// Updates all balances periodically
export function useBalanceUpdater() {
Expand All @@ -12,14 +13,17 @@ export function useBalanceUpdater() {
const { address: walletAddress } = useAccount()
const latestTokenBridge = useLatest(arbTokenBridge)

const { updateUSDCBalances } = useUpdateUSDCBalances({
const { updateUsdcBalances } = useUpdateUsdcBalances({
walletAddress
})

useInterval(() => {
updateUSDCBalances()

if (selectedToken) {
if (isTokenNativeUSDC(selectedToken.address)) {
updateUsdcBalances()
return
}

latestTokenBridge?.current?.token?.updateTokenData(selectedToken.address)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just thinking here, can we maybe call updateUSDCBalances in updateTokenData directly?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

supposedly, i think it requires some exploration and so i haven't created any tickets for it or dealt with it on this PR as it's out of scope

}
}, 10000)
Expand Down

This file was deleted.

135 changes: 135 additions & 0 deletions packages/arb-token-bridge-ui/src/hooks/CCTP/useUpdateUsdcBalances.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { useCallback, useMemo } from 'react'
import { isAddress } from 'ethers/lib/utils.js'
import { Address } from 'wagmi'
import useSWRImmutable from 'swr/immutable'

import { CommonAddress } from '../../util/CommonAddressUtils'
import { getL2ERC20Address } from '../../util/TokenUtils'
import { useNetworks } from '../useNetworks'
import { useNetworksRelationship } from '../useNetworksRelationship'
import { isNetwork } from '../../util/networks'
import { useBalances } from '../useBalances'
import { getProviderForChainId } from '@/token-bridge-sdk/utils'

export async function childChainUsdcAddressFetcher([
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we do something like this, also renaming the method? I see that it's easier to pass directly from SWR with an array, but it's just harder to read when calling the method.

getChildUsdcAddress({
   parentUsdcAddress,
   parentChainId,
   childChainId
)}

nit: I don't think we need to usd chain in variable names, it's implied. We've been using it without chain on the bridge already and everywhere in the sdk. Might wanna follow the same structure.

_parentChainUsdcAddress,
Copy link
Contributor

@brtkx brtkx Jan 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we can do something about _parentChainUsdcAddress, it should not be required for non-Orbit chains, so we should be able to just call the method without specifying parent USDC address and rely on chain ID only.

Maybe we don't need useParentChainUsdcAddress, we could just make it a util method and use it here as well?

parentChainId,
childChainId
]: [Address, number, number]) {
const {
isEthereumMainnet: isParentEthereumMainnet,
isSepolia: isParentSepolia
} = isNetwork(parentChainId)

if (isParentEthereumMainnet) {
return CommonAddress.ArbitrumOne.USDC
}

if (isParentSepolia) {
return CommonAddress.ArbitrumSepolia.USDC
}

const _parentChainProvider = getProviderForChainId(parentChainId)
const _childChainProvider = getProviderForChainId(childChainId)

return getL2ERC20Address({
erc20L1Address: _parentChainUsdcAddress,
l1Provider: _parentChainProvider,
l2Provider: _childChainProvider
})
}

export function useParentChainUsdcAddress() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IF you decide to go with variable names without 'chain', can rename this to useParentUsdcAddress. Otherwise keep consistent.

const [networks] = useNetworks()
const { parentChain } = useNetworksRelationship(networks)

return useMemo(() => {
fionnachan marked this conversation as resolved.
Show resolved Hide resolved
const {
isEthereumMainnet: isParentEthereumMainnet,
isSepolia: isParentSepolia,
isArbitrumOne: isParentArbitrumOne,
isArbitrumSepolia: isParentArbitrumSepolia
} = isNetwork(parentChain.id)

if (isParentEthereumMainnet) {
return CommonAddress.Ethereum.USDC
}

if (isParentSepolia) {
return CommonAddress.Sepolia.USDC
}

if (isParentArbitrumOne) {
return CommonAddress.ArbitrumOne.USDC
}

if (isParentArbitrumSepolia) {
return CommonAddress.ArbitrumSepolia.USDC
}
}, [parentChain.id])
}

export function useUpdateUsdcBalances({
walletAddress
}: {
walletAddress: string | undefined
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit

Suggested change
walletAddress: string | undefined
walletAddress: Address | undefined

}) {
const [networks] = useNetworks()
const { parentChain, childChain } = useNetworksRelationship(networks)

const _walletAddress: Address | undefined =
walletAddress && isAddress(walletAddress) ? walletAddress : undefined
fionnachan marked this conversation as resolved.
Show resolved Hide resolved
const {
updateErc20ParentBalances: updateErc20ParentBalance,
updateErc20ChildBalances: updateErc20ChildBalance
} = useBalances({
parentWalletAddress: _walletAddress,
childWalletAddress: _walletAddress
})

const parentChainUsdcAddress = useParentChainUsdcAddress()

// we don't have native USDC addresses for Orbit chains, we need to fetch it
const {
data: childChainUsdcAddress,
error, // can be unbridged to Orbit chain so no address to be found
fionnachan marked this conversation as resolved.
Show resolved Hide resolved
isLoading
} = useSWRImmutable(
typeof parentChainUsdcAddress !== 'undefined'
? [
parentChainUsdcAddress,
parentChain.id,
childChain.id,
'fetchChildChainUsdcAddress'
]
: null,
childChainUsdcAddressFetcher
)

const updateUsdcBalances = useCallback(() => {
// USDC is not native for the selected networks, do nothing
if (!parentChainUsdcAddress) {
return
}

if (isLoading) {
return
}

updateErc20ParentBalance([parentChainUsdcAddress.toLowerCase()])

if (childChainUsdcAddress) {
updateErc20ChildBalance([childChainUsdcAddress.toLowerCase()])
}
}, [
isLoading,
childChainUsdcAddress,
parentChainUsdcAddress,
updateErc20ChildBalance,
updateErc20ParentBalance
])

return {
updateUsdcBalances
}
}
Loading
Loading