From cb02e2797a0922c786771a962490b495ba902db4 Mon Sep 17 00:00:00 2001 From: Alexander Ivchenko <47615361+TravellerOnTheRun@users.noreply.github.com> Date: Fri, 15 Sep 2023 17:45:35 +0400 Subject: [PATCH] US-996 RIF Wallet libs - Sending a transaction should check if the user has the funds + fee before sending (RIF RELAY) (#739) * feat: handle insuffient funds * refactor: use feeContract as address to search balances --- src/lib/i18n.ts | 1 + .../TransactionSummaryComponent.tsx | 2 +- .../ReviewTransactionContainer.tsx | 35 ++++++++++++++++--- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/lib/i18n.ts b/src/lib/i18n.ts index e28deb258..5f9129efd 100644 --- a/src/lib/i18n.ts +++ b/src/lib/i18n.ts @@ -207,6 +207,7 @@ const resources = { transaction_summary_function_type: 'type', transaction_summary_plus_fees: '+ fees', transaction_summary_plus_fees_capitalcase: '+ Fees', + transaction_summary_insufficient_funds: 'Insufficient funds', profile_screen_title: 'Profile', profile_contact_details_subtitle: 'Contact Details', profile_phone_label: 'Phone Number', diff --git a/src/screens/transactionSummary/TransactionSummaryComponent.tsx b/src/screens/transactionSummary/TransactionSummaryComponent.tsx index 29ebaae8d..a3164c9cb 100644 --- a/src/screens/transactionSummary/TransactionSummaryComponent.tsx +++ b/src/screens/transactionSummary/TransactionSummaryComponent.tsx @@ -33,8 +33,8 @@ import { import { TransactionSummaryScreenProps } from '.' interface Props { - goBack?: () => void wallet: RIFWallet + goBack?: () => void } type TransactionSummaryComponentProps = Omit< diff --git a/src/ux/requestsModal/ReviewRelayTransaction/ReviewTransactionContainer.tsx b/src/ux/requestsModal/ReviewRelayTransaction/ReviewTransactionContainer.tsx index 5dc920112..353c3a93a 100644 --- a/src/ux/requestsModal/ReviewRelayTransaction/ReviewTransactionContainer.tsx +++ b/src/ux/requestsModal/ReviewRelayTransaction/ReviewTransactionContainer.tsx @@ -5,7 +5,7 @@ import { import { BigNumber, constants } from 'ethers' import { useCallback, useEffect, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' -import { StyleSheet, View } from 'react-native' +import { Alert, StyleSheet, View } from 'react-native' import { useSafeAreaInsets } from 'react-native-safe-area-context' import { isAddress } from '@rsksmart/rsk-utils' @@ -18,15 +18,22 @@ import { TransactionSummaryScreenProps } from 'screens/transactionSummary' import { TransactionSummaryComponent } from 'screens/transactionSummary/TransactionSummaryComponent' import { sharedColors } from 'shared/constants' import { chainTypesById } from 'shared/constants/chainConstants' -import { errorHandler } from 'shared/utils' +import { castStyle, errorHandler } from 'shared/utils' import { selectWalletState } from 'store/slices/settingsSlice' import { ChainTypeEnum } from 'store/slices/settingsSlice/types' import { selectUsdPrices } from 'store/slices/usdPricesSlice' import { useAppDispatch, useAppSelector } from 'store/storeUtils' import { addRecentContact } from 'store/slices/contactsSlice' +import { selectBalances } from 'store/slices/balancesSlice' import useEnhancedWithGas from '../useEnhancedWithGas' +const tokenToBoolMap = new Map([ + [TokenSymbol.RIF, true], + [TokenSymbol.TRIF, true], + [undefined, false], +]) + interface Props { request: SendTransactionRequest onConfirm: () => void @@ -43,6 +50,7 @@ export const ReviewTransactionContainer = ({ const tokenPrices = useAppSelector(selectUsdPrices) // enhance the transaction to understand what it is: const { wallet, chainId } = useAppSelector(selectWalletState) + const balances = useAppSelector(selectBalances) const [txCostInRif, setTxCostInRif] = useState() const { t } = useTranslation() @@ -144,6 +152,22 @@ export const ReviewTransactionContainer = ({ const feeValue = txCostInRif ? `${balanceToDisplay(txCostInRif, 18, 0)}` : '0' + + let insufficientFunds = false + + if (tokenToBoolMap.get(symbol as TokenSymbol)) { + insufficientFunds = + Number(value) + Number(feeValue) > Number(balances[feeContract].balance) + } else { + insufficientFunds = + Number(feeValue) > Number(balances[feeContract].balance) + } + + if (insufficientFunds) { + Alert.alert(t('transaction_summary_insufficient_funds')) + } + + // get usd values const tokenUsd = convertToUSD(Number(value), tokenQuote) const feeUsd = convertToUSD(Number(feeValue), feeQuote) @@ -174,6 +198,7 @@ export const ReviewTransactionContainer = ({ color: sharedColors.white, textColor: sharedColors.black, accessibilityLabel: 'Confirm', + disabled: insufficientFunds, }, { style: { marginTop: 10 }, @@ -186,6 +211,8 @@ export const ReviewTransactionContainer = ({ functionName, } }, [ + feeContract, + balances, txCostInRif, value, tokenQuote, @@ -211,10 +238,10 @@ export const ReviewTransactionContainer = ({ } const styles = StyleSheet.create({ - container: { + container: castStyle.view({ width: '100%', height: '100%', zIndex: 999, position: 'absolute', - }, + }), })