feature: WIP - add mocked tx to the list
This commit is contained in:
parent
be4caa1baf
commit
141e05c2e8
|
@ -0,0 +1,6 @@
|
|||
// @flow
|
||||
import { createAction } from 'redux-actions'
|
||||
|
||||
export const ADD_CANCELLATION_TRANSACTION = 'ADD_CANCELLATION_TRANSACTION'
|
||||
|
||||
export const addCancellationTransaction = createAction<string, *>(ADD_CANCELLATION_TRANSACTION)
|
|
@ -0,0 +1,6 @@
|
|||
// @flow
|
||||
import { createAction } from 'redux-actions'
|
||||
|
||||
export const ADD_TRANSACTION = 'ADD_TRANSACTION'
|
||||
|
||||
export const addTransaction = createAction<string, *>(ADD_TRANSACTION)
|
|
@ -1,8 +1,9 @@
|
|||
// @flow
|
||||
import { push } from 'connected-react-router'
|
||||
import type { RecordInstance } from 'immutable'
|
||||
import { List } from 'immutable'
|
||||
import type { GetState, Dispatch as ReduxDispatch } from 'redux'
|
||||
import semverSatisfies from 'semver/functions/satisfies'
|
||||
// import semverSatisfies from 'semver/functions/satisfies'
|
||||
|
||||
import { makeConfirmation } from '../../models/confirmation'
|
||||
|
||||
|
@ -20,13 +21,22 @@ import {
|
|||
saveTxToHistory,
|
||||
} from '~/logic/safe/transactions'
|
||||
import { estimateSafeTxGas } from '~/logic/safe/transactions/gasNew'
|
||||
import { SAFE_VERSION_FOR_OFFCHAIN_SIGNATURES, tryOffchainSigning } from '~/logic/safe/transactions/offchainSigner'
|
||||
import { getCurrentSafeVersion } from '~/logic/safe/utils/safeVersion'
|
||||
import { ZERO_ADDRESS } from '~/logic/wallets/ethAddresses'
|
||||
// import { SAFE_VERSION_FOR_OFFCHAIN_SIGNATURES, tryOffchainSigning } from '~/logic/safe/transactions/offchainSigner'
|
||||
// import { getCurrentSafeVersion } from '~/logic/safe/utils/safeVersion'
|
||||
import { TOKEN_REDUCER_ID } from '~/logic/tokens/store/reducer/tokens'
|
||||
import { ZERO_ADDRESS, sameAddress } from '~/logic/wallets/ethAddresses'
|
||||
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
|
||||
import { providerSelector } from '~/logic/wallets/store/selectors'
|
||||
import { SAFELIST_ADDRESS } from '~/routes/routes'
|
||||
import { addCancellationTransaction } from '~/routes/safe/store/actions/transactions/addCancellationTransaction'
|
||||
import { addTransaction } from '~/routes/safe/store/actions/transactions/addTransaction'
|
||||
import type { TxServiceModel } from '~/routes/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions'
|
||||
import { buildTransactionFrom } from '~/routes/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions'
|
||||
import { updateCancellationTransaction } from '~/routes/safe/store/actions/transactions/updateCancellationTransaction'
|
||||
import { getLastTx, getNewTxNonce, shouldExecuteTransaction } from '~/routes/safe/store/actions/utils'
|
||||
import type { TransactionProps } from '~/routes/safe/store/models/transaction'
|
||||
import { CANCELLATION_TRANSACTIONS_REDUCER_ID } from '~/routes/safe/store/reducer/cancellationTransactions'
|
||||
import { TRANSACTIONS_REDUCER_ID } from '~/routes/safe/store/reducer/transactions'
|
||||
import { type GlobalState } from '~/store'
|
||||
import { getErrorMessage } from '~/test/utils/ethereumErrors'
|
||||
|
||||
|
@ -44,6 +54,49 @@ export type CreateTransactionArgs = {
|
|||
origin?: string | null,
|
||||
}
|
||||
|
||||
async function mockMyTransaction(safeAddress: string, state, tx: {}) {
|
||||
const submissionDate = new Date().toISOString()
|
||||
const knownTokens = state[TOKEN_REDUCER_ID]
|
||||
const cancellationTx = sameAddress(tx.to, safeAddress) && Number(tx.value) === 0 && !tx.data
|
||||
const existentTx: TransactionProps =
|
||||
state[cancellationTx ? CANCELLATION_TRANSACTIONS_REDUCER_ID : TRANSACTIONS_REDUCER_ID]
|
||||
.get(safeAddress)
|
||||
.find(({ nonce }) => nonce === tx.nonce) || null
|
||||
|
||||
const transactionStructure: TxServiceModel = {
|
||||
...tx,
|
||||
value: tx.valueInWei,
|
||||
blockNumber: null,
|
||||
confirmations: [], // this is used to determine if a tx is pending or not. See `getTxStatus` selector
|
||||
confirmationsRequired: null,
|
||||
dataDecoded: {},
|
||||
ethGasPrice: null,
|
||||
executionDate: null,
|
||||
executor: null,
|
||||
fee: null,
|
||||
gasUsed: null,
|
||||
isExecuted: false,
|
||||
isSuccessful: null,
|
||||
origin: null,
|
||||
safeTxHash: null,
|
||||
signatures: null,
|
||||
transactionHash: null,
|
||||
...existentTx,
|
||||
modified: submissionDate,
|
||||
submissionDate,
|
||||
safe: safeAddress,
|
||||
}
|
||||
|
||||
const mockedTransaction: RecordInstance<TransactionProps> = await buildTransactionFrom(
|
||||
safeAddress,
|
||||
transactionStructure,
|
||||
knownTokens,
|
||||
null,
|
||||
)
|
||||
|
||||
return { cancellationTx, existentTx, mockedTransaction }
|
||||
}
|
||||
|
||||
const createTransaction = ({
|
||||
safeAddress,
|
||||
to,
|
||||
|
@ -66,12 +119,12 @@ const createTransaction = ({
|
|||
const ready = await onboardUser()
|
||||
if (!ready) return
|
||||
|
||||
const { account: from, hardwareWallet, smartContractWallet } = providerSelector(state)
|
||||
const { account: from /*, hardwareWallet, smartContractWallet*/ } = providerSelector(state)
|
||||
const safeInstance = await getGnosisSafeInstanceAt(safeAddress)
|
||||
const lastTx = await getLastTx(safeAddress)
|
||||
const nonce = await getNewTxNonce(txNonce, lastTx, safeInstance)
|
||||
const isExecution = await shouldExecuteTransaction(safeInstance, nonce, lastTx)
|
||||
const safeVersion = await getCurrentSafeVersion(safeInstance)
|
||||
// const safeVersion = await getCurrentSafeVersion(safeInstance)
|
||||
const safeTxGas = await estimateSafeTxGas(safeInstance, safeAddress, txData, to, valueInWei, operation)
|
||||
|
||||
// https://docs.gnosis.io/safe/docs/docs5/#pre-validated-signatures
|
||||
|
@ -105,25 +158,26 @@ const createTransaction = ({
|
|||
try {
|
||||
// Here we're checking that safe contract version is greater or equal 1.1.1, but
|
||||
// theoretically EIP712 should also work for 1.0.0 contracts
|
||||
const canTryOffchainSigning =
|
||||
!isExecution && !smartContractWallet && semverSatisfies(safeVersion, SAFE_VERSION_FOR_OFFCHAIN_SIGNATURES)
|
||||
if (false) {
|
||||
const signature = await tryOffchainSigning({ ...txArgs, safeAddress }, hardwareWallet)
|
||||
|
||||
if (signature) {
|
||||
closeSnackbar(beforeExecutionKey)
|
||||
|
||||
await saveTxToHistory({
|
||||
...txArgs,
|
||||
signature,
|
||||
origin,
|
||||
})
|
||||
showSnackbar(notificationsQueue.afterExecution.moreConfirmationsNeeded, enqueueSnackbar, closeSnackbar)
|
||||
|
||||
dispatch(fetchTransactions(safeAddress))
|
||||
return
|
||||
}
|
||||
}
|
||||
// TODO: revert this
|
||||
// const canTryOffchainSigning =
|
||||
// !isExecution && !smartContractWallet && semverSatisfies(safeVersion, SAFE_VERSION_FOR_OFFCHAIN_SIGNATURES)
|
||||
// if (canTryOffchainSigning) {
|
||||
// const signature = await tryOffchainSigning({ ...txArgs, safeAddress }, hardwareWallet)
|
||||
//
|
||||
// if (signature) {
|
||||
// closeSnackbar(beforeExecutionKey)
|
||||
//
|
||||
// await saveTxToHistory({
|
||||
// ...txArgs,
|
||||
// signature,
|
||||
// origin,
|
||||
// })
|
||||
// showSnackbar(notificationsQueue.afterExecution.moreConfirmationsNeeded, enqueueSnackbar, closeSnackbar)
|
||||
//
|
||||
// dispatch(fetchTransactions(safeAddress))
|
||||
// return
|
||||
// }
|
||||
// }
|
||||
|
||||
tx = isExecution ? await getExecutionTransaction(txArgs) : await getApprovalTransaction(txArgs)
|
||||
|
||||
|
@ -143,11 +197,26 @@ const createTransaction = ({
|
|||
pendingExecutionKey = showSnackbar(notificationsQueue.pendingExecution, enqueueSnackbar, closeSnackbar)
|
||||
|
||||
try {
|
||||
await saveTxToHistory({
|
||||
// TODO: let's mock the tx
|
||||
const { cancellationTx, existentTx, mockedTransaction } = await mockMyTransaction(safeAddress, state, {
|
||||
...txArgs,
|
||||
txHash,
|
||||
origin,
|
||||
})
|
||||
if (cancellationTx) {
|
||||
if (existentTx) {
|
||||
dispatch(updateCancellationTransaction({ safeAddress, transaction: mockedTransaction }))
|
||||
} else {
|
||||
dispatch(addCancellationTransaction({ safeAddress, transaction: mockedTransaction }))
|
||||
}
|
||||
} else {
|
||||
if (existentTx) {
|
||||
dispatch(updateTransaction({ safeAddress, transaction: mockedTransaction }))
|
||||
} else {
|
||||
dispatch(addTransaction({ safeAddress, transaction: mockedTransaction }))
|
||||
}
|
||||
}
|
||||
|
||||
await saveTxToHistory({ ...txArgs, txHash, origin })
|
||||
await dispatch(fetchTransactions(safeAddress))
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
|
|
|
@ -10,6 +10,7 @@ import { decodeParamsFromSafeMethod } from '~/logic/contracts/methodIds'
|
|||
import { buildTxServiceUrl } from '~/logic/safe/transactions/txHistory'
|
||||
import { getTokenInfos } from '~/logic/tokens/store/actions/fetchTokens'
|
||||
import { TOKEN_REDUCER_ID } from '~/logic/tokens/store/reducer/tokens'
|
||||
import { ALTERNATIVE_TOKEN_ABI } from '~/logic/tokens/utils/alternativeAbi'
|
||||
import {
|
||||
SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH,
|
||||
isMultisendTransaction,
|
||||
|
@ -179,7 +180,7 @@ export const buildTransactionFrom = async (
|
|||
})
|
||||
}
|
||||
|
||||
const batchTxTokenRequest = (txs: any[]) => {
|
||||
export const batchTxTokenRequest = (txs: any[]) => {
|
||||
const batch = new web3ReadOnly.BatchRequest()
|
||||
|
||||
const whenTxsValues = txs.map((tx) => {
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
// @flow
|
||||
import { createAction } from 'redux-actions'
|
||||
|
||||
export const UPDATE_CANCELLATION_TRANSACTION = 'UPDATE_CANCELLATION_TRANSACTION'
|
||||
|
||||
export const updateCancellationTransaction = createAction<string, *>(UPDATE_CANCELLATION_TRANSACTION)
|
|
@ -2,7 +2,9 @@
|
|||
import { List, Map } from 'immutable'
|
||||
import { type ActionType, handleActions } from 'redux-actions'
|
||||
|
||||
import { ADD_CANCELLATION_TRANSACTION } from '~/routes/safe/store/actions/transactions/addCancellationTransaction'
|
||||
import { ADD_CANCELLATION_TRANSACTIONS } from '~/routes/safe/store/actions/transactions/addCancellationTransactions'
|
||||
import { UPDATE_CANCELLATION_TRANSACTION } from '~/routes/safe/store/actions/transactions/updateCancellationTransaction'
|
||||
import { type Transaction } from '~/routes/safe/store/models/transaction'
|
||||
|
||||
export const CANCELLATION_TRANSACTIONS_REDUCER_ID = 'cancellationTransactions'
|
||||
|
@ -11,7 +13,32 @@ export type CancelState = Map<string, List<Transaction>>
|
|||
|
||||
export default handleActions<CancelState, *>(
|
||||
{
|
||||
[ADD_CANCELLATION_TRANSACTION]: (state: CancelState, action: ActionType<Function>): CancelState => {
|
||||
const { safeAddress, transaction } = action.payload
|
||||
const transactionList = state.get(safeAddress)
|
||||
return state.set(safeAddress, transactionList.push(transaction))
|
||||
},
|
||||
[ADD_CANCELLATION_TRANSACTIONS]: (state: CancelState, action: ActionType<Function>): CancelState => action.payload,
|
||||
[UPDATE_CANCELLATION_TRANSACTION]: (state: CancelState, action: ActionType<Function>): CancelState => {
|
||||
const { safeAddress, transaction } = action.payload
|
||||
|
||||
const transactionList = state.get(safeAddress)
|
||||
|
||||
if (!transaction) {
|
||||
return state
|
||||
}
|
||||
|
||||
const storedTransactionIndex = transactionList.findIndex((tx) => tx.safeTxHash === transaction.safeTxHash)
|
||||
|
||||
if (storedTransactionIndex === -1) {
|
||||
return state
|
||||
}
|
||||
|
||||
return state.set(
|
||||
safeAddress,
|
||||
transactionList.update(storedTransactionIndex, (tx) => tx.merge(transaction)),
|
||||
)
|
||||
},
|
||||
},
|
||||
Map(),
|
||||
)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import { List, Map } from 'immutable'
|
||||
import { type ActionType, handleActions } from 'redux-actions'
|
||||
|
||||
import { ADD_TRANSACTION } from '~/routes/safe/store/actions/transactions/addTransaction'
|
||||
import { ADD_TRANSACTIONS } from '~/routes/safe/store/actions/transactions/addTransactions'
|
||||
import { UPDATE_TRANSACTION } from '~/routes/safe/store/actions/transactions/updateTransaction'
|
||||
import { type Transaction } from '~/routes/safe/store/models/transaction'
|
||||
|
@ -12,6 +13,11 @@ export type State = Map<string, List<Transaction>>
|
|||
|
||||
export default handleActions<State, *>(
|
||||
{
|
||||
[ADD_TRANSACTION]: (state: State, action: ActionType<Function>): State => {
|
||||
const { safeAddress, transaction } = action.payload
|
||||
const transactionList = state.get(safeAddress)
|
||||
return state.set(safeAddress, transactionList.push(transaction))
|
||||
},
|
||||
[ADD_TRANSACTIONS]: (state: State, action: ActionType<Function>): State => action.payload,
|
||||
[UPDATE_TRANSACTION]: (state: State, action: ActionType<Function>): State => {
|
||||
const { safeAddress, transaction } = action.payload
|
||||
|
|
Loading…
Reference in New Issue