From bc4854d644d3249d90bf2410edb95f2003fd6e27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Mart=C3=ADnez?= Date: Wed, 11 Sep 2019 15:24:08 +0200 Subject: [PATCH 01/12] Remove unused params --- .../Settings/ManageOwners/ReplaceOwnerModal/index.jsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/index.jsx b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/index.jsx index 27705bf2..02b9037e 100644 --- a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/index.jsx +++ b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/index.jsx @@ -36,8 +36,6 @@ export const sendReplaceOwner = async ( values: Object, safeAddress: string, ownerAddressToRemove: string, - ownerNameToRemove: string, - ownersOld: List, openSnackbar: Function, createTransaction: Function, replaceSafeOwner: Function, @@ -109,8 +107,6 @@ const ReplaceOwner = ({ values, safeAddress, ownerAddress, - ownerName, - owners, openSnackbar, createTransaction, replaceSafeOwner, From 39111829cb89a4736da1df74a45e0522963742c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Mart=C3=ADnez?= Date: Thu, 19 Sep 2019 18:37:29 +0200 Subject: [PATCH 02/12] Update isTokenTransfer --- src/logic/tokens/utils/tokenHelpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/logic/tokens/utils/tokenHelpers.js b/src/logic/tokens/utils/tokenHelpers.js index 1fac59f9..7723664a 100644 --- a/src/logic/tokens/utils/tokenHelpers.js +++ b/src/logic/tokens/utils/tokenHelpers.js @@ -49,4 +49,4 @@ export const isAddressAToken = async (tokenAddress: string) => { return call !== '0x' } -export const isTokenTransfer = async (data: string, value: number) => data.substring(0, 10) === '0xa9059cbb' && value === 0 +export const isTokenTransfer = async (data: string, value: number) => data && data.substring(0, 10) === '0xa9059cbb' && value === 0 From c9791bc1a678de3e3d34487a8ea803b383e5f1f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Mart=C3=ADnez?= Date: Thu, 19 Sep 2019 18:55:12 +0200 Subject: [PATCH 03/12] Fix error when a transaction is manually rejected in MM popup --- src/routes/safe/store/actions/createTransaction.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/safe/store/actions/createTransaction.js b/src/routes/safe/store/actions/createTransaction.js index 4d9359c5..7f60f96e 100644 --- a/src/routes/safe/store/actions/createTransaction.js +++ b/src/routes/safe/store/actions/createTransaction.js @@ -42,7 +42,7 @@ const createTransaction = ( openSnackbar(notifications.CREATED_MORE_CONFIRMATIONS_NEEDED, 'success') } } catch (err) { - openSnackbar(notifications.ERROR, '') + openSnackbar(notifications.ERROR, 'error') console.error(`Error while creating transaction: ${err}`) } From 838fa20cd104e61378c51edf0da9f25f442d20e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Mart=C3=ADnez?= Date: Thu, 19 Sep 2019 20:00:52 +0200 Subject: [PATCH 04/12] Refactor executeTransaction to show notification after confirmation --- src/logic/safe/transactions/send.js | 56 ++++++++++--------- .../safe/store/actions/createTransaction.js | 4 +- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/src/logic/safe/transactions/send.js b/src/logic/safe/transactions/send.js index 0381a7f5..8e560350 100644 --- a/src/logic/safe/transactions/send.js +++ b/src/logic/safe/transactions/send.js @@ -1,4 +1,5 @@ // @flow +import GnosisSafeSol from '@gnosis.pm/safe-contracts/build/contracts/GnosisSafe.json' import { getWeb3 } from '~/logic/wallets/getWeb3' import { getStandardTokenContract } from '~/logic/tokens/store/actions/fetchTokens' import { EMPTY_DATA } from '~/logic/wallets/ethTransactions' @@ -55,6 +56,7 @@ export const approveTransaction = async ( } export const executeTransaction = async ( + showNotification: Function, safeInstance: any, to: string, valueInWei: number | string, @@ -75,33 +77,37 @@ export const executeTransaction = async ( } try { - const receipt = await safeInstance.execTransaction( - to, - valueInWei, - data, - operation, - 0, - 0, - 0, - ZERO_ADDRESS, - ZERO_ADDRESS, - sigs, - { from: sender }, - ) + const web3 = getWeb3() + const contract = new web3.eth.Contract(GnosisSafeSol.abi, safeInstance.address) - await saveTxToHistory( - safeInstance, - to, - valueInWei, - data, - operation, - nonce, - receipt.tx, // tx hash, - sender, - TX_TYPE_EXECUTION, - ) + const transactionHash = await contract.methods + .execTransaction(to, valueInWei, data, operation, 0, 0, 0, ZERO_ADDRESS, ZERO_ADDRESS, sigs) + .send({ + from: sender, + }) + .once('transactionHash', (transactionHash) => { + showNotification() + }) + .on('error', (error) => { + console.log('Tx error:', error) + }) + .then(async (receipt) => { + await saveTxToHistory( + safeInstance, + to, + valueInWei, + data, + operation, + nonce, + receipt.transactionHash, + sender, + TX_TYPE_EXECUTION, + ) - return receipt + return receipt.transactionHash + }) + + return transactionHash } catch (error) { /* eslint-disable */ const executeDataUsedSignatures = safeInstance.contract.methods diff --git a/src/routes/safe/store/actions/createTransaction.js b/src/routes/safe/store/actions/createTransaction.js index 7f60f96e..c60a3e05 100644 --- a/src/routes/safe/store/actions/createTransaction.js +++ b/src/routes/safe/store/actions/createTransaction.js @@ -33,8 +33,8 @@ const createTransaction = ( let txHash try { if (isExecution) { - openSnackbar(notifications.BEFORE_EXECUTION_OR_CREATION, 'success') - txHash = await executeTransaction(safeInstance, to, valueInWei, txData, CALL, nonce, from) + const showNotification = () => openSnackbar(notifications.BEFORE_EXECUTION_OR_CREATION, 'success') + txHash = await executeTransaction(showNotification, safeInstance, to, valueInWei, txData, CALL, nonce, from) openSnackbar(notifications.AFTER_EXECUTION, 'success') } else { openSnackbar(notifications.BEFORE_EXECUTION_OR_CREATION, 'success') From 110ba591a4a09a6c98049cde800014e7bad43a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Mart=C3=ADnez?= Date: Thu, 19 Sep 2019 20:16:25 +0200 Subject: [PATCH 05/12] Refactor approveTransaction to show notification after confirmation --- src/logic/safe/transactions/send.js | 55 ++++++++++++++----- .../safe/store/actions/createTransaction.js | 4 +- .../safe/store/actions/processTransaction.js | 27 +++++++-- 3 files changed, 65 insertions(+), 21 deletions(-) diff --git a/src/logic/safe/transactions/send.js b/src/logic/safe/transactions/send.js index 8e560350..128f63f8 100644 --- a/src/logic/safe/transactions/send.js +++ b/src/logic/safe/transactions/send.js @@ -15,6 +15,7 @@ export const TX_TYPE_EXECUTION = 'execution' export const TX_TYPE_CONFIRMATION = 'confirmation' export const approveTransaction = async ( + showNotification: Function, safeInstance: any, to: string, valueInWei: number | string, @@ -23,7 +24,7 @@ export const approveTransaction = async ( nonce: number, sender: string, ) => { - const contractTxHash = await safeInstance.getTransactionHash( + const txHash = await safeInstance.getTransactionHash( to, valueInWei, data, @@ -38,21 +39,45 @@ export const approveTransaction = async ( from: sender, }, ) - const receipt = await safeInstance.approveHash(contractTxHash, { from: sender }) - await saveTxToHistory( - safeInstance, - to, - valueInWei, - data, - operation, - nonce, - receipt.tx, // tx hash, - sender, - TX_TYPE_CONFIRMATION, - ) + try { + const web3 = getWeb3() + const contract = new web3.eth.Contract(GnosisSafeSol.abi, safeInstance.address) - return receipt + const transactionHash = await contract.methods.approveHash(txHash) + .send({ + from: sender, + }).once('transactionHash', () => { + showNotification() + }) + .on('error', (error) => { + console.log('Tx error:', error) + }) + .then(async (receipt) => { + await saveTxToHistory( + safeInstance, + to, + valueInWei, + data, + operation, + nonce, + receipt.transactionHash, + sender, + TX_TYPE_CONFIRMATION, + ) + + return receipt.transactionHash + }) + + return transactionHash + } catch (error) { + /* eslint-disable */ + const executeData = safeInstance.contract.methods.approveHash(txHash).encodeABI() + const errMsg = await getErrorMessage(safeInstance.address, 0, executeData, sender) + console.log(`Error executing the TX: ${errMsg}`) + + throw error + } } export const executeTransaction = async ( @@ -85,7 +110,7 @@ export const executeTransaction = async ( .send({ from: sender, }) - .once('transactionHash', (transactionHash) => { + .once('transactionHash', () => { showNotification() }) .on('error', (error) => { diff --git a/src/routes/safe/store/actions/createTransaction.js b/src/routes/safe/store/actions/createTransaction.js index c60a3e05..ad14b901 100644 --- a/src/routes/safe/store/actions/createTransaction.js +++ b/src/routes/safe/store/actions/createTransaction.js @@ -37,8 +37,8 @@ const createTransaction = ( txHash = await executeTransaction(showNotification, safeInstance, to, valueInWei, txData, CALL, nonce, from) openSnackbar(notifications.AFTER_EXECUTION, 'success') } else { - openSnackbar(notifications.BEFORE_EXECUTION_OR_CREATION, 'success') - txHash = await approveTransaction(safeInstance, to, valueInWei, txData, CALL, nonce, from) + const showNotification = () => openSnackbar(notifications.BEFORE_EXECUTION_OR_CREATION, 'success') + txHash = await approveTransaction(showNotification, safeInstance, to, valueInWei, txData, CALL, nonce, from) openSnackbar(notifications.CREATED_MORE_CONFIRMATIONS_NEEDED, 'success') } } catch (err) { diff --git a/src/routes/safe/store/actions/processTransaction.js b/src/routes/safe/store/actions/processTransaction.js index c30fd27c..1a077488 100644 --- a/src/routes/safe/store/actions/processTransaction.js +++ b/src/routes/safe/store/actions/processTransaction.js @@ -46,12 +46,31 @@ const processTransaction = ( let txHash if (shouldExecute) { - openSnackbar('Transaction has been submitted', 'success') - txHash = await executeTransaction(safeInstance, tx.recipient, tx.value, tx.data, CALL, nonce, from, sigs) + const showNotification = () => openSnackbar('Transaction has been submitted', 'success') + txHash = await executeTransaction( + showNotification, + safeInstance, + tx.recipient, + tx.value, + tx.data, + CALL, + nonce, + from, + sigs, + ) openSnackbar('Transaction has been confirmed', 'success') } else { - openSnackbar('Approval transaction has been submitted', 'success') - txHash = await approveTransaction(safeInstance, tx.recipient, tx.value, tx.data, CALL, nonce, from) + const showNotification = () => openSnackbar('Approval transaction has been submitted', 'success') + txHash = await approveTransaction( + showNotification, + safeInstance, + tx.recipient, + tx.value, + tx.data, + CALL, + nonce, + from, + ) openSnackbar('Approval transaction has been confirmed', 'success') } From 10fc44d3d929659037c9230fc964f6e2ca44d20b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Mart=C3=ADnez?= Date: Thu, 19 Sep 2019 20:18:06 +0200 Subject: [PATCH 06/12] Display value in custom transactions detail in transaction list --- .../ExpandedTx/TxDescription/index.jsx | 26 ++++++++++++++++--- .../ExpandedTx/TxDescription/utils.js | 8 +++--- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/index.jsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/index.jsx index b4123640..70fbfe14 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/index.jsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/index.jsx @@ -13,7 +13,8 @@ export const TRANSACTIONS_DESC_ADD_OWNER_TEST_ID = 'tx-description-add-owner' export const TRANSACTIONS_DESC_REMOVE_OWNER_TEST_ID = 'tx-description-remove-owner' export const TRANSACTIONS_DESC_CHANGE_THRESHOLD_TEST_ID = 'tx-description-change-threshold' export const TRANSACTIONS_DESC_SEND_TEST_ID = 'tx-description-send' -export const TRANSACTIONS_DESC_CUSTOM_TEST_ID = 'tx-description-custom' +export const TRANSACTIONS_DESC_CUSTOM_VALUE_TEST_ID = 'tx-description-custom-value' +export const TRANSACTIONS_DESC_CUSTOM_DATA_TEST_ID = 'tx-description-custom-data' export const styles = () => ({ txDataContainer: { @@ -42,6 +43,8 @@ type DescriptionDescProps = { } type CustomDescProps = { + value: string, + recipient: string, data: String, classes: Obeject, } @@ -88,9 +91,24 @@ const SettingsDescription = ({ removedOwner, addedOwner, newThreshold }: Descrip ) -const CustomDescription = ({ data, classes }: CustomDescProps) => ( +const CustomDescription = ({ + data, value = 0, recipient, classes, +}: CustomDescProps) => ( <> - + + + Send + {' '} + {value} + {' '} + ETH + {' '} + to: + +
+ +
+ Data (hex encoded):
{data} @@ -109,7 +127,7 @@ const TxDescription = ({ tx, classes }: Props) => { )} {customTx && ( - + )} {!cancellationTx && !modifySettingsTx && !customTx && ( diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/utils.js b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/utils.js index affddad6..a55c986a 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/utils.js +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/utils.js @@ -23,6 +23,11 @@ export const getTxData = (tx: Transaction): DecodedTxData => { if (tx.isTokenTransfer && tx.decodedParams) { txData.recipient = tx.decodedParams.recipient txData.value = fromWei(toBN(tx.decodedParams.value), 'ether') + } 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') @@ -49,9 +54,6 @@ export const getTxData = (tx: Transaction): DecodedTxData => { } } else if (tx.cancellationTx) { txData.cancellationTx = true - } else if (tx.customTx) { - txData.data = tx.data - txData.customTx = true } return txData From b5784d8e7ec78f2fc0fb51990f2caf2f8ea9c880 Mon Sep 17 00:00:00 2001 From: mmv Date: Wed, 25 Sep 2019 19:28:18 +0400 Subject: [PATCH 07/12] refactor transactions logic functions and actions so the logic for sending notifications/posting to service is contained in actions only --- src/logic/safe/transactions/send.js | 64 ++------------- .../safe/store/actions/createTransaction.js | 75 +++++++++++++++-- .../safe/store/actions/processTransaction.js | 81 +++++++++++++++---- 3 files changed, 141 insertions(+), 79 deletions(-) diff --git a/src/logic/safe/transactions/send.js b/src/logic/safe/transactions/send.js index 128f63f8..c98bdf94 100644 --- a/src/logic/safe/transactions/send.js +++ b/src/logic/safe/transactions/send.js @@ -6,7 +6,7 @@ import { EMPTY_DATA } from '~/logic/wallets/ethTransactions' import { isEther } from '~/logic/tokens/utils/tokenHelpers' import { type Token } from '~/logic/tokens/store/model/token' import { getGnosisSafeInstanceAt } from '~/logic/contracts/safeContracts' -import { type Operation, saveTxToHistory } from '~/logic/safe/transactions' +import { type Operation } from '~/logic/safe/transactions' import { ZERO_ADDRESS } from '~/logic/wallets/ethAddresses' import { getErrorMessage } from '~/test/utils/ethereumErrors' @@ -14,8 +14,7 @@ export const CALL = 0 export const TX_TYPE_EXECUTION = 'execution' export const TX_TYPE_CONFIRMATION = 'confirmation' -export const approveTransaction = async ( - showNotification: Function, +export const getApprovalTransaction = async ( safeInstance: any, to: string, valueInWei: number | string, @@ -44,32 +43,7 @@ export const approveTransaction = async ( const web3 = getWeb3() const contract = new web3.eth.Contract(GnosisSafeSol.abi, safeInstance.address) - const transactionHash = await contract.methods.approveHash(txHash) - .send({ - from: sender, - }).once('transactionHash', () => { - showNotification() - }) - .on('error', (error) => { - console.log('Tx error:', error) - }) - .then(async (receipt) => { - await saveTxToHistory( - safeInstance, - to, - valueInWei, - data, - operation, - nonce, - receipt.transactionHash, - sender, - TX_TYPE_CONFIRMATION, - ) - - return receipt.transactionHash - }) - - return transactionHash + return contract.methods.approveHash(txHash) } catch (error) { /* eslint-disable */ const executeData = safeInstance.contract.methods.approveHash(txHash).encodeABI() @@ -80,8 +54,7 @@ export const approveTransaction = async ( } } -export const executeTransaction = async ( - showNotification: Function, +export const getExecutionTransaction = async ( safeInstance: any, to: string, valueInWei: number | string, @@ -105,34 +78,7 @@ export const executeTransaction = async ( const web3 = getWeb3() const contract = new web3.eth.Contract(GnosisSafeSol.abi, safeInstance.address) - const transactionHash = await contract.methods - .execTransaction(to, valueInWei, data, operation, 0, 0, 0, ZERO_ADDRESS, ZERO_ADDRESS, sigs) - .send({ - from: sender, - }) - .once('transactionHash', () => { - showNotification() - }) - .on('error', (error) => { - console.log('Tx error:', error) - }) - .then(async (receipt) => { - await saveTxToHistory( - safeInstance, - to, - valueInWei, - data, - operation, - nonce, - receipt.transactionHash, - sender, - TX_TYPE_EXECUTION, - ) - - return receipt.transactionHash - }) - - return transactionHash + return contract.methods.execTransaction(to, valueInWei, data, operation, 0, 0, 0, ZERO_ADDRESS, ZERO_ADDRESS, sigs) } catch (error) { /* eslint-disable */ const executeDataUsedSignatures = safeInstance.contract.methods diff --git a/src/routes/safe/store/actions/createTransaction.js b/src/routes/safe/store/actions/createTransaction.js index ad14b901..5505b313 100644 --- a/src/routes/safe/store/actions/createTransaction.js +++ b/src/routes/safe/store/actions/createTransaction.js @@ -6,11 +6,14 @@ import fetchTransactions from '~/routes/safe/store/actions/fetchTransactions' import { type GlobalState } from '~/store' import { getGnosisSafeInstanceAt } from '~/logic/contracts/safeContracts' import { - approveTransaction, - executeTransaction, + getApprovalTransaction, + getExecutionTransaction, CALL, type Notifications, DEFAULT_NOTIFICATIONS, + TX_TYPE_CONFIRMATION, + TX_TYPE_EXECUTION, + saveTxToHistory, } from '~/logic/safe/transactions' const createTransaction = ( @@ -34,11 +37,73 @@ const createTransaction = ( try { if (isExecution) { const showNotification = () => openSnackbar(notifications.BEFORE_EXECUTION_OR_CREATION, 'success') - txHash = await executeTransaction(showNotification, safeInstance, to, valueInWei, txData, CALL, nonce, from) + const tx = await getExecutionTransaction( + showNotification, + safeInstance, + to, + valueInWei, + txData, + CALL, + nonce, + from, + ) + + await tx + .send({ + from, + }) + .once('transactionHash', (hash: string) => { + txHash = hash + openSnackbar(notifications.BEFORE_EXECUTION_OR_CREATION, 'success') + }) + .on('error', (error) => { + console.error('Tx error: ', error) + }) + .then(async (receipt) => { + await saveTxToHistory( + safeInstance, + to, + valueInWei, + txData, + CALL, + nonce, + receipt.transactionHash, + from, + TX_TYPE_EXECUTION, + ) + + return receipt.transactionHash + }) openSnackbar(notifications.AFTER_EXECUTION, 'success') } else { - const showNotification = () => openSnackbar(notifications.BEFORE_EXECUTION_OR_CREATION, 'success') - txHash = await approveTransaction(showNotification, safeInstance, to, valueInWei, txData, CALL, nonce, from) + const tx = await getApprovalTransaction(safeInstance, to, valueInWei, txData, CALL, nonce, from) + + await tx.send({ + from, + }) + .once('transactionHash', (hash) => { + txHash = hash + openSnackbar(notifications.BEFORE_EXECUTION_OR_CREATION, 'success') + }) + .on('error', (error) => { + console.error('Tx error: ', error) + }) + .then(async (receipt) => { + await saveTxToHistory( + safeInstance, + to, + valueInWei, + txData, + CALL, + nonce, + receipt.transactionHash, + from, + TX_TYPE_CONFIRMATION, + ) + + return receipt.transactionHash + }) + openSnackbar(notifications.CREATED_MORE_CONFIRMATIONS_NEEDED, 'success') } } catch (err) { diff --git a/src/routes/safe/store/actions/processTransaction.js b/src/routes/safe/store/actions/processTransaction.js index 1a077488..d650722b 100644 --- a/src/routes/safe/store/actions/processTransaction.js +++ b/src/routes/safe/store/actions/processTransaction.js @@ -5,7 +5,14 @@ import { userAccountSelector } from '~/logic/wallets/store/selectors' import fetchTransactions from '~/routes/safe/store/actions/fetchTransactions' import { type GlobalState } from '~/store' import { getGnosisSafeInstanceAt } from '~/logic/contracts/safeContracts' -import { approveTransaction, executeTransaction, CALL } from '~/logic/safe/transactions' +import { + getApprovalTransaction, + getExecutionTransaction, + CALL, + saveTxToHistory, + TX_TYPE_EXECUTION, + TX_TYPE_CONFIRMATION, +} from '~/logic/safe/transactions' // https://gnosis-safe.readthedocs.io/en/latest/contracts/signatures.html#pre-validated-signatures // https://github.com/gnosis/safe-contracts/blob/master/test/gnosisSafeTeamEdition.js#L26 @@ -46,9 +53,7 @@ const processTransaction = ( let txHash if (shouldExecute) { - const showNotification = () => openSnackbar('Transaction has been submitted', 'success') - txHash = await executeTransaction( - showNotification, + const transaction = await getExecutionTransaction( safeInstance, tx.recipient, tx.value, @@ -58,19 +63,65 @@ const processTransaction = ( from, sigs, ) + + await transaction + .send({ + from, + }) + .once('transactionHash', (hash: string) => { + txHash = hash + openSnackbar('Transaction has been submitted', 'success') + }) + .on('error', (error) => { + console.error('Tx error: ', error) + }) + .then(async (receipt) => { + await saveTxToHistory( + safeInstance, + tx.recipient, + tx.value, + tx.data, + CALL, + nonce, + receipt.transactionHash, + from, + TX_TYPE_EXECUTION, + ) + + return receipt.transactionHash + }) + openSnackbar('Transaction has been confirmed', 'success') } else { - const showNotification = () => openSnackbar('Approval transaction has been submitted', 'success') - txHash = await approveTransaction( - showNotification, - safeInstance, - tx.recipient, - tx.value, - tx.data, - CALL, - nonce, - from, - ) + const transaction = await getApprovalTransaction(safeInstance, tx.recipient, tx.value, tx.data, CALL, nonce, from) + + await transaction + .send({ + from, + }) + .once('transactionHash', (hash) => { + txHash = hash + openSnackbar('Approval transaction has been submitted', 'success') + }) + .on('error', (error) => { + console.error('Tx error: ', error) + }) + .then(async (receipt) => { + await saveTxToHistory( + safeInstance, + tx.recipient, + tx.value, + tx.data, + CALL, + nonce, + receipt.transactionHash, + from, + TX_TYPE_CONFIRMATION, + ) + + return receipt.transactionHash + }) + openSnackbar('Approval transaction has been confirmed', 'success') } From b2ff828792814fea2f3b05adcc6cc017cd992f16 Mon Sep 17 00:00:00 2001 From: mmv Date: Wed, 25 Sep 2019 19:31:14 +0400 Subject: [PATCH 08/12] remove showNotification from createTransaction action --- src/routes/safe/store/actions/createTransaction.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/routes/safe/store/actions/createTransaction.js b/src/routes/safe/store/actions/createTransaction.js index 5505b313..58ddbe67 100644 --- a/src/routes/safe/store/actions/createTransaction.js +++ b/src/routes/safe/store/actions/createTransaction.js @@ -36,9 +36,7 @@ const createTransaction = ( let txHash try { if (isExecution) { - const showNotification = () => openSnackbar(notifications.BEFORE_EXECUTION_OR_CREATION, 'success') const tx = await getExecutionTransaction( - showNotification, safeInstance, to, valueInWei, From 6702056709300fe9c21d963585bb2d37652f4ef0 Mon Sep 17 00:00:00 2001 From: mmv Date: Thu, 26 Sep 2019 15:41:36 +0400 Subject: [PATCH 09/12] Refactor createTransaction action, reuse the events code for both execution and confirmation txs' --- .../safe/store/actions/createTransaction.js | 93 +++++++------------ 1 file changed, 31 insertions(+), 62 deletions(-) diff --git a/src/routes/safe/store/actions/createTransaction.js b/src/routes/safe/store/actions/createTransaction.js index 58ddbe67..a1fe34ca 100644 --- a/src/routes/safe/store/actions/createTransaction.js +++ b/src/routes/safe/store/actions/createTransaction.js @@ -34,76 +34,45 @@ const createTransaction = ( const isExecution = threshold.toNumber() === 1 || shouldExecute let txHash + let tx try { if (isExecution) { - const tx = await getExecutionTransaction( - safeInstance, - to, - valueInWei, - txData, - CALL, - nonce, - from, - ) - - await tx - .send({ - from, - }) - .once('transactionHash', (hash: string) => { - txHash = hash - openSnackbar(notifications.BEFORE_EXECUTION_OR_CREATION, 'success') - }) - .on('error', (error) => { - console.error('Tx error: ', error) - }) - .then(async (receipt) => { - await saveTxToHistory( - safeInstance, - to, - valueInWei, - txData, - CALL, - nonce, - receipt.transactionHash, - from, - TX_TYPE_EXECUTION, - ) - - return receipt.transactionHash - }) - openSnackbar(notifications.AFTER_EXECUTION, 'success') + tx = await getExecutionTransaction(safeInstance, to, valueInWei, txData, CALL, nonce, from) } else { - const tx = await getApprovalTransaction(safeInstance, to, valueInWei, txData, CALL, nonce, from) + tx = await getApprovalTransaction(safeInstance, to, valueInWei, txData, CALL, nonce, from) + } - await tx.send({ + await tx + .send({ from, }) - .once('transactionHash', (hash) => { - txHash = hash - openSnackbar(notifications.BEFORE_EXECUTION_OR_CREATION, 'success') - }) - .on('error', (error) => { - console.error('Tx error: ', error) - }) - .then(async (receipt) => { - await saveTxToHistory( - safeInstance, - to, - valueInWei, - txData, - CALL, - nonce, - receipt.transactionHash, - from, - TX_TYPE_CONFIRMATION, - ) + .once('transactionHash', (hash) => { + txHash = hash + openSnackbar(notifications.BEFORE_EXECUTION_OR_CREATION, 'success') + }) + .on('error', (error) => { + console.error('Tx error: ', error) + }) + .then(async (receipt) => { + await saveTxToHistory( + safeInstance, + to, + valueInWei, + txData, + CALL, + nonce, + receipt.transactionHash, + from, + isExecution ? TX_TYPE_EXECUTION : TX_TYPE_CONFIRMATION, + ) - return receipt.transactionHash - }) + return receipt.transactionHash + }) - openSnackbar(notifications.CREATED_MORE_CONFIRMATIONS_NEEDED, 'success') - } + openSnackbar( + isExecution ? notifications.AFTER_EXECUTION : notifications.CREATED_MORE_CONFIRMATIONS_NEEDED, + 'success', + ) } catch (err) { openSnackbar(notifications.ERROR, 'error') console.error(`Error while creating transaction: ${err}`) From 4dad9ce19734936209bf66b425544e354315d8ba Mon Sep 17 00:00:00 2001 From: mmv Date: Thu, 26 Sep 2019 16:30:20 +0400 Subject: [PATCH 10/12] refactor processTransaction like createTrasnaction, so we reuse code for executing/approval txs --- .../safe/store/actions/processTransaction.js | 104 ++++++------------ 1 file changed, 35 insertions(+), 69 deletions(-) diff --git a/src/routes/safe/store/actions/processTransaction.js b/src/routes/safe/store/actions/processTransaction.js index d650722b..5f4f3d99 100644 --- a/src/routes/safe/store/actions/processTransaction.js +++ b/src/routes/safe/store/actions/processTransaction.js @@ -52,79 +52,45 @@ const processTransaction = ( const sigs = generateSignaturesFromTxConfirmations(tx, approveAndExecute && userAddress) let txHash + let transaction if (shouldExecute) { - const transaction = await getExecutionTransaction( - safeInstance, - tx.recipient, - tx.value, - tx.data, - CALL, - nonce, - from, - sigs, - ) - - await transaction - .send({ - from, - }) - .once('transactionHash', (hash: string) => { - txHash = hash - openSnackbar('Transaction has been submitted', 'success') - }) - .on('error', (error) => { - console.error('Tx error: ', error) - }) - .then(async (receipt) => { - await saveTxToHistory( - safeInstance, - tx.recipient, - tx.value, - tx.data, - CALL, - nonce, - receipt.transactionHash, - from, - TX_TYPE_EXECUTION, - ) - - return receipt.transactionHash - }) - - openSnackbar('Transaction has been confirmed', 'success') + transaction = await getExecutionTransaction(safeInstance, tx.recipient, tx.value, tx.data, CALL, nonce, from, sigs) } else { - const transaction = await getApprovalTransaction(safeInstance, tx.recipient, tx.value, tx.data, CALL, nonce, from) - - await transaction - .send({ - from, - }) - .once('transactionHash', (hash) => { - txHash = hash - openSnackbar('Approval transaction has been submitted', 'success') - }) - .on('error', (error) => { - console.error('Tx error: ', error) - }) - .then(async (receipt) => { - await saveTxToHistory( - safeInstance, - tx.recipient, - tx.value, - tx.data, - CALL, - nonce, - receipt.transactionHash, - from, - TX_TYPE_CONFIRMATION, - ) - - return receipt.transactionHash - }) - - openSnackbar('Approval transaction has been confirmed', 'success') + transaction = await getApprovalTransaction(safeInstance, tx.recipient, tx.value, tx.data, CALL, nonce, from) } + await transaction + .send({ + from, + }) + .once('transactionHash', (hash) => { + txHash = hash + openSnackbar( + shouldExecute ? 'Transaction has been submitted' : 'Approval transaction has been submitted', + 'success', + ) + }) + .on('error', (error) => { + console.error('Processing transaction error: ', error) + }) + .then(async (receipt) => { + await saveTxToHistory( + safeInstance, + tx.recipient, + tx.value, + tx.data, + CALL, + nonce, + receipt.transactionHash, + from, + shouldExecute ? TX_TYPE_EXECUTION : TX_TYPE_CONFIRMATION, + ) + + return receipt.transactionHash + }) + + openSnackbar(shouldExecute ? 'Transaction has been confirmed' : 'Approval transaction has been confirmed', 'success') + dispatch(fetchTransactions(safeAddress)) return txHash From ade301026069b80a5aaccd07945518d37fc0ae78 Mon Sep 17 00:00:00 2001 From: mmv Date: Thu, 26 Sep 2019 16:51:58 +0400 Subject: [PATCH 11/12] Increase gas limit for txs in test environment --- src/routes/safe/store/actions/createTransaction.js | 13 ++++++++++--- src/routes/safe/store/actions/processTransaction.js | 13 ++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/routes/safe/store/actions/createTransaction.js b/src/routes/safe/store/actions/createTransaction.js index a1fe34ca..852df77c 100644 --- a/src/routes/safe/store/actions/createTransaction.js +++ b/src/routes/safe/store/actions/createTransaction.js @@ -41,11 +41,18 @@ const createTransaction = ( } else { tx = await getApprovalTransaction(safeInstance, to, valueInWei, txData, CALL, nonce, from) } + + const sendParams = { + from, + } + + // if not set owner management tests will fail on ganache + if (process.env.NODE_ENV === 'test') { + sendParams.gas = '7000000' + } await tx - .send({ - from, - }) + .send(sendParams) .once('transactionHash', (hash) => { txHash = hash openSnackbar(notifications.BEFORE_EXECUTION_OR_CREATION, 'success') diff --git a/src/routes/safe/store/actions/processTransaction.js b/src/routes/safe/store/actions/processTransaction.js index 5f4f3d99..010d62ef 100644 --- a/src/routes/safe/store/actions/processTransaction.js +++ b/src/routes/safe/store/actions/processTransaction.js @@ -59,10 +59,17 @@ const processTransaction = ( transaction = await getApprovalTransaction(safeInstance, tx.recipient, tx.value, tx.data, CALL, nonce, from) } + const sendParams = { + from, + } + + // if not set owner management tests will fail on ganache + if (process.env.NODE_ENV === 'test') { + sendParams.gas = '7000000' + } + await transaction - .send({ - from, - }) + .send(sendParams) .once('transactionHash', (hash) => { txHash = hash openSnackbar( From 4decf9a32390aa1db2b1697084b8ae7e1054881e Mon Sep 17 00:00:00 2001 From: mmv Date: Thu, 26 Sep 2019 16:59:14 +0400 Subject: [PATCH 12/12] Eslint fix --- src/routes/safe/store/actions/createTransaction.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/safe/store/actions/createTransaction.js b/src/routes/safe/store/actions/createTransaction.js index 852df77c..9f9f573a 100644 --- a/src/routes/safe/store/actions/createTransaction.js +++ b/src/routes/safe/store/actions/createTransaction.js @@ -41,7 +41,7 @@ const createTransaction = ( } else { tx = await getApprovalTransaction(safeInstance, to, valueInWei, txData, CALL, nonce, from) } - + const sendParams = { from, }