diff --git a/wormhole-connect/src/hooks/useComputeDestinationTokens.ts b/wormhole-connect/src/hooks/useComputeDestinationTokens.ts new file mode 100644 index 000000000..6a0b089b9 --- /dev/null +++ b/wormhole-connect/src/hooks/useComputeDestinationTokens.ts @@ -0,0 +1,125 @@ +import config from 'config'; +import { useEffect } from 'react'; +import { useDispatch } from 'react-redux'; + +import { + setDestToken, + setSupportedDestTokens, + setAllSupportedDestTokens, + getNativeVersionOfToken, +} from 'store/transferInput'; + +import type { Route } from 'config/types'; +import type { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; + +import { isPorticoRoute } from 'routes/porticoBridge/utils'; +import { ETHBridge } from 'routes/porticoBridge/ethBridge'; +import { wstETHBridge } from 'routes/porticoBridge/wstETHBridge'; +import RouteOperator from 'routes/operator'; + +import { getWrappedToken } from 'utils'; + +type Props = { + sourceChain: ChainName | undefined; + sourceToken: string; + destChain: ChainName | undefined; + destToken: string; + route: Route | undefined; +}; + +export const useComputeDestinationTokens = (props: Props): void => { + const { sourceChain, destChain, sourceToken, destToken, route } = props; + + const dispatch = useDispatch(); + + useEffect(() => { + if (!destChain) { + return; + } + + let canceled = false; + + const computeDestTokens = async () => { + let supported = await RouteOperator.allSupportedDestTokens( + config.tokens[sourceToken], + sourceChain, + destChain, + ); + if (sourceToken) { + // If any of the tokens are native to the chain, only select those. + // This is to avoid users inadvertently receiving wrapped versions of the token. + const nativeTokens = supported.filter( + (t) => t.nativeChain === destChain, + ); + if (nativeTokens.length > 0) { + supported = nativeTokens; + } + } + dispatch(setSupportedDestTokens(supported)); + const allSupported = await RouteOperator.allSupportedDestTokens( + undefined, + sourceChain, + destChain, + ); + dispatch(setAllSupportedDestTokens(allSupported)); + if (destChain && supported.length === 1) { + if (!canceled) { + dispatch(setDestToken(supported[0].key)); + } + } + + // If all the supported tokens are the same token + // select the native version for applicable tokens + const symbols = supported.map((t) => t.symbol); + if ( + destChain && + symbols.every((s) => s === symbols[0]) && + ['USDC', 'tBTC'].includes(symbols[0]) + ) { + const key = supported.find( + (t) => + t.symbol === symbols[0] && + t.nativeChain === t.tokenId?.chain && + t.nativeChain === destChain, + )?.key; + if (!canceled && key) { + dispatch(setDestToken(key)); + } + } + + // If the source token is supported by a Portico bridge route, + // then select the native version on the dest chain + if ( + sourceToken && + destToken === '' && + destChain && + (!route || isPorticoRoute(route)) + ) { + const tokenSymbol = config.tokens[sourceToken]?.symbol; + const porticoTokens = [ + ...ETHBridge.SUPPORTED_TOKENS, + ...wstETHBridge.SUPPORTED_TOKENS, + ]; + if (porticoTokens.includes(tokenSymbol)) { + const isTokenSupported = + sourceToken && supported.some((t) => t.key === sourceToken); + let key = getNativeVersionOfToken(tokenSymbol, destChain); + if (!key) { + const wrapped = getWrappedToken(config.tokens[sourceToken]); + key = getNativeVersionOfToken(wrapped.symbol, destChain); + } + if (!canceled && key && isTokenSupported) { + dispatch(setDestToken(key)); + } + } + } + }; + + computeDestTokens(); + + return () => { + canceled = true; + }; + // IMPORTANT: do not include destToken in dependency array + }, [route, sourceToken, sourceChain, destChain, dispatch]); +}; diff --git a/wormhole-connect/src/hooks/useComputeReceiveAmount.ts b/wormhole-connect/src/hooks/useComputeReceiveAmount.ts new file mode 100644 index 000000000..bda08d4d0 --- /dev/null +++ b/wormhole-connect/src/hooks/useComputeReceiveAmount.ts @@ -0,0 +1,92 @@ +import { useEffect } from 'react'; +import { useDispatch } from 'react-redux'; + +import { isPorticoRoute } from 'routes/porticoBridge/utils'; +import RouteOperator from 'routes/operator'; + +import { + setReceiveAmount, + setFetchingReceiveAmount, + setReceiveAmountError, +} from 'store/transferInput'; + +import type { Route } from 'config/types'; +import type { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; +import type { PorticoBridgeState } from 'store/porticoBridge'; + +type Props = { + sourceChain: ChainName | undefined; + sourceToken: string; + destChain: ChainName | undefined; + destToken: string; + route: Route | undefined; + amount: string; + portico: PorticoBridgeState; + toNativeToken: number; + relayerFee: number | undefined; +}; + +export const useComputeReceiveAmount = (props: Props): void => { + const { + sourceChain, + destChain, + sourceToken, + destToken, + amount, + portico, + route, + toNativeToken, + relayerFee, + } = props; + + const dispatch = useDispatch(); + + useEffect(() => { + if ( + !route || + !amount || + !sourceToken || + !destToken || + !sourceChain || + !destChain + ) { + return; + } + + const recomputeReceive = async () => { + try { + const routeOptions = isPorticoRoute(route) + ? portico + : { toNativeToken, relayerFee }; + + dispatch(setFetchingReceiveAmount()); + + const newReceiveAmount = await RouteOperator.computeReceiveAmount( + route, + Number.parseFloat(amount), + sourceToken, + destToken, + sourceChain, + destChain, + routeOptions, + ); + dispatch(setReceiveAmount(newReceiveAmount.toString())); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } catch (e: any) { + dispatch(setReceiveAmountError(e.message)); + } + }; + recomputeReceive(); + }, [ + amount, + toNativeToken, + relayerFee, + route, + sourceToken, + destToken, + destChain, + sourceChain, + portico, + dispatch, + ]); +}; diff --git a/wormhole-connect/src/hooks/useComputeReceiverNativeBalance.ts b/wormhole-connect/src/hooks/useComputeReceiverNativeBalance.ts new file mode 100644 index 000000000..bc3c45773 --- /dev/null +++ b/wormhole-connect/src/hooks/useComputeReceiverNativeBalance.ts @@ -0,0 +1,46 @@ +import config from 'config'; +import { useEffect } from 'react'; +import { useDispatch } from 'react-redux'; +import { BigNumber } from 'ethers'; +import { setReceiverNativeBalance } from 'store/transferInput'; + +import type { WalletData } from 'store/wallet'; +import type { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; + +import { getTokenDecimals } from 'utils'; +import { toChainId } from 'utils/sdk'; +import { toDecimals } from 'utils/balance'; + +type Props = { + sourceChain: ChainName | undefined; + destChain: ChainName | undefined; + receiving: WalletData; +}; + +export const useComputeReceiverNativeBalance = (props: Props): void => { + const { sourceChain, destChain, receiving } = props; + const dispatch = useDispatch(); + // check destination native balance + useEffect(() => { + if (!sourceChain || !destChain || !receiving.address) { + return; + } + + const chainConfig = config.chains?.[destChain]; + + config.wh + .getNativeBalance(receiving.address, destChain) + .then((res: BigNumber) => { + const tokenConfig = chainConfig?.gasToken + ? config.tokens[chainConfig.gasToken] + : undefined; + if (!tokenConfig) + throw new Error('Could not get native gas token config'); + const decimals = getTokenDecimals( + toChainId(tokenConfig.nativeChain), + 'native', + ); + dispatch(setReceiverNativeBalance(toDecimals(res, decimals, 6))); + }); + }, [sourceChain, destChain, receiving.address, dispatch]); +}; diff --git a/wormhole-connect/src/hooks/useComputeSourceTokens.ts b/wormhole-connect/src/hooks/useComputeSourceTokens.ts new file mode 100644 index 000000000..4cacb40a1 --- /dev/null +++ b/wormhole-connect/src/hooks/useComputeSourceTokens.ts @@ -0,0 +1,58 @@ +import config from 'config'; +import { useEffect } from 'react'; +import { useDispatch } from 'react-redux'; + +import { setToken, setSupportedSourceTokens } from 'store/transferInput'; + +import type { Route } from 'config/types'; +import type { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; + +import RouteOperator from 'routes/operator'; + +type Props = { + sourceChain: ChainName | undefined; + sourceToken: string; + destChain: ChainName | undefined; + destToken: string; + route: Route | undefined; +}; + +export const useComputeSourceTokens = (props: Props): void => { + const { sourceChain, destChain, sourceToken, destToken, route } = props; + + const dispatch = useDispatch(); + + useEffect(() => { + if (!sourceChain) { + return; + } + + let active = true; + + const computeSrcTokens = async () => { + const supported = await RouteOperator.allSupportedSourceTokens( + config.tokens[destToken], + sourceChain, + destChain, + ); + if (active) { + dispatch(setSupportedSourceTokens(supported)); + const isTokenSupported = + sourceToken && supported.some((t) => t.key === sourceToken); + if (!isTokenSupported) { + dispatch(setToken('')); + } + if (supported.length === 1 && sourceToken === '') { + dispatch(setToken(supported[0].key)); + } + } + }; + + computeSrcTokens(); + + return () => { + active = false; + }; + // IMPORTANT: do not include token in dependency array + }, [route, sourceChain, destToken, dispatch]); +}; diff --git a/wormhole-connect/src/hooks/useGasSlider.ts b/wormhole-connect/src/hooks/useGasSlider.ts new file mode 100644 index 000000000..83de7633b --- /dev/null +++ b/wormhole-connect/src/hooks/useGasSlider.ts @@ -0,0 +1,43 @@ +import config from 'config'; +import RouteOperator from 'routes/operator'; +import { getWrappedToken } from 'utils'; + +import type { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; +import type { Route } from 'config/types'; + +type Props = { + destChain: ChainName | undefined; + destToken: string; + route: Route | undefined; + valid: boolean; + isTransactionInProgress: boolean; +}; + +export const useGasSlider = ( + props: Props, +): { + disabled: boolean; + showGasSlider: boolean | undefined; +} => { + const { destChain, destToken, route, isTransactionInProgress, valid } = props; + + const disabled = !valid || isTransactionInProgress; + const toChainConfig = destChain ? config.chains[destChain] : undefined; + const gasTokenConfig = toChainConfig + ? config.tokens[toChainConfig.gasToken] + : undefined; + const wrappedGasTokenConfig = gasTokenConfig + ? getWrappedToken(gasTokenConfig) + : undefined; + const willReceiveGasToken = + wrappedGasTokenConfig && destToken === wrappedGasTokenConfig.key; + const showGasSlider = + route && + RouteOperator.getRoute(route).NATIVE_GAS_DROPOFF_SUPPORTED && + !willReceiveGasToken; + + return { + disabled, + showGasSlider, + }; +}; diff --git a/wormhole-connect/src/utils/index.ts b/wormhole-connect/src/utils/index.ts index 5bfe0cd2c..f4ed68446 100644 --- a/wormhole-connect/src/utils/index.ts +++ b/wormhole-connect/src/utils/index.ts @@ -354,7 +354,7 @@ export const removeDust = (amount: BigNumber, decimals: number): BigNumber => { * isEmptyObject({ 'a': 1 }) * // => false */ -export const isEmptyObject = (value: Object | null | undefined) => { +export const isEmptyObject = (value: object | null | undefined) => { if (value === null || value === undefined) { return true; } diff --git a/wormhole-connect/src/views/Bridge/Bridge.tsx b/wormhole-connect/src/views/Bridge/Bridge.tsx index 303cd64f8..b02b8c3ff 100644 --- a/wormhole-connect/src/views/Bridge/Bridge.tsx +++ b/wormhole-connect/src/views/Bridge/Bridge.tsx @@ -1,31 +1,13 @@ -import React, { useEffect } from 'react'; -import { useSelector, useDispatch } from 'react-redux'; +import React from 'react'; +import { useSelector } from 'react-redux'; import { makeStyles } from 'tss-react/mui'; -import { BigNumber } from 'ethers'; import { RootState } from 'store'; -import { - setReceiverNativeBalance, - setReceiveAmount, - setDestToken, - setToken, - setSupportedSourceTokens, - setSupportedDestTokens, - setAllSupportedDestTokens, - TransferInputState, - getNativeVersionOfToken, - setFetchingReceiveAmount, - setReceiveAmountError, -} from 'store/transferInput'; +import { TransferInputState } from 'store/transferInput'; import config from 'config'; -import { TokenConfig } from 'config/types'; -import { getTokenDecimals, getWrappedToken } from 'utils'; -import { toChainId } from 'utils/sdk'; import { joinClass } from 'utils/style'; -import { toDecimals } from 'utils/balance'; import { isTransferValid, useValidate } from 'utils/transferValidation'; import useConfirmBeforeLeaving from 'utils/confirmBeforeLeaving'; -import RouteOperator from 'routes/operator'; import GasSlider from './NativeGasSlider'; import Preview from './Preview'; @@ -41,15 +23,17 @@ import ValidationError from './ValidationError'; import PoweredByIcon from 'icons/PoweredBy'; import { Alignment } from 'components/Header'; import FooterNavBar from 'components/FooterNavBar'; -import { isPorticoRoute } from 'routes/porticoBridge/utils'; -import { ETHBridge } from 'routes/porticoBridge/ethBridge'; -import { wstETHBridge } from 'routes/porticoBridge/wstETHBridge'; +import { useComputeDestinationTokens } from 'hooks/useComputeDestinationTokens'; +import { useComputeReceiveAmount } from 'hooks/useComputeReceiveAmount'; +import { useComputeSourceTokens } from 'hooks/useComputeSourceTokens'; import { usePorticoSwapInfo } from 'hooks/usePorticoSwapInfo'; import { usePorticoRelayerFee } from 'hooks/usePorticoRelayerFee'; import { useFetchTokenPrices } from 'hooks/useFetchTokenPrices'; +import { useGasSlider } from 'hooks/useGasSlider'; import NttInboundCapacityWarning from './NttInboundCapacityWarning'; import { isNttRoute } from 'routes/utils'; import { useConnectToLastUsedWallet } from 'utils/wallet'; +import { useComputeReceiverNativeBalance } from 'hooks/useComputeReceiverNativeBalance'; const useStyles = makeStyles()((_theme) => ({ spacer: { @@ -79,18 +63,9 @@ const useStyles = makeStyles()((_theme) => ({ }, })); -function isSupportedToken( - token: string, - supportedTokens: TokenConfig[], -): boolean { - if (!token) return true; - return supportedTokens.some((t) => t.key === token); -} - function Bridge() { const { classes } = useStyles(); const theme = useTheme(); - const dispatch = useDispatch(); const { showValidationState, validations, @@ -108,193 +83,48 @@ function Bridge() { (state: RootState) => state.relay, ); const portico = useSelector((state: RootState) => state.porticoBridge); - const { receiving } = useSelector((state: RootState) => state.wallet); + const receiving = useSelector((state: RootState) => state.wallet.receiving); // Warn user before closing tab if transaction has begun useConfirmBeforeLeaving(isTransactionInProgress); - // check destination native balance - useEffect(() => { - if (!fromChain || !toChain || !receiving.address) { - return; - } - - const chainConfig = config.chains[toChain]!; - - config.wh - .getNativeBalance(receiving.address, toChain) - .then((res: BigNumber) => { - const tokenConfig = config.tokens[chainConfig.gasToken]; - if (!tokenConfig) - throw new Error('Could not get native gas token config'); - const decimals = getTokenDecimals( - toChainId(tokenConfig.nativeChain), - 'native', - ); - dispatch(setReceiverNativeBalance(toDecimals(res, decimals, 6))); - }); - }, [fromChain, toChain, receiving.address, dispatch]); - - useEffect(() => { - if (!fromChain) { - return; - } - - let active = true; - - const computeSrcTokens = async () => { - const supported = await RouteOperator.allSupportedSourceTokens( - config.tokens[destToken], - fromChain, - toChain, - ); - if (active) { - dispatch(setSupportedSourceTokens(supported)); - const selectedIsSupported = isSupportedToken(token, supported); - if (!selectedIsSupported) { - dispatch(setToken('')); - } - if (supported.length === 1 && token === '') { - dispatch(setToken(supported[0].key)); - } - } - }; - - computeSrcTokens(); - - return () => { - active = false; - }; - // IMPORTANT: do not include token in dependency array - }, [route, fromChain, destToken, dispatch]); - - useEffect(() => { - if (!toChain) { - return; - } - - let canceled = false; - - const computeDestTokens = async () => { - let supported = await RouteOperator.allSupportedDestTokens( - config.tokens[token], - fromChain, - toChain, - ); - if (token) { - // If any of the tokens are native to the chain, only select those. - // This is to avoid users inadvertently receiving wrapped versions of the token. - const nativeTokens = supported.filter((t) => t.nativeChain === toChain); - if (nativeTokens.length > 0) { - supported = nativeTokens; - } - } - dispatch(setSupportedDestTokens(supported)); - const allSupported = await RouteOperator.allSupportedDestTokens( - undefined, - fromChain, - toChain, - ); - dispatch(setAllSupportedDestTokens(allSupported)); - if (toChain && supported.length === 1) { - if (!canceled) { - dispatch(setDestToken(supported[0].key)); - } - } - - // If all the supported tokens are the same token - // select the native version for applicable tokens - const symbols = supported.map((t) => t.symbol); - if ( - toChain && - symbols.every((s) => s === symbols[0]) && - ['USDC', 'tBTC'].includes(symbols[0]) - ) { - const key = supported.find( - (t) => - t.symbol === symbols[0] && - t.nativeChain === t.tokenId?.chain && - t.nativeChain === toChain, - )?.key; - if (!canceled && key) { - dispatch(setDestToken(key)); - } - } - - // If the source token is supported by a Portico bridge route, - // then select the native version on the dest chain - if ( - token && - destToken === '' && - toChain && - (!route || isPorticoRoute(route)) - ) { - const tokenSymbol = config.tokens[token]?.symbol; - const porticoTokens = [ - ...ETHBridge.SUPPORTED_TOKENS, - ...wstETHBridge.SUPPORTED_TOKENS, - ]; - if (porticoTokens.includes(tokenSymbol)) { - let key = getNativeVersionOfToken(tokenSymbol, toChain); - if (!key) { - const wrapped = getWrappedToken(config.tokens[token]); - key = getNativeVersionOfToken(wrapped.symbol, toChain); - } - if (!canceled && key && isSupportedToken(key, supported)) { - dispatch(setDestToken(key)); - } - } - } - }; - - computeDestTokens(); - - return () => { - canceled = true; - }; - // IMPORTANT: do not include destToken in dependency array - }, [route, token, fromChain, toChain, dispatch]); - - useEffect(() => { - if (!route || !amount || !token || !destToken || !fromChain || !toChain) { - return; - } - - const recomputeReceive = async () => { - try { - const routeOptions = isPorticoRoute(route) - ? portico - : { toNativeToken, relayerFee }; + // Compute and set destination native balance + useComputeReceiverNativeBalance({ + sourceChain: fromChain, + destChain: toChain, + receiving, + }); + + // Compute and set source tokens + useComputeSourceTokens({ + sourceChain: fromChain, + destChain: toChain, + sourceToken: token, + destToken, + route, + }); - dispatch(setFetchingReceiveAmount()); + // Compute and set destination tokens + useComputeDestinationTokens({ + sourceChain: fromChain, + destChain: toChain, + sourceToken: token, + destToken, + route, + }); - const newReceiveAmount = await RouteOperator.computeReceiveAmount( - route, - Number.parseFloat(amount), - token, - destToken, - fromChain, - toChain, - routeOptions, - ); - dispatch(setReceiveAmount(newReceiveAmount.toString())); - } catch (e: any) { - dispatch(setReceiveAmountError(e.message)); - } - }; - recomputeReceive(); - }, [ + // Compute and set receive amount + useComputeReceiveAmount({ + sourceChain: fromChain, + destChain: toChain, + sourceToken: token, + destToken, amount, + portico, + route, toNativeToken, relayerFee, - route, - token, - destToken, - toChain, - fromChain, - portico, - dispatch, - ]); + }); // Route specific hooks usePorticoSwapInfo(); @@ -305,26 +135,15 @@ function Bridge() { // validate transfer inputs useValidate(); const valid = isTransferValid(validations); - const disabled = !valid || isTransactionInProgress; - // if the dest token is the wrapped gas token, then disable the gas slider, - // because it will be unwrapped by the relayer contract - const toChainConfig = toChain ? config.chains[toChain] : undefined; - const gasTokenConfig = toChainConfig - ? config.tokens[toChainConfig.gasToken] - : undefined; - const wrappedGasTokenConfig = gasTokenConfig - ? getWrappedToken(gasTokenConfig) - : undefined; - const willReceiveGasToken = - wrappedGasTokenConfig && destToken === wrappedGasTokenConfig.key; - - const showGasSlider = - route && - RouteOperator.getRoute(route).NATIVE_GAS_DROPOFF_SUPPORTED && - !willReceiveGasToken; - const showRouteValidation = - !!fromChain && !!toChain && !!token && !!destToken && !!amount; + // Get Gas Slider props + const { disabled, showGasSlider } = useGasSlider({ + destChain: toChain, + destToken: destToken, + route, + valid, + isTransactionInProgress, + }); const pageHeader = getPageHeader(); @@ -340,7 +159,9 @@ function Bridge() { diff --git a/wormhole-connect/src/views/Bridge/Inputs/From.tsx b/wormhole-connect/src/views/Bridge/Inputs/From.tsx index dd502b800..9b611c703 100644 --- a/wormhole-connect/src/views/Bridge/Inputs/From.tsx +++ b/wormhole-connect/src/views/Bridge/Inputs/From.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; +import type { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; import { RootState } from 'store'; import { diff --git a/wormhole-connect/src/views/Bridge/Inputs/Inputs.tsx b/wormhole-connect/src/views/Bridge/Inputs/Inputs.tsx index 689badabb..8ff4778da 100644 --- a/wormhole-connect/src/views/Bridge/Inputs/Inputs.tsx +++ b/wormhole-connect/src/views/Bridge/Inputs/Inputs.tsx @@ -3,7 +3,7 @@ import { useSelector } from 'react-redux'; import { makeStyles } from 'tss-react/mui'; import { useTheme } from '@mui/material/styles'; import useMediaQuery from '@mui/material/useMediaQuery'; -import { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; +import type { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; import config from 'config'; import { TransferSide } from 'config/types'; diff --git a/wormhole-connect/src/views/Bridge/Inputs/To.tsx b/wormhole-connect/src/views/Bridge/Inputs/To.tsx index 26178b124..c1b5001e0 100644 --- a/wormhole-connect/src/views/Bridge/Inputs/To.tsx +++ b/wormhole-connect/src/views/Bridge/Inputs/To.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; +import type { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; import { RootState } from 'store'; import { diff --git a/wormhole-connect/src/views/Bridge/RouteOptions.tsx b/wormhole-connect/src/views/Bridge/RouteOptions.tsx index 57ecb655b..36a91177d 100644 --- a/wormhole-connect/src/views/Bridge/RouteOptions.tsx +++ b/wormhole-connect/src/views/Bridge/RouteOptions.tsx @@ -13,7 +13,7 @@ import { calculateUSDPrice, getDisplayName } from 'utils'; import config from 'config'; import { Route } from 'config/types'; import { RoutesConfig, RouteData } from 'config/routes'; -import { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; +import type { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; import BridgeCollapse, { CollapseControlStyle } from './Collapse'; import TokenIcon from 'icons/TokenIcons'; diff --git a/wormhole-connect/src/views/Bridge/Send.tsx b/wormhole-connect/src/views/Bridge/Send.tsx index a89462806..2ace036b2 100644 --- a/wormhole-connect/src/views/Bridge/Send.tsx +++ b/wormhole-connect/src/views/Bridge/Send.tsx @@ -1,6 +1,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useSelector, useDispatch } from 'react-redux'; -import { Context, TokenId } from '@wormhole-foundation/wormhole-connect-sdk'; +import { Context } from '@wormhole-foundation/wormhole-connect-sdk'; +import type { TokenId } from '@wormhole-foundation/wormhole-connect-sdk'; import { makeStyles } from 'tss-react/mui'; import config from 'config'; diff --git a/wormhole-connect/src/views/Bridge/TransferLimitedWarning.tsx b/wormhole-connect/src/views/Bridge/TransferLimitedWarning.tsx index 9c2131fc7..d451ef63b 100644 --- a/wormhole-connect/src/views/Bridge/TransferLimitedWarning.tsx +++ b/wormhole-connect/src/views/Bridge/TransferLimitedWarning.tsx @@ -1,5 +1,5 @@ import React, { useEffect } from 'react'; -import { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; +import type { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; import useIsTransferLimited from 'hooks/useIsTransferLimited'; import Dialog from '@mui/material/Dialog'; import ScopedCssBaseline from '@mui/material/ScopedCssBaseline'; diff --git a/wormhole-connect/src/views/Redeem/AddToWallet.tsx b/wormhole-connect/src/views/Redeem/AddToWallet.tsx index 807a2abd8..be3f20d63 100644 --- a/wormhole-connect/src/views/Redeem/AddToWallet.tsx +++ b/wormhole-connect/src/views/Redeem/AddToWallet.tsx @@ -1,9 +1,8 @@ import { Link, Typography } from '@mui/material'; -import { isEVMChain } from '@certusone/wormhole-sdk'; import React, { useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { makeStyles } from 'tss-react/mui'; -import { +import type { ChainName, SuiContext, WormholeContext, @@ -20,6 +19,7 @@ import { getDisplayName, getChainConfig, } from 'utils'; +import { isEvmChain } from 'utils/sdk'; import { TransferWallet, switchChain, watchAsset } from 'utils/wallet'; import TokenIcon from 'icons/TokenIcons'; @@ -219,7 +219,7 @@ function AddToWallet() { if (!targetToken || !targetAddress) return <>; - if (isEVMChain(chainId)) { + if (isEvmChain(chainId)) { return ; } else if ( chainId === MAINNET_CHAINS.solana?.id && diff --git a/wormhole-connect/src/views/Redeem/Confirmations.tsx b/wormhole-connect/src/views/Redeem/Confirmations.tsx index ac5883695..206bc86eb 100644 --- a/wormhole-connect/src/views/Redeem/Confirmations.tsx +++ b/wormhole-connect/src/views/Redeem/Confirmations.tsx @@ -1,6 +1,6 @@ import { LinearProgress, linearProgressClasses } from '@mui/material'; import { styled } from '@mui/material/styles'; -import { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; +import type { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; import React, { useEffect, useMemo, useState } from 'react'; import { useSelector } from 'react-redux'; import { makeStyles } from 'tss-react/mui'; diff --git a/wormhole-connect/src/views/Redeem/ExplorerLink.tsx b/wormhole-connect/src/views/Redeem/ExplorerLink.tsx index 05412beaf..ebc807c2a 100644 --- a/wormhole-connect/src/views/Redeem/ExplorerLink.tsx +++ b/wormhole-connect/src/views/Redeem/ExplorerLink.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; +import type { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; import { makeStyles } from 'tss-react/mui'; import { LINK } from 'utils/style'; import config from 'config'; diff --git a/wormhole-connect/src/views/Redeem/GovernorEnqueuedWarning.tsx b/wormhole-connect/src/views/Redeem/GovernorEnqueuedWarning.tsx index 1ad2a14be..86578ed28 100644 --- a/wormhole-connect/src/views/Redeem/GovernorEnqueuedWarning.tsx +++ b/wormhole-connect/src/views/Redeem/GovernorEnqueuedWarning.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { makeStyles } from 'tss-react/mui'; -import { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; +import type { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; import config from 'config'; import { GOVERNOR_WHITEPAPER_URL } from 'consts'; import AlertBanner from 'components/AlertBanner'; diff --git a/wormhole-connect/src/views/Redeem/Header.tsx b/wormhole-connect/src/views/Redeem/Header.tsx index 4e5c8494c..83b88d041 100644 --- a/wormhole-connect/src/views/Redeem/Header.tsx +++ b/wormhole-connect/src/views/Redeem/Header.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { makeStyles } from 'tss-react/mui'; -import { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; +import type { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; import config from 'config'; import { displayAddress } from 'utils'; diff --git a/wormhole-connect/src/views/TxSearch.tsx b/wormhole-connect/src/views/TxSearch.tsx index 970e0a362..5e27fd532 100644 --- a/wormhole-connect/src/views/TxSearch.tsx +++ b/wormhole-connect/src/views/TxSearch.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useState } from 'react'; import { makeStyles } from 'tss-react/mui'; import { useDispatch } from 'react-redux'; import { Select, MenuItem, CircularProgress } from '@mui/material'; -import { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; +import type { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; import config from 'config'; import { isValidTxId } from 'utils'; diff --git a/wormhole-connect/src/views/WalletModal.tsx b/wormhole-connect/src/views/WalletModal.tsx index 09b4b5d0c..527d5af26 100644 --- a/wormhole-connect/src/views/WalletModal.tsx +++ b/wormhole-connect/src/views/WalletModal.tsx @@ -3,7 +3,7 @@ import { makeStyles } from 'tss-react/mui'; import { useTheme } from '@mui/material/styles'; import CircularProgress from '@mui/material/CircularProgress'; import { useDispatch, useSelector } from 'react-redux'; -import { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; +import type { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; import config from 'config'; import { RootState } from 'store';