WA-238 Adding create multisig tx logic
This commit is contained in:
parent
f9407397db
commit
abb949702c
|
@ -46,7 +46,8 @@ class GnoSafe extends React.PureComponent<SafeProps, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
onAddTx = () => {
|
onAddTx = () => {
|
||||||
this.setState({ component: <Transactions balance={Number(this.props.balance)} onReset={this.onSeeTxs} /> })
|
const { balance, safe } = this.props
|
||||||
|
this.setState({ component: <Transactions safe={safe} balance={Number(balance)} onReset={this.onSeeTxs} /> })
|
||||||
}
|
}
|
||||||
|
|
||||||
onSeeTxs = () => {
|
onSeeTxs = () => {
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
// @flow
|
||||||
|
import fetchTransactions from '~/routes/safe/store/actions/fetchTransactions'
|
||||||
|
|
||||||
|
export type Actions = {
|
||||||
|
fetchTransactions: typeof fetchTransactions,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
fetchTransactions,
|
||||||
|
}
|
|
@ -1,6 +1,12 @@
|
||||||
// @flow
|
// @flow
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
import Stepper from '~/components/Stepper'
|
import Stepper from '~/components/Stepper'
|
||||||
|
import { sleep } from '~/utils/timer'
|
||||||
|
import { type Safe } from '~/routes/safe/store/model/safe'
|
||||||
|
import actions, { type Actions } from './actions'
|
||||||
|
import selector, { type SelectorProps } from './selector'
|
||||||
|
import transaction, { createTransaction, TX_NAME_PARAM, TX_DESTINATION_PARAM, TX_VALUE_PARAM } from './transactions'
|
||||||
import MultisigForm from './MultisigForm'
|
import MultisigForm from './MultisigForm'
|
||||||
import ReviewTx from './ReviewTx'
|
import ReviewTx from './ReviewTx'
|
||||||
|
|
||||||
|
@ -8,14 +14,8 @@ const getSteps = () => [
|
||||||
'Fill Mutlisig Tx form', 'Review Tx',
|
'Fill Mutlisig Tx form', 'Review Tx',
|
||||||
]
|
]
|
||||||
|
|
||||||
/*
|
|
||||||
type Props = SelectorProps & Actions & {
|
type Props = SelectorProps & Actions & {
|
||||||
safeAddress: string,
|
safe: Safe,
|
||||||
dailyLimit: DailyLimit,
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
balance: number,
|
balance: number,
|
||||||
onReset: () => void,
|
onReset: () => void,
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,24 @@ class Transactions extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
onTransaction = async (values: Object) => {
|
onTransaction = async (values: Object) => {
|
||||||
// eslint-disable-next-line
|
try {
|
||||||
console.log("Executing transaction with params " + JSON.stringify(values))
|
const { safe, userAddress } = this.props
|
||||||
|
const nonce = Date.now()
|
||||||
|
const destination = values[TX_DESTINATION_PARAM]
|
||||||
|
const value = values[TX_VALUE_PARAM]
|
||||||
|
const tx = await transaction(safe.get('address'), destination, value, nonce, userAddress)
|
||||||
|
await createTransaction(
|
||||||
|
values[TX_NAME_PARAM], nonce, destination, value, userAddress,
|
||||||
|
safe.get('owners'), tx, safe.get('address'), safe.get('confirmations'),
|
||||||
|
)
|
||||||
|
await sleep(1500)
|
||||||
|
this.props.fetchTransactions()
|
||||||
|
this.setState({ done: true })
|
||||||
|
} catch (error) {
|
||||||
|
this.setState({ done: false })
|
||||||
|
// eslint-disable-next-line
|
||||||
|
console.log('Error while creating multisig tx ' + error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onReset = () => {
|
onReset = () => {
|
||||||
|
@ -68,5 +84,4 @@ class Transactions extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Transactions
|
export default connect(selector, actions)(Transactions)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
// @flow
|
||||||
|
import { createStructuredSelector } from 'reselect'
|
||||||
|
import { userAccountSelector } from '~/wallets/store/selectors/index'
|
||||||
|
|
||||||
|
export type SelectorProps = {
|
||||||
|
userAddress: userAccountSelector,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default createStructuredSelector({
|
||||||
|
userAddress: userAccountSelector,
|
||||||
|
})
|
|
@ -31,7 +31,7 @@ describe('Transactions Suite', () => {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
const txName = 'Buy butteries for project'
|
const txName = 'Buy butteries for project'
|
||||||
const nonce: number = 10
|
const nonce: number = 10
|
||||||
createTransaction(txName, nonce, destination, value, 'foo', owners, '', safe.get('name'), safe.get('address'), safe.get('confirmations'))
|
createTransaction(txName, nonce, destination, value, 'foo', owners, '', safe.get('address'), safe.get('confirmations'))
|
||||||
|
|
||||||
// WHEN
|
// WHEN
|
||||||
const transactions: Map<string, List<Transaction>> = loadSafeTransactions()
|
const transactions: Map<string, List<Transaction>> = loadSafeTransactions()
|
||||||
|
@ -51,11 +51,11 @@ describe('Transactions Suite', () => {
|
||||||
const firstTxName = 'Buy butteries for project'
|
const firstTxName = 'Buy butteries for project'
|
||||||
const firstNonce: number = Date.now()
|
const firstNonce: number = Date.now()
|
||||||
const safeAddress = safe.get('address')
|
const safeAddress = safe.get('address')
|
||||||
createTransaction(firstTxName, firstNonce, destination, value, 'foo', owners, '', safe.get('name'), safeAddress, safe.get('confirmations'))
|
createTransaction(firstTxName, firstNonce, destination, value, 'foo', owners, '', safeAddress, safe.get('confirmations'))
|
||||||
|
|
||||||
const secondTxName = 'Buy printers for project'
|
const secondTxName = 'Buy printers for project'
|
||||||
const secondNonce: number = firstNonce + 100
|
const secondNonce: number = firstNonce + 100
|
||||||
createTransaction(secondTxName, secondNonce, destination, value, 'foo', owners, '', safe.get('name'), safeAddress, safe.get('confirmations'))
|
createTransaction(secondTxName, secondNonce, destination, value, 'foo', owners, '', safeAddress, safe.get('confirmations'))
|
||||||
|
|
||||||
// WHEN
|
// WHEN
|
||||||
const transactions: Map<string, List<Transaction>> = loadSafeTransactions()
|
const transactions: Map<string, List<Transaction>> = loadSafeTransactions()
|
||||||
|
@ -75,7 +75,7 @@ describe('Transactions Suite', () => {
|
||||||
const txName = 'Buy batteris for Alplha project'
|
const txName = 'Buy batteris for Alplha project'
|
||||||
const nonce = 10
|
const nonce = 10
|
||||||
const safeAddress = safe.address
|
const safeAddress = safe.address
|
||||||
createTransaction(txName, nonce, destination, value, 'foo', owners, '', safe.get('name'), safeAddress, safe.get('confirmations'))
|
createTransaction(txName, nonce, destination, value, 'foo', owners, '', safeAddress, safe.get('confirmations'))
|
||||||
|
|
||||||
const secondSafe = SafeFactory.dailyLimitSafe(10, 2)
|
const secondSafe = SafeFactory.dailyLimitSafe(10, 2)
|
||||||
const txSecondName = 'Buy batteris for Beta project'
|
const txSecondName = 'Buy batteris for Beta project'
|
||||||
|
@ -83,7 +83,7 @@ describe('Transactions Suite', () => {
|
||||||
const secondSafeAddress = secondSafe.address
|
const secondSafeAddress = secondSafe.address
|
||||||
createTransaction(
|
createTransaction(
|
||||||
txSecondName, txSecondNonce, destination, value, '0x03db1a8b26d08df23337e9276a36b474510f0023',
|
txSecondName, txSecondNonce, destination, value, '0x03db1a8b26d08df23337e9276a36b474510f0023',
|
||||||
secondSafe.get('owners'), '', secondSafe.get('name'), secondSafeAddress, secondSafe.get('confirmations'),
|
secondSafe.get('owners'), '', secondSafeAddress, secondSafe.get('confirmations'),
|
||||||
)
|
)
|
||||||
|
|
||||||
let transactions: Map<string, List<Transaction>> = loadSafeTransactions()
|
let transactions: Map<string, List<Transaction>> = loadSafeTransactions()
|
||||||
|
@ -102,7 +102,7 @@ describe('Transactions Suite', () => {
|
||||||
const txFirstNonce = 11
|
const txFirstNonce = 11
|
||||||
createTransaction(
|
createTransaction(
|
||||||
txFirstName, txFirstNonce, destination, value, 'foo',
|
txFirstName, txFirstNonce, destination, value, 'foo',
|
||||||
safe.get('owners'), '', safe.get('name'), safe.get('address'), safe.get('confirmations'),
|
safe.get('owners'), '', safe.get('address'), safe.get('confirmations'),
|
||||||
)
|
)
|
||||||
|
|
||||||
transactions = loadSafeTransactions()
|
transactions = loadSafeTransactions()
|
||||||
|
@ -136,10 +136,10 @@ describe('Transactions Suite', () => {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
const txName = 'Buy butteries for project'
|
const txName = 'Buy butteries for project'
|
||||||
const nonce: number = 10
|
const nonce: number = 10
|
||||||
createTransaction(txName, nonce, destination, value, 'foo', owners, '', safe.get('name'), safe.get('address'), safe.get('confirmations'))
|
createTransaction(txName, nonce, destination, value, 'foo', owners, '', safe.get('address'), safe.get('confirmations'))
|
||||||
|
|
||||||
// WHEN
|
// WHEN
|
||||||
const createTxFnc = () => createTransaction(txName, nonce, destination, value, 'foo', owners, '', safe.get('name'), safe.get('address'), safe.get('confirmations'))
|
const createTxFnc = () => createTransaction(txName, nonce, destination, value, 'foo', owners, '', safe.get('address'), safe.get('confirmations'))
|
||||||
expect(createTxFnc).toThrow(/Transaction with same nonce/)
|
expect(createTxFnc).toThrow(/Transaction with same nonce/)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ describe('Transactions Suite', () => {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
const txName = 'Buy butteries for project'
|
const txName = 'Buy butteries for project'
|
||||||
const nonce: number = 10
|
const nonce: number = 10
|
||||||
createTransaction(txName, nonce, destination, value, 'foo', owners, '', safe.get('name'), safe.get('address'), safe.get('confirmations'))
|
createTransaction(txName, nonce, destination, value, 'foo', owners, '', safe.get('address'), safe.get('confirmations'))
|
||||||
|
|
||||||
// WHEN
|
// WHEN
|
||||||
const transactions: Map<string, List<Transaction>> = loadSafeTransactions()
|
const transactions: Map<string, List<Transaction>> = loadSafeTransactions()
|
||||||
|
@ -161,7 +161,7 @@ describe('Transactions Suite', () => {
|
||||||
const txName = 'Buy butteries for project'
|
const txName = 'Buy butteries for project'
|
||||||
const nonce: number = 10
|
const nonce: number = 10
|
||||||
const ownerName = 'invented'
|
const ownerName = 'invented'
|
||||||
const createTxFnc = () => createTransaction(txName, nonce, destination, value, ownerName, owners, '', safe.get('name'), safe.get('address'), safe.get('confirmations'))
|
const createTxFnc = () => createTransaction(txName, nonce, destination, value, ownerName, owners, '', safe.get('address'), safe.get('confirmations'))
|
||||||
|
|
||||||
expect(createTxFnc).toThrow(/The creator of the tx is not an owner/)
|
expect(createTxFnc).toThrow(/The creator of the tx is not an owner/)
|
||||||
})
|
})
|
||||||
|
@ -172,7 +172,7 @@ describe('Transactions Suite', () => {
|
||||||
const txName = 'Buy butteries for project'
|
const txName = 'Buy butteries for project'
|
||||||
const nonce: number = 10
|
const nonce: number = 10
|
||||||
const tx = ''
|
const tx = ''
|
||||||
const createTxFnc = () => createTransaction(txName, nonce, destination, value, ownerName, oneOwnerSafe.get('owners'), tx, oneOwnerSafe.get('name'), oneOwnerSafe.get('address'), oneOwnerSafe.get('confirmations'))
|
const createTxFnc = () => createTransaction(txName, nonce, destination, value, ownerName, oneOwnerSafe.get('owners'), tx, oneOwnerSafe.get('address'), oneOwnerSafe.get('confirmations'))
|
||||||
|
|
||||||
expect(createTxFnc).toThrow(/The tx should be mined before storing it in safes with one owner/)
|
expect(createTxFnc).toThrow(/The tx should be mined before storing it in safes with one owner/)
|
||||||
})
|
})
|
||||||
|
|
|
@ -4,6 +4,8 @@ import { type Owner } from '~/routes/safe/store/model/owner'
|
||||||
import { load, TX_KEY } from '~/utils/localStorage'
|
import { load, TX_KEY } from '~/utils/localStorage'
|
||||||
import { type Confirmation, makeConfirmation } from '~/routes/safe/store/model/confirmation'
|
import { type Confirmation, makeConfirmation } from '~/routes/safe/store/model/confirmation'
|
||||||
import { makeTransaction, type Transaction, type TransactionProps } from '~/routes/safe/store/model/transaction'
|
import { makeTransaction, type Transaction, type TransactionProps } from '~/routes/safe/store/model/transaction'
|
||||||
|
import { getGnosisSafeContract } from '~/wallets/safeContracts'
|
||||||
|
import { getWeb3 } from '~/wallets/getWeb3'
|
||||||
|
|
||||||
export const TX_NAME_PARAM = 'txName'
|
export const TX_NAME_PARAM = 'txName'
|
||||||
export const TX_DESTINATION_PARAM = 'txDestination'
|
export const TX_DESTINATION_PARAM = 'txDestination'
|
||||||
|
@ -29,7 +31,6 @@ export const createTransaction = (
|
||||||
creator: string,
|
creator: string,
|
||||||
owners: List<Owner>,
|
owners: List<Owner>,
|
||||||
tx: string,
|
tx: string,
|
||||||
safeName: string,
|
|
||||||
safeAddress: string,
|
safeAddress: string,
|
||||||
safeThreshold: number,
|
safeThreshold: number,
|
||||||
) => {
|
) => {
|
||||||
|
@ -56,3 +57,16 @@ export const createTransaction = (
|
||||||
|
|
||||||
localStorage.setItem(TX_KEY, JSON.stringify(safeTransactions))
|
localStorage.setItem(TX_KEY, JSON.stringify(safeTransactions))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const transactions = async (safeAddress: string, destination: string, value: number, nonce: number, user: string) => {
|
||||||
|
const web3 = getWeb3()
|
||||||
|
const GnosisSafe = await getGnosisSafeContract(web3)
|
||||||
|
const gnosisSafe = GnosisSafe.at(safeAddress)
|
||||||
|
|
||||||
|
const valueInWei = web3.toWei(value, 'ether')
|
||||||
|
const CALL = 0
|
||||||
|
|
||||||
|
return gnosisSafe.approveTransactionWithParameters(destination, valueInWei, '0x', CALL, nonce, { from: user, gas: '5000000' })
|
||||||
|
}
|
||||||
|
|
||||||
|
export default transactions
|
||||||
|
|
Loading…
Reference in New Issue