(Fix) Pending transaction amount set to zero (#1316)
* fix: prevent runtime error when prev is `undefined` * fix: prevent runtime error when prev is `undefined` * fix: prevent runtime error when 'safes' is `undefined` * fix: add `dataDecoded` to the mocked tx so information is properly displayed for known methods * fix: set 'pending' status for tx being processed - given that the confirmations key is no longer an empty array, tx status must be explicitly set this way * fix: properly update mockedTx * fix: hide buttons when tx is pending * fix: type error * Rollback patches trying to fix bug Co-authored-by: Daniel Sanchez <daniel.sanchez@gnosis.pm> Co-authored-by: Mikhail Mikheev <mmvsha73@gmail.com>
This commit is contained in:
parent
5b99ceaa6d
commit
ac92f49c72
|
@ -5,6 +5,7 @@ import semverSatisfies from 'semver/functions/satisfies'
|
|||
import { ThunkAction } from 'redux-thunk'
|
||||
|
||||
import { onboardUser } from 'src/components/ConnectButton'
|
||||
import { decodeMethods } from 'src/logic/contracts/methodIds'
|
||||
import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts'
|
||||
import { getNotificationsFromTxType } from 'src/logic/notifications'
|
||||
import {
|
||||
|
@ -205,6 +206,7 @@ const createTransaction = (
|
|||
confirmations: [], // this is used to determine if a tx is pending or not. See `calculateTransactionStatus` helper
|
||||
value: txArgs.valueInWei,
|
||||
safeTxHash,
|
||||
dataDecoded: decodeMethods(txArgs.data),
|
||||
submissionDate: new Date().toISOString(),
|
||||
}
|
||||
const mockedTx = await mockTransaction(txToMock, safeAddress, state)
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { fromJS } from 'immutable'
|
||||
import semverSatisfies from 'semver/functions/satisfies'
|
||||
|
||||
import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts'
|
||||
|
@ -20,9 +19,9 @@ import {
|
|||
import { getLastTx, getNewTxNonce, shouldExecuteTransaction } from 'src/logic/safe/store/actions/utils'
|
||||
|
||||
import { getErrorMessage } from 'src/test/utils/ethereumErrors'
|
||||
import { makeConfirmation } from '../models/confirmation'
|
||||
import { storeTx } from './createTransaction'
|
||||
import { TransactionStatus } from '../models/types/transaction'
|
||||
import { TransactionStatus } from 'src/logic/safe/store/models/types/transaction'
|
||||
import { makeConfirmation } from 'src/logic/safe/store/models/confirmation'
|
||||
|
||||
const processTransaction = ({ approveAndExecute, notifiedTransaction, safeAddress, tx, userAddress }) => async (
|
||||
dispatch,
|
||||
|
@ -85,6 +84,8 @@ const processTransaction = ({ approveAndExecute, notifiedTransaction, safeAddres
|
|||
dispatch(closeSnackbarAction(beforeExecutionKey))
|
||||
|
||||
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(enqueueSnackbar(notificationsQueue.afterExecution.moreConfirmationsNeeded))
|
||||
|
||||
dispatch(fetchTransactions(safeAddress))
|
||||
|
@ -105,9 +106,7 @@ const processTransaction = ({ approveAndExecute, notifiedTransaction, safeAddres
|
|||
|
||||
const txToMock: TxToMock = {
|
||||
...txArgs,
|
||||
confirmations: txArgs.confirmations, // this is used to determine if a tx is pending or not. See `calculateTransactionStatus` helper
|
||||
value: txArgs.valueInWei,
|
||||
submissionDate: txArgs.submissionDate,
|
||||
}
|
||||
const mockedTx = await mockTransaction(txToMock, safeAddress, state)
|
||||
|
||||
|
@ -123,10 +122,14 @@ const processTransaction = ({ approveAndExecute, notifiedTransaction, safeAddres
|
|||
await Promise.all([
|
||||
saveTxToHistory({ ...txArgs, txHash }),
|
||||
storeTx(
|
||||
mockedTx.updateIn(
|
||||
['ownersWithPendingActions', mockedTx.isCancellationTx ? 'reject' : 'confirm'],
|
||||
(previous) => previous.push(from),
|
||||
),
|
||||
mockedTx.withMutations((record) => {
|
||||
record
|
||||
.updateIn(
|
||||
['ownersWithPendingActions', mockedTx.isCancellationTx ? 'reject' : 'confirm'],
|
||||
(previous) => previous.push(from),
|
||||
)
|
||||
.set('status', TransactionStatus.PENDING)
|
||||
}),
|
||||
safeAddress,
|
||||
dispatch,
|
||||
state,
|
||||
|
@ -175,16 +178,20 @@ const processTransaction = ({ approveAndExecute, notifiedTransaction, safeAddres
|
|||
: TransactionStatus.FAILED,
|
||||
)
|
||||
.updateIn(['ownersWithPendingActions', 'reject'], (prev) => prev.clear())
|
||||
.updateIn(['ownersWithPendingActions', 'confirm'], (prev) => prev.clear())
|
||||
})
|
||||
: mockedTx.withMutations((record) => {
|
||||
record
|
||||
.updateIn(['ownersWithPendingActions', toStoreTx.isCancellationTx ? 'reject' : 'confirm'], (previous) =>
|
||||
previous.pop(),
|
||||
)
|
||||
.set('status', TransactionStatus.AWAITING_CONFIRMATIONS)
|
||||
})
|
||||
: mockedTx.set('status', TransactionStatus.AWAITING_CONFIRMATIONS)
|
||||
|
||||
await storeTx(
|
||||
toStoreTx.withMutations((record) => {
|
||||
record
|
||||
.set('confirmations', fromJS([...tx.confirmations, makeConfirmation({ owner: from })]))
|
||||
.updateIn(['ownersWithPendingActions', toStoreTx.isCancellationTx ? 'reject' : 'confirm'], (previous) =>
|
||||
previous.pop(from),
|
||||
)
|
||||
toStoreTx.update('confirmations', (confirmations) => {
|
||||
const index = confirmations.findIndex(({ owner }) => owner === from)
|
||||
return index === -1 ? confirmations.push(makeConfirmation({ owner: from })) : confirmations
|
||||
}),
|
||||
safeAddress,
|
||||
dispatch,
|
||||
|
|
|
@ -34,7 +34,7 @@ import { TypedDataUtils } from 'eth-sig-util'
|
|||
import { Token } from 'src/logic/tokens/store/model/token'
|
||||
import { ProviderRecord } from 'src/logic/wallets/store/model/provider'
|
||||
import { SafeRecord } from 'src/logic/safe/store/models/safe'
|
||||
import { DecodedParams } from 'src/routes/safe/store/models/types/transactions.d'
|
||||
import { DataDecoded, DecodedParams } from 'src/routes/safe/store/models/types/transactions.d'
|
||||
|
||||
export const isEmptyData = (data?: string | null): boolean => {
|
||||
return !data || data === EMPTY_DATA
|
||||
|
@ -316,6 +316,7 @@ export type TxToMock = TxArgs & {
|
|||
safeTxHash: string
|
||||
value: string
|
||||
submissionDate: string
|
||||
dataDecoded: DataDecoded | null
|
||||
}
|
||||
|
||||
export const mockTransaction = (tx: TxToMock, safeAddress: string, state: AppReduxState): Promise<Transaction> => {
|
||||
|
|
|
@ -142,6 +142,7 @@ const OwnersColumn = ({
|
|||
displayButtonRow = false
|
||||
}
|
||||
|
||||
// TODO: simplify this whole logic around tx status, it's getting hard to maintain and follow
|
||||
const showConfirmBtn =
|
||||
!tx.isExecuted &&
|
||||
tx.status !== 'pending' &&
|
||||
|
@ -151,7 +152,8 @@ const OwnersColumn = ({
|
|||
!currentUserAlreadyConfirmed &&
|
||||
!thresholdReached
|
||||
|
||||
const showExecuteBtn = canExecute && !tx.isExecuted && thresholdReached
|
||||
const showExecuteBtn =
|
||||
canExecute && !tx.isExecuted && thresholdReached && tx.status !== 'pending' && cancelTx.status !== 'pending'
|
||||
|
||||
const showRejectBtn =
|
||||
!cancelTx.isExecuted &&
|
||||
|
@ -163,7 +165,13 @@ const OwnersColumn = ({
|
|||
!cancelThresholdReached &&
|
||||
displayButtonRow
|
||||
|
||||
const showExecuteRejectBtn = !cancelTx.isExecuted && !tx.isExecuted && canExecuteCancel && cancelThresholdReached
|
||||
const showExecuteRejectBtn =
|
||||
!cancelTx.isExecuted &&
|
||||
!tx.isExecuted &&
|
||||
canExecuteCancel &&
|
||||
cancelThresholdReached &&
|
||||
tx.status !== 'pending' &&
|
||||
cancelTx.status !== 'pending'
|
||||
|
||||
const txThreshold = cancelTx.isExecuted ? tx.confirmations.size : threshold
|
||||
const cancelThreshold = tx.isExecuted ? cancelTx.confirmations.size : threshold
|
||||
|
|
Loading…
Reference in New Issue