send transaction for threshold = 1

This commit is contained in:
Mikhail Mikheev 2019-05-24 17:26:38 +04:00
parent 051f26aa76
commit 7a8a69b528
5 changed files with 168 additions and 89 deletions

View File

@ -1,4 +1,5 @@
// @flow
export * from './gas'
export * from './send'
export * from './safeBlockchainOperations'
export * from './safeTxSignerEIP712'

View File

@ -54,89 +54,89 @@ export const approveTransaction = async (
return txHash
}
export const executeTransaction = async (
safeAddress: string,
to: string,
valueInWei: number,
data: string,
operation: Operation,
nonce: number,
sender: string,
ownersWhoHasSigned: List<string>,
) => {
const gasPrice = await calculateGasPrice()
// export const executeTransaction = async (
// safeAddress: string,
// to: string,
// valueInWei: number,
// data: string,
// operation: Operation,
// nonce: number,
// sender: string,
// ownersWhoHasSigned: List<string>,
// ) => {
// const gasPrice = await calculateGasPrice()
if (signaturesViaMetamask()) {
const safe = await getSafeEthereumInstance(safeAddress)
const txGasEstimate = await generateTxGasEstimateFrom(safe, safeAddress, data, to, valueInWei, operation)
const signature = await generateMetamaskSignature(
safe,
safeAddress,
sender,
to,
valueInWei,
nonce,
data,
operation,
txGasEstimate,
)
storeSignature(safeAddress, nonce, signature)
// if (signaturesViaMetamask()) {
// const safe = await getSafeEthereumInstance(safeAddress)
// const txGasEstimate = await generateTxGasEstimateFrom(safe, safeAddress, data, to, valueInWei, operation)
// const signature = await generateMetamaskSignature(
// safe,
// safeAddress,
// sender,
// to,
// valueInWei,
// nonce,
// data,
// operation,
// txGasEstimate,
// )
// storeSignature(safeAddress, nonce, signature)
const sigs = getSignaturesFrom(safeAddress, nonce)
const threshold = await safe.getThreshold()
const gas = await estimateDataGas(
safe,
to,
valueInWei,
data,
operation,
txGasEstimate,
0,
nonce,
Number(threshold),
0,
)
const numOwners = await safe.getOwners()
const gasIncludingRemovingStoreUpfront = gas + txGasEstimate + numOwners.length * 15000
// const sigs = getSignaturesFrom(safeAddress, nonce)
// const threshold = await safe.getThreshold()
// const gas = await estimateDataGas(
// safe,
// to,
// valueInWei,
// data,
// operation,
// txGasEstimate,
// 0,
// nonce,
// Number(threshold),
// 0,
// )
// const numOwners = await safe.getOwners()
// const gasIncludingRemovingStoreUpfront = gas + txGasEstimate + numOwners.length * 15000
const txReceipt = await safe.execTransaction(
to,
valueInWei,
data,
operation,
txGasEstimate,
0, // dataGasEstimate
0, // gasPrice
0, // txGasToken
0, // refundReceiver
sigs,
{ from: sender, gas: gasIncludingRemovingStoreUpfront, gasPrice },
)
// const txReceipt = await safe.execTransaction(
// to,
// valueInWei,
// data,
// operation,
// txGasEstimate,
// 0, // dataGasEstimate
// 0, // gasPrice
// 0, // txGasToken
// 0, // refundReceiver
// sigs,
// { from: sender, gas: gasIncludingRemovingStoreUpfront, gasPrice },
// )
const txHash = txReceipt.tx
await checkReceiptStatus(txHash)
// await submitOperation(safeAddress, to, valueInWei, data, operation, nonce, txHash, sender, 'execution')
// const txHash = txReceipt.tx
// await checkReceiptStatus(txHash)
// // await submitOperation(safeAddress, to, valueInWei, data, operation, nonce, txHash, sender, 'execution')
return txHash
}
// return txHash
// }
const gnosisSafe = await getSafeEthereumInstance(safeAddress)
const signatures = buildSignaturesFrom(ownersWhoHasSigned, sender)
const txExecutionData = gnosisSafe.contract.methods
.execTransaction(to, valueInWei, data, operation, 0, 0, 0, 0, 0, signatures)
.encodeABI()
const gas = await calculateGasOf(txExecutionData, sender, safeAddress)
const numOwners = await gnosisSafe.getOwners()
const gasIncludingRemovingStoreUpfront = gas + numOwners.length * 15000
const txReceipt = await gnosisSafe.execTransaction(to, valueInWei, data, operation, 0, 0, 0, 0, 0, signatures, {
from: sender,
gas: gasIncludingRemovingStoreUpfront,
gasPrice,
})
const txHash = txReceipt.tx
await checkReceiptStatus(txHash)
// const gnosisSafe = await getSafeEthereumInstance(safeAddress)
// const signatures = buildSignaturesFrom(ownersWhoHasSigned, sender)
// const txExecutionData = gnosisSafe.contract.methods
// .execTransaction(to, valueInWei, data, operation, 0, 0, 0, 0, 0, signatures)
// .encodeABI()
// const gas = await calculateGasOf(txExecutionData, sender, safeAddress)
// const numOwners = await gnosisSafe.getOwners()
// const gasIncludingRemovingStoreUpfront = gas + numOwners.length * 15000
// const txReceipt = await gnosisSafe.execTransaction(to, valueInWei, data, operation, 0, 0, 0, 0, 0, signatures, {
// from: sender,
// gas: gasIncludingRemovingStoreUpfront,
// gasPrice,
// })
// const txHash = txReceipt.tx
// await checkReceiptStatus(txHash)
await submitOperation(safeAddress, to, valueInWei, data, operation, nonce, txHash, sender, 'execution')
// await submitOperation(safeAddress, to, valueInWei, data, operation, nonce, txHash, sender, 'execution')
return txHash
}
// return txHash
// }

View File

@ -0,0 +1,75 @@
// @flow
import { getWeb3 } from '~/logic/wallets/getWeb3'
import { getStandardTokenContract } from '~/logic/tokens/store/actions/fetchTokens'
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
import { isEther } from '~/logic/tokens/utils/tokenHelpers'
import { type Token } from '~/logic/tokens/store/model/token'
import { getSafeEthereumInstance } from '../safeFrontendOperations'
const CALL = 0
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
export const executeTransaction = async (
safeInstance: any,
to: string,
valueInWei: number,
data: string,
operation: number | string,
nonce: string | number,
sender: string,
) => {
try {
// https://gnosis-safe.readthedocs.io/en/latest/contracts/signatures.html#pre-validated-signatures
const sigs = `0x000000000000000000000000${sender.replace(
'0x',
'',
)}000000000000000000000000000000000000000000000000000000000000000001`
const tx = await safeInstance.execTransaction(
to,
valueInWei,
data,
CALL,
0,
0,
0,
ZERO_ADDRESS,
ZERO_ADDRESS,
sigs,
{ from: sender },
)
return tx
} catch (error) {
// eslint-disable-next-line
console.log('Error calculating tx gas estimation ' + error)
return 0
}
}
export const createTransaction = async (safeAddress: string, to: string, valueInEth: string, token: Token) => {
const safeInstance = await getSafeEthereumInstance(safeAddress)
const web3 = getWeb3()
const from = web3.currentProvider.selectedAddress
const threshold = await safeInstance.getThreshold()
const nonce = await safeInstance.nonce()
const valueInWei = web3.utils.toWei(valueInEth, 'ether')
const isExecution = threshold.toNumber() === 1
let txData = EMPTY_DATA
if (!isEther(token.symbol)) {
const StandardToken = await getStandardTokenContract()
const sendToken = await StandardToken.at(token.address)
txData = sendToken.contract.transfer(to, valueInWei).encodeABI()
}
let txHash
if (isExecution) {
txHash = await executeTransaction(safeInstance, to, valueInWei, txData, CALL, nonce, from)
} else {
// txHash = await approveTransaction(safeAddress, to, valueInWei, txData, CALL, nonce)
}
return txHash
}

View File

@ -19,6 +19,7 @@ import { setImageToPlaceholder } from '~/routes/safe/components/Balances/utils'
import ArrowDown from '../assets/arrow-down.svg'
import { secondary } from '~/theme/variables'
import { styles } from './style'
import { createTransaction } from '~/logic/safe/transactions'
type Props = {
onClose: () => void,
@ -97,8 +98,18 @@ const ReviewTx = ({
<Button className={classes.button} minWidth={140} onClick={onClickBack}>
Back
</Button>
<Button type="submit" className={classes.button} variant="contained" minWidth={140} color="primary">
Review
<Button
type="submit"
className={classes.button}
onClick={async () => {
await createTransaction(safeAddress, tx.recipientAddress, tx.amount, tx.token)
onClose()
}}
variant="contained"
minWidth={140}
color="primary"
>
SUBMIT
</Button>
</Row>
</React.Fragment>

View File

@ -13671,7 +13671,7 @@ react-event-listener@^0.6.2:
prop-types "^15.6.0"
warning "^4.0.1"
react-fast-compare@^2.0.2, react-fast-compare@^2.0.3:
react-fast-compare@^2.0.2:
version "2.0.4"
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"
integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==
@ -18371,14 +18371,6 @@ which@^1.2.14, which@^1.2.9, which@^1.3.0, which@^1.3.1:
dependencies:
isexe "^2.0.0"
why-did-you-update@^1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/why-did-you-update/-/why-did-you-update-1.0.6.tgz#2e2c6a04291e715755ecdff1ac8272f721df6f04"
integrity sha512-XVrdHhdrPBDuSW8b/uH6DCb1/0984qv8KElpE8NZiRvWZX8nw49av577+ZyIrxSNesi6r2cQEhpxQTKFFHTj8A==
dependencies:
lodash "^4.17.11"
react-fast-compare "^2.0.3"
wide-align@^1.1.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457"