From dcaff2d918f262847e402c7a9e6c370609e77ef1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Jos=C3=A9=20Ram=C3=ADrez?= Date: Fri, 4 Oct 2024 09:32:05 -0300 Subject: [PATCH 1/6] fix(requst): clean error message before trying again Refs: #102 --- src/components/Request/Pay/Views/Initial.view.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Request/Pay/Views/Initial.view.tsx b/src/components/Request/Pay/Views/Initial.view.tsx index ec71ac17..39d67031 100644 --- a/src/components/Request/Pay/Views/Initial.view.tsx +++ b/src/components/Request/Pay/Views/Initial.view.tsx @@ -80,6 +80,7 @@ export const InitialView = ({ const { feeEstimation, estimatedFromAmount } = txData setEstimatedFromValue(estimatedFromAmount) if (Number(feeEstimation) > 0) { + setErrorState({ showError: false, errorMessage: '' }) setIsFeeEstimationError(false) setTxFee(Number(feeEstimation).toFixed(2)) setLinkState(RequestStatus.CLAIM) From 29e02caa6f707b5c7f149ca91fd3c54c6c7ca6b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Jos=C3=A9=20Ram=C3=ADrez?= Date: Fri, 4 Oct 2024 09:33:41 -0300 Subject: [PATCH 2/6] refactor(request): treat token data from selector as an unit From the request pay init, we need to now the token address, chain and decimals in order to calculate the squid router fee. Previously we depended on those three data points separately. This caused that when the user seleted a token, we tried to calculate the route for that token but with the decimals from the previous one (the effect tasked with cleaning this also depends on the change of selected token, so they both executed at the same time). In reality, from the pay we depend on the whole token data and only care when it updates completely. This refactor reflects that and avoid calling squid with bad data. Refs: #102 --- .../Request/Pay/Views/Initial.view.tsx | 58 +++++++++---------- src/context/tokenSelector.context.tsx | 30 ++++++---- 2 files changed, 47 insertions(+), 41 deletions(-) diff --git a/src/components/Request/Pay/Views/Initial.view.tsx b/src/components/Request/Pay/Views/Initial.view.tsx index 39d67031..81752afe 100644 --- a/src/components/Request/Pay/Views/Initial.view.tsx +++ b/src/components/Request/Pay/Views/Initial.view.tsx @@ -31,12 +31,9 @@ export const InitialView = ({ const { open } = useWeb3Modal() const { setLoadingState, loadingState, isLoading } = useContext(context.loadingStateContext) const { - selectedChainID, + selectedTokenData, setSelectedChainID, - selectedTokenAddress, setSelectedTokenAddress, - selectedTokenDecimals, - isTokenPriceFetchingComplete, setIsXChain, } = useContext(context.tokenSelectorContext) const [errorState, setErrorState] = useState<{ @@ -48,26 +45,31 @@ export const InitialView = ({ const [linkState, setLinkState] = useState(RequestStatus.NOT_CONNECTED) const [estimatedFromValue, setEstimatedFromValue] = useState('0') const createXChainUnsignedTx = async () => { + // This function is only makes sense if selectedTokenData is defined + // Chack that it is defined before calling this function + console.assert(selectedTokenData, 'selectedTokenData must be defined before estimating tx fee') + const xchainUnsignedTxs = await peanut.prepareXchainRequestFulfillmentTransaction({ - fromToken: selectedTokenAddress, - fromChainId: selectedChainID, + fromToken: selectedTokenData!.tokenAddress, + fromChainId: selectedTokenData!.chainId, senderAddress: address ?? '', link: requestLinkData.link, squidRouterUrl: 'https://apiplus.squidrouter.com/v2/route', apiUrl: '/api/proxy/get', - provider: await peanut.getDefaultProvider(selectedChainID), - tokenType: selectedTokenAddress === ADDRESS_ZERO ? EPeanutLinkType.native : EPeanutLinkType.erc20, - fromTokenDecimals: selectedTokenDecimals as number, + provider: await peanut.getDefaultProvider(selectedTokenData!.chainId), + tokenType: selectedTokenData!.tokenAddress === ADDRESS_ZERO ? EPeanutLinkType.native : EPeanutLinkType.erc20, + fromTokenDecimals: selectedTokenData!.decimals as number, }) return xchainUnsignedTxs } useEffect(() => { const estimateTxFee = async () => { + setLinkState(RequestStatus.LOADING) if ( - selectedChainID === requestLinkData.chainId - && utils.areTokenAddressesEqual(selectedTokenAddress, requestLinkData.tokenAddress) + selectedTokenData!.chainId === requestLinkData.chainId + && utils.areTokenAddressesEqual(selectedTokenData!.tokenAddress, requestLinkData.tokenAddress) ) { setErrorState({ showError: false, errorMessage: '' }) setIsFeeEstimationError(false) @@ -98,9 +100,9 @@ export const InitialView = ({ } } - const isXChain = selectedChainID !== requestLinkData.chainId + const isXChain = selectedTokenData?.chainId !== requestLinkData.chainId || !utils.areTokenAddressesEqual( - selectedTokenAddress, + selectedTokenData?.tokenAddress, requestLinkData.tokenAddress ) setIsXChain(isXChain) @@ -108,16 +110,10 @@ export const InitialView = ({ // wait for token selector to fetch token price, both effects depend on // selectedTokenAddress and selectedChainID, but we depend on that // effect being completed first - if (!isConnected || (isXChain && !isTokenPriceFetchingComplete)) return + if (!isConnected || (isXChain && !selectedTokenData)) return estimateTxFee() - }, [ - selectedTokenAddress, - selectedChainID, - selectedTokenDecimals, - isTokenPriceFetchingComplete, - requestLinkData - ]) + }, [selectedTokenData, requestLinkData]) const handleConnectWallet = async () => { open().finally(() => { @@ -147,12 +143,12 @@ export const InitialView = ({ setErrorState({ showError: false, errorMessage: '' }) if (!unsignedTx) return if ( - selectedChainID === requestLinkData.chainId - && utils.areTokenAddressesEqual(selectedTokenAddress, requestLinkData.tokenAddress) + selectedTokenData!.chainId === requestLinkData.chainId + && utils.areTokenAddressesEqual(selectedTokenData!.tokenAddress, requestLinkData.tokenAddress) ){ await checkUserHasEnoughBalance({ tokenValue: requestLinkData.tokenAmount }) - if (selectedChainID !== String(currentChain?.id)) { - await switchNetwork(selectedChainID) + if (selectedTokenData?.chainId !== String(currentChain?.id)) { + await switchNetwork(selectedTokenData!.chainId) } setLoadingState('Sign in wallet') const hash = await sendTransactions({ @@ -185,8 +181,8 @@ export const InitialView = ({ onNext() } else { await checkUserHasEnoughBalance({ tokenValue: estimatedFromValue }) - if (selectedChainID !== String(currentChain?.id)) { - await switchNetwork(selectedChainID) + if (selectedTokenData!.chainId !== String(currentChain?.id)) { + await switchNetwork(selectedTokenData!.chainId) } setLoadingState('Sign in wallet') const xchainUnsignedTxs = await createXChainUnsignedTx() @@ -330,12 +326,12 @@ export const InitialView = ({