diff --git a/src/components/Claim/Claim.tsx b/src/components/Claim/Claim.tsx index cb8817537..644027734 100644 --- a/src/components/Claim/Claim.tsx +++ b/src/components/Claim/Claim.tsx @@ -110,8 +110,6 @@ export const Claim = ({}) => { return chain }) - setSelectedChainID(filteredXchainDetails[0].chainId) - setSelectedTokenAddress(filteredXchainDetails[0].tokens[0].address) return filteredXchainDetails } else { return undefined @@ -133,34 +131,35 @@ export const Claim = ({}) => { }) setClaimLinkData(linkDetails) + setSelectedChainID(linkDetails.chainId) + setSelectedTokenAddress(linkDetails.tokenAddress) + if (linkDetails.claimed) { setLinkState(_consts.claimLinkStateType.ALREADY_CLAIMED) + return + } + + const crossChainDetails = await getCrossChainDetails(linkDetails) + setCrossChainDetails(crossChainDetails) + const tokenPrice = await utils.fetchTokenPrice(linkDetails.tokenAddress.toLowerCase(), linkDetails.chainId) + tokenPrice && setTokenPrice(tokenPrice?.price) + + if (address) { + setRecipient({ name: '', address }) + + const estimatedPoints = await estimatePoints({ + address: address ?? '', + chainId: linkDetails.chainId, + amountUSD: Number(linkDetails.tokenAmount) * (tokenPrice?.price ?? 0), + actionType: ActionType.CLAIM, + }) + setEstimatedPoints(estimatedPoints) + } + + if (address && linkDetails.senderAddress === address) { + setLinkState(_consts.claimLinkStateType.CLAIM_SENDER) } else { - const crossChainDetails = await getCrossChainDetails(linkDetails) - setCrossChainDetails(crossChainDetails) - const tokenPrice = await utils.fetchTokenPrice( - linkDetails.tokenAddress.toLowerCase(), - linkDetails.chainId - ) - tokenPrice && setTokenPrice(tokenPrice?.price) - - if (address) { - setRecipient({ name: '', address }) - - const estimatedPoints = await estimatePoints({ - address: address ?? '', - chainId: linkDetails.chainId, - amountUSD: Number(linkDetails.tokenAmount) * (tokenPrice?.price ?? 0), - actionType: ActionType.CLAIM, - }) - setEstimatedPoints(estimatedPoints) - } - - if (address && linkDetails.senderAddress === address) { - setLinkState(_consts.claimLinkStateType.CLAIM_SENDER) - } else { - setLinkState(_consts.claimLinkStateType.CLAIM) - } + setLinkState(_consts.claimLinkStateType.CLAIM) } } catch (error) { setLinkState(_consts.claimLinkStateType.NOT_FOUND) diff --git a/src/components/Claim/Link/Initial.view.tsx b/src/components/Claim/Link/Initial.view.tsx index eb2fcd347..9d03acf37 100644 --- a/src/components/Claim/Link/Initial.view.tsx +++ b/src/components/Claim/Link/Initial.view.tsx @@ -9,9 +9,16 @@ import useClaimLink from '../useClaimLink' import * as context from '@/context' import Loading from '@/components/Global/Loading' import * as consts from '@/constants' -import * as utils from '@/utils' +import { + areTokenAddressesEqual, + saveClaimedLinkToLocalStorage, + ErrorHandler, + getBridgeTokenName, + getBridgeChainName, + checkifImageType, + formatTokenAmount, +} from '@/utils' import MoreInfo from '@/components/Global/MoreInfo' -import TokenSelectorXChain from '@/components/Global/TokenSelector/TokenSelectorXChain' import { getSquidRouteRaw } from '@squirrel-labs/peanut-sdk' import * as _interfaces from '../Claim.interfaces' import * as _utils from '../Claim.utils' @@ -27,6 +34,7 @@ import { } from '@/components/Offramp/Offramp.consts' import { TOOLTIPS } from '@/constants/tooltips' import AddressLink from '@/components/Global/AddressLink' +import TokenSelector from '@/components/Global/TokenSelector/TokenSelector' export const InitialClaimLinkView = ({ onNext, @@ -62,9 +70,16 @@ export const InitialClaimLinkView = ({ const [inputChanging, setInputChanging] = useState(false) const { setLoadingState, loadingState, isLoading } = useContext(context.loadingStateContext) - const { selectedChainID, selectedTokenAddress, refetchXchainRoute, setRefetchXchainRoute } = useContext( - context.tokenSelectorContext - ) + const { + selectedChainID, + setSelectedChainID, + selectedTokenAddress, + setSelectedTokenAddress, + refetchXchainRoute, + setRefetchXchainRoute, + isXChain, + setIsXChain, + } = useContext(context.tokenSelectorContext) const mappedData: _interfaces.CombinedType[] = _utils.mapToIPeanutChainDetailsArray(crossChainDetails) const { claimLink } = useClaimLink() const { open } = useWeb3Modal() @@ -98,7 +113,7 @@ export const InitialClaimLinkView = ({ }) if (claimTxHash) { - utils.saveClaimedLinkToLocalStorage({ + saveClaimedLinkToLocalStorage({ address: address ?? '', data: { ...claimLinkData, @@ -117,7 +132,7 @@ export const InitialClaimLinkView = ({ throw new Error('Error claiming link') } } catch (error) { - const errorString = utils.ErrorHandler(error) + const errorString = ErrorHandler(error) setErrorState({ showError: true, errorMessage: errorString, @@ -134,8 +149,8 @@ export const InitialClaimLinkView = ({ errorMessage: '', }) setLoadingState('Fetching route') - let tokenName = utils.getBridgeTokenName(claimLinkData.chainId, claimLinkData.tokenAddress) - let chainName = utils.getBridgeChainName(claimLinkData.chainId) + let tokenName = getBridgeTokenName(claimLinkData.chainId, claimLinkData.tokenAddress) + let chainName = getBridgeChainName(claimLinkData.chainId) if (tokenPrice) { const cashoutUSDAmount = Number(claimLinkData.tokenAmount) * tokenPrice @@ -153,8 +168,7 @@ export const InitialClaimLinkView = ({ } } - if (tokenName && chainName) { - } else { + if (!tokenName || !chainName) { if (!crossChainDetails) { setErrorState({ showError: true, @@ -277,6 +291,19 @@ export const InitialClaimLinkView = ({ } }, [address]) + useEffect(() => { + if ( + selectedChainID === claimLinkData.chainId && + areTokenAddressesEqual(selectedTokenAddress, claimLinkData.tokenAddress) + ) { + setIsXChain(false) + setSelectedRoute(null) + setHasFetchedRoute(false) + } else { + setIsXChain(true) + } + }, [selectedChainID, selectedTokenAddress, claimLinkData.chainId, claimLinkData.tokenAddress]) + useEffect(() => { if (refetchXchainRoute) { setIsXchainLoading(true) @@ -299,10 +326,12 @@ export const InitialClaimLinkView = ({ route.fromChain === claimLinkData.chainId && route.fromToken.toLowerCase() === claimLinkData.tokenAddress.toLowerCase() && route.toChain === selectedChainID && - utils.areTokenAddressesEqual(route.toToken, selectedTokenAddress) + areTokenAddressesEqual(route.toToken, selectedTokenAddress) ) if (existingRoute) { setSelectedRoute(existingRoute) + } else if (!isXChain) { + setHasFetchedRoute(false) } else { const tokenAmount = Math.floor( Number(claimLinkData.tokenAmount) * Math.pow(10, claimLinkData.tokenDecimals) @@ -357,7 +386,7 @@ export const InitialClaimLinkView = ({ {(attachment.message || attachment.attachmentUrl) && ( <>
{attachment.message && ( {tokenPrice ? ( ) : (
- chain.chainId === selectedRoute.route.params.toChain) - ?.name - : mappedData.find((data) => data.chainId === selectedChainID)?.name - : consts.supportedPeanutChains.find((chain) => chain.chainId === claimLinkData.chainId) - ?.name - } - tokenSymbol={ - hasFetchedRoute - ? selectedRoute - ? selectedRoute.route.estimate.toToken.symbol - : mappedData - .find((data) => data.chainId === selectedChainID) - ?.tokens?.find((token) => - utils.areTokenAddressesEqual(token.address, selectedTokenAddress) - )?.symbol - : claimLinkData.tokenSymbol - } - tokenLogoUrl={ - hasFetchedRoute - ? selectedRoute - ? selectedRoute.route.estimate.toToken.logoURI - : mappedData - .find((data) => data.chainId === selectedChainID) - ?.tokens?.find((token) => - utils.areTokenAddressesEqual(token.address, selectedTokenAddress) - )?.logoURI - : consts.peanutTokenDetails - .find((chain) => chain.chainId === claimLinkData.chainId) - ?.tokens.find((token) => - utils.areTokenAddressesEqual(token.address, claimLinkData.tokenAddress) - )?.logoURI - } - chainLogoUrl={ - hasFetchedRoute - ? selectedRoute - ? crossChainDetails?.find( - (chain) => chain.chainId === selectedRoute.route.params.toChain - )?.chainIconURI - : mappedData.find((data) => data.chainId === selectedChainID)?.icon.url - : consts.supportedPeanutChains.find((chain) => chain.chainId === claimLinkData.chainId) - ?.icon.url - } - tokenAmount={ - hasFetchedRoute - ? selectedRoute - ? utils.formatTokenAmount( - utils.formatAmountWithDecimals({ - amount: selectedRoute.route.estimate.toAmountMin, - decimals: selectedRoute.route.estimate.toToken.decimals, - }), - 4 - ) - : undefined - : claimLinkData.tokenAmount - } - isLoading={isXchainLoading} - routeError={errorState.errorMessage === 'No route found for the given token pair.'} - routeFound={selectedRoute ? true : false} - onReset={() => { - setSelectedRoute(null) - setHasFetchedRoute(false) - setErrorState({ - showError: false, - errorMessage: '', - }) - }} - isStatic={ - recipientType === 'iban' || recipientType === 'us' || !crossChainDetails ? true : false - } - /> + {recipientType !== 'iban' && recipientType !== 'us' && ( + { + setSelectedChainID(claimLinkData.chainId) + setSelectedTokenAddress(claimLinkData.tokenAddress) + }} + /> + )} { - const [visible, setVisible] = useState(false) - const [filterValue, setFilterValue] = useState('') - const focusButtonRef = useRef(null) - - const { balances } = useBalance() - const { selectedChainID, selectedTokenAddress, setSelectedTokenAddress, setRefetchXchainRoute } = useContext( - context.tokenSelectorContext - ) - - const _tokensToDisplay = useMemo(() => { - let _tokens - if (data) { - _tokens = data.find((detail) => detail.chainId === selectedChainID)?.tokens || [] - } else { - _tokens = peanutTokenDetails.find((detail) => detail.chainId === selectedChainID)?.tokens || [] - } - - //Filtering on name and symbol - if (filterValue && filterValue.length > 0) { - _tokens = _tokens.filter( - (token) => - token.name.toLowerCase().includes(filterValue.toLowerCase()) || - token.symbol.toLowerCase().includes(filterValue.toLowerCase()) - ) - return _tokens - } - - //only return the first 6 tokens if not filtering - return _tokens - }, [filterValue, selectedChainID]) - - function setToken(address: string): void { - setRefetchXchainRoute(true) - setSelectedTokenAddress(address) - setTimeout(() => { - setFilterValue('') - }, 1000) - setVisible(false) - } - - useEffect(() => { - if (focusButtonRef.current) { - focusButtonRef.current.focus() - } - }, [visible]) - - return ( - <> - - - { - setVisible(false) - }} - title={'Select Token'} - classNameWrapperDiv="px-5 pb-7 pt-8" - > -
-
-
- - {filterValue.length > 0 - ? components.tokenDisplay(_tokensToDisplay, setToken, balances, selectedChainID) - : components.simpleTokenDisplay(_tokensToDisplay, setToken)} -
-
- - ) -} - -export default TokenSelectorXChain diff --git a/src/context/tokenSelector.context.tsx b/src/context/tokenSelector.context.tsx index 7b8782f2d..8681cac2d 100644 --- a/src/context/tokenSelector.context.tsx +++ b/src/context/tokenSelector.context.tsx @@ -114,6 +114,7 @@ export const TokenContextProvider = ({ children }: { children: React.ReactNode } if (selectedTokenAddress && selectedChainID) { setIsFetchingTokenData(true) setSelectedTokenData(undefined) + setRefetchXchainRoute(true) setSelectedTokenPrice(undefined) setSelectedTokenDecimals(undefined) setInputDenomination('TOKEN')