Skip to content
Draft
Show file tree
Hide file tree
Changes from 3 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
58 changes: 6 additions & 52 deletions packages/arb-token-bridge-ui/src/components/App/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useMemo, useState } from 'react'
import { useEffect, useMemo } from 'react'
import { useAccount, WagmiProvider } from 'wagmi'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { darkTheme, RainbowKitProvider, Theme } from '@rainbow-me/rainbowkit'
Expand All @@ -9,22 +9,18 @@ import { createOvermind } from 'overmind'
import { Provider } from 'overmind-react'
import { useLocalStorage } from '@uidotdev/usehooks'

import { TokenBridgeParams } from '../../hooks/useArbTokenBridge'
import { WelcomeDialog } from './WelcomeDialog'
import { BlockedDialog } from './BlockedDialog'
import { AppContextProvider } from './AppContext'
import { config, useActions } from '../../state'
import { MainContent } from '../MainContent/MainContent'
import { ArbTokenBridgeStoreSync } from '../syncers/ArbTokenBridgeStoreSync'
import { TokenListSyncer } from '../syncers/TokenListSyncer'
import { useSyncTokenList } from '../syncers/useSyncTokenList'
import { ArbQueryParamProvider } from '../../hooks/useArbQueryParams'
import { Header, HeaderAccountOrConnectWalletButton } from '../common/Header'
import { TOS_LOCALSTORAGE_KEY } from '../../constants'
import { getProps } from '../../util/wagmi/setup'
import { useAccountIsBlocked } from '../../hooks/useAccountIsBlocked'
import { useCCTPIsBlocked } from '../../hooks/CCTP/useCCTPIsBlocked'
import { useNetworks } from '../../hooks/useNetworks'
import { useNetworksRelationship } from '../../hooks/useNetworksRelationship'
import { useSyncConnectedChainToAnalytics } from './useSyncConnectedChainToAnalytics'
import { useSyncConnectedChainToQueryParams } from './useSyncConnectedChainToQueryParams'
import React from 'react'
Expand All @@ -46,52 +42,15 @@ const rainbowkitTheme = merge(darkTheme(), {

const queryClient = new QueryClient()

const ArbTokenBridgeStoreSyncWrapper = (): JSX.Element | null => {
const useArbTokenBridgeStoreSync = () => {
const actions = useActions()
const [networks] = useNetworks()
const { childChain, childChainProvider, parentChain, parentChainProvider } =
useNetworksRelationship(networks)

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

useSyncConnectedChainToAnalytics()
useSyncConnectedChainToQueryParams()

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

// Listen for account and network changes
useEffect(() => {
// Any time one of those changes
setTokenBridgeParams(null)

actions.app.reset()
actions.app.setChainIds({
l1NetworkChainId: parentChain.id,
l2NetworkChainId: childChain.id
})

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 @@ -104,19 +63,16 @@ const ArbTokenBridgeStoreSyncWrapper = (): JSX.Element | null => {
console.warn('Failed to fetch warning tokens:', err)
})
}, [])

if (!tokenBridgeParams) {
return null
}

return <ArbTokenBridgeStoreSync tokenBridgeParams={tokenBridgeParams} />
}

const AppContent = React.memo(() => {
const { address } = useAccount()
const { isBlocked } = useAccountIsBlocked()
const [tosAccepted] = useLocalStorage<boolean>(TOS_LOCALSTORAGE_KEY, false)

useArbTokenBridgeStoreSync()
useSyncTokenList()

if (!tosAccepted) {
return (
<>
Expand Down Expand Up @@ -146,8 +102,6 @@ const AppContent = React.memo(() => {
<Header>
<HeaderAccountOrConnectWalletButton />
</Header>
<TokenListSyncer />
<ArbTokenBridgeStoreSyncWrapper />
<MainContent />
</>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { TokenInfo } from './TokenInfo'
import { NoteBox } from '../common/NoteBox'
import { useSelectedToken } from '../../hooks/useSelectedToken'
import { addressesEqual } from '../../util/AddressUtils'
import { useArbTokenBridge } from '../../hooks/useArbTokenBridge'

enum ImportStatus {
LOADING,
Expand Down Expand Up @@ -61,11 +62,8 @@ export function TokenImportDialog({
onClose,
tokenAddress
}: TokenImportDialogProps): JSX.Element {
const {
app: {
arbTokenBridge: { bridgeTokens, token }
}
} = useAppState()
const arbTokenBridge = useArbTokenBridge()
const { bridgeTokens, token } = arbTokenBridge
const [selectedToken, setSelectedToken] = useSelectedToken()
const [networks] = useNetworks()
const { childChainProvider, parentChainProvider } =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { TokenLogoFallback } from './TokenInfo'
import { useBalanceOnSourceChain } from '../../hooks/useBalanceOnSourceChain'
import { useSourceChainNativeCurrencyDecimals } from '../../hooks/useSourceChainNativeCurrencyDecimals'
import { BlockExplorerTokenLink } from './TokenInfoTooltip'
import { useArbTokenBridge } from '../../hooks/useArbTokenBridge'

function tokenListIdsToNames(ids: string[]): string {
return ids
Expand Down Expand Up @@ -214,11 +215,8 @@ function ArbitrumTokenBadge() {
}

function TokenBalance({ token }: { token: ERC20BridgeToken | null }) {
const {
app: {
arbTokenBridge: { bridgeTokens }
}
} = useAppState()
const arbTokenBridge = useArbTokenBridge()
const { bridgeTokens } = arbTokenBridge
const { isLoading: isLoadingAccountType } = useAccountType()
const { balance, symbol } = useTokenInfo(token)
const nativeCurrencyDecimalsOnSourceChain =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { AutoSizer, List, ListRowProps } from 'react-virtualized'
import { twMerge } from 'tailwind-merge'
import useSWRImmutable from 'swr/immutable'

import { useAppState } from '../../state'
import {
BRIDGE_TOKEN_LISTS,
BridgeTokenList,
Expand Down Expand Up @@ -40,6 +39,7 @@ import { useBalances } from '../../hooks/useBalances'
import { useSetInputAmount } from '../../hooks/TransferPanel/useSetInputAmount'
import { addressesEqual } from '../../util/AddressUtils'
import { getProviderForChainId } from '@/token-bridge-sdk/utils'
import { useArbTokenBridge } from '../../hooks/useArbTokenBridge'

export const ARB_ONE_NATIVE_USDC_TOKEN = {
...ArbOneNativeUSDC,
Expand All @@ -60,9 +60,7 @@ export const ARB_SEPOLIA_NATIVE_USDC_TOKEN = {
}

function TokenListRow({ tokenList }: { tokenList: BridgeTokenList }) {
const {
app: { arbTokenBridge }
} = useAppState()
const arbTokenBridge = useArbTokenBridge()
const { bridgeTokens, token } = arbTokenBridge

const toggleTokenList = useCallback(
Expand All @@ -76,10 +74,15 @@ function TokenListRow({ tokenList }: { tokenList: BridgeTokenList }) {
[arbTokenBridge, token]
)

const isActive = Object.keys(bridgeTokens ?? []).some(address => {
const token = bridgeTokens?.[address]
return token?.listIds.has(tokenList?.id)
})
const isActive = useMemo(() => {
if (!bridgeTokens) {
return false
}
return Object.keys(bridgeTokens).some(address => {
const token = bridgeTokens[address]
return token?.listIds.has(tokenList?.id)
})
}, [bridgeTokens])
Copy link
Contributor

Choose a reason for hiding this comment

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

That would be nice to refactor that a bitt, but maybe that's out of scope of that PR.


const switchOnClick = useCallback(
() => toggleTokenList(tokenList, isActive),
Expand Down Expand Up @@ -168,11 +171,8 @@ function TokensPanel({
onTokenSelected: (token: ERC20BridgeToken | null) => void
}): JSX.Element {
const { address: walletAddress } = useAccount()
const {
app: {
arbTokenBridge: { token, bridgeTokens }
}
} = useAppState()
const arbTokenBridge = useArbTokenBridge()
const { token, bridgeTokens } = arbTokenBridge
const [networks] = useNetworks()
const { childChain, childChainProvider, parentChain, isDepositMode } =
useNetworksRelationship(networks)
Expand Down Expand Up @@ -398,6 +398,7 @@ function TokensPanel({
return bal1.gt(bal2) ? -1 : 1
})
}, [
arbTokenBridge.bridgeTokens,
newToken,
tokensFromUser,
tokensFromLists,
Expand Down Expand Up @@ -568,11 +569,8 @@ export function TokenSearch({
close: () => void
}) {
const { setAmount2 } = useSetInputAmount()
const {
app: {
arbTokenBridge: { token, bridgeTokens }
}
} = useAppState()
const arbTokenBridge = useArbTokenBridge()
const { token, bridgeTokens } = arbTokenBridge
const [, setSelectedToken] = useSelectedToken()
const [networks] = useNetworks()
const { childChain, parentChainProvider } = useNetworksRelationship(networks)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ import { useLifiMergedTransactionCacheStore } from '../../hooks/useLifiMergedTra
import { getStepTransaction } from '@lifi/sdk'
import { isValidTransactionRequest } from '../../util/isValidTransactionRequest'
import { getAmountToPay } from './useTransferReadiness'
import { useArbTokenBridge } from '../../hooks/useArbTokenBridge'

const signerUndefinedError = 'Signer is undefined'
const transferNotAllowedError = 'Transfer not allowed'
Expand Down Expand Up @@ -125,11 +126,11 @@ export function TransferPanel() {
useState(false)

const {
app: {
arbTokenBridge: { token },
warningTokens
}
app: { warningTokens }
} = useAppState()

const arbTokenBridge = useArbTokenBridge()
const { token } = arbTokenBridge
const { address: walletAddress, chain, isConnected } = useAccount()
const [selectedToken, setSelectedToken] = useSelectedToken()
const { switchChainAsync } = useSwitchNetworkWithConfig({
Expand Down Expand Up @@ -161,7 +162,7 @@ export function TransferPanel() {
const { isSmartContractWallet } = useAccountType()

const { current: signer } = useLatest(
useEthersSigner({ chainId: networks.sourceChain.id })
useEthersSigner({ chainId: latestNetworks.current.sourceChain.id })
)
const wagmiConfig = useConfig()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@ import { useNetworksRelationship } from '../../../hooks/useNetworksRelationship'
import { CommonAddress } from '../../../util/CommonAddressUtils'
import { isNetwork } from '../../../util/networks'
import { useSelectedToken } from '../../../hooks/useSelectedToken'
import { useArbTokenBridge } from '../../../hooks/useArbTokenBridge'

export function useUpdateUSDCTokenData() {
const actions = useActions()
const {
app: {
arbTokenBridge: { token }
}
} = useAppState()
const arbTokenBridge = useArbTokenBridge()
const { token } = arbTokenBridge
const [selectedToken, setSelectedToken] = useSelectedToken()
const [networks] = useNetworks()
const { isDepositMode } = useNetworksRelationship(networks)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import { useAccount } from 'wagmi'
import { useAppState } from '../../../state'
import { useNetworks } from '../../../hooks/useNetworks'
import { useDestinationAddressError } from './useDestinationAddressError'
import { useArbTokenBridge } from '../../../hooks/useArbTokenBridge'

export function useIsTransferAllowed() {
const {
app: {
arbTokenBridgeLoaded,
arbTokenBridge: { eth }
}
app: { arbTokenBridgeLoaded }
} = useAppState()

const arbTokenBridge = useArbTokenBridge()
const { eth } = arbTokenBridge
// do not use `useChainId` because it won't detect chains outside of our wagmi config
const { address: walletAddress, isConnected, chain } = useAccount()
const [networks] = useNetworks()
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@ import { isTokenNativeUSDC } from '../../util/TokenUtils'
import { useSelectedToken } from '../../hooks/useSelectedToken'
import { useUpdateUsdcBalances } from '../../hooks/CCTP/useUpdateUsdcBalances'
import { useBalances } from '../../hooks/useBalances'
import { useArbTokenBridge } from '../../hooks/useArbTokenBridge'

// Updates all balances periodically
export function useBalanceUpdater() {
const {
app: { arbTokenBridge }
} = useAppState()

const arbTokenBridge = useArbTokenBridge()
const [selectedToken] = useSelectedToken()
const { address: walletAddress } = useAccount()
const latestTokenBridge = useLatest(arbTokenBridge)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,20 @@ import { useEffect } from 'react'
import { useNetworks } from '../../hooks/useNetworks'
import { useNetworksRelationship } from '../../hooks/useNetworksRelationship'

import { useAppState } from '../../state'
import {
addBridgeTokenListToBridge,
BRIDGE_TOKEN_LISTS
} from '../../util/TokenListUtils'
import { useArbTokenBridge } from '../../hooks/useArbTokenBridge'

// Adds whitelisted tokens to the bridge data on app load
// In the token list we should show later only tokens with positive balances
const TokenListSyncer = (): JSX.Element => {
const {
app: { arbTokenBridge, arbTokenBridgeLoaded }
} = useAppState()
export const useSyncTokenList = () => {
const arbTokenBridge = useArbTokenBridge()
const [networks] = useNetworks()
const { childChain } = useNetworksRelationship(networks)

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

const tokenListsToSet = BRIDGE_TOKEN_LISTS.filter(bridgeTokenList => {
// Always load the Arbitrum Token token list
if (bridgeTokenList.isArbitrumTokenTokenList) {
Expand All @@ -39,11 +33,7 @@ const TokenListSyncer = (): JSX.Element => {
})
}, [
// arbTokenBridge.token is not a memoized object, adding it here would cause infinite loop
childChain.id,
arbTokenBridgeLoaded
arbTokenBridge.token,
childChain.id
])

return <></>
}

export { TokenListSyncer }
Loading
Loading