From b8ec60c542185cd8a4044e5c851cfc02c1cfad25 Mon Sep 17 00:00:00 2001 From: Razvan Tomegea Date: Thu, 4 Apr 2024 16:56:31 +0300 Subject: [PATCH] Changed signTransactions to prevent re-fetching of account during validation (#1123) * Changed signTransactions to prevent re-fetching of account during validation * 2.29.0-beta.27 * Updated CHANGELOG.md * Lint fix --- CHANGELOG.md | 3 ++ package.json | 2 +- .../useSignMultipleTransactions.tsx | 51 +++++++++---------- .../transactions/useSignTransactions.tsx | 31 ++++++----- 4 files changed, 46 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa15992db..beba1537a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [[v2.29.0-beta.27]](https://github.com/multiversx/mx-sdk-dapp/pull/1124)] - 2024-04-04 +- [Changed signTransactions to prevent re-fetching of account during validation](https://github.com/multiversx/mx-sdk-dapp/pull/1123) + ## [[v2.29.0-beta.26]](https://github.com/multiversx/mx-sdk-dapp/pull/1120)] - 2024-04-03 - [Added SWR API calls](https://github.com/multiversx/mx-sdk-dapp/pull/1117) diff --git a/package.json b/package.json index 2fbfe20e9..391ca4bf4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@multiversx/sdk-dapp", - "version": "2.29.0-beta.26", + "version": "2.29.0-beta.27", "description": "A library to hold the main logic for a dapp on the MultiversX blockchain", "author": "MultiversX", "license": "GPL-3.0-or-later", diff --git a/src/hooks/transactions/useSignMultipleTransactions.tsx b/src/hooks/transactions/useSignMultipleTransactions.tsx index 1f6171608..484c1f743 100644 --- a/src/hooks/transactions/useSignMultipleTransactions.tsx +++ b/src/hooks/transactions/useSignMultipleTransactions.tsx @@ -6,6 +6,7 @@ import { TransactionVersion } from '@multiversx/sdk-core'; +import { useGetAccountFromApi } from 'apiCalls/accounts/useGetAccountFromApi'; import { SENDER_DIFFERENT_THAN_LOGGED_IN_ADDRESS } from 'constants/index'; import { useParseMultiEsdtTransferData } from 'hooks/transactions/useParseMultiEsdtTransferData'; import { @@ -14,7 +15,6 @@ import { Nullable, ScamInfoType } from 'types'; -import { getAccount } from 'utils/account/getAccount'; import { getLedgerErrorCodes } from 'utils/internal/getLedgerErrorCodes'; import { isTokenTransfer } from 'utils/transactions/isTokenTransfer'; import { @@ -94,15 +94,20 @@ export const useSignMultipleTransactions = ({ }); const isLastTransaction = currentStep === allTransactions.length - 1; + const currentTx = allTransactions[currentStep]; + const sender = currentTransaction?.transaction?.getSender().toString(); - const extractTransactionsInfo = async () => { - const tx = allTransactions[currentStep]; + // Skip account fetching if the sender is missing or same as current account + const { data: senderAccount } = useGetAccountFromApi( + !sender || sender === address ? null : sender + ); - if (tx == null) { + const extractTransactionsInfo = async () => { + if (currentTx == null) { return; } - const { transaction, multiTxData, transactionIndex } = tx; + const { transaction, multiTxData, transactionIndex } = currentTx; const dataField = transaction.getData().toString(); const transactionTokenInfo = getTxInfoByDataField( transaction.getData().toString(), @@ -111,21 +116,15 @@ export const useSignMultipleTransactions = ({ const { tokenId } = transactionTokenInfo; const receiver = transaction.getReceiver().toString(); - const sender = transaction.getSender().toString(); - - if (!sender) { - console.error(SENDER_DIFFERENT_THAN_LOGGED_IN_ADDRESS); - - return onCancel?.(); - } - const senderAccount = await getAccount(sender); - const isValidSender = checkIsValidSender(senderAccount, address); + if (sender && sender !== address) { + const isValidSender = checkIsValidSender(senderAccount, address); - if (!isValidSender) { - console.error(SENDER_DIFFERENT_THAN_LOGGED_IN_ADDRESS); + if (!isValidSender) { + console.error(SENDER_DIFFERENT_THAN_LOGGED_IN_ADDRESS); - return onCancel?.(); + return onCancel?.(); + } } const notSender = address !== receiver; @@ -155,13 +154,13 @@ export const useSignMultipleTransactions = ({ useEffect(() => { extractTransactionsInfo(); - }, [currentStep, allTransactions]); + }, [currentTx, senderAccount]); - function reset() { + const reset = () => { setCurrentStep(0); setSignedTransactions(undefined); setWaitingForDevice(false); - } + }; const sign = async () => { const existingSignedTransactions = Object.values(signedTransactions ?? {}); @@ -254,13 +253,13 @@ export const useSignMultipleTransactions = ({ const isFirst = currentStep === 0; - function handleAbort() { + const handleAbort = () => { if (isFirst) { onCancel?.(); } else { setCurrentStep((existing) => existing - 1); } - } + }; const shouldContinueWithoutSigning = Boolean( currentTransaction?.transactionTokenInfo?.type && @@ -278,7 +277,7 @@ export const useSignMultipleTransactions = ({ await signTx(); }; - function onNext() { + const onNext = () => { setCurrentStep((current) => { const nextStep = current + 1; if (nextStep > allTransactions?.length) { @@ -286,9 +285,9 @@ export const useSignMultipleTransactions = ({ } return nextStep; }); - } + }; - function onPrev() { + const onPrev = () => { setCurrentStep((current) => { const nextStep = current - 1; if (nextStep < 0) { @@ -296,7 +295,7 @@ export const useSignMultipleTransactions = ({ } return nextStep; }); - } + }; return { allTransactions, diff --git a/src/hooks/transactions/useSignTransactions.tsx b/src/hooks/transactions/useSignTransactions.tsx index d71c56f6f..d1e0e06c0 100644 --- a/src/hooks/transactions/useSignTransactions.tsx +++ b/src/hooks/transactions/useSignTransactions.tsx @@ -10,6 +10,7 @@ import { MetamaskProvider } from '@multiversx/sdk-metamask-provider/out/metamask import { CrossWindowProvider } from '@multiversx/sdk-web-wallet-cross-window-provider/out/CrossWindowProvider/CrossWindowProvider'; import uniq from 'lodash/uniq'; +import { useGetAccountFromApi } from 'apiCalls/accounts/useGetAccountFromApi'; import { ERROR_SIGNING, ERROR_SIGNING_TX, @@ -41,8 +42,6 @@ import { LoginMethodsEnum, TransactionBatchStatusesEnum } from 'types/enums.types'; - -import { getAccount } from 'utils/account/getAccount'; import { builtCallbackUrl } from 'utils/transactions/builtCallbackUrl'; import { parseTransactionAfterSigning } from 'utils/transactions/parseTransactionAfterSigning'; import { getDefaultCallbackUrl } from 'utils/window'; @@ -81,7 +80,20 @@ export const useSignTransactions = () => { useParseSignedTransactions(onAbort); - function clearSignInfo(sessionId?: string) { + const senderAddresses = uniq( + transactionsToSign?.transactions + .map((tx) => tx.getSender().toString()) + .filter((sender) => sender) + ) as string[]; + + const sender = senderAddresses?.[0]; + + // Skip account fetching if the sender is missing or same as current account + const { data: senderAccount } = useGetAccountFromApi( + !sender || sender === address ? null : sender + ); + + const clearSignInfo = (sessionId?: string) => { const isExtensionProvider = provider instanceof ExtensionProvider; const isCrossWindowProvider = provider instanceof CrossWindowProvider; const isMetamaskProvider = provider instanceof MetamaskProvider; @@ -111,7 +123,7 @@ export const useSignTransactions = () => { if (isExperiementalWebviewProvider) { ExperimentalWebviewProvider.getInstance()?.cancelAction?.(); } - } + }; const onCancel = (errorMessage: string, sessionId?: string) => { const isSigningWithWalletConnectV2 = @@ -296,20 +308,11 @@ export const useSignTransactions = () => { return; } - const senderAddresses = uniq( - transactions - .map((tx) => tx.getSender().toString()) - .filter((sender) => sender) - ) as string[]; - if (senderAddresses.length > 1) { throw new Error('Multiple senders are not allowed'); } - const sender = senderAddresses?.[0]; - if (sender && sender !== address) { - const senderAccount = sender ? await getAccount(sender) : null; const isValidSender = checkIsValidSender(senderAccount, address); if (!isValidSender) { @@ -366,7 +369,7 @@ export const useSignTransactions = () => { } else { isSigningRef.current = false; } - }, [transactionsToSign, hasTransactions]); + }, [transactionsToSign, hasTransactions, senderAccount]); return { error,