From b4a470a77078b622ca76f8169fcd6ad9c9d30462 Mon Sep 17 00:00:00 2001 From: fernandomg Date: Fri, 22 May 2020 16:48:57 -0300 Subject: [PATCH] chore: fix build after development merge --- .../container/hooks/useCheckForUpdates.tsx | 2 +- .../actions/addCancellationTransactions.ts | 5 - .../safe/store/actions/addTransactions.ts | 5 - .../safe/store/actions/fetchTransactions.ts | 348 ------------------ src/test/builder/safe.dom.utils.tsx | 24 +- 5 files changed, 13 insertions(+), 371 deletions(-) delete mode 100644 src/routes/safe/store/actions/addCancellationTransactions.ts delete mode 100644 src/routes/safe/store/actions/addTransactions.ts delete mode 100644 src/routes/safe/store/actions/fetchTransactions.ts diff --git a/src/routes/safe/container/hooks/useCheckForUpdates.tsx b/src/routes/safe/container/hooks/useCheckForUpdates.tsx index 407ff510..62a0da70 100644 --- a/src/routes/safe/container/hooks/useCheckForUpdates.tsx +++ b/src/routes/safe/container/hooks/useCheckForUpdates.tsx @@ -5,7 +5,7 @@ import fetchCollectibles from 'src/logic/collectibles/store/actions/fetchCollect import fetchSafeTokens from 'src/logic/tokens/store/actions/fetchSafeTokens' import fetchEtherBalance from 'src/routes/safe/store/actions/fetchEtherBalance' import { checkAndUpdateSafe } from 'src/routes/safe/store/actions/fetchSafe' -import fetchTransactions from 'src/routes/safe/store/actions/fetchTransactions' +import fetchTransactions from 'src/routes/safe/store/actions/transactions/fetchTransactions' import { safeParamAddressFromStateSelector } from 'src/routes/safe/store/selectors' import { TIMEOUT } from 'src/utils/constants' diff --git a/src/routes/safe/store/actions/addCancellationTransactions.ts b/src/routes/safe/store/actions/addCancellationTransactions.ts deleted file mode 100644 index 6d91ef5d..00000000 --- a/src/routes/safe/store/actions/addCancellationTransactions.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { createAction } from 'redux-actions' - -export const ADD_CANCELLATION_TRANSACTIONS = 'ADD_CANCELLATION_TRANSACTIONS' - -export const addCancellationTransactions = createAction(ADD_CANCELLATION_TRANSACTIONS) diff --git a/src/routes/safe/store/actions/addTransactions.ts b/src/routes/safe/store/actions/addTransactions.ts deleted file mode 100644 index 5dc28279..00000000 --- a/src/routes/safe/store/actions/addTransactions.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { createAction } from 'redux-actions' - -export const ADD_TRANSACTIONS = 'ADD_TRANSACTIONS' - -export const addTransactions = createAction(ADD_TRANSACTIONS) diff --git a/src/routes/safe/store/actions/fetchTransactions.ts b/src/routes/safe/store/actions/fetchTransactions.ts deleted file mode 100644 index f7fb37de..00000000 --- a/src/routes/safe/store/actions/fetchTransactions.ts +++ /dev/null @@ -1,348 +0,0 @@ -import ERC20Detailed from '@openzeppelin/contracts/build/contracts/ERC20Detailed.json' -import axios from 'axios' -import bn from 'bignumber.js' -import { List, Map } from 'immutable' -import { batch } from 'react-redux' - -import { addIncomingTransactions } from './addIncomingTransactions' -import { addTransactions } from './addTransactions' - -import generateBatchRequests from 'src/logic/contracts/generateBatchRequests' -import { decodeParamsFromSafeMethod } from 'src/logic/contracts/methodIds' -import { buildIncomingTxServiceUrl } from 'src/logic/safe/transactions/incomingTxHistory' -import { buildTxServiceUrl } from 'src/logic/safe/transactions/txHistory' -import { TOKEN_REDUCER_ID } from 'src/logic/tokens/store/reducer/tokens' -import { ALTERNATIVE_TOKEN_ABI } from 'src/logic/tokens/utils/alternativeAbi' -import { - SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH, - isMultisendTransaction, - isTokenTransfer, - isUpgradeTransaction, -} from 'src/logic/tokens/utils/tokenHelpers' -import { ZERO_ADDRESS, sameAddress } from 'src/logic/wallets/ethAddresses' -import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions' -import { getWeb3 } from 'src/logic/wallets/getWeb3' -import { addCancellationTransactions } from 'src/routes/safe/store/actions/addCancellationTransactions' -import { makeConfirmation } from 'src/routes/safe/store/models/confirmation' -import { makeIncomingTransaction } from 'src/routes/safe/store/models/incomingTransaction' -import { makeTransaction } from 'src/routes/safe/store/models/transaction' - -let web3 - -export const buildTransactionFrom = async ( - safeAddress, - knownTokens, - tx, - txTokenCode, - txTokenDecimals, - txTokenName, - txTokenSymbol, -) => { - const confirmations = List( - tx.confirmations.map((conf) => - makeConfirmation({ - owner: conf.owner, - type: conf.confirmationType.toLowerCase(), - 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 = - (txTokenCode && txTokenCode.includes(SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH)) || - (isTokenTransfer(tx.data, Number(tx.value)) && !knownTokens.get(tx.to) && txTokenDecimals !== null) - let isSendTokenTx = !isERC721Token && isTokenTransfer(tx.data, Number(tx.value)) - const isMultiSendTx = isMultisendTransaction(tx.data, Number(tx.value)) - const isUpgradeTx = isMultiSendTx && isUpgradeTransaction(tx.data) - let customTx = !sameAddress(tx.to, safeAddress) && !!tx.data && !isSendTokenTx && !isUpgradeTx && !isERC721Token - - let refundParams = null - if (tx.gasPrice > 0) { - const refundSymbol = txTokenSymbol || 'ETH' - const decimals = txTokenDecimals || 18 - const feeString = (tx.gasPrice * (tx.baseGas + tx.safeTxGas)).toString().padStart(decimals, '0') - const whole = feeString.slice(0, feeString.length - decimals) || '0' - const fraction = feeString.slice(feeString.length - decimals) - - const formattedFee = `${whole}.${fraction}` - refundParams = { - fee: formattedFee, - symbol: refundSymbol, - } - } - - let symbol = txTokenSymbol || 'ETH' - let decimals = txTokenDecimals || 18 - let decodedParams - if (isSendTokenTx) { - if (txTokenSymbol === null || txTokenDecimals === null) { - try { - const [tokenSymbol, tokenDecimals] = await Promise.all( - generateBatchRequests({ - abi: ALTERNATIVE_TOKEN_ABI, - address: tx.to, - methods: ['symbol', 'decimals'], - }), - ) - - symbol = tokenSymbol - decimals = tokenDecimals - } catch (e) { - // some contracts may implement the same methods as in ERC20 standard - // we may falsely treat them as tokens, so in case we get any errors when getting token info - // we fallback to displaying custom transaction - isSendTokenTx = false - customTx = true - } - } - - const params = web3.eth.abi.decodeParameters(['address', 'uint256'], tx.data.slice(10)) - decodedParams = { - recipient: params[0], - value: params[1], - } - } else if (modifySettingsTx && tx.data) { - decodedParams = decodeParamsFromSafeMethod(tx.data) - } else if (customTx && tx.data) { - decodedParams = decodeParamsFromSafeMethod(tx.data) - } - - return makeTransaction({ - symbol, - nonce: tx.nonce, - blockNumber: tx.blockNumber, - value: tx.value.toString(), - confirmations, - decimals, - recipient: tx.to, - data: tx.data ? tx.data : EMPTY_DATA, - operation: tx.operation, - safeTxGas: tx.safeTxGas, - baseGas: tx.baseGas, - gasPrice: tx.gasPrice, - gasToken: tx.gasToken || ZERO_ADDRESS, - refundReceiver: tx.refundReceiver || ZERO_ADDRESS, - refundParams, - isExecuted: tx.isExecuted, - isSuccessful: tx.isSuccessful, - submissionDate: tx.submissionDate, - executor: tx.executor, - executionDate: tx.executionDate, - executionTxHash: tx.transactionHash, - safeTxHash: tx.safeTxHash, - isTokenTransfer: isSendTokenTx, - multiSendTx: isMultiSendTx, - upgradeTx: isUpgradeTx, - decodedParams, - modifySettingsTx, - customTx, - cancellationTx, - creationTx: tx.creationTx, - origin: tx.origin, - }) -} - -const addMockSafeCreationTx = (safeAddress) => [ - { - blockNumber: null, - baseGas: 0, - confirmations: [], - data: null, - executionDate: null, - gasPrice: 0, - gasToken: '0x0000000000000000000000000000000000000000', - isExecuted: true, - nonce: null, - operation: 0, - refundReceiver: '0x0000000000000000000000000000000000000000', - safe: safeAddress, - safeTxGas: 0, - safeTxHash: '', - signatures: null, - submissionDate: null, - executor: '', - to: '', - transactionHash: null, - value: 0, - creationTx: true, - }, -] - -const batchRequestTxsData = (txs) => { - const web3Batch = new web3.BatchRequest() - - const txsTokenInfo = txs.map((tx) => { - const methods = [{ method: 'getCode', type: 'eth', args: [tx.to] }, 'decimals', 'name', 'symbol'] - return generateBatchRequests({ - abi: ERC20Detailed.abi, - address: tx.to, - batch: web3Batch, - context: tx, - methods, - }) - }) - - web3Batch.execute() - - return Promise.all(txsTokenInfo) -} - -const batchRequestIncomingTxsData = (txs) => { - const web3Batch = new web3.BatchRequest() - - const whenTxsValues = txs.map((tx) => { - const methods = ['symbol', 'decimals', { method: 'getTransaction', args: [tx.transactionHash], type: 'eth' }] - - return generateBatchRequests({ - abi: ALTERNATIVE_TOKEN_ABI, - address: tx.tokenAddress, - batch: web3Batch, - context: tx, - methods, - }) - }) - - web3Batch.execute() - - return Promise.all(whenTxsValues).then((txsValues) => - txsValues.map(([tx, symbol, decimals, { gas, gasPrice }]) => [ - tx, - symbol === null ? 'ETH' : symbol, - decimals === null ? '18' : decimals, - new bn(gas).div(gasPrice).toFixed(), - ]), - ) -} - -export const buildIncomingTransactionFrom = ([tx, symbol, decimals, fee]) => { - // this is a particular treatment for the DCD token, as it seems to lack of symbol and decimal methods - if (tx.tokenAddress && tx.tokenAddress.toLowerCase() === '0xe0b7927c4af23765cb51314a0e0521a9645f0e2a') { - symbol = 'DCD' - decimals = '9' - } - - const { transactionHash, ...incomingTx } = tx - - return makeIncomingTransaction({ - ...incomingTx, - symbol, - decimals, - fee, - executionTxHash: transactionHash, - safeTxHash: transactionHash, - }) -} - -let etagSafeTransactions = null -let etagCachedSafeIncommingTransactions = null -export const loadSafeTransactions = async (safeAddress, getState) => { - let transactions = addMockSafeCreationTx(safeAddress) - - try { - const config = etagSafeTransactions - ? { - headers: { - 'If-None-Match': etagSafeTransactions, - }, - } - : undefined - - const url = buildTxServiceUrl(safeAddress) - const response = await axios.get(url, config) - if (response.data.count > 0) { - if (etagSafeTransactions === response.headers.etag) { - // The txs are the same, we can return the cached ones - return - } - transactions = transactions.concat(response.data.results) - etagSafeTransactions = response.headers.etag - } - } catch (err) { - if (err && err.response && err.response.status === 304) { - // NOTE: this is the expected implementation, currently the backend is not returning 304. - // So I check if the returned etag is the same instead (see above) - return - } else { - console.error(`Requests for outgoing transactions for ${safeAddress} failed with 404`, err) - } - } - - const state = getState() - const knownTokens = state[TOKEN_REDUCER_ID] - const txsWithData = await batchRequestTxsData(transactions) - // In case that the etags don't match, we parse the new transactions and save them to the cache - const txsRecord = await Promise.all( - txsWithData.map(([tx, code, decimals, name, symbol]) => { - const knownToken = knownTokens.get(tx.to) - - if (knownToken) { - ;({ decimals, name, symbol } = knownToken) - } - - return buildTransactionFrom(safeAddress, knownTokens, tx, code, decimals, name, symbol) - }), - ) - - const groupedTxs = List(txsRecord).groupBy((tx) => (tx.get('cancellationTx') ? 'cancel' : 'outgoing')) - - return { - outgoing: Map().set(safeAddress, groupedTxs.get('outgoing')), - cancel: Map().set(safeAddress, groupedTxs.get('cancel')), - } -} - -export const loadSafeIncomingTransactions = async (safeAddress) => { - let incomingTransactions = [] - try { - const config = etagCachedSafeIncommingTransactions - ? { - headers: { - 'If-None-Match': etagCachedSafeIncommingTransactions, - }, - } - : undefined - const url = buildIncomingTxServiceUrl(safeAddress) - const response = await axios.get(url, config) - if (response.data.count > 0) { - incomingTransactions = response.data.results - if (etagCachedSafeIncommingTransactions === response.headers.etag) { - // The txs are the same, we can return the cached ones - return - } - etagCachedSafeIncommingTransactions = response.headers.etag - } - } catch (err) { - if (err && err.response && err.response.status === 304) { - // We return cached transactions - return - } else { - console.error(`Requests for incoming transactions for ${safeAddress} failed with 404`, err) - } - } - - const incomingTxsWithData = await batchRequestIncomingTxsData(incomingTransactions) - const incomingTxsRecord = incomingTxsWithData.map(buildIncomingTransactionFrom) - return Map().set(safeAddress, List(incomingTxsRecord)) -} - -export default (safeAddress) => async (dispatch, getState) => { - web3 = await getWeb3() - - const transactions = await loadSafeTransactions(safeAddress, getState) - if (transactions) { - const { cancel, outgoing } = transactions - - batch(() => { - dispatch(addCancellationTransactions(cancel)) - dispatch(addTransactions(outgoing)) - }) - } - - const incomingTransactions = await loadSafeIncomingTransactions(safeAddress) - - if (incomingTransactions) { - dispatch(addIncomingTransactions(incomingTransactions)) - } -} diff --git a/src/test/builder/safe.dom.utils.tsx b/src/test/builder/safe.dom.utils.tsx index 276f69db..f90b72f5 100644 --- a/src/test/builder/safe.dom.utils.tsx +++ b/src/test/builder/safe.dom.utils.tsx @@ -5,7 +5,7 @@ import { render } from '@testing-library/react' import { ConnectedRouter } from 'connected-react-router' import PageFrame from 'src/components/layout/PageFrame' import ListItemText from 'src/components/List/ListItemText/index' -import fetchTransactions from 'src/routes/safe/store/actions/fetchTransactions' +// import fetchTransactions from 'src/routes/safe/store/actions/transactions/fetchTransactions' import { sleep } from 'src/utils/timer' import { history, } from 'src/store' import AppRoutes from 'src/routes' @@ -13,13 +13,13 @@ import { SAFELIST_ADDRESS } from 'src/routes/routes' import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions' import { wrapInSuspense } from 'src/utils/wrapInSuspense' -export const EXPAND_BALANCE_INDEX = 0 -export const EXPAND_OWNERS_INDEX = 1 -export const ADD_OWNERS_INDEX = 2 -export const EDIT_THRESHOLD_INDEX = 3 -export const EDIT_INDEX = 4 -export const WITHDRAW_INDEX = 5 -export const LIST_TXS_INDEX = 6 +// export const EXPAND_BALANCE_INDEX = 0 +// export const EXPAND_OWNERS_INDEX = 1 +// export const ADD_OWNERS_INDEX = 2 +// export const EDIT_THRESHOLD_INDEX = 3 +// export const EDIT_INDEX = 4 +// export const WITHDRAW_INDEX = 5 +// export const LIST_TXS_INDEX = 6 export const checkMinedTx = (Transaction, name) => { const paragraphs = TestUtils.scryRenderedDOMComponentsWithTag(Transaction, 'p') @@ -78,10 +78,10 @@ export const checkPendingTx = async ( } } -export const refreshTransactions = async (store, safeAddress) => { - await store.dispatch(fetchTransactions(safeAddress)) - await sleep(1500) -} +// export const refreshTransactions = async (store, safeAddress) => { +// await store.dispatch(fetchTransactions(safeAddress)) +// await sleep(1500) +// } const renderApp = (store) => ({ ...render(