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: Remove useArbTokenBridge from store 3/3 #2090

Open
wants to merge 5 commits into
base: fs-1001/add-usecallbacks
Choose a base branch
from
Open
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
117 changes: 22 additions & 95 deletions packages/arb-token-bridge-ui/src/components/App/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,11 @@ import { createOvermind, Overmind } from 'overmind'
import { Provider } from 'overmind-react'
import { useLocalStorage } from '@uidotdev/usehooks'

import { ConnectionState } from '../../util'
import { TokenBridgeParams } from '../../hooks/useArbTokenBridge'
import { WelcomeDialog } from './WelcomeDialog'
import { BlockedDialog } from './BlockedDialog'
import { AppContextProvider } from './AppContext'
import { config, useActions, useAppState } from '../../state'
import { MainContent } from '../MainContent/MainContent'
import { ArbTokenBridgeStoreSync } from '../syncers/ArbTokenBridgeStoreSync'
import { BalanceUpdater } from '../syncers/BalanceUpdater'
import { TokenListSyncer } from '../syncers/TokenListSyncer'
import { Header } from '../common/Header'
import { HeaderAccountPopover } from '../common/HeaderAccountPopover'
Expand All @@ -34,14 +30,14 @@ import { TOS_LOCALSTORAGE_KEY } from '../../constants'
import { getProps } from '../../util/wagmi/setup'
import { useAccountIsBlocked } from '../../hooks/useAccountIsBlocked'
import { useCCTPIsBlocked } from '../../hooks/CCTP/useCCTPIsBlocked'
import { useNativeCurrency } from '../../hooks/useNativeCurrency'
import { sanitizeQueryParams, useNetworks } from '../../hooks/useNetworks'
import { useNetworksRelationship } from '../../hooks/useNetworksRelationship'
import { sanitizeQueryParams } from '../../hooks/useNetworks'
import { HeaderConnectWalletButton } from '../common/HeaderConnectWalletButton'
import { onDisconnectHandler } from '../../util/walletConnectUtils'
import { addressIsSmartContract } from '../../util/AddressUtils'
import { useSyncConnectedChainToAnalytics } from './useSyncConnectedChainToAnalytics'
import { isDepositMode } from '../../util/isDepositMode'
import { useInterval } from 'react-use'
import { useArbTokenBridge } from '../../hooks/useArbTokenBridge'
import { useUpdateUSDCBalances } from '../../hooks/CCTP/useUpdateUSDCBalances'

declare global {
interface Window {
Expand All @@ -58,86 +54,25 @@ const rainbowkitTheme = merge(darkTheme(), {
}
} as Theme)

const ArbTokenBridgeStoreSyncWrapper = (): JSX.Element | null => {
function AppContent() {
const { address, isConnected } = useAccount()
const { isBlocked } = useAccountIsBlocked()
const [tosAccepted] = useLocalStorage<boolean>(TOS_LOCALSTORAGE_KEY, false)
const { openConnectModal } = useConnectModal()
const actions = useActions()
const {
app: { selectedToken }
} = useAppState()
const [networks] = useNetworks()
const { childChain, childChainProvider, parentChain, parentChainProvider } =
useNetworksRelationship(networks)
const nativeCurrency = useNativeCurrency({ provider: childChainProvider })
const {
token: { updateTokenData }
} = useArbTokenBridge()
const { updateUSDCBalances } = useUpdateUSDCBalances({
walletAddress: address
})

// We want to be sure this fetch is completed by the time we open the USDC modals
useCCTPIsBlocked()

const [tokenBridgeParams, setTokenBridgeParams] =
useState<TokenBridgeParams | null>(null)

useEffect(() => {
if (!nativeCurrency.isCustom) {
return
}

const selectedTokenAddress = selectedToken?.address.toLowerCase()
const selectedTokenL2Address = selectedToken?.l2Address?.toLowerCase()
// This handles a super weird edge case where, for example:
//
// Your setup is: from Arbitrum One to Mainnet, and you have $ARB selected as the token you want to bridge over.
// You then switch your destination network to a network that has $ARB as its native currency.
// For this network, $ARB can only be bridged as the native currency, and not as a standard ERC-20, which is why we have to reset the selected token.
if (
selectedTokenAddress === nativeCurrency.address ||
selectedTokenL2Address === nativeCurrency.address
) {
actions.app.setSelectedToken(null)
}
}, [selectedToken, nativeCurrency])
Comment on lines -77 to -95
Copy link
Member

Choose a reason for hiding this comment

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

nice, tested with APE token for Ape chain and it works well after deletion


// Listen for account and network changes
useEffect(() => {
// Any time one of those changes
setTokenBridgeParams(null)
actions.app.setConnectionState(ConnectionState.LOADING)
actions.app.reset(networks.sourceChain.id)
actions.app.setChainIds({
l1NetworkChainId: parentChain.id,
l2NetworkChainId: childChain.id
})

if (
isDepositMode({
sourceChainId: networks.sourceChain.id,
destinationChainId: networks.destinationChain.id
})
) {
console.info('Deposit mode detected:')
actions.app.setConnectionState(ConnectionState.L1_CONNECTED)
} else {
console.info('Withdrawal mode detected:')
actions.app.setConnectionState(ConnectionState.L2_CONNECTED)
}

setTokenBridgeParams({
l1: {
network: parentChain,
provider: parentChainProvider
},
l2: {
network: childChain,
provider: childChainProvider
}
})
}, [
networks.sourceChain.id,
parentChain.id,
childChain.id,
parentChain,
childChain,
parentChainProvider,
childChainProvider
])

useEffect(() => {
axios
.get(
Expand All @@ -149,20 +84,14 @@ const ArbTokenBridgeStoreSyncWrapper = (): JSX.Element | null => {
.catch(err => {
console.warn('Failed to fetch warning tokens:', err)
})
}, [])

if (!tokenBridgeParams) {
return null
}

return <ArbTokenBridgeStoreSync tokenBridgeParams={tokenBridgeParams} />
}
}, [actions.app])

function AppContent() {
const { address, isConnected } = useAccount()
const { isBlocked } = useAccountIsBlocked()
const [tosAccepted] = useLocalStorage<boolean>(TOS_LOCALSTORAGE_KEY, false)
const { openConnectModal } = useConnectModal()
useInterval(() => {
updateUSDCBalances()
if (selectedToken) {
updateTokenData(selectedToken.address)
}
Comment on lines +91 to +93
Copy link
Member

Choose a reason for hiding this comment

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

missing updateUSDCBalances() from BalanceUpdater and so USDC doesn't get updated, e.g. native USDC on Arb Sepolia

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed back here aa3d8fc (#2090)

}, 10_000)

useEffect(() => {
if (tosAccepted && !isConnected) {
Expand Down Expand Up @@ -219,8 +148,6 @@ function AppContent() {
<HeaderAccountPopover />
</Header>
<TokenListSyncer />
<BalanceUpdater />
<ArbTokenBridgeStoreSyncWrapper />
<MainContent />
</>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useLatest } from 'react-use'
import { create } from 'zustand'

import { useERC20L1Address } from '../../hooks/useERC20L1Address'
import { useActions, useAppState } from '../../state'
import { useActions } from '../../state'
import {
erc20DataToErc20BridgeToken,
fetchErc20Data,
Expand All @@ -22,6 +22,8 @@ import { useTransferDisabledDialogStore } from './TransferDisabledDialog'
import { TokenInfo } from './TokenInfo'
import { NoteBox } from '../common/NoteBox'
import { isTeleportEnabledToken } from '../../util/TokenTeleportEnabledUtils'
import { useBridgeTokensStore } from '../../hooks/useBridgeTokensStore'
import { useArbTokenBridge } from '../../hooks/useArbTokenBridge'

enum ImportStatus {
LOADING,
Expand Down Expand Up @@ -64,12 +66,11 @@ export function TokenImportDialog({
tokenAddress
}: TokenImportDialogProps): JSX.Element {
const { address: walletAddress } = useAccount()

const { bridgeTokens } = useBridgeTokensStore()
const {
app: {
arbTokenBridge: { bridgeTokens, token },
selectedToken
}
} = useAppState()
token: { updateTokenData, add: addToken }
} = useArbTokenBridge()
const [networks] = useNetworks()
const {
childChain,
Expand Down Expand Up @@ -176,10 +177,10 @@ export function TokenImportDialog({

const selectToken = useCallback(
async (_token: ERC20BridgeToken) => {
await token.updateTokenData(_token.address)
await updateTokenData(_token.address)
actions.app.setSelectedToken(_token)
},
[token, actions]
[updateTokenData, actions]
)

useEffect(() => {
Expand Down Expand Up @@ -231,47 +232,6 @@ export function TokenImportDialog({
searchForTokenInLists
])

useEffect(() => {
if (!isOpen) {
return
}

if (isL1AddressLoading && !l1Address) {
return
}

const foundToken = tokensFromUser[l1Address || tokenAddress]

if (typeof foundToken === 'undefined') {
return
}

// Listen for the token to be added to the bridge so we can automatically select it
if (foundToken.address !== selectedToken?.address) {
onClose(true)
selectToken(foundToken)
}
}, [
isL1AddressLoading,
tokenAddress,
isOpen,
l1Address,
onClose,
selectToken,
selectedToken,
tokensFromUser
])

async function storeNewToken(newToken: string) {
return token.add(newToken).catch((ex: Error) => {
setStatus(ImportStatus.ERROR)

if (ex.name === 'TokenDisabledError') {
warningToast('This token is currently paused in the bridge')
}
})
}

function handleTokenImport() {
if (typeof bridgeTokens === 'undefined') {
return
Expand All @@ -293,9 +253,18 @@ export function TokenImportDialog({
selectToken(tokenToImport!)
} else {
// Token is not added to the bridge, so we add it
storeNewToken(l1Address).catch(() => {
setStatus(ImportStatus.ERROR)
})
addToken(l1Address)
.then(() => {
onClose(true)
selectToken(tokenToImport!)
})
.catch(ex => {
setStatus(ImportStatus.ERROR)

if (ex.name === 'TokenDisabledError') {
warningToast('This token is currently paused in the bridge')
}
})
}

if (isTransferDisabledToken(l1Address, childChain.id)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { useNetworksRelationship } from '../../hooks/useNetworksRelationship'
import { TokenLogoFallback } from './TokenInfo'
import { useBalanceOnSourceChain } from '../../hooks/useBalanceOnSourceChain'
import { useSourceChainNativeCurrencyDecimals } from '../../hooks/useSourceChainNativeCurrencyDecimals'
import { useBridgeTokensStore } from '../../hooks/useBridgeTokensStore'

function tokenListIdsToNames(ids: number[]): string {
return ids
Expand Down Expand Up @@ -238,11 +239,7 @@ function ArbitrumTokenBadge() {
}

function TokenBalance({ token }: { token: ERC20BridgeToken | null }) {
const {
app: {
arbTokenBridge: { bridgeTokens }
}
} = useAppState()
const { bridgeTokens } = useBridgeTokensStore()
const { isLoading: isLoadingAccountType } = useAccountType()
const { balance, symbol } = useTokenInfo(token)
const nativeCurrencyDecimalsOnSourceChain =
Expand Down
Loading
Loading