diff --git a/src/modules/account/hooks/useCurrentAccount.js b/src/modules/account/hooks/useCurrentAccount.js index 3df938a30a..b7cd9edbd6 100644 --- a/src/modules/account/hooks/useCurrentAccount.js +++ b/src/modules/account/hooks/useCurrentAccount.js @@ -19,8 +19,11 @@ export function useCurrentAccount() { (stake) => stake.confirmed !== stake.unconfirmed ); - const setAccount = (encryptedAccount, referrer, redirect = true) => { + // eslint-disable-next-line max-statements + const setAccount = (encryptedAccount, referrer, redirect = true, urlState) => { // clear stakes list during login or accounts switch + const relativeUrlPath = referrer || routes.wallet.path; + if (pendingStakes.length) { const onCancel = /* istanbul ignore next */ () => removeSearchParamsFromUrl(history, ['modal']); @@ -28,7 +31,7 @@ export function useCurrentAccount() { dispatch(setCurrentAccount(encryptedAccount)); dispatch(stakesReset()); - history.push(referrer || routes.wallet.path); + history.push(relativeUrlPath); }; const state = createConfirmSwitchState({ mode: 'pendingStakes', @@ -40,7 +43,16 @@ export function useCurrentAccount() { } else { dispatch(setCurrentAccount(encryptedAccount)); if (redirect) { - history.push(referrer || routes.wallet.path); + if (urlState) { + const { pathname, search } = new URL(relativeUrlPath, window.location.origin); + history.push({ + pathname, + search, + state: urlState, + }); + } else { + history.push(relativeUrlPath); + } } } }; diff --git a/src/modules/transaction/components/Multisignature/Multisignature.js b/src/modules/transaction/components/Multisignature/Multisignature.js index 4949cd4ef0..aa81c2fbb4 100644 --- a/src/modules/transaction/components/Multisignature/Multisignature.js +++ b/src/modules/transaction/components/Multisignature/Multisignature.js @@ -17,6 +17,7 @@ import WarningNotification from '@common/components/warningNotification'; import AccountRow from '@account/components/AccountRow'; import classNames from 'classnames'; import { getNextAccountToSign } from '@transaction/utils/multisignatureUtils'; +import generateUniqueId from 'src/utils/generateUniqueId'; import getIllustration from '../TxBroadcaster/illustrationsMap'; import styles from './Multisignature.css'; import useTxInitiatorAccount from '../../hooks/useTxInitiatorAccount'; @@ -28,15 +29,18 @@ export const PartiallySignedActions = ({ transactionJSON, reset, }) => { - const [, setCurrentAccount] = useCurrentAccount(); + const [currentAccount, setCurrentAccount] = useCurrentAccount(); const handleSwitchAccount = () => { const stringifiedTransaction = encodeURIComponent(JSON.stringify(transactionJSON)); + const uniqueUrlIdToPreventHashError = generateUniqueId(); setCurrentAccount( nextAccountToSign, - `/wallet?modal=signMultiSignTransaction&stringifiedTransaction=${stringifiedTransaction}`, + `/wallet?modal=signMultiSignTransaction&prevAccount=${currentAccount.metadata.address}&uniqueId=${uniqueUrlIdToPreventHashError}`, true, - { stringifiedTransaction } + { + stringifiedTransaction, + } ); reset?.(); }; diff --git a/src/modules/transaction/configuration/statusConfig.js b/src/modules/transaction/configuration/statusConfig.js index de1e56064b..ec73ce8b31 100644 --- a/src/modules/transaction/configuration/statusConfig.js +++ b/src/modules/transaction/configuration/statusConfig.js @@ -2,6 +2,7 @@ import { transactions as LiskTransaction } from '@liskhq/lisk-client'; import { isEmpty } from 'src/utils/helpers'; import { txStatusTypes } from '@transaction/configuration/txStatus'; +import { calculateRemainingAndSignedMembers } from '@wallet/utils/account'; import { getNumberOfSignatures, joinModuleAndCommand, toTransactionJSON } from '../utils'; import { MODULE_COMMANDS_NAME_MAP } from './moduleCommand'; @@ -85,6 +86,24 @@ const getErrorMessage = (transaction, paramSchema, errorMessage) => { }; }; +function getHasRemainingMandatorySignatures(signedTransaction, walletKeys) { + const transactionSignaturesAsStrings = signedTransaction.signatures.map((signature) => + signature.toString('hex') + ); + + const moduleCommand = joinModuleAndCommand(signedTransaction); + const isMultisignatureRegistration = + moduleCommand === MODULE_COMMANDS_NAME_MAP.registerMultisignature; + + const { remaining } = calculateRemainingAndSignedMembers( + walletKeys, + { ...signedTransaction, signatures: transactionSignaturesAsStrings }, + isMultisignatureRegistration + ); + + return remaining.some(({ mandatory }) => mandatory); +} + /** * Defines the Status of the broadcasted tx. */ @@ -135,6 +154,12 @@ export const getTransactionStatus = (account, transactions, options = {}) => { moduleCommand === MODULE_COMMANDS_NAME_MAP.registerMultisignature; const isMultisignature = account?.summary?.isMultisignature || options.isMultisignature; const isInitatorAccountMultiSig = account?.numberOfSignatures > 0; + + const hasRemainingMandatorySignatures = getHasRemainingMandatorySignatures( + transactions.signedTransaction, + account?.keys + ); + let nonEmptySignatures = transactions.signedTransaction.signatures.filter( (sig) => sig.length > 0 ).length; @@ -146,6 +171,7 @@ export const getTransactionStatus = (account, transactions, options = {}) => { } if ( + hasRemainingMandatorySignatures || nonEmptySignatures < numberOfSignatures || (isMultisignature && nonEmptySignatures === numberOfSignatures && diff --git a/src/modules/wallet/components/signMultisigView/index.js b/src/modules/wallet/components/signMultisigView/index.js index 755899a623..7b22871ee6 100644 --- a/src/modules/wallet/components/signMultisigView/index.js +++ b/src/modules/wallet/components/signMultisigView/index.js @@ -16,8 +16,7 @@ import Status from '../signMultisigStatus'; const SignMultisigView = ({ history }) => { const [currentStep, setCurrentStep] = useState(); const location = useLocation(); - const queryParams = new URLSearchParams(location.search); - const stringifiedTransaction = queryParams.get('stringifiedTransaction'); + const stringifiedTransaction = location.state?.stringifiedTransaction; const onMultiStepChange = useCallback(({ step: { current } }) => { setCurrentStep(current);