diff --git a/packages/core-mobile/app/contexts/SendContext.tsx b/packages/core-mobile/app/contexts/SendContext.tsx index 17ff58497..768303ce3 100644 --- a/packages/core-mobile/app/contexts/SendContext.tsx +++ b/packages/core-mobile/app/contexts/SendContext.tsx @@ -26,8 +26,8 @@ interface SendContextState { setError: Dispatch isSending: boolean setIsSending: Dispatch - isValidating: boolean - setIsValidating: Dispatch + canValidate: boolean + setCanValidate: Dispatch isValid: boolean } @@ -53,7 +53,7 @@ export const SendContextProvider = ({ const { data: networkFee } = useNetworkFee(activeNetwork) const [error, setError] = useState() const [isSending, setIsSending] = useState(false) - const [isValidating, setIsValidating] = useState(false) + const [canValidate, setCanValidate] = useState(false) const [defaultMaxFeePerGas, setDefaultMaxFeePerGas] = useState(0n) @@ -88,8 +88,8 @@ export const SendContextProvider = ({ setError, isSending, setIsSending, - isValidating, - setIsValidating, + canValidate, + setCanValidate, isValid: error === undefined } return {children} diff --git a/packages/core-mobile/app/screens/nft/send/NftSend.tsx b/packages/core-mobile/app/screens/nft/send/NftSend.tsx index 648cbfcc4..aaa8ea0f1 100644 --- a/packages/core-mobile/app/screens/nft/send/NftSend.tsx +++ b/packages/core-mobile/app/screens/nft/send/NftSend.tsx @@ -57,7 +57,7 @@ export default function NftSend({ error, isSending, isValid, - isValidating + setCanValidate } = useSendContext() const { activeNetwork } = useNetworks() const activeAccount = useSelector(selectActiveAccount) @@ -87,7 +87,7 @@ export default function NftSend({ }) const canSubmit = - !isValidating && !isSending && isValid && !!toAddress && error === undefined + !isSending && isValid && !!toAddress && error === undefined && touched const { saveRecentContact, @@ -143,7 +143,11 @@ export default function NftSend({ if (touched === false && toAddress) { setTouched(true) } - }, [toAddress, token, touched]) + }, [toAddress, touched, setCanValidate]) + + useEffect(() => { + setCanValidate(touched) + }, [touched, setCanValidate]) const onContactSelected = ( item: Contact | Account, diff --git a/packages/core-mobile/app/screens/send/components/SendAVM.tsx b/packages/core-mobile/app/screens/send/components/SendAVM.tsx index 7883d11f7..754af4c17 100644 --- a/packages/core-mobile/app/screens/send/components/SendAVM.tsx +++ b/packages/core-mobile/app/screens/send/components/SendAVM.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react' +import React from 'react' import { useSendContext } from 'contexts/SendContext' import { Network } from '@avalabs/core-chains-sdk' import { TokenWithBalanceAVM } from '@avalabs/vm-module-types' @@ -26,17 +26,8 @@ const SendAVM = ({ onSuccess: (txHash: string) => void onFailure: (txError: unknown) => void }): JSX.Element => { - const { - setToAddress, - token, - setToken, - maxAmount, - error, - isValid, - isValidating, - isSending, - maxFee - } = useSendContext() + const { setToAddress, token, maxAmount, error, isValid, isSending, maxFee } = + useSendContext() const activeAccount = useSelector(selectActiveAccount) const fromAddress = activeAccount?.addressAVM ?? '' @@ -49,10 +40,6 @@ const SendAVM = ({ account }) - useEffect(() => { - setToken(nativeToken) - }, [nativeToken, setToken]) - const handleSend = async (): Promise => { if (token === undefined) { return @@ -79,7 +66,6 @@ const SendAVM = ({ error={error} isValid={isValid} isSending={isSending} - isValidating={isValidating} onOpenQRScanner={onOpenQRScanner} onOpenAddressBook={onOpenAddressBook} onSelectContact={handleSelectContact} diff --git a/packages/core-mobile/app/screens/send/components/SendPVM.tsx b/packages/core-mobile/app/screens/send/components/SendPVM.tsx index 6f0fc1f24..47435dd50 100644 --- a/packages/core-mobile/app/screens/send/components/SendPVM.tsx +++ b/packages/core-mobile/app/screens/send/components/SendPVM.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react' +import React from 'react' import { useSendContext } from 'contexts/SendContext' import { Network } from '@avalabs/core-chains-sdk' import { TokenWithBalancePVM } from '@avalabs/vm-module-types' @@ -26,17 +26,8 @@ const SendPVM = ({ onSuccess: (txHash: string) => void onFailure: (txError: unknown) => void }): JSX.Element => { - const { - setToAddress, - token, - setToken, - maxAmount, - error, - isValid, - isValidating, - isSending, - maxFee - } = useSendContext() + const { setToAddress, token, maxAmount, error, isValid, isSending, maxFee } = + useSendContext() const activeAccount = useSelector(selectActiveAccount) const fromAddress = activeAccount?.addressPVM ?? '' @@ -49,10 +40,6 @@ const SendPVM = ({ account }) - useEffect(() => { - setToken(nativeToken) - }, [nativeToken, setToken]) - const handleSend = async (): Promise => { if (token === undefined) { return @@ -79,7 +66,6 @@ const SendPVM = ({ error={error} isValid={isValid} isSending={isSending} - isValidating={isValidating} onOpenQRScanner={onOpenQRScanner} onOpenAddressBook={onOpenAddressBook} onSelectContact={handleSelectContact} diff --git a/packages/core-mobile/app/screens/send/components/SendTokenForm.tsx b/packages/core-mobile/app/screens/send/components/SendTokenForm.tsx index fbb9f159c..ab5c94cbb 100644 --- a/packages/core-mobile/app/screens/send/components/SendTokenForm.tsx +++ b/packages/core-mobile/app/screens/send/components/SendTokenForm.tsx @@ -25,7 +25,6 @@ const SendTokenForm = ({ addressPlaceholder, error, isValid, - isValidating, isSending, onOpenQRScanner, onOpenAddressBook, @@ -37,15 +36,21 @@ const SendTokenForm = ({ addressPlaceholder: string error: string | undefined isValid: boolean - isValidating: boolean isSending: boolean onOpenQRScanner: () => void onOpenAddressBook: () => void onSelectContact: (item: Contact | CorePrimaryAccount) => void onSend: () => void }): JSX.Element => { - const { setToken, token, setAmount, amount, toAddress, setToAddress } = - useSendContext() + const { + setToken, + token, + setAmount, + amount, + toAddress, + setToAddress, + setCanValidate + } = useSendContext() const [isAddressTouched, setIsAddressTouched] = useState(false) const [isTokenTouched, setIsTokenTouched] = useState(false) const [isAmountTouched, setIsAmountTouched] = useState(false) @@ -108,7 +113,11 @@ const SendTokenForm = ({ [isAddressTouched, isTokenTouched, isAmountTouched] ) - const canSubmit = !isValidating && !isSending && isValid + useEffect(() => { + setCanValidate(isAllFieldsTouched) + }, [isAllFieldsTouched, setCanValidate]) + + const canSubmit = !isSending && isValid && isAllFieldsTouched return ( diff --git a/packages/core-mobile/app/screens/send/hooks/useAVMSend.ts b/packages/core-mobile/app/screens/send/hooks/useAVMSend.ts index 8e6545dfb..010e5b1b5 100644 --- a/packages/core-mobile/app/screens/send/hooks/useAVMSend.ts +++ b/packages/core-mobile/app/screens/send/hooks/useAVMSend.ts @@ -17,11 +17,11 @@ const useAVMSend: SendAdapterAVM = ({ const { setMaxAmount, setError, - setIsValidating, setIsSending, amount, token, - toAddress + toAddress, + canValidate } = useSendContext() const send = useCallback(async () => { @@ -56,9 +56,6 @@ const useAVMSend: SendAdapterAVM = ({ ) const validate = useCallback(async () => { - setIsValidating(true) - setError(undefined) - try { validateAVMSend({ amount: amount?.bn, @@ -67,25 +64,18 @@ const useAVMSend: SendAdapterAVM = ({ token: token as TokenWithBalanceAVM, onCalculateMaxAmount: setMaxAmount }) + + setError(undefined) } catch (err) { handleError(err) - } finally { - setIsValidating(false) } - }, [ - maxFee, - setMaxAmount, - setError, - handleError, - setIsValidating, - toAddress, - amount, - token - ]) + }, [maxFee, setMaxAmount, setError, handleError, toAddress, amount, token]) useEffect(() => { - validate() - }, [validate]) + if (canValidate) { + validate() + } + }, [validate, canValidate]) return { send diff --git a/packages/core-mobile/app/screens/send/hooks/useBTCSend.ts b/packages/core-mobile/app/screens/send/hooks/useBTCSend.ts index f72fbd662..35cb3b602 100644 --- a/packages/core-mobile/app/screens/send/hooks/useBTCSend.ts +++ b/packages/core-mobile/app/screens/send/hooks/useBTCSend.ts @@ -26,11 +26,11 @@ const useBTCSend: SendAdapterBTC = ({ const { setMaxAmount, setError, - setIsValidating, setIsSending, toAddress, token, - amount + amount, + canValidate } = useSendContext() const provider = useBitcoinProvider(!!network.isTestnet) @@ -63,9 +63,6 @@ const useBTCSend: SendAdapterBTC = ({ return } - setIsValidating(true) - setError(undefined) - try { const maxAmountValue = BigInt( Math.max( @@ -88,13 +85,13 @@ const useBTCSend: SendAdapterBTC = ({ maxFee, isMainnet }) + + setError(undefined) } catch (e) { if (e instanceof Error) { setError(e.message) Logger.error('failed to validate send', e) } - } finally { - setIsValidating(false) } }, [ fromAddress, @@ -104,7 +101,6 @@ const useBTCSend: SendAdapterBTC = ({ isMainnet, setMaxAmount, setError, - setIsValidating, toAddress, token, amount @@ -131,8 +127,10 @@ const useBTCSend: SendAdapterBTC = ({ }, [isMainnet, maxFee, fromAddress, request, setIsSending, toAddress, amount]) useEffect(() => { - validate() - }, [validate]) + if (canValidate) { + validate() + } + }, [validate, canValidate]) return { send diff --git a/packages/core-mobile/app/screens/send/hooks/useEVMSend.ts b/packages/core-mobile/app/screens/send/hooks/useEVMSend.ts index dfc6c8d7c..2aaa5cc93 100644 --- a/packages/core-mobile/app/screens/send/hooks/useEVMSend.ts +++ b/packages/core-mobile/app/screens/send/hooks/useEVMSend.ts @@ -28,10 +28,10 @@ const useEVMSend: SendAdapterEVM = ({ setMaxAmount, setError, setIsSending, - setIsValidating, token, toAddress, - amount + amount, + canValidate } = useSendContext() const provider = useEVMProvider(network) @@ -78,9 +78,6 @@ const useEVMSend: SendAdapterEVM = ({ ) const validate = useCallback(async () => { - setIsValidating(true) - setError(undefined) - try { validateBasicInputs(token, toAddress, maxFee) @@ -120,10 +117,10 @@ const useEVMSend: SendAdapterEVM = ({ } validateGasLimit(gasLimit) + + setError(undefined) } catch (err) { handleError(err) - } finally { - setIsValidating(false) } }, [ nativeToken, @@ -131,7 +128,6 @@ const useEVMSend: SendAdapterEVM = ({ provider, handleError, setError, - setIsValidating, maxFee, setMaxAmount, token, @@ -140,8 +136,10 @@ const useEVMSend: SendAdapterEVM = ({ ]) useEffect(() => { - validate() - }, [validate]) + if (canValidate) { + validate() + } + }, [validate, canValidate]) return { send diff --git a/packages/core-mobile/app/screens/send/hooks/usePVMSend.ts b/packages/core-mobile/app/screens/send/hooks/usePVMSend.ts index aa7e56d50..8a12fa6bc 100644 --- a/packages/core-mobile/app/screens/send/hooks/usePVMSend.ts +++ b/packages/core-mobile/app/screens/send/hooks/usePVMSend.ts @@ -18,10 +18,10 @@ const usePVMSend: SendAdapterPVM = ({ setMaxAmount, setError, setIsSending, - setIsValidating, token, toAddress, - amount + amount, + canValidate } = useSendContext() const send = useCallback(async () => { @@ -66,9 +66,6 @@ const usePVMSend: SendAdapterPVM = ({ ) const validate = useCallback(async () => { - setIsValidating(true) - setError(undefined) - try { validatePVMSend({ amount: amount?.bn ?? 0n, @@ -77,25 +74,18 @@ const usePVMSend: SendAdapterPVM = ({ token: token as TokenWithBalancePVM, onCalculateMaxAmount: setMaxAmount }) + + setError(undefined) } catch (err) { handleError(err) - } finally { - setIsValidating(false) } - }, [ - maxFee, - setMaxAmount, - setError, - handleError, - setIsValidating, - token, - toAddress, - amount - ]) + }, [maxFee, setMaxAmount, setError, handleError, token, toAddress, amount]) useEffect(() => { - validate() - }, [validate]) + if (canValidate) { + validate() + } + }, [validate, canValidate]) return { send diff --git a/packages/core-mobile/app/screens/send/utils/pvm/validate.ts b/packages/core-mobile/app/screens/send/utils/pvm/validate.ts index ab8fae543..d57a0516f 100644 --- a/packages/core-mobile/app/screens/send/utils/pvm/validate.ts +++ b/packages/core-mobile/app/screens/send/utils/pvm/validate.ts @@ -22,7 +22,7 @@ export const validate = ({ const fee = maxFee ? BigInt(GAS_LIMIT_FOR_XP_CHAIN) * maxFee : 0n - const balance = token.balance + const balance = token.available ?? 0n const maxAmountValue = balance - fee const maxAmount = maxAmountValue > 0n ? maxAmountValue : 0n