transaction decoder wip
This commit is contained in:
parent
480da937b4
commit
5c00c48d75
|
@ -4,7 +4,6 @@ import axios from 'axios'
|
|||
import { getTxServiceHost, getTxServiceUriFrom } from '~/config'
|
||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||
|
||||
export type TxServiceType = 'confirmation' | 'execution' | 'initialised'
|
||||
export type Operation = 0 | 1 | 2
|
||||
|
||||
const calculateBodyFrom = async (
|
||||
|
|
|
@ -17,7 +17,7 @@ import { SAFELIST_ADDRESS } from '~/routes/routes'
|
|||
import SendModal from '~/routes/safe/components/Balances/SendModal'
|
||||
import DropdownCurrency from '~/routes/safe/components/DropdownCurrency'
|
||||
import { useFetchTokens } from '~/routes/safe/container/Hooks/useFetchTokens'
|
||||
import { safeFeaturesEnabledSelector, safeParamAddressFromStateSelector } from '~/routes/safe/store/selectors'
|
||||
import { safeEnabledFeaturesSelector, safeParamAddressFromStateSelector } from '~/routes/safe/store/selectors'
|
||||
import { history } from '~/store'
|
||||
import { wrapInSuspense } from '~/utils/wrapInSuspense'
|
||||
const Collectibles = React.lazy(() => import('~/routes/safe/components/Balances/Collectibles'))
|
||||
|
@ -64,7 +64,7 @@ const Balances = (props: Props) => {
|
|||
const [state, setState] = useState(INITIAL_STATE)
|
||||
|
||||
const address = useSelector(safeParamAddressFromStateSelector)
|
||||
const featuresEnabled = useSelector(safeFeaturesEnabledSelector)
|
||||
const featuresEnabled = useSelector(safeEnabledFeaturesSelector)
|
||||
|
||||
useFetchTokens()
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@ import { useSelector } from 'react-redux'
|
|||
import Page from '~/components/layout/Page'
|
||||
import { type Token } from '~/logic/tokens/store/model/token'
|
||||
import Layout from '~/routes/safe/components/Layout'
|
||||
import { useCheckForUpdates } from '~/routes/safe/container/Hooks/useCheckForUpdates'
|
||||
import { useLoadSafe } from '~/routes/safe/container/Hooks/useLoadSafe'
|
||||
import { useCheckForUpdates } from '~/routes/safe/container/hooks/useCheckForUpdates'
|
||||
import { useLoadSafe } from '~/routes/safe/container/hooks/useLoadSafe'
|
||||
import { safeParamAddressFromStateSelector } from '~/routes/safe/store/selectors'
|
||||
|
||||
type Action = 'Send' | 'Receive'
|
||||
|
|
|
@ -5,7 +5,7 @@ import { List, Map, type RecordInstance } from 'immutable'
|
|||
|
||||
import generateBatchRequests from '~/logic/contracts/generateBatchRequests'
|
||||
import { decodeParamsFromSafeMethod } from '~/logic/contracts/methodIds'
|
||||
import { type TxServiceType, buildTxServiceUrl } from '~/logic/safe/transactions/txHistory'
|
||||
import { buildTxServiceUrl } from '~/logic/safe/transactions/txHistory'
|
||||
import { TOKEN_REDUCER_ID } from '~/logic/tokens/store/reducer/tokens'
|
||||
import {
|
||||
SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH,
|
||||
|
@ -22,7 +22,7 @@ import { type Transaction, makeTransaction } from '~/routes/safe/store/models/tr
|
|||
type ConfirmationServiceModel = {
|
||||
owner: string,
|
||||
submissionDate: Date,
|
||||
confirmationType: string,
|
||||
signature: string,
|
||||
transactionHash: string,
|
||||
}
|
||||
|
||||
|
@ -67,14 +67,12 @@ export const buildTransactionFrom = async (
|
|||
tx.confirmations.map((conf: ConfirmationServiceModel) =>
|
||||
makeConfirmation({
|
||||
owner: conf.owner,
|
||||
type: ((conf.confirmationType.toLowerCase(): any): TxServiceType),
|
||||
hash: conf.transactionHash,
|
||||
signature: conf.signature,
|
||||
}),
|
||||
),
|
||||
)
|
||||
const modifySettingsTx = sameAddress(tx.to, safeAddress) && Number(tx.value) === 0 && !!tx.data
|
||||
const cancellationTx = sameAddress(tx.to, safeAddress) && Number(tx.value) === 0 && !tx.data
|
||||
|
||||
const isERC721Token =
|
||||
(code && code.includes(SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH)) ||
|
||||
(isTokenTransfer(tx.data, Number(tx.value)) && !knownTokens.get(tx.to) && txTokenDecimals !== null)
|
||||
|
@ -161,9 +159,7 @@ export const buildTransactionFrom = async (
|
|||
multiSendTx: isMultiSendTx,
|
||||
upgradeTx: isUpgradeTx,
|
||||
decodedParams,
|
||||
modifySettingsTx,
|
||||
customTx,
|
||||
cancellationTx,
|
||||
creationTx: tx.creationTx,
|
||||
origin: tx.origin,
|
||||
})
|
||||
|
@ -188,18 +184,18 @@ const batchTxTokenRequest = (txs: any[]) => {
|
|||
return Promise.all(whenTxsValues)
|
||||
}
|
||||
|
||||
let prevSaveTransactionsEtag = null
|
||||
let prevOutgoingTxsEtag = null
|
||||
export const loadOutgoingTransactions = async (
|
||||
safeAddress: string,
|
||||
getState: GetState,
|
||||
): Promise<SafeTransactionsType> => {
|
||||
let transactions: TxServiceModel[] = addMockSafeCreationTx(safeAddress)
|
||||
let transactions: TxServiceModel[] = []
|
||||
|
||||
try {
|
||||
const config = prevSaveTransactionsEtag
|
||||
const config = prevOutgoingTxsEtag
|
||||
? {
|
||||
headers: {
|
||||
'If-None-Match': prevSaveTransactionsEtag,
|
||||
'If-None-Match': prevOutgoingTxsEtag,
|
||||
},
|
||||
}
|
||||
: undefined
|
||||
|
@ -207,12 +203,12 @@ export const loadOutgoingTransactions = async (
|
|||
const url = buildTxServiceUrl(safeAddress)
|
||||
const response = await axios.get(url, config)
|
||||
if (response.data.count > 0) {
|
||||
if (prevSaveTransactionsEtag === response.headers.etag) {
|
||||
if (prevOutgoingTxsEtag === response.headers.etag) {
|
||||
// The txs are the same as we currently have, we don't have to proceed
|
||||
return
|
||||
}
|
||||
transactions = transactions.concat(response.data.results)
|
||||
prevSaveTransactionsEtag = response.headers.etag
|
||||
prevOutgoingTxsEtag = response.headers.etag
|
||||
}
|
||||
} catch (err) {
|
||||
if (err && err.response && err.response.status === 304) {
|
||||
|
|
|
@ -2,18 +2,14 @@
|
|||
import { Record } from 'immutable'
|
||||
import type { RecordFactory, RecordOf } from 'immutable'
|
||||
|
||||
import { type TxServiceType } from '~/logic/safe/transactions/txHistory'
|
||||
|
||||
export type ConfirmationProps = {
|
||||
owner: string,
|
||||
type: TxServiceType,
|
||||
hash: string,
|
||||
signature?: string,
|
||||
}
|
||||
|
||||
export const makeConfirmation: RecordFactory<ConfirmationProps> = Record({
|
||||
owner: '',
|
||||
type: 'initialised',
|
||||
hash: '',
|
||||
signature: null,
|
||||
})
|
||||
|
|
|
@ -150,8 +150,8 @@ export const safeSelector: OutputSelector<GlobalState, RouterProps, SafeSelector
|
|||
if (!address) {
|
||||
return undefined
|
||||
}
|
||||
const checksumed = getWeb3().utils.toChecksumAddress(address)
|
||||
const safe = safes.get(checksumed)
|
||||
const checksummed = getWeb3().utils.toChecksumAddress(address)
|
||||
const safe = safes.get(checksummed)
|
||||
|
||||
return safe
|
||||
},
|
||||
|
@ -276,7 +276,7 @@ export const safeOwnersSelector: OutputSelector<GlobalState, RouterProps, Map<st
|
|||
},
|
||||
)
|
||||
|
||||
export const safeFeaturesEnabledSelector: OutputSelector<
|
||||
export const safeEnabledFeaturesSelector: OutputSelector<
|
||||
GlobalState,
|
||||
RouterProps,
|
||||
Map<string, string>,
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
// @flow
|
||||
import { List, Map } from 'immutable'
|
||||
import { type Selector, createSelector } from 'reselect'
|
||||
|
||||
import { userAccountSelector } from '~/logic/wallets/store/selectors'
|
||||
import type { IncomingTransaction } from '~/routes/safe/store/models/incomingTransaction'
|
||||
import { type Safe } from '~/routes/safe/store/models/safe'
|
||||
import { type Transaction, type TransactionStatus } from '~/routes/safe/store/models/transaction'
|
||||
import {
|
||||
type RouterProps,
|
||||
safeCancellationTransactionsSelector,
|
||||
safeIncomingTransactionsSelector,
|
||||
safeSelector,
|
||||
safeTransactionsSelector,
|
||||
} from '~/routes/safe/store/selectors'
|
||||
import { type GlobalState } from '~/store'
|
||||
|
||||
const getTxStatus = (tx: Transaction, userAddress: string, safe: Safe): TransactionStatus => {
|
||||
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
|
||||
}
|
||||
|
||||
export const extendedTransactionsSelector: Selector<
|
||||
GlobalState,
|
||||
RouterProps,
|
||||
List<Transaction | IncomingTransaction>,
|
||||
> = 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: Transaction) =>
|
||||
tx.withMutations((transaction) => {
|
||||
transaction.set('modifySettingsTx', sameAddress(transaction.to, safe) && Number(tx.value) === 0 && !!tx.data)
|
||||
transaction.set('cancellationTx', sameAddress(transaction.to, safe) && Number(tx.value) === 0 && !tx.data)
|
||||
|
||||
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])
|
||||
},
|
||||
)
|
|
@ -0,0 +1,5 @@
|
|||
// @flow
|
||||
import { sameAddress } from '~/logic/wallets/ethAddresses'
|
||||
import { type Transaction } from '~/routes/safe/store/models/transaction'
|
||||
|
||||
const isModifySettingsTx = (tx: Transaction) => sameAddress(transaction.to, safe) && Number(tx.value) === 0 && !!tx.data
|
Loading…
Reference in New Issue