diff --git a/wormhole-connect/src/views/v2/Bridge/AssetPicker/TokenWarnings.tsx b/wormhole-connect/src/views/v2/Bridge/AssetPicker/TokenWarnings.tsx deleted file mode 100644 index fef0dc7f0..000000000 --- a/wormhole-connect/src/views/v2/Bridge/AssetPicker/TokenWarnings.tsx +++ /dev/null @@ -1,344 +0,0 @@ -import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import { makeStyles } from 'tss-react/mui'; - -import { RootState } from 'store'; -import { - //setAssociatedTokenAddress, - setForeignAsset, -} from 'store/transferInput'; -import config from 'config'; -import { /*getTokenById,*/ getWrappedTokenId } from 'utils'; -//import { TransferWallet, signAndSendTransaction } from 'utils/wallet'; -import { joinClass } from 'utils/style'; -//import { solanaContext } from 'utils/sdk'; - -import { CircularProgress, Link, Typography } from '@mui/material'; -import AlertBannerV2 from 'components/v2/AlertBanner'; -import { isNttRoute } from 'routes'; - -const useStyles = makeStyles()((theme: any) => ({ - associatedTokenWarning: { - display: 'flex', - flexDirection: 'column', - alignItems: 'start', - }, - link: { - textDecoration: 'underline', - opacity: 0.8, - padding: '4px 0', - cursor: 'pointer', - '&:hover': { - opacity: 1, - }, - }, - disabled: { - cursor: 'not-allowed', - opacity: 0.6, - '&:hover': { - opacity: 0.6, - }, - }, - inProgress: { - marginRight: '8px', - }, - error: { - color: theme.palette.error[500], - marginTop: '4px', - }, -})); - -const AssociatedTokenWarning = (props: { - createAssociatedTokenAccount: any; -}) => { - const { classes } = useStyles(); - const [inProgress, setInProgress] = useState(false); - const [error, setError] = useState(''); - - const createAccount = async () => { - // if `createAccount` is already in progress, disable function - if (inProgress) { - return; - } - - setInProgress(true); - setError(''); - - try { - await props.createAssociatedTokenAccount(); - setError(''); - } catch (e) { - setError('Encountered an error, please try again.'); - console.error(e); - } finally { - setInProgress(false); - } - }; - - return ( -
- No associated token account exists for your wallet on Solana. You must - create it before proceeding. - {error &&
{error}
} -
- {inProgress && ( - - )} - Create account -
-
- ); -}; - -const TokenWarnings = () => { - const dispatch = useDispatch(); - - const { - fromChain: sourceChain, - toChain: destChain, - token: sourceToken, - destToken, - foreignAsset, - associatedTokenAddress, - route, - } = useSelector((state: RootState) => state.transferInput); - - const { receiving } = useSelector((state: RootState) => state.wallet); - - const [showWarning, setShowWarning] = useState(false); - const [usdcAndNoCCTP, setUsdcAndNoCCTP] = useState(false); - - const sourceTokenConfig = config.tokens[sourceToken]; - const destTokenConfig = config.tokens[destToken]; - - // check if the destination token contract is deployed - useEffect(() => { - // Avoid race conditions - let active = true; - - const checkWrappedTokenExists = async () => { - if (!destChain || !sourceTokenConfig || !route) { - dispatch(setForeignAsset('')); - setShowWarning(false); - return; - } - - const tokenId = getWrappedTokenId(sourceTokenConfig); - - if (!tokenId) { - throw new Error('Could not retrieve target token info'); - } - - const address = await config.routes - .get(route) - .getForeignAsset(tokenId, destChain, destTokenConfig); - - if (!active) { - return; - } - - if (address) { - dispatch(setForeignAsset(address)); - setShowWarning(false); - } else { - dispatch(setForeignAsset('')); - setShowWarning(true); - } - }; - - checkWrappedTokenExists(); - - return () => { - active = false; - }; - }, [destChain, sourceTokenConfig, route, destTokenConfig, dispatch]); - - // the associated token account address is deterministic, so we still - // need to check if there is an account created for that address - const checkSolanaAssociatedTokenAccount = - useCallback(async (): Promise => { - return true; - - /* TODO SDKV2 - if (!foreignAsset || !tokenConfig) { - setShowErrors(false); - return false; - } - const tokenId = - getTokenById({ chain: 'Solana', address: foreignAsset })?.tokenId || - getWrappedTokenId(tokenConfig); - const account = await solanaContext().getAssociatedTokenAccount( - tokenId, - receiving.address, - ); - // only set address if that actual account exists - if (account) { - dispatch(setAssociatedTokenAddress(account.toString())); - setShowErrors(false); - return true; - } else { - dispatch(setAssociatedTokenAddress('')); - setShowErrors(true); - return false; - } - */ - }, [foreignAsset, sourceTokenConfig, receiving, dispatch]); - - const createAssociatedTokenAccount = useCallback(async () => { - /* - * TODO SDKV2 - if (!receiving.address || !token) - throw new Error( - 'Must fill in all fields before you can create a token account', - ); - if (!foreignAsset) - throw new Error( - 'The token must be registered on Solana before an associated token account can be created', - ); - const tokenId = - getTokenById({ chain: 'Solana', address: foreignAsset })?.tokenId || - getWrappedTokenId(sourceTokenConfig); - const tx = await solanaContext().createAssociatedTokenAccount( - tokenId, - receiving.address, - 'finalized', - ); - // if `tx` is null it means the account already exists - if (!tx) return; - await signAndSendTransaction('Solana', tx, TransferWallet.RECEIVING); - - let accountExists = false; - let retries = 0; - return await new Promise((resolve) => { - const checkAccount = setInterval(async () => { - if (accountExists || retries > 20) { - clearInterval(checkAccount); - resolve(true); - } else { - accountExists = await checkSolanaAssociatedTokenAccount(); - retries += 1; - } - }, 1000); - }); - */ - }, [ - sourceToken, - receiving, - foreignAsset, - sourceTokenConfig, - checkSolanaAssociatedTokenAccount, - ]); - - useEffect(() => { - // if the url it's empty that means the user doesn't want this feature - const cctpWarningFlag = !!config.cctpWarning; - // check if the tokens will be wrapped USDC - const isResultWrappedUSDC = - sourceTokenConfig?.symbol === 'USDC' && - destTokenConfig?.symbol === 'USDC' && - destTokenConfig?.nativeChain !== destChain; - // check if the chains support CCTP - const bothChainsSupportCCTP = - destChain && - //CCTP_CHAINS.includes(destChain) && TODO SDKV2 - sourceChain; //&& - //CCTP_CHAINS.includes(destChain); TODO SDKV2 - // check if the result is wrapped USDC and the chains involved support CCTP - // rationale: - // - transferring wrapped USDC back home (unwrapping) shouldn't be a warning - // - CCTP would show as USDC on both ends, but the result would be native (the same check as above) - // - if both chains don't support CCTP, it doesn't make sense to suggest using it, - // (at least not with this warning) as the user doesn't have a clear alternative - // and using the USDC (CCTP) only bridge wouldn't help - const usdcAndNoCCTP = - cctpWarningFlag && isResultWrappedUSDC && bothChainsSupportCCTP; - - if (!destChain || !sourceToken || !receiving.address) return; - // The tBTC associated token account will be created if it doesn't exist in the redeem tx - // The NTT ATA will be created if it doesn't exist in the redeem tx - if ( - destChain === 'Solana' && - foreignAsset && - !isNttRoute(route) - //TODO SDKV2 - //route !== Route.TBTC && - ) { - checkSolanaAssociatedTokenAccount(); - } - if (usdcAndNoCCTP) { - setShowWarning(true); - setUsdcAndNoCCTP(true); - } else { - setShowWarning(false); - setUsdcAndNoCCTP(false); - } - }, [ - destChain, - sourceToken, - foreignAsset, - receiving, - associatedTokenAddress, - checkSolanaAssociatedTokenAccount, - route, - sourceTokenConfig?.symbol, - sourceTokenConfig?.nativeChain, - destTokenConfig?.symbol, - destTokenConfig?.nativeChain, - sourceChain, - ]); - - const noForeignAssetWarning = useMemo( - () => ( - - This token is not registered, you must{' '} - - register - {' '} - it before you continue. Newly registered tokens will not have liquid - markets. - - ), - [], - ); - - const noAssociatedTokenAccount = useMemo( - () => ( - - ), - [], - ); - - // warning message for users that attempt to transfer USDC using a different corridor than CCTP - const warningNoCCTPOption = useMemo( - () => ( - - This transaction will transfer wrapped USDC (wUSDC) to the destination - chain. If you want to transfer native USDC on chains supported by - Circle's CCTP, use the{' '} - - USDC Bridge - - . - - ), - [], - ); - - let content; - if (!foreignAsset) { - content = noForeignAssetWarning; - } else if (destChain === 'Solana' && route !== 'AutomaticTokenBridge') { - content = noAssociatedTokenAccount; - } else if (usdcAndNoCCTP) { - content = warningNoCCTPOption; - } - - return ; -}; - -export default TokenWarnings; diff --git a/wormhole-connect/src/views/v2/Bridge/index.tsx b/wormhole-connect/src/views/v2/Bridge/index.tsx index ca75e0bac..83ed7588c 100644 --- a/wormhole-connect/src/views/v2/Bridge/index.tsx +++ b/wormhole-connect/src/views/v2/Bridge/index.tsx @@ -32,7 +32,6 @@ import { isTransferValid, useValidate } from 'utils/transferValidation'; import { TransferWallet, useConnectToLastUsedWallet } from 'utils/wallet'; import WalletConnector from 'views/v2/Bridge/WalletConnector'; import AssetPicker from 'views/v2/Bridge/AssetPicker'; -import TokenWarnings from 'views/v2/Bridge/AssetPicker/TokenWarnings'; import WalletController from 'views/v2/Bridge/WalletConnector/Controller'; import AmountInput from 'views/v2/Bridge/AmountInput'; import Routes from 'views/v2/Bridge/Routes'; @@ -435,7 +434,6 @@ const Bridge = () => { {bridgeHeader} {sourceAssetPicker} {destAssetPicker} -