diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/index.tsx
index 51c351d2..7f7f7309 100644
--- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/index.tsx
+++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/index.tsx
@@ -15,7 +15,6 @@ import Block from 'src/components/layout/Block'
import Col from 'src/components/layout/Col'
import Img from 'src/components/layout/Img'
import Paragraph from 'src/components/layout/Paragraph/index'
-import { TX_TYPE_CONFIRMATION } from 'src/logic/safe/transactions/send'
import { userAccountSelector } from 'src/logic/wallets/store/selectors'
import { makeTransaction } from 'src/routes/safe/store/models/transaction'
import { safeOwnersSelector, safeThresholdSelector } from 'src/routes/safe/store/selectors'
@@ -29,11 +28,8 @@ function getOwnersConfirmations(tx, userAddress) {
currentUserAlreadyConfirmed = true
}
- if (conf.type === TX_TYPE_CONFIRMATION) {
- ownersWhoConfirmed.push(conf.owner)
- }
+ ownersWhoConfirmed.push(conf.owner)
})
-
return [ownersWhoConfirmed, currentUserAlreadyConfirmed]
}
diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/utils.ts b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/utils.ts
index 05356aca..bcf7a81c 100644
--- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/utils.ts
+++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/utils.ts
@@ -1,5 +1,4 @@
import { SAFE_METHODS_NAMES } from 'src/logic/contracts/methodIds'
-import { getWeb3 } from 'src/logic/wallets/getWeb3'
const getSafeVersion = (data) => {
const contractAddress = data.substr(340, 40).toLowerCase()
@@ -12,43 +11,50 @@ const getSafeVersion = (data) => {
}
export const getTxData = (tx) => {
- const web3 = getWeb3()
- const { fromWei, toBN } = web3.utils
-
const txData: any = {}
- if (tx.isTokenTransfer && tx.decodedParams) {
- txData.recipient = tx.decodedParams.recipient
- txData.value = fromWei(toBN(tx.decodedParams.value), 'ether')
+ if (tx.decodedParams) {
+ if (tx.isTokenTransfer) {
+ const { to } = tx.decodedParams.transfer
+ txData.recipient = to
+ txData.isTokenTransfer = true
+ }
+ if (tx.isCollectibleTransfer) {
+ const { safeTransferFrom, transfer, transferFrom } = tx.decodedParams
+ const { to, value } = safeTransferFrom || transferFrom || transfer
+ txData.recipient = to
+ txData.tokenId = value
+ txData.isCollectibleTransfer = true
+ }
} else if (tx.customTx) {
txData.recipient = tx.recipient
- txData.value = fromWei(toBN(tx.value), 'ether')
txData.data = tx.data
txData.customTx = true
} else if (Number(tx.value) > 0) {
txData.recipient = tx.recipient
- txData.value = fromWei(toBN(tx.value), 'ether')
} else if (tx.modifySettingsTx) {
txData.recipient = tx.recipient
txData.modifySettingsTx = true
if (tx.decodedParams) {
- txData.action = tx.decodedParams.methodName
-
- if (txData.action === SAFE_METHODS_NAMES.REMOVE_OWNER) {
- txData.removedOwner = tx.decodedParams.args[1]
- txData.newThreshold = tx.decodedParams.args[2]
- } else if (txData.action === SAFE_METHODS_NAMES.CHANGE_THRESHOLD) {
- txData.newThreshold = tx.decodedParams.args[0]
- } else if (txData.action === SAFE_METHODS_NAMES.ADD_OWNER_WITH_THRESHOLD) {
- txData.addedOwner = tx.decodedParams.args[0]
- txData.newThreshold = tx.decodedParams.args[1]
- } else if (txData.action === SAFE_METHODS_NAMES.SWAP_OWNER) {
- txData.removedOwner = tx.decodedParams.args[1]
- txData.addedOwner = tx.decodedParams.args[2]
+ if (tx.decodedParams[SAFE_METHODS_NAMES.REMOVE_OWNER]) {
+ const { _threshold, owner } = tx.decodedParams[SAFE_METHODS_NAMES.REMOVE_OWNER]
+ txData.removedOwner = owner
+ txData.newThreshold = _threshold
+ } else if (tx.decodedParams[SAFE_METHODS_NAMES.CHANGE_THRESHOLD]) {
+ const { _threshold } = tx.decodedParams[SAFE_METHODS_NAMES.CHANGE_THRESHOLD]
+ txData.newThreshold = _threshold
+ } else if (tx.decodedParams[SAFE_METHODS_NAMES.ADD_OWNER_WITH_THRESHOLD]) {
+ const { _threshold, owner } = tx.decodedParams[SAFE_METHODS_NAMES.ADD_OWNER_WITH_THRESHOLD]
+ txData.addedOwner = owner
+ txData.newThreshold = _threshold
+ } else if (tx.decodedParams[SAFE_METHODS_NAMES.SWAP_OWNER]) {
+ const { newOwner, oldOwner } = tx.decodedParams[SAFE_METHODS_NAMES.SWAP_OWNER]
+ txData.removedOwner = oldOwner
+ txData.addedOwner = newOwner
}
}
- } else if (tx.cancellationTx) {
+ } else if (tx.isCancellationTx) {
txData.cancellationTx = true
} else if (tx.creationTx) {
txData.creationTx = true
@@ -57,7 +63,6 @@ export const getTxData = (tx) => {
txData.data = `The contract of this Safe is upgraded to Version ${getSafeVersion(tx.data)}`
} else {
txData.recipient = tx.recipient
- txData.value = 0
}
return txData
diff --git a/src/routes/safe/components/Transactions/TxsTable/TxType/index.tsx b/src/routes/safe/components/Transactions/TxsTable/TxType/index.tsx
index bec45804..487f628a 100644
--- a/src/routes/safe/components/Transactions/TxsTable/TxType/index.tsx
+++ b/src/routes/safe/components/Transactions/TxsTable/TxType/index.tsx
@@ -11,6 +11,8 @@ import { getAppInfoFromOrigin, getAppInfoFromUrl } from 'src/routes/safe/compone
const typeToIcon = {
outgoing: OutgoingTxIcon,
+ token: OutgoingTxIcon,
+ collectible: OutgoingTxIcon,
incoming: IncomingTxIcon,
custom: CustomTxIcon,
settings: SettingsTxIcon,
@@ -21,6 +23,8 @@ const typeToIcon = {
const typeToLabel = {
outgoing: 'Outgoing transfer',
+ token: 'Outgoing transfer',
+ collectible: 'Outgoing transfer',
incoming: 'Incoming transfer',
custom: 'Contract Interaction',
settings: 'Modify settings',
diff --git a/src/routes/safe/components/Transactions/TxsTable/columns.tsx b/src/routes/safe/components/Transactions/TxsTable/columns.tsx
index a856fdb7..b5cda0cb 100644
--- a/src/routes/safe/components/Transactions/TxsTable/columns.tsx
+++ b/src/routes/safe/components/Transactions/TxsTable/columns.tsx
@@ -2,7 +2,7 @@ import { BigNumber } from 'bignumber.js'
import format from 'date-fns/format'
import getTime from 'date-fns/getTime'
import parseISO from 'date-fns/parseISO'
-import { List, Map } from 'immutable'
+import { List } from 'immutable'
import React from 'react'
import TxType from './TxType'
@@ -43,7 +43,7 @@ export const getIncomingTxAmount = (tx, formatted = true) => {
export const getTxAmount = (tx, formatted = true) => {
const { decimals = 18, decodedParams, isTokenTransfer, symbol } = tx
- const { value } = isTokenTransfer && decodedParams && decodedParams.value ? decodedParams : tx
+ const { value } = isTokenTransfer && !!decodedParams && !!decodedParams.transfer ? decodedParams.transfer : tx
if (!isTokenTransfer && !(Number(value) > 0)) {
return NOT_AVAILABLE
@@ -65,22 +65,9 @@ const getIncomingTxTableData = (tx) => ({
const getTransactionTableData = (tx, cancelTx) => {
const txDate = tx.submissionDate
- let txType = 'outgoing'
- if (tx.modifySettingsTx) {
- txType = 'settings'
- } else if (tx.cancellationTx) {
- txType = 'cancellation'
- } else if (tx.customTx) {
- txType = 'custom'
- } else if (tx.creationTx) {
- txType = 'creation'
- } else if (tx.upgradeTx) {
- txType = 'upgrade'
- }
-
return {
[TX_TABLE_ID]: tx.blockNumber,
- [TX_TABLE_TYPE_ID]: ,
+ [TX_TABLE_TYPE_ID]: ,
[TX_TABLE_DATE_ID]: txDate ? formatDate(txDate) : '',
[buildOrderFieldFrom(TX_TABLE_DATE_ID)]: txDate ? getTime(parseISO(txDate)) : null,
[TX_TABLE_AMOUNT_ID]: getTxAmount(tx),
@@ -91,17 +78,12 @@ const getTransactionTableData = (tx, cancelTx) => {
}
export const getTxTableData = (transactions, cancelTxs) => {
- const cancelTxsByNonce = cancelTxs.reduce((acc, tx) => acc.set(tx.nonce, tx), Map())
-
return transactions.map((tx) => {
- if (INCOMING_TX_TYPES[tx.type]) {
+ if (INCOMING_TX_TYPES[tx.type] !== undefined) {
return getIncomingTxTableData(tx)
}
- return getTransactionTableData(
- tx,
- Number.isInteger(Number.parseInt(tx.nonce, 10)) ? cancelTxsByNonce.get(tx.nonce) : undefined,
- )
+ return getTransactionTableData(tx, cancelTxs.get(`${tx.nonce}`))
})
}
diff --git a/src/routes/safe/components/Transactions/TxsTable/index.tsx b/src/routes/safe/components/Transactions/TxsTable/index.tsx
index e5dbd6bc..56ec6177 100644
--- a/src/routes/safe/components/Transactions/TxsTable/index.tsx
+++ b/src/routes/safe/components/Transactions/TxsTable/index.tsx
@@ -19,8 +19,8 @@ import Table from 'src/components/Table'
import { cellWidth } from 'src/components/Table/TableHead'
import Block from 'src/components/layout/Block'
import Row from 'src/components/layout/Row'
-import { extendedTransactionsSelector } from 'src/routes/safe/container/selector'
import { safeCancellationTransactionsSelector } from 'src/routes/safe/store/selectors'
+import { extendedTransactionsSelector } from '../../../store/selectors/transactions'
export const TRANSACTION_ROW_TEST_ID = 'transaction-row'
@@ -36,8 +36,8 @@ const TxsTable = ({ classes }) => {
const cancellationTransactions = useSelector(safeCancellationTransactionsSelector)
const transactions = useSelector(extendedTransactionsSelector)
- const handleTxExpand = (safeTxHash) => {
- setExpandedTx((prevTx) => (prevTx === safeTxHash ? null : safeTxHash))
+ const handleTxExpand = (rowCombinedId) => {
+ setExpandedTx((prevId) => (prevId === rowCombinedId ? null : rowCombinedId))
}
const columns = generateColumns()
@@ -83,58 +83,65 @@ const TxsTable = ({ classes }) => {
size={filteredData.size}
>
{(sortedData) =>
- sortedData.map((row, index) => (
-
- handleTxExpand(row.tx.safeTxHash)}
- tabIndex={-1}
- >
- {autoColumns.map((column: any) => (
-
- {row[column.id]}
+ sortedData.map((row, index) => {
+ const rowCombinedId = `${row.tx.nonce + row.tx.data}`
+
+ return (
+
+ handleTxExpand(rowCombinedId)}
+ tabIndex={-1}
+ >
+ {autoColumns.map((column: any) => (
+
+ {row[column.id]}
+
+ ))}
+
+
+
+
- ))}
-
-
-
-
-
-
- {!row.tx.creationTx && (
-
- {expandedTx === row.safeTxHash ? : }
-
- )}
-
-
- {!row.tx.creationTx && (
-
-
-
+
+ {!row.tx.creationTx && (
+
+ {expandedTx === rowCombinedId ? : }
+
+ )}
- )}
-
- ))
+ {!row.tx.creationTx && (
+
+
+
+
+
+ )}
+
+ )
+ })
}
diff --git a/src/routes/safe/container/selector.ts b/src/routes/safe/container/selector.ts
index 9c63b816..9c9fb0b4 100644
--- a/src/routes/safe/container/selector.ts
+++ b/src/routes/safe/container/selector.ts
@@ -1,4 +1,4 @@
-import { List, Map } from 'immutable'
+import { Map } from 'immutable'
import { createSelector } from 'reselect'
import { tokensSelector } from 'src/logic/tokens/store/selectors'
@@ -6,39 +6,7 @@ import { getEthAsToken } from 'src/logic/tokens/utils/tokenHelpers'
import { isUserOwner } from 'src/logic/wallets/ethAddresses'
import { userAccountSelector } from 'src/logic/wallets/store/selectors'
-import {
- safeActiveTokensSelector,
- safeBalancesSelector,
- safeCancellationTransactionsSelector,
- safeIncomingTransactionsSelector,
- safeSelector,
- safeTransactionsSelector,
-} from 'src/routes/safe/store/selectors'
-
-const getTxStatus = (tx, userAddress, safe) => {
- let txStatus
- if (tx.executionTxHash) {
- txStatus = 'success'
- } else if (tx.cancelled) {
- txStatus = 'cancelled'
- } else if (tx.confirmations.size === safe.threshold) {
- txStatus = 'awaiting_execution'
- } else if (tx.creationTx) {
- txStatus = 'success'
- } else if (!tx.confirmations.size) {
- txStatus = 'pending'
- } else {
- const userConfirmed = tx.confirmations.filter((conf) => conf.owner === userAddress).size === 1
- const userIsSafeOwner = safe.owners.filter((owner) => owner.address === userAddress).size === 1
- txStatus = !userConfirmed && userIsSafeOwner ? 'awaiting_your_confirmation' : 'awaiting_confirmations'
- }
-
- if (tx.isSuccessful === false) {
- txStatus = 'failed'
- }
-
- return txStatus
-}
+import { safeActiveTokensSelector, safeBalancesSelector, safeSelector } from 'src/routes/safe/store/selectors'
export const grantedSelector = createSelector(userAccountSelector, safeSelector, (userAccount, safe) =>
isUserOwner(safe, userAccount),
@@ -76,31 +44,3 @@ export const extendedSafeTokensSelector = createSelector(
return extendedTokens.toList()
},
)
-
-export const extendedTransactionsSelector = createSelector(
- safeSelector,
- userAccountSelector,
- safeTransactionsSelector,
- safeCancellationTransactionsSelector,
- safeIncomingTransactionsSelector,
- (safe, userAddress, transactions, cancellationTransactions, incomingTransactions) => {
- const cancellationTransactionsByNonce = cancellationTransactions.reduce((acc, tx) => acc.set(tx.nonce, tx), Map())
- const extendedTransactions = transactions.map((tx) => {
- let extendedTx = tx
-
- if (!tx.isExecuted) {
- if (
- (cancellationTransactionsByNonce.get(tx.nonce) &&
- cancellationTransactionsByNonce.get(tx.nonce).get('isExecuted')) ||
- transactions.find((safeTx) => tx.nonce === safeTx.nonce && safeTx.isExecuted)
- ) {
- extendedTx = tx.set('cancelled', true)
- }
- }
-
- return extendedTx.set('status', getTxStatus(extendedTx, userAddress, safe))
- })
-
- return List([...extendedTransactions, ...incomingTransactions])
- },
-)
diff --git a/src/routes/safe/store/selectors/transactions.ts b/src/routes/safe/store/selectors/transactions.ts
index b5dbb408..da4b7782 100644
--- a/src/routes/safe/store/selectors/transactions.ts
+++ b/src/routes/safe/store/selectors/transactions.ts
@@ -1,65 +1,10 @@
-import { List, Map } from 'immutable'
+import { List } from 'immutable'
import { createSelector } from 'reselect'
-import { userAccountSelector } from 'src/logic/wallets/store/selectors'
-import {
- safeCancellationTransactionsSelector,
- safeIncomingTransactionsSelector,
- safeSelector,
- safeTransactionsSelector,
-} from 'src/routes/safe/store/selectors'
-
-const getTxStatus = (tx: any, userAddress: string, safe): string => {
- let txStatus
-
- if (tx.executionTxHash) {
- txStatus = 'success'
- } else if (tx.cancelled) {
- txStatus = 'cancelled'
- } else if (tx.confirmations.size === safe.threshold) {
- txStatus = 'awaiting_execution'
- } else if (tx.creationTx) {
- txStatus = 'success'
- } else if (!tx.confirmations.size) {
- txStatus = 'pending'
- } else {
- const userConfirmed = tx.confirmations.filter((conf) => conf.owner === userAddress).size === 1
- const userIsSafeOwner = safe.owners.filter((owner) => owner.address === userAddress).size === 1
- txStatus = !userConfirmed && userIsSafeOwner ? 'awaiting_your_confirmation' : 'awaiting_confirmations'
- }
-
- if (tx.isSuccessful === false) {
- txStatus = 'failed'
- }
-
- return txStatus
-}
+import { safeIncomingTransactionsSelector, safeTransactionsSelector } from 'src/routes/safe/store/selectors'
export const extendedTransactionsSelector = createSelector(
- safeSelector,
- userAccountSelector,
safeTransactionsSelector,
- safeCancellationTransactionsSelector,
safeIncomingTransactionsSelector,
- (safe, userAddress, transactions, cancellationTransactions, incomingTransactions) => {
- const cancellationTransactionsByNonce = cancellationTransactions.reduce((acc, tx) => acc.set(tx.nonce, tx), Map())
- const extendedTransactions = transactions.map((tx: any) =>
- tx.withMutations((transaction) => {
- if (!transaction.isExecuted) {
- if (
- (cancellationTransactionsByNonce.get(tx.nonce) &&
- cancellationTransactionsByNonce.get(tx.nonce).get('isExecuted')) ||
- transactions.find((safeTx) => tx.nonce === safeTx.nonce && safeTx.isExecuted)
- ) {
- transaction.set('cancelled', true)
- }
- }
- transaction.set('status', getTxStatus(transaction, userAddress, safe))
-
- return transaction
- }),
- )
-
- return List([...extendedTransactions, ...incomingTransactions])
- },
+ (transactions, incomingTransactions) => List([...transactions, ...incomingTransactions]),
)