diff --git a/src/logic/safe/transactions/awaitingTransactions.ts b/src/logic/safe/transactions/awaitingTransactions.ts index 25d3f3ae..c15bfc91 100644 --- a/src/logic/safe/transactions/awaitingTransactions.ts +++ b/src/logic/safe/transactions/awaitingTransactions.ts @@ -1,33 +1,18 @@ -import { Map } from 'immutable' +import { List } from 'immutable' -export const getAwaitingTransactions = (allTransactions, cancellationTransactionsByNonce, userAccount) => { - if (!allTransactions) { - return Map({}) - } +import { isPendingTransaction } from 'src/routes/safe/store/actions/transactions/utils/transactionHelpers' - const allAwaitingTransactions = allTransactions.map((safeTransactions) => { - const nonCancelledTransactions = safeTransactions.filter((transaction) => { - // If transactions are not executed, but there's a transaction with the same nonce EXECUTED later - // it means that the transaction was cancelled (Replaced) and shouldn't get executed - let isTransactionCancelled = false - if (!transaction.isExecuted) { - if (cancellationTransactionsByNonce.get(transaction.nonce)) { - // eslint-disable-next-line no-param-reassign - isTransactionCancelled = true - } - } - // The transaction is not executed and is not cancelled, so it's still waiting confirmations - if (!transaction.executionTxHash && !isTransactionCancelled) { - // Then we check if the waiting confirmations are not from the current user, otherwise, filters this - // transaction - const transactionWaitingUser = transaction.confirmations.filter(({ owner }) => owner !== userAccount) +export const getAwaitingTransactions = (allTransactions = List([]), cancellationTxs, userAccount: string) => { + return allTransactions.filter((tx) => { + const cancelTx = !!tx.nonce && !isNaN(Number(tx.nonce)) ? cancellationTxs.get(`${tx.nonce}`) : null - return transactionWaitingUser.size > 0 - } - return false - }) - return nonCancelledTransactions + // The transaction is not executed and is not cancelled, nor pending, so it's still waiting confirmations + if (!tx.executionTxHash && !tx.cancelled && !isPendingTransaction(tx, cancelTx)) { + // Then we check if the waiting confirmations are not from the current user, otherwise, filters this transaction + const transactionWaitingUser = tx.confirmations.filter(({ owner }) => owner !== userAccount) + return transactionWaitingUser.size > 0 + } + + return false }) - - return allAwaitingTransactions } diff --git a/src/routes/safe/store/middleware/notificationsMiddleware.ts b/src/routes/safe/store/middleware/notificationsMiddleware.ts index bea90187..ce6956e6 100644 --- a/src/routes/safe/store/middleware/notificationsMiddleware.ts +++ b/src/routes/safe/store/middleware/notificationsMiddleware.ts @@ -1,5 +1,4 @@ import { push } from 'connected-react-router' -import { List, Map } from 'immutable' import { NOTIFICATIONS, enhanceSnackbarForAction } from 'src/logic/notifications' import closeSnackbarAction from 'src/logic/notifications/store/actions/closeSnackbar' @@ -12,13 +11,14 @@ import { getIncomingTxAmount } from 'src/routes/safe/components/Transactions/Txs import { grantedSelector } from 'src/routes/safe/container/selector' import { ADD_INCOMING_TRANSACTIONS } from 'src/routes/safe/store/actions/addIncomingTransactions' import { ADD_SAFE } from 'src/routes/safe/store/actions/addSafe' -import { ADD_TRANSACTIONS } from 'src/routes/safe/store/actions/addTransactions' +import { ADD_OR_UPDATE_TRANSACTIONS } from 'src/routes/safe/store/actions/transactions/addOrUpdateTransactions' import updateSafe from 'src/routes/safe/store/actions/updateSafe' +import { CANCELLATION_TRANSACTIONS_REDUCER_ID } from 'src/routes/safe/store/reducer/cancellationTransactions' import { safeParamAddressFromStateSelector, safesMapSelector } from 'src/routes/safe/store/selectors' import { loadFromStorage, saveToStorage } from 'src/utils/storage' -const watchedActions = [ADD_TRANSACTIONS, ADD_INCOMING_TRANSACTIONS, ADD_SAFE] +const watchedActions = [ADD_OR_UPDATE_TRANSACTIONS, ADD_INCOMING_TRANSACTIONS, ADD_SAFE] const sendAwaitingTransactionNotification = async ( dispatch, @@ -59,48 +59,41 @@ const sendAwaitingTransactionNotification = async ( await saveToStorage(LAST_TIME_USED_LOGGED_IN_ID, lastTimeUserLoggedInForSafes) } +const onNotificationClicked = (dispatch, notificationKey, safeAddress) => () => { + dispatch(closeSnackbarAction({ key: notificationKey })) + dispatch(push(`/safes/${safeAddress}/transactions`)) +} + const notificationsMiddleware = (store) => (next) => async (action) => { const handledAction = next(action) const { dispatch } = store if (watchedActions.includes(action.type)) { const state = store.getState() + switch (action.type) { - case ADD_TRANSACTIONS: { - const transactionsList = action.payload - const userAddress = userAccountSelector(state) - const safeAddress = action.payload.keySeq().get(0) - const cancellationTransactions = state.cancellationTransactions.get(safeAddress) - const cancellationTransactionsByNonce = cancellationTransactions - ? cancellationTransactions.reduce((acc, tx) => acc.set(tx.nonce, tx), Map()) - : Map() - const awaitingTransactions = getAwaitingTransactions( - transactionsList, - cancellationTransactionsByNonce, - userAddress, - ) - const awaitingTxsSubmissionDateList = awaitingTransactions - .get(safeAddress, List([])) - .map((tx) => tx.submissionDate) + case ADD_OR_UPDATE_TRANSACTIONS: { + const { safeAddress, transactions } = action.payload + const userAddress: string = userAccountSelector(state) + const cancellationTransactions = state[CANCELLATION_TRANSACTIONS_REDUCER_ID].get(safeAddress) + const awaitingTransactions = getAwaitingTransactions(transactions, cancellationTransactions, userAddress) + const awaitingTxsSubmissionDateList = awaitingTransactions.map((tx) => tx.submissionDate) const safes = safesMapSelector(state) const currentSafe = safes.get(safeAddress) - if (!isUserOwner(currentSafe, userAddress) || awaitingTxsSubmissionDateList.size === 0) { + if (!isUserOwner(currentSafe, userAddress) || awaitingTransactions.size === 0) { break } + const notificationKey = `${safeAddress}-awaiting` - const onNotificationClicked = () => { - dispatch(closeSnackbarAction({ key: notificationKey })) - dispatch(push(`/safes/${safeAddress}/transactions`)) - } await sendAwaitingTransactionNotification( dispatch, safeAddress, awaitingTxsSubmissionDateList, notificationKey, - onNotificationClicked, + onNotificationClicked(dispatch, notificationKey, safeAddress), ) break diff --git a/src/store/index.ts b/src/store/index.ts index 9f92024c..8574ecc4 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -38,9 +38,9 @@ const finalCreateStore = composeEnhancers( applyMiddleware( thunk, routerMiddleware(history), + notificationsMiddleware, safeStorage, providerWatcher, - notificationsMiddleware, addressBookMiddleware, currencyValuesStorageMiddleware, ),