diff --git a/src/hooks/useHasEnoughBalance.ts b/src/hooks/useHasEnoughBalance.ts index f9179628c22..72da88cf43b 100644 --- a/src/hooks/useHasEnoughBalance.ts +++ b/src/hooks/useHasEnoughBalance.ts @@ -20,11 +20,10 @@ type BalanceCheckParams = { }; export const useHasEnoughBalance = ({ isMessageRequest, walletBalance, chainId, selectedGasFee, req }: BalanceCheckParams) => { - const [isBalanceEnough, setIsBalanceEnough] = useState(); + const [isBalanceEnough, setIsBalanceEnough] = useState(isMessageRequest); useEffect(() => { if (isMessageRequest) { - setIsBalanceEnough(true); return; } diff --git a/src/hooks/useSubmitTransaction.ts b/src/hooks/useSubmitTransaction.ts index 8d6f861ae25..fd9c0215483 100644 --- a/src/hooks/useSubmitTransaction.ts +++ b/src/hooks/useSubmitTransaction.ts @@ -1,4 +1,4 @@ -import { useCallback, useState } from 'react'; +import { Dispatch, SetStateAction, useCallback, useState } from 'react'; import { performanceTracking, TimeToSignOperation } from '@/state/performance/performance'; import Routes from '@/navigation/routesNames'; import { useNavigation } from '@/navigation'; @@ -7,11 +7,13 @@ import { SCREEN_FOR_REQUEST_SOURCE } from '@/components/Transactions/constants'; import { logger, RainbowError } from '@/logger'; export const useTransactionSubmission = ({ + isMessageRequest, isBalanceEnough, accountInfo, onConfirm, source, }: { + isMessageRequest: boolean; isBalanceEnough: boolean | undefined; accountInfo: { isHardwareWallet: boolean }; onConfirm: () => Promise; @@ -30,26 +32,26 @@ export const useTransactionSubmission = ({ } finally { setIsAuthorizing(false); } - }, [isAuthorizing, onConfirm]); + }, [isAuthorizing, onConfirm, setIsAuthorizing]); const submitFn = useCallback( () => performanceTracking.getState().executeFn({ fn: async () => { - if (!isBalanceEnough) { - navigate(Routes.ADD_CASH_SHEET); - return; + if (!isBalanceEnough && !isMessageRequest) { + return navigate(Routes.ADD_CASH_SHEET); } + if (accountInfo.isHardwareWallet) { - navigate(Routes.HARDWARE_WALLET_TX_NAVIGATOR, { submit: onPressSend }); - } else { - await onPressSend(); + return navigate(Routes.HARDWARE_WALLET_TX_NAVIGATOR, { submit: onPressSend }); } + + return onPressSend(); }, operation: TimeToSignOperation.CallToAction, screen: SCREEN_FOR_REQUEST_SOURCE[source], })(), - [accountInfo.isHardwareWallet, isBalanceEnough, navigate, onPressSend, source] + [accountInfo.isHardwareWallet, isBalanceEnough, isMessageRequest, navigate, onPressSend, source] ); return { submitFn, isAuthorizing }; diff --git a/src/languages/en_US.json b/src/languages/en_US.json index e49299f792b..d6965750799 100644 --- a/src/languages/en_US.json +++ b/src/languages/en_US.json @@ -2908,6 +2908,7 @@ "buttons": { "cancel": "Cancel", "confirm": "􀎽 Confirm", + "confirming": "Confirming", "get_native_token": "Get %{symbol}", "buy_native_token": "Buy %{symbol}" }, diff --git a/src/screens/SignTransactionSheet.tsx b/src/screens/SignTransactionSheet.tsx index f4ef840c5fd..2a5b2e16bb9 100644 --- a/src/screens/SignTransactionSheet.tsx +++ b/src/screens/SignTransactionSheet.tsx @@ -266,7 +266,7 @@ export const SignTransactionSheet = () => { const txPayload = req; let { gas } = txPayload; const gasLimitFromPayload = txPayload?.gasLimit; - if (!chainId) return; + try { logger.debug( '[SignTransactionSheet]: gas suggested by dapp', @@ -280,6 +280,9 @@ export const SignTransactionSheet = () => { // Estimate the tx with gas limit padding before sending const rawGasLimit = await estimateGasWithPadding(txPayload, null, null, provider); if (!rawGasLimit) { + logger.error(new RainbowError('[SignTransactionSheet]: error estimating gas'), { + rawGasLimit, + }); return; } @@ -321,9 +324,6 @@ export const SignTransactionSheet = () => { let response = null; try { - if (!chainId) { - return; - } const existingWallet = await performanceTracking.getState().executeFn({ fn: loadWallet, screen: SCREEN_FOR_REQUEST_SOURCE[source], @@ -550,19 +550,55 @@ export const SignTransactionSheet = () => { handleConfirmTransaction, }); - const { submitFn } = useTransactionSubmission({ + const { submitFn, isAuthorizing } = useTransactionSubmission({ + isMessageRequest, isBalanceEnough, accountInfo, onConfirm, source, }); + const canPressConfirm = useMemo(() => { + if (isMessageRequest) { + return !isAuthorizing; // Only check authorization state for message requests + } + + return !isAuthorizing && isBalanceEnough && !!chainId && !!selectedGasFee?.gasFee?.estimatedFee; + }, [isAuthorizing, isMessageRequest, isBalanceEnough, chainId, selectedGasFee?.gasFee?.estimatedFee]); + + const primaryActionButtonLabel = useMemo(() => { + if (isAuthorizing) { + return i18n.t(i18n.l.walletconnect.simulation.buttons.confirming); + } + + if (!txSimulationLoading && isBalanceEnough === false) { + return i18n.t(i18n.l.walletconnect.simulation.buttons.buy_native_token, { symbol: walletBalance?.symbol }); + } + + return i18n.t(i18n.l.walletconnect.simulation.buttons.confirm); + }, [txSimulationLoading, isBalanceEnough, isAuthorizing, walletBalance]); + + const primaryActionButtonColor = useMemo(() => { + let color = colors.appleBlue; + + if ( + simulationResult?.simulationError || + (simulationResult?.simulationScanResult && simulationResult.simulationScanResult !== TransactionScanResultType.Ok) + ) { + if (simulationResult?.simulationScanResult === TransactionScanResultType.Warning) { + color = colors.orange; + } else { + color = colors.red; + } + } + + return colors.alpha(color, canPressConfirm ? 1 : 0.6); + }, [colors, simulationResult?.simulationError, simulationResult?.simulationScanResult, canPressConfirm]); + const onPressCancel = useCallback(() => onCancel(), [onCancel]); const expandedCardBottomInset = EXPANDED_CARD_BOTTOM_INSET + (isMessageRequest ? 0 : GAS_BUTTON_SPACE); - const canPressConfirm = isMessageRequest || (!!walletBalance?.isLoaded && !!chainId && !!selectedGasFee?.gasFee?.estimatedFee); - return ( @@ -732,24 +768,13 @@ export const SignTransactionSheet = () => { weight="bold" />