-
Notifications
You must be signed in to change notification settings - Fork 196
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: show Ether for custom gas token chains #1764
base: master
Are you sure you want to change the base?
Changes from 2 commits
913d7b4
9e8f308
2dc8751
6d7ca2c
0bde9c6
3fada3a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,6 @@ import { ChevronDownIcon } from '@heroicons/react/24/outline' | |
import { twMerge } from 'tailwind-merge' | ||
|
||
import { useAppState } from '../../state' | ||
import { sanitizeImageSrc } from '../../util' | ||
import { TokenSearch } from '../TransferPanel/TokenSearch' | ||
import { sanitizeTokenSymbol } from '../../util/TokenUtils' | ||
import { useNativeCurrency } from '../../hooks/useNativeCurrency' | ||
|
@@ -16,53 +15,32 @@ import { | |
import { useNetworks } from '../../hooks/useNetworks' | ||
import { useNetworksRelationship } from '../../hooks/useNetworksRelationship' | ||
import { Transition } from '../common/Transition' | ||
import { ether } from '../../constants' | ||
|
||
export function TokenButton(): JSX.Element { | ||
const { | ||
app: { | ||
selectedToken, | ||
arbTokenBridge: { bridgeTokens }, | ||
arbTokenBridgeLoaded | ||
} | ||
app: { selectedToken, isSelectedTokenEther } | ||
} = useAppState() | ||
const [networks] = useNetworks() | ||
const { childChainProvider } = useNetworksRelationship(networks) | ||
|
||
const nativeCurrency = useNativeCurrency({ provider: childChainProvider }) | ||
|
||
const tokenLogo = useMemo<string | undefined>(() => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not used |
||
const selectedAddress = selectedToken?.address | ||
if (!selectedAddress) { | ||
return nativeCurrency.logoUrl | ||
} | ||
if (!arbTokenBridgeLoaded) { | ||
return undefined | ||
} | ||
if (typeof bridgeTokens === 'undefined') { | ||
return undefined | ||
} | ||
const logo = bridgeTokens[selectedAddress]?.logoURI | ||
if (logo) { | ||
return sanitizeImageSrc(logo) | ||
} | ||
return undefined | ||
}, [ | ||
nativeCurrency, | ||
bridgeTokens, | ||
selectedToken?.address, | ||
arbTokenBridgeLoaded | ||
]) | ||
|
||
const tokenSymbol = useMemo(() => { | ||
if (!selectedToken) { | ||
return nativeCurrency.symbol | ||
return isSelectedTokenEther ? ether.symbol : nativeCurrency.symbol | ||
} | ||
|
||
return sanitizeTokenSymbol(selectedToken.symbol, { | ||
erc20L1Address: selectedToken.address, | ||
chainId: networks.sourceChain.id | ||
}) | ||
}, [selectedToken, networks.sourceChain.id, nativeCurrency.symbol]) | ||
}, [ | ||
selectedToken, | ||
networks.sourceChain.id, | ||
isSelectedTokenEther, | ||
nativeCurrency.symbol | ||
]) | ||
|
||
return ( | ||
<> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,7 +27,11 @@ import { StatusBadge } from '../common/StatusBadge' | |
import { ERC20BridgeToken } from '../../hooks/arbTokenBridge.types' | ||
import { ExternalLink } from '../common/ExternalLink' | ||
import { useAccountType } from '../../hooks/useAccountType' | ||
import { useNativeCurrency } from '../../hooks/useNativeCurrency' | ||
import { | ||
isNativeCurrencyEther, | ||
NativeCurrencyEther, | ||
useNativeCurrency | ||
} from '../../hooks/useNativeCurrency' | ||
import { useNetworks } from '../../hooks/useNetworks' | ||
import { useNetworksRelationship } from '../../hooks/useNetworksRelationship' | ||
import { TokenLogoFallback } from './TokenInfo' | ||
|
@@ -69,14 +73,23 @@ function BlockExplorerTokenLink({ | |
) | ||
} | ||
|
||
function TokenListInfo({ token }: { token: ERC20BridgeToken | null }) { | ||
function TokenListInfo({ | ||
token | ||
}: { | ||
token: ERC20BridgeToken | NativeCurrencyEther | null | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here, and in some of the following methods, we pass an additional |
||
}) { | ||
const [networks] = useNetworks() | ||
const { childChain, childChainProvider } = useNetworksRelationship(networks) | ||
const { childChain, childChainProvider, parentChain } = | ||
useNetworksRelationship(networks) | ||
const { isCustom: childChainNativeCurrencyIsCustom } = useNativeCurrency({ | ||
provider: childChainProvider | ||
}) | ||
|
||
const tokenListInfo = useMemo(() => { | ||
if (isNativeCurrencyEther(token)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
See |
||
return null | ||
} | ||
|
||
if (!token) { | ||
return null | ||
} | ||
|
@@ -109,6 +122,16 @@ function TokenListInfo({ token }: { token: ERC20BridgeToken | null }) { | |
) | ||
}, [token]) | ||
|
||
if (isNativeCurrencyEther(token)) { | ||
const parentChainName = getNetworkName(parentChain.id) | ||
|
||
return ( | ||
<span className="flex text-xs text-white/70"> | ||
Native token on {parentChainName} | ||
</span> | ||
) | ||
} | ||
|
||
if (!token) { | ||
const nativeTokenChain = getNetworkName( | ||
(childChainNativeCurrencyIsCustom ? childChain : networks.sourceChain).id | ||
|
@@ -135,18 +158,26 @@ function TokenListInfo({ token }: { token: ERC20BridgeToken | null }) { | |
|
||
interface TokenRowProps { | ||
style?: React.CSSProperties | ||
onTokenSelected: (token: ERC20BridgeToken | null) => void | ||
token: ERC20BridgeToken | null | ||
onTokenSelected: ( | ||
token: ERC20BridgeToken | NativeCurrencyEther | null | ||
) => void | ||
token: ERC20BridgeToken | NativeCurrencyEther | null | ||
} | ||
|
||
function useTokenInfo(token: ERC20BridgeToken | null) { | ||
function useTokenInfo(token: ERC20BridgeToken | NativeCurrencyEther | null) { | ||
const [networks] = useNetworks() | ||
const { childChain, childChainProvider, parentChain, isDepositMode } = | ||
useNetworksRelationship(networks) | ||
const chainId = isDepositMode ? parentChain.id : childChain.id | ||
const nativeCurrency = useNativeCurrency({ provider: childChainProvider }) | ||
|
||
const name = useMemo(() => { | ||
if (isNativeCurrencyEther(token)) { | ||
return sanitizeTokenName(token.name, { | ||
chainId | ||
}) | ||
} | ||
|
||
if (token) { | ||
return sanitizeTokenName(token.name, { | ||
erc20L1Address: token.address, | ||
|
@@ -158,6 +189,12 @@ function useTokenInfo(token: ERC20BridgeToken | null) { | |
}, [token, nativeCurrency.name, chainId]) | ||
|
||
const symbol = useMemo(() => { | ||
if (isNativeCurrencyEther(token)) { | ||
return sanitizeTokenSymbol(token.symbol, { | ||
chainId | ||
}) | ||
} | ||
|
||
if (token) { | ||
return sanitizeTokenSymbol(token.symbol, { | ||
erc20L1Address: token.address, | ||
|
@@ -169,6 +206,10 @@ function useTokenInfo(token: ERC20BridgeToken | null) { | |
}, [token, nativeCurrency.symbol, chainId]) | ||
|
||
const logoURI = useMemo(() => { | ||
if (isNativeCurrencyEther(token)) { | ||
return token.logoUrl | ||
} | ||
|
||
if (!token) { | ||
return nativeCurrency.logoUrl | ||
} | ||
|
@@ -179,6 +220,10 @@ function useTokenInfo(token: ERC20BridgeToken | null) { | |
const balance = useBalanceOnSourceChain(token) | ||
|
||
const isArbitrumToken = useMemo(() => { | ||
if (isNativeCurrencyEther(token)) { | ||
return false | ||
} | ||
|
||
if (!token) { | ||
return false | ||
} | ||
|
@@ -198,6 +243,10 @@ function useTokenInfo(token: ERC20BridgeToken | null) { | |
}, [token, isArbitrumToken]) | ||
|
||
const isBridgeable = useMemo(() => { | ||
if (isNativeCurrencyEther(token)) { | ||
return true | ||
} | ||
|
||
if (!token) { | ||
return true | ||
} | ||
|
@@ -236,7 +285,11 @@ function ArbitrumTokenBadge() { | |
) | ||
} | ||
|
||
function TokenBalance({ token }: { token: ERC20BridgeToken | null }) { | ||
function TokenBalance({ | ||
token | ||
}: { | ||
token: ERC20BridgeToken | NativeCurrencyEther | null | ||
}) { | ||
const { | ||
app: { | ||
arbTokenBridge: { bridgeTokens } | ||
|
@@ -246,15 +299,20 @@ function TokenBalance({ token }: { token: ERC20BridgeToken | null }) { | |
const { balance, symbol } = useTokenInfo(token) | ||
|
||
const isArbitrumNativeUSDC = | ||
isTokenArbitrumOneNativeUSDC(token?.address) || | ||
isTokenArbitrumSepoliaNativeUSDC(token?.address) | ||
!isNativeCurrencyEther(token) && | ||
(isTokenArbitrumOneNativeUSDC(token?.address) || | ||
isTokenArbitrumSepoliaNativeUSDC(token?.address)) | ||
|
||
const tokenIsAddedToTheBridge = useMemo(() => { | ||
// Can happen when switching networks. | ||
if (typeof bridgeTokens === 'undefined') { | ||
return true | ||
} | ||
|
||
if (isNativeCurrencyEther(token)) { | ||
return true | ||
} | ||
|
||
if (!token) { | ||
return true | ||
} | ||
|
@@ -289,7 +347,11 @@ function TokenBalance({ token }: { token: ERC20BridgeToken | null }) { | |
) | ||
} | ||
|
||
function TokenContractLink({ token }: { token: ERC20BridgeToken | null }) { | ||
function TokenContractLink({ | ||
token | ||
}: { | ||
token: ERC20BridgeToken | NativeCurrencyEther | null | ||
}) { | ||
const [networks] = useNetworks() | ||
const { childChain, childChainProvider, parentChain, isDepositMode } = | ||
useNetworksRelationship(networks) | ||
|
@@ -298,6 +360,10 @@ function TokenContractLink({ token }: { token: ERC20BridgeToken | null }) { | |
|
||
const isCustomFeeTokenRow = token === null && nativeCurrency.isCustom | ||
|
||
if (isNativeCurrencyEther(token)) { | ||
return null | ||
} | ||
|
||
if (isCustomFeeTokenRow && isDepositMode) { | ||
return ( | ||
<BlockExplorerTokenLink | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setSelectedToken
payload has changed to include an optional flagisSelectedTokenEther
.When
isSelectedTokenEther === true
andtoken === null
, everything will assume that the native currency is Ether.When
isSelectedTokenEther === false
andtoken === null
, everything will work as previously, which means it will default to the native currency on the child chain. Note this still could be ETH,isSelectedTokenEther
just serves as an override to cover custom gas token scenarios.When
isSelectedTokenEther
is not provided it will always set it tofalse
, so that we don't have to refactor the majority of the existing code. All we have to do is to pass atoken
object instead.See
actions.ts
andstate.ts
for more.