diff --git a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenImportDialog.tsx b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenImportDialog.tsx index 6709ca10d1..a8b68822ec 100644 --- a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenImportDialog.tsx +++ b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenImportDialog.tsx @@ -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, @@ -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, @@ -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, @@ -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(() => { @@ -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 @@ -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)) { diff --git a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenRow.tsx b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenRow.tsx index 65fcb9dafe..9734ce15a5 100644 --- a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenRow.tsx +++ b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenRow.tsx @@ -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 @@ -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 = diff --git a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx index 93af1c6977..ed8de6f96c 100644 --- a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx +++ b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearch.tsx @@ -5,11 +5,10 @@ import { useAccount } from 'wagmi' import { AutoSizer, List, ListRowProps } from 'react-virtualized' import { twMerge } from 'tailwind-merge' -import { useActions, useAppState } from '../../state' +import { useActions } from '../../state' import { BRIDGE_TOKEN_LISTS, BridgeTokenList, - addBridgeTokenListToBridge, SPECIAL_ARBITRUM_TOKEN_TOKEN_LIST_ID } from '../../util/TokenListUtils' import { @@ -44,6 +43,8 @@ import { Switch } from '../common/atoms/Switch' import { isTeleportEnabledToken } from '../../util/TokenTeleportEnabledUtils' import { useBalances } from '../../hooks/useBalances' import { useSetInputAmount } from '../../hooks/TransferPanel/useSetInputAmount' +import { useArbTokenBridge } from '../../hooks/useArbTokenBridge' +import { useBridgeTokensStore } from '../../hooks/useBridgeTokensStore' export const ARB_ONE_NATIVE_USDC_TOKEN = { ...ArbOneNativeUSDC, @@ -65,19 +66,19 @@ export const ARB_SEPOLIA_NATIVE_USDC_TOKEN = { function TokenListRow({ tokenList }: { tokenList: BridgeTokenList }) { const { - app: { arbTokenBridge } - } = useAppState() - const { bridgeTokens, token } = arbTokenBridge + token: { removeTokensFromList, addBridgeTokenListToBridge } + } = useArbTokenBridge() + const { bridgeTokens } = useBridgeTokensStore() const toggleTokenList = useCallback( (bridgeTokenList: BridgeTokenList, isActive: boolean) => { if (isActive) { - token.removeTokensFromList(bridgeTokenList.id) + removeTokensFromList(bridgeTokenList.id) } else { - addBridgeTokenListToBridge(bridgeTokenList, arbTokenBridge) + addBridgeTokenListToBridge(bridgeTokenList) } }, - [arbTokenBridge, token] + [addBridgeTokenListToBridge, removeTokensFromList] ) const isActive = Object.keys(bridgeTokens ?? []).some(address => { @@ -172,11 +173,10 @@ function TokensPanel({ onTokenSelected: (token: ERC20BridgeToken | null) => void }): JSX.Element { const { address: walletAddress } = useAccount() + const { bridgeTokens } = useBridgeTokensStore() const { - app: { - arbTokenBridge: { token, bridgeTokens } - } - } = useAppState() + token: { addL2NativeToken, add: addToken } + } = useArbTokenBridge() const [networks] = useNetworks() const { childChain, childChainProvider, parentChain, isDepositMode } = useNetworksRelationship(networks) @@ -386,7 +386,7 @@ function TokensPanel({ try { // Try to add the token as an L2-native token - token.addL2NativeToken(newToken) + addL2NativeToken(newToken) isSuccessful = true } catch (error) { // @@ -394,7 +394,7 @@ function TokensPanel({ try { // Try to add the token as a regular bridged token - await token.add(newToken) + await addToken(newToken) isSuccessful = true } catch (ex: any) { if (ex.name === 'TokenDisabledError') { @@ -522,11 +522,11 @@ export function TokenSearch({ }) { const { address: walletAddress } = useAccount() const { setAmount2 } = useSetInputAmount() + + const { bridgeTokens } = useBridgeTokensStore() const { - app: { - arbTokenBridge: { token, bridgeTokens } - } - } = useAppState() + token: { updateTokenData } + } = useArbTokenBridge() const { app: { setSelectedToken } } = useActions() @@ -624,7 +624,7 @@ export function TokenSearch({ }) if (data) { - token.updateTokenData(_token.address) + updateTokenData(_token.address) setSelectedToken({ ...erc20DataToErc20BridgeToken(data), l2Address: _token.l2Address diff --git a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearchUtils.ts b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearchUtils.ts index 1d2c279256..acd2de00b1 100644 --- a/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearchUtils.ts +++ b/packages/arb-token-bridge-ui/src/components/TransferPanel/TokenSearchUtils.ts @@ -1,5 +1,4 @@ import { useMemo } from 'react' -import { useAppState } from '../../state' import { ContractStorage, ERC20BridgeToken, @@ -9,6 +8,7 @@ import { useTokenLists } from '../../hooks/useTokenLists' import { TokenListWithId } from '../../util/TokenListUtils' import { useNetworksRelationship } from '../../hooks/useNetworksRelationship' import { useNetworks } from '../../hooks/useNetworks' +import { useBridgeTokensStore } from '../../hooks/useBridgeTokensStore' export function useTokensFromLists(): ContractStorage { const [networks] = useNetworks() @@ -25,11 +25,7 @@ export function useTokensFromLists(): ContractStorage { } export function useTokensFromUser(): ContractStorage { - const { - app: { - arbTokenBridge: { bridgeTokens } - } - } = useAppState() + const { bridgeTokens } = useBridgeTokensStore() return useMemo(() => { const storage: ContractStorage = {} diff --git a/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanel.tsx b/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanel.tsx index c51d2d6785..5548448e55 100644 --- a/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanel.tsx +++ b/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanel.tsx @@ -78,6 +78,7 @@ import { MoveFundsButton } from './MoveFundsButton' import { ProjectsListing } from '../common/ProjectsListing' import { useAmountBigNumber } from './hooks/useAmountBigNumber' import { useSourceChainNativeCurrencyDecimals } from '../../hooks/useSourceChainNativeCurrencyDecimals' +import { useArbTokenBridge } from '../../hooks/useArbTokenBridge' const signerUndefinedError = 'Signer is undefined' const transferNotAllowedError = 'Transfer not allowed' @@ -106,13 +107,11 @@ export function TransferPanel() { useState(false) const { - app: { - connectionState, - selectedToken, - arbTokenBridge: { token }, - warningTokens - } + app: { selectedToken, warningTokens } } = useAppState() + const { + token: { updateTokenData } + } = useArbTokenBridge() const { address: walletAddress } = useAccount() const { switchNetworkAsync } = useSwitchNetworkWithConfig({ isSwitchingNetworkBeforeTx: true @@ -209,8 +208,7 @@ export function TransferPanel() { } useImportTokenModal({ - importTokenModalStatus, - connectionState + importTokenModalStatus }) const isBridgingANewStandardToken = useMemo(() => { @@ -848,7 +846,7 @@ export function TransferPanel() { await Promise.all([updateEthParentBalance(), updateEthChildBalance()]) if (selectedToken) { - token.updateTokenData(selectedToken.address) + updateTokenData(selectedToken.address) } if (nativeCurrency.isCustom) { diff --git a/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanelMain/hooks.ts b/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanelMain/hooks.ts index 4d748b11ca..53d5c1c517 100644 --- a/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanelMain/hooks.ts +++ b/packages/arb-token-bridge-ui/src/components/TransferPanel/TransferPanelMain/hooks.ts @@ -10,6 +10,7 @@ import { useNetworksRelationship } from '../../../hooks/useNetworksRelationship' import { TokenType } from '../../../hooks/arbTokenBridge.types' import { CommonAddress } from '../../../util/CommonAddressUtils' import { isNetwork } from '../../../util/networks' +import { useArbTokenBridge } from '../../../hooks/useArbTokenBridge' const commonUSDC = { name: 'USD Coin', @@ -22,11 +23,11 @@ const commonUSDC = { export function useUpdateUSDCTokenData() { const actions = useActions() const { - app: { - arbTokenBridge: { token }, - selectedToken - } + app: { selectedToken } } = useAppState() + const { + token: { updateTokenData } + } = useArbTokenBridge() const [networks] = useNetworks() const { isDepositMode } = useNetworksRelationship(networks) const { @@ -47,7 +48,7 @@ export function useUpdateUSDCTokenData() { } if (isArbOneUSDC && isDestinationChainArbitrumOne) { - token.updateTokenData(CommonAddress.Ethereum.USDC) + updateTokenData(CommonAddress.Ethereum.USDC) actions.app.setSelectedToken({ ...commonUSDC, address: CommonAddress.Ethereum.USDC, @@ -56,7 +57,7 @@ export function useUpdateUSDCTokenData() { } if (isArbSepoliaUSDC && isDestinationChainArbitrumSepolia) { - token.updateTokenData(CommonAddress.Sepolia.USDC) + updateTokenData(CommonAddress.Sepolia.USDC) actions.app.setSelectedToken({ ...commonUSDC, address: CommonAddress.Sepolia.USDC, @@ -69,6 +70,6 @@ export function useUpdateUSDCTokenData() { isDestinationChainArbitrumOne, isDestinationChainArbitrumSepolia, selectedToken, - token + updateTokenData ]) } diff --git a/packages/arb-token-bridge-ui/src/components/TransferPanel/hooks/useIsTransferAllowed.ts b/packages/arb-token-bridge-ui/src/components/TransferPanel/hooks/useIsTransferAllowed.ts index ce849ae6f8..f4b62e236b 100644 --- a/packages/arb-token-bridge-ui/src/components/TransferPanel/hooks/useIsTransferAllowed.ts +++ b/packages/arb-token-bridge-ui/src/components/TransferPanel/hooks/useIsTransferAllowed.ts @@ -1,17 +1,10 @@ import { useMemo } from 'react' import { useAccount, useNetwork } from 'wagmi' -import { useAppState } from '../../../state' import { useNetworks } from '../../../hooks/useNetworks' import { useDestinationAddressError } from './useDestinationAddressError' export function useIsTransferAllowed() { - const { - app: { - arbTokenBridgeLoaded, - arbTokenBridge: { eth } - } - } = useAppState() const { address: walletAddress, isConnected } = useAccount() // do not use `useChainId` because it won't detect chains outside of our wagmi config const { chain } = useNetwork() @@ -21,12 +14,6 @@ export function useIsTransferAllowed() { return useMemo(() => { const isConnectedToTheWrongChain = chain?.id !== networks.sourceChain.id - if (!arbTokenBridgeLoaded) { - return false - } - if (!eth) { - return false - } if (!isConnected) { return false } @@ -41,11 +28,9 @@ export function useIsTransferAllowed() { } return true }, [ - arbTokenBridgeLoaded, chain?.id, destinationAddressError, isConnected, - eth, networks.sourceChain.id, walletAddress ]) diff --git a/packages/arb-token-bridge-ui/src/hooks/TransferPanel/useImportTokenModal.ts b/packages/arb-token-bridge-ui/src/hooks/TransferPanel/useImportTokenModal.ts index 32f4a04d69..ca26144dd7 100644 --- a/packages/arb-token-bridge-ui/src/hooks/TransferPanel/useImportTokenModal.ts +++ b/packages/arb-token-bridge-ui/src/hooks/TransferPanel/useImportTokenModal.ts @@ -1,14 +1,11 @@ import { useEffect } from 'react' import { ImportTokenModalStatus } from '../../components/TransferPanel/TransferPanelUtils' -import { ConnectionState } from '../../util' import { useTokenImportDialogStore } from '../../components/TransferPanel/TokenImportDialog' export function useImportTokenModal({ - importTokenModalStatus, - connectionState + importTokenModalStatus }: { importTokenModalStatus: ImportTokenModalStatus - connectionState: number }) { const { openDialog: openTokenImportDialog } = useTokenImportDialogStore() useEffect(() => { @@ -16,11 +13,6 @@ export function useImportTokenModal({ return } - if ( - connectionState === ConnectionState.L1_CONNECTED || - connectionState === ConnectionState.L2_CONNECTED - ) { - openTokenImportDialog() - } - }, [connectionState, importTokenModalStatus, openTokenImportDialog]) + openTokenImportDialog() + }, [importTokenModalStatus, openTokenImportDialog]) } diff --git a/packages/arb-token-bridge-ui/src/hooks/arbTokenBridge.types.ts b/packages/arb-token-bridge-ui/src/hooks/arbTokenBridge.types.ts index c4b4451e12..91cdb1b3a8 100644 --- a/packages/arb-token-bridge-ui/src/hooks/arbTokenBridge.types.ts +++ b/packages/arb-token-bridge-ui/src/hooks/arbTokenBridge.types.ts @@ -21,6 +21,7 @@ import { Transaction, ParentToChildMessageData } from './useTransactions' +import { BridgeTokenList } from '../util/TokenListUtils' export { OutgoingMessageState } @@ -154,6 +155,7 @@ export interface ArbTokenBridgeToken { event: L2ToL1EventResultPlus l1Signer: Signer }) => Promise + addBridgeTokenListToBridge: (bridgeTokenList: BridgeTokenList) => void } export interface TransactionActions { diff --git a/packages/arb-token-bridge-ui/src/hooks/useClaimWithdrawal.ts b/packages/arb-token-bridge-ui/src/hooks/useClaimWithdrawal.ts index f174dc8fb3..614f19b40d 100644 --- a/packages/arb-token-bridge-ui/src/hooks/useClaimWithdrawal.ts +++ b/packages/arb-token-bridge-ui/src/hooks/useClaimWithdrawal.ts @@ -1,7 +1,6 @@ import { useCallback, useState } from 'react' import { useAccount, useSigner } from 'wagmi' -import { useAppState } from '../state' import { MergedTransaction, WithdrawalStatus } from '../state/app/state' import { isUserRejectedError } from '../util/isUserRejectedError' import { errorToast } from '../components/common/atoms/Toast' @@ -15,6 +14,7 @@ import { fetchErc20Data } from '../util/TokenUtils' import { fetchNativeCurrency } from './useNativeCurrency' import { getProviderForChainId } from '@/token-bridge-sdk/utils' import { captureSentryErrorWithExtraData } from '../util/SentryUtils' +import { useArbTokenBridge } from './useArbTokenBridge' export type UseClaimWithdrawalResult = { claim: () => Promise @@ -25,8 +25,9 @@ export function useClaimWithdrawal( tx: MergedTransaction ): UseClaimWithdrawalResult { const { - app: { arbTokenBridge } - } = useAppState() + eth: { triggerOutbox: triggerEthOutbox }, + token: { triggerOutbox: triggerTokenOutbox } + } = useArbTokenBridge() const { address } = useAccount() const { data: signer } = useSigner({ chainId: tx.parentChainId }) const { updatePendingTransaction } = useTransactionHistory(address) @@ -85,12 +86,12 @@ export function useClaimWithdrawal( throw 'Signer is undefined' } if (tx.assetType === AssetType.ETH) { - res = await arbTokenBridge.eth.triggerOutbox({ + res = await triggerEthOutbox({ event: extendedEvent, l1Signer: signer }) } else { - res = await arbTokenBridge.token.triggerOutbox({ + res = await triggerTokenOutbox({ event: extendedEvent, l1Signer: signer }) @@ -127,8 +128,8 @@ export function useClaimWithdrawal( setParentChainTxDetailsOfWithdrawalClaimTx(tx, txHash) } }, [ - arbTokenBridge.eth, - arbTokenBridge.token, + triggerEthOutbox, + triggerTokenOutbox, isClaiming, signer, tx,