(Fix) Stop from notifying user's wallet tx confirmation (#2007)
Co-authored-by: Daniel Sanchez <daniel.sanchez@gnosis.pm> Co-authored-by: Mati Dastugue <matias.dastugue@altoros.com>
This commit is contained in:
parent
78191e979d
commit
1818302d5d
|
@ -12,6 +12,7 @@ import {
|
||||||
tryOffchainSigning,
|
tryOffchainSigning,
|
||||||
} from 'src/logic/safe/transactions'
|
} from 'src/logic/safe/transactions'
|
||||||
import { estimateGasForTransactionCreation } from 'src/logic/safe/transactions/gas'
|
import { estimateGasForTransactionCreation } from 'src/logic/safe/transactions/gas'
|
||||||
|
import * as aboutToExecuteTx from 'src/logic/safe/utils/aboutToExecuteTx'
|
||||||
import { getCurrentSafeVersion } from 'src/logic/safe/utils/safeVersion'
|
import { getCurrentSafeVersion } from 'src/logic/safe/utils/safeVersion'
|
||||||
import { ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses'
|
import { ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses'
|
||||||
import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions'
|
import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions'
|
||||||
|
@ -148,6 +149,9 @@ export const createTransaction = (
|
||||||
|
|
||||||
await saveTxToHistory({ ...txArgs, txHash, origin })
|
await saveTxToHistory({ ...txArgs, txHash, origin })
|
||||||
|
|
||||||
|
// store the pending transaction's nonce
|
||||||
|
isExecution && aboutToExecuteTx.setNonce(txArgs.nonce)
|
||||||
|
|
||||||
dispatch(fetchTransactions(safeAddress))
|
dispatch(fetchTransactions(safeAddress))
|
||||||
})
|
})
|
||||||
.on('error', (error) => {
|
.on('error', (error) => {
|
||||||
|
@ -156,10 +160,6 @@ export const createTransaction = (
|
||||||
onError?.()
|
onError?.()
|
||||||
})
|
})
|
||||||
.then(async (receipt) => {
|
.then(async (receipt) => {
|
||||||
if (isExecution) {
|
|
||||||
dispatch(enqueueSnackbar(notificationsQueue.afterExecution.noMoreConfirmationsNeeded))
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch(fetchTransactions(safeAddress))
|
dispatch(fetchTransactions(safeAddress))
|
||||||
|
|
||||||
return receipt.transactionHash
|
return receipt.transactionHash
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
} from 'src/logic/safe/safeTxSigner'
|
} from 'src/logic/safe/safeTxSigner'
|
||||||
import { getApprovalTransaction, getExecutionTransaction, saveTxToHistory } from 'src/logic/safe/transactions'
|
import { getApprovalTransaction, getExecutionTransaction, saveTxToHistory } from 'src/logic/safe/transactions'
|
||||||
import { tryOffchainSigning } from 'src/logic/safe/transactions/offchainSigner'
|
import { tryOffchainSigning } from 'src/logic/safe/transactions/offchainSigner'
|
||||||
|
import * as aboutToExecuteTx from 'src/logic/safe/utils/aboutToExecuteTx'
|
||||||
import { getCurrentSafeVersion } from 'src/logic/safe/utils/safeVersion'
|
import { getCurrentSafeVersion } from 'src/logic/safe/utils/safeVersion'
|
||||||
import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions'
|
import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions'
|
||||||
import { providerSelector } from 'src/logic/wallets/store/selectors'
|
import { providerSelector } from 'src/logic/wallets/store/selectors'
|
||||||
|
@ -117,8 +118,6 @@ export const processTransaction = ({
|
||||||
|
|
||||||
dispatch(updateTransactionStatus({ txStatus: 'PENDING', safeAddress, nonce: tx.nonce, id: tx.id }))
|
dispatch(updateTransactionStatus({ txStatus: 'PENDING', safeAddress, nonce: tx.nonce, id: tx.id }))
|
||||||
await saveTxToHistory({ ...txArgs, signature })
|
await saveTxToHistory({ ...txArgs, signature })
|
||||||
// TODO: while we wait for the tx to be stored in the service and later update the tx info
|
|
||||||
// we should update the tx status in the store to disable owners' action buttons
|
|
||||||
|
|
||||||
dispatch(fetchTransactions(safeAddress))
|
dispatch(fetchTransactions(safeAddress))
|
||||||
return
|
return
|
||||||
|
@ -154,6 +153,10 @@ export const processTransaction = ({
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await saveTxToHistory({ ...txArgs, txHash })
|
await saveTxToHistory({ ...txArgs, txHash })
|
||||||
|
|
||||||
|
// store the pending transaction's nonce
|
||||||
|
isExecution && aboutToExecuteTx.setNonce(txArgs.nonce)
|
||||||
|
|
||||||
dispatch(fetchTransactions(safeAddress))
|
dispatch(fetchTransactions(safeAddress))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
|
@ -172,10 +175,6 @@ export const processTransaction = ({
|
||||||
console.error('Processing transaction error: ', error)
|
console.error('Processing transaction error: ', error)
|
||||||
})
|
})
|
||||||
.then(async (receipt) => {
|
.then(async (receipt) => {
|
||||||
if (isExecution) {
|
|
||||||
dispatch(enqueueSnackbar(notificationsQueue.afterExecution.noMoreConfirmationsNeeded))
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch(fetchTransactions(safeAddress))
|
dispatch(fetchTransactions(safeAddress))
|
||||||
|
|
||||||
if (isExecution) {
|
if (isExecution) {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { push } from 'connected-react-router'
|
import { push } from 'connected-react-router'
|
||||||
|
import { Action } from 'redux-actions'
|
||||||
|
|
||||||
import { NOTIFICATIONS, enhanceSnackbarForAction } from 'src/logic/notifications'
|
import { NOTIFICATIONS, enhanceSnackbarForAction } from 'src/logic/notifications'
|
||||||
import closeSnackbarAction from 'src/logic/notifications/store/actions/closeSnackbar'
|
import closeSnackbarAction from 'src/logic/notifications/store/actions/closeSnackbar'
|
||||||
|
@ -8,14 +9,19 @@ import { getSafeVersionInfo } from 'src/logic/safe/utils/safeVersion'
|
||||||
import { isUserAnOwner } from 'src/logic/wallets/ethAddresses'
|
import { isUserAnOwner } from 'src/logic/wallets/ethAddresses'
|
||||||
import { userAccountSelector } from 'src/logic/wallets/store/selectors'
|
import { userAccountSelector } from 'src/logic/wallets/store/selectors'
|
||||||
import { grantedSelector } from 'src/routes/safe/container/selector'
|
import { grantedSelector } from 'src/routes/safe/container/selector'
|
||||||
import { ADD_QUEUED_TRANSACTIONS } from 'src/logic/safe/store/actions/transactions/gatewayTransactions'
|
import {
|
||||||
|
ADD_QUEUED_TRANSACTIONS,
|
||||||
|
ADD_HISTORY_TRANSACTIONS,
|
||||||
|
} from 'src/logic/safe/store/actions/transactions/gatewayTransactions'
|
||||||
|
import * as aboutToExecuteTx from 'src/logic/safe/utils/aboutToExecuteTx'
|
||||||
|
import { QueuedPayload } from 'src/logic/safe/store/reducer/gatewayTransactions'
|
||||||
import { safeParamAddressFromStateSelector, safesMapSelector } from 'src/logic/safe/store/selectors'
|
import { safeParamAddressFromStateSelector, safesMapSelector } from 'src/logic/safe/store/selectors'
|
||||||
|
|
||||||
import { isTransactionSummary } from 'src/logic/safe/store/models/types/gateway.d'
|
import { isTransactionSummary, TransactionGatewayResult } from 'src/logic/safe/store/models/types/gateway.d'
|
||||||
import { loadFromStorage, saveToStorage } from 'src/utils/storage'
|
import { loadFromStorage, saveToStorage } from 'src/utils/storage'
|
||||||
import { ADD_OR_UPDATE_SAFE } from '../actions/addOrUpdateSafe'
|
import { ADD_OR_UPDATE_SAFE } from '../actions/addOrUpdateSafe'
|
||||||
|
|
||||||
const watchedActions = [ADD_OR_UPDATE_SAFE, ADD_QUEUED_TRANSACTIONS]
|
const watchedActions = [ADD_OR_UPDATE_SAFE, ADD_QUEUED_TRANSACTIONS, ADD_HISTORY_TRANSACTIONS]
|
||||||
|
|
||||||
const LAST_TIME_USED_LOGGED_IN_ID = 'LAST_TIME_USED_LOGGED_IN_ID'
|
const LAST_TIME_USED_LOGGED_IN_ID = 'LAST_TIME_USED_LOGGED_IN_ID'
|
||||||
|
|
||||||
|
@ -70,9 +76,21 @@ const notificationsMiddleware = (store) => (next) => async (action) => {
|
||||||
const state = store.getState()
|
const state = store.getState()
|
||||||
|
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
|
case ADD_HISTORY_TRANSACTIONS: {
|
||||||
|
const userAddress: string = userAccountSelector(state)
|
||||||
|
const safes = safesMapSelector(state)
|
||||||
|
|
||||||
|
const executedTxNotification = aboutToExecuteTx.getNotification(action.payload, userAddress, safes)
|
||||||
|
// if we have a notification, dispatch it depending on transaction's status
|
||||||
|
executedTxNotification && dispatch(enqueueSnackbar(executedTxNotification))
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
case ADD_QUEUED_TRANSACTIONS: {
|
case ADD_QUEUED_TRANSACTIONS: {
|
||||||
const { safeAddress, values } = action.payload
|
const { safeAddress, values } = (action as Action<QueuedPayload>).payload
|
||||||
const transactions = values.filter((tx) => isTransactionSummary(tx)).map((item) => item.transaction)
|
const transactions = values
|
||||||
|
.filter((tx) => isTransactionSummary(tx))
|
||||||
|
.map((item: TransactionGatewayResult) => item.transaction)
|
||||||
const userAddress: string = userAccountSelector(state)
|
const userAddress: string = userAccountSelector(state)
|
||||||
const awaitingTransactions = getAwaitingGatewayTransactions(transactions, userAddress)
|
const awaitingTransactions = getAwaitingGatewayTransactions(transactions, userAddress)
|
||||||
|
|
||||||
|
|
|
@ -344,6 +344,7 @@ export const gatewayTransactions = handleActions<AppReduxState['gatewayTransacti
|
||||||
}
|
}
|
||||||
case 'queued.queued': {
|
case 'queued.queued': {
|
||||||
queued.queued[nonce] = queued.queued[nonce].map((txToUpdate) => {
|
queued.queued[nonce] = queued.queued[nonce].map((txToUpdate) => {
|
||||||
|
// TODO: review if is this `PENDING` status required under `queued.queued` list
|
||||||
// prevent setting `PENDING_FAILED` status, if previous status wasn't `PENDING`
|
// prevent setting `PENDING_FAILED` status, if previous status wasn't `PENDING`
|
||||||
if (txStatus === 'PENDING_FAILED' && txToUpdate.txStatus !== 'PENDING') {
|
if (txStatus === 'PENDING_FAILED' && txToUpdate.txStatus !== 'PENDING') {
|
||||||
return txToUpdate
|
return txToUpdate
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
import { getNotificationsFromTxType } from 'src/logic/notifications'
|
||||||
|
import {
|
||||||
|
isStatusFailed,
|
||||||
|
isTransactionSummary,
|
||||||
|
TransactionGatewayResult,
|
||||||
|
} from 'src/logic/safe/store/models/types/gateway.d'
|
||||||
|
import { HistoryPayload } from 'src/logic/safe/store/reducer/gatewayTransactions'
|
||||||
|
import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions'
|
||||||
|
import { isUserAnOwner } from 'src/logic/wallets/ethAddresses'
|
||||||
|
import { SafesMap } from 'src/routes/safe/store/reducer/types/safe'
|
||||||
|
|
||||||
|
let nonce: number | undefined
|
||||||
|
|
||||||
|
export const setNonce = (newNonce: typeof nonce): void => {
|
||||||
|
nonce = newNonce
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getNotification = (
|
||||||
|
{ safeAddress, values }: HistoryPayload,
|
||||||
|
userAddress: string,
|
||||||
|
safes: SafesMap,
|
||||||
|
): undefined => {
|
||||||
|
const currentSafe = safes.get(safeAddress)
|
||||||
|
|
||||||
|
// no notification if not in the current safe or if its not an owner
|
||||||
|
if (!currentSafe || !isUserAnOwner(currentSafe, userAddress)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we have a nonce, then we have a tx that is about to be executed
|
||||||
|
if (nonce !== undefined) {
|
||||||
|
const executedTx = values
|
||||||
|
.filter(isTransactionSummary)
|
||||||
|
.map((item: TransactionGatewayResult) => item.transaction)
|
||||||
|
.find((transaction) => transaction.executionInfo?.nonce === nonce)
|
||||||
|
|
||||||
|
// transaction that was pending, was moved into history
|
||||||
|
// that is: it was executed
|
||||||
|
if (executedTx !== undefined) {
|
||||||
|
const notificationsQueue = getNotificationsFromTxType(TX_NOTIFICATION_TYPES.STANDARD_TX)
|
||||||
|
const notification = isStatusFailed(executedTx.txStatus)
|
||||||
|
? notificationsQueue.afterExecutionError
|
||||||
|
: notificationsQueue.afterExecution.noMoreConfirmationsNeeded
|
||||||
|
|
||||||
|
// reset nonce value
|
||||||
|
setNonce(undefined)
|
||||||
|
|
||||||
|
return notification
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue