refactor createTRansaction method to accept safe settings txs

This commit is contained in:
mmv 2019-06-18 15:55:53 +04:00
parent 4b31e6130e
commit 8ec1d6f528
5 changed files with 108 additions and 104 deletions

View File

@ -12,7 +12,7 @@ const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
export const executeTransaction = async ( export const executeTransaction = async (
safeInstance: any, safeInstance: any,
to: string, to: string,
valueInWei: number, valueInWei: number | string,
data: string, data: string,
operation: number | string, operation: number | string,
nonce: string | number, nonce: string | number,

View File

@ -17,8 +17,12 @@ import { copyToClipboard } from '~/utils/clipboard'
import Hairline from '~/components/layout/Hairline' import Hairline from '~/components/layout/Hairline'
import SafeInfo from '~/routes/safe/components/Balances/SendModal/SafeInfo' import SafeInfo from '~/routes/safe/components/Balances/SendModal/SafeInfo'
import { setImageToPlaceholder } from '~/routes/safe/components/Balances/utils' import { setImageToPlaceholder } from '~/routes/safe/components/Balances/utils'
import { getStandardTokenContract } from '~/logic/tokens/store/actions/fetchTokens'
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
import { getWeb3 } from '~/logic/wallets/getWeb3'
import ArrowDown from '../assets/arrow-down.svg' import ArrowDown from '../assets/arrow-down.svg'
import { secondary } from '~/theme/variables' import { secondary } from '~/theme/variables'
import { isEther } from '~/logic/tokens/utils/tokenHelpers'
import { styles } from './style' import { styles } from './style'
type Props = { type Props = {
@ -50,7 +54,31 @@ const ReviewTx = ({
createTransaction, createTransaction,
}: Props) => ( }: Props) => (
<SharedSnackbarConsumer> <SharedSnackbarConsumer>
{({ openSnackbar }) => ( {({ openSnackbar }) => {
const submitTx = async () => {
const web3 = getWeb3()
const isSendingETH = isEther(tx.token.symbol)
const txRecipient = isSendingETH ? tx.recipientAddress : tx.token.address
let txData = EMPTY_DATA
let txAmount = web3.utils.toWei(tx.amount, 'ether')
if (!isSendingETH) {
const StandardToken = await getStandardTokenContract()
const tokenInstance = await StandardToken.at(tx.token.address)
txData = tokenInstance.contract.methods.transfer(tx.recipientAddress, txAmount).encodeABI()
// txAmount should be 0 if we send tokens
// the real value is encoded in txData and will be used by the contract
// if txAmount > 0 it would send ETH from the safe
txAmount = 0
}
createTransaction(safeAddress, txRecipient, txAmount, txData, openSnackbar)
onClose()
}
return (
<React.Fragment> <React.Fragment>
<Row align="center" grow className={classes.heading}> <Row align="center" grow className={classes.heading}>
<Paragraph weight="bolder" className={classes.headingText} noMargin> <Paragraph weight="bolder" className={classes.headingText} noMargin>
@ -117,10 +145,7 @@ const ReviewTx = ({
<Button <Button
type="submit" type="submit"
className={classes.button} className={classes.button}
onClick={() => { onClick={submitTx}
createTransaction(safeAddress, tx.recipientAddress, tx.amount, tx.token, openSnackbar)
onClose()
}}
variant="contained" variant="contained"
minWidth={140} minWidth={140}
color="primary" color="primary"
@ -130,7 +155,8 @@ const ReviewTx = ({
</Button> </Button>
</Row> </Row>
</React.Fragment> </React.Fragment>
)} )
}}
</SharedSnackbarConsumer> </SharedSnackbarConsumer>
) )

View File

@ -18,7 +18,6 @@ import {
sm, xs, secondary, smallFontSize, sm, xs, secondary, smallFontSize,
} from '~/theme/variables' } from '~/theme/variables'
import { copyToClipboard } from '~/utils/clipboard' import { copyToClipboard } from '~/utils/clipboard'
import type { Safe } from '~/routes/safe/store/models/safe'
import Balances from './Balances' import Balances from './Balances'
import Settings from './Settings' import Settings from './Settings'

View File

@ -11,7 +11,7 @@ export type Props = Actions &
granted: boolean, granted: boolean,
} }
const TIMEOUT = process.env.NODE_ENV === 'test' ? 1500 : 15000 const TIMEOUT = process.env.NODE_ENV === 'test' ? 1500 : 5000
class SafeView extends React.Component<Props> { class SafeView extends React.Component<Props> {
componentDidMount() { componentDidMount() {

View File

@ -1,15 +1,11 @@
// @flow // @flow
import type { Dispatch as ReduxDispatch, GetState } from 'redux' import type { Dispatch as ReduxDispatch, GetState } from 'redux'
import { createAction } from 'redux-actions' import { createAction } from 'redux-actions'
import { getWeb3 } from '~/logic/wallets/getWeb3'
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions' import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
import { type Token } from '~/logic/tokens/store/model/token'
import { userAccountSelector } from '~/logic/wallets/store/selectors' import { userAccountSelector } from '~/logic/wallets/store/selectors'
import { type GlobalState } from '~/store' import { type GlobalState } from '~/store'
import { isEther } from '~/logic/tokens/utils/tokenHelpers'
import { getGnosisSafeInstanceAt } from '~/logic/contracts/safeContracts' import { getGnosisSafeInstanceAt } from '~/logic/contracts/safeContracts'
import { executeTransaction, CALL } from '~/logic/safe/transactions' import { executeTransaction, CALL } from '~/logic/safe/transactions'
import { getStandardTokenContract } from '~/logic/tokens/store/actions/fetchTokens'
export const ADD_TRANSACTIONS = 'ADD_TRANSACTIONS' export const ADD_TRANSACTIONS = 'ADD_TRANSACTIONS'
export const addTransactions = createAction<string, *>(ADD_TRANSACTIONS) export const addTransactions = createAction<string, *>(ADD_TRANSACTIONS)
@ -17,40 +13,23 @@ export const addTransactions = createAction<string, *>(ADD_TRANSACTIONS)
const createTransaction = ( const createTransaction = (
safeAddress: string, safeAddress: string,
to: string, to: string,
valueInEth: string, valueInWei: string,
token: Token,
openSnackbar: Function,
txData: string = EMPTY_DATA, txData: string = EMPTY_DATA,
openSnackbar: Function,
) => async (dispatch: ReduxDispatch<GlobalState>, getState: GetState<GlobalState>) => { ) => async (dispatch: ReduxDispatch<GlobalState>, getState: GetState<GlobalState>) => {
const isSendingETH = isEther(token.symbol)
const state: GlobalState = getState() const state: GlobalState = getState()
const safeInstance = await getGnosisSafeInstanceAt(safeAddress) const safeInstance = await getGnosisSafeInstanceAt(safeAddress)
const web3 = getWeb3()
const from = userAccountSelector(state) const from = userAccountSelector(state)
const threshold = await safeInstance.getThreshold() const threshold = await safeInstance.getThreshold()
const nonce = await safeInstance.nonce() const nonce = await safeInstance.nonce()
const txRecipient = isSendingETH ? to : token.address
const valueInWei = web3.utils.toWei(valueInEth, 'ether')
let txAmount = valueInWei
const isExecution = threshold.toNumber() === 1 const isExecution = threshold.toNumber() === 1
let txData = EMPTY_DATA
if (!isSendingETH) {
const StandardToken = await getStandardTokenContract()
const sendToken = await StandardToken.at(token.address)
txData = sendToken.contract.methods.transfer(to, valueInWei).encodeABI()
// txAmount should be 0 if we send tokens
// the real value is encoded in txData and will be used by the contract
// if txAmount > 0 it would send ETH from the safe
txAmount = 0
}
let txHash let txHash
if (isExecution) { if (isExecution) {
openSnackbar('Transaction has been submitted', 'success') openSnackbar('Transaction has been submitted', 'success')
txHash = await executeTransaction(safeInstance, txRecipient, txAmount, txData, CALL, nonce, from) txHash = await executeTransaction(safeInstance, to, valueInWei, txData, CALL, nonce, from)
openSnackbar('Transaction has been confirmed', 'success') openSnackbar('Transaction has been confirmed', 'success')
} else { } else {
// txHash = await approveTransaction(safeAddress, to, valueInWei, txData, CALL, nonce) // txHash = await approveTransaction(safeAddress, to, valueInWei, txData, CALL, nonce)