Transactions gas costs wip
This commit is contained in:
parent
712fc80b1e
commit
387ea01d5e
|
@ -0,0 +1,57 @@
|
||||||
|
// @flow
|
||||||
|
import GnosisSafeSol from '@gnosis.pm/safe-contracts/build/contracts/GnosisSafe.json'
|
||||||
|
import { getWeb3, getAccountFrom } from '~/logic/wallets/getWeb3'
|
||||||
|
import { type Operation } from '~/logic/safe/transactions'
|
||||||
|
import { calculateGasOf, calculateGasPrice } from '~/logic/wallets/ethTransactions'
|
||||||
|
import { ZERO_ADDRESS } from '~/logic/wallets/ethAddresses'
|
||||||
|
import { CALL } from '.'
|
||||||
|
|
||||||
|
export const estimateApprovalTxGasCosts = async (safeAddress: string, to: string, data: string): Promise<number> => {
|
||||||
|
try {
|
||||||
|
const web3 = getWeb3()
|
||||||
|
const from = await getAccountFrom(web3)
|
||||||
|
const safeInstance = new web3.eth.Contract(GnosisSafeSol.abi, safeAddress)
|
||||||
|
const nonce = await safeInstance.methods.nonce().call()
|
||||||
|
const txHash = await safeInstance.methods
|
||||||
|
.getTransactionHash(to, 0, data, CALL, 0, 0, 0, ZERO_ADDRESS, ZERO_ADDRESS, nonce)
|
||||||
|
.call({
|
||||||
|
from,
|
||||||
|
})
|
||||||
|
const approvalData = await safeInstance.methods.approveHash(txHash).encodeABI()
|
||||||
|
const gas = await calculateGasOf(approvalData, from, safeAddress)
|
||||||
|
const gasPrice = await calculateGasPrice()
|
||||||
|
|
||||||
|
return gas * parseInt(gasPrice, 10)
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Error while estimating approval transaction gas costs: ${err}`)
|
||||||
|
|
||||||
|
return 1000000000000000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const estimateExecuteTxGasCosts = async (
|
||||||
|
safeInstance: any,
|
||||||
|
to: string,
|
||||||
|
valueInWei: number | string,
|
||||||
|
data: string,
|
||||||
|
operation: Operation,
|
||||||
|
nonce: string | number,
|
||||||
|
sender: string,
|
||||||
|
sigs: string,
|
||||||
|
): Promise<number> => {
|
||||||
|
try {
|
||||||
|
const web3 = getWeb3()
|
||||||
|
const contract = new web3.eth.Contract(GnosisSafeSol.abi, safeInstance.address)
|
||||||
|
const executionData = await contract.methods
|
||||||
|
.execTransaction(to, valueInWei, data, operation, 0, 0, 0, ZERO_ADDRESS, ZERO_ADDRESS)
|
||||||
|
.encodeABI()
|
||||||
|
const gas = await calculateGasOf(executionData, sender, safeInstance.address)
|
||||||
|
const gasPrice = await calculateGasPrice()
|
||||||
|
|
||||||
|
return gas * parseInt(gasPrice, 10)
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Error while estimating transaction execution gas costs: ${err}`)
|
||||||
|
|
||||||
|
return 0.001
|
||||||
|
}
|
||||||
|
}
|
|
@ -64,7 +64,7 @@ const getProviderName: Function = (web3Provider): string => {
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
const getAccountFrom: Function = async (web3Provider): Promise<string | null> => {
|
export const getAccountFrom: Function = async (web3Provider): Promise<string | null> => {
|
||||||
const accounts = await web3Provider.eth.getAccounts()
|
const accounts = await web3Provider.eth.getAccounts()
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'test' && window.testAccountIndex) {
|
if (process.env.NODE_ENV === 'test' && window.testAccountIndex) {
|
||||||
|
|
|
@ -67,7 +67,7 @@ const Routes = ({ defaultSafe, location }: RoutesProps) => {
|
||||||
<Route path={SAFE_ADDRESS} component={Safe} />
|
<Route path={SAFE_ADDRESS} component={Safe} />
|
||||||
<Route exact path={OPENING_ADDRESS} component={Opening} />
|
<Route exact path={OPENING_ADDRESS} component={Opening} />
|
||||||
<Route exact path={LOAD_ADDRESS} component={Load} />
|
<Route exact path={LOAD_ADDRESS} component={Load} />
|
||||||
{/* <Redirect to="/" /> */}
|
<Redirect to="/" />
|
||||||
</Switch>
|
</Switch>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// @flow
|
// @flow
|
||||||
import React from 'react'
|
import React, { useEffect, useState } from 'react'
|
||||||
import { BigNumber } from 'bignumber.js'
|
import { BigNumber } from 'bignumber.js'
|
||||||
import OpenInNew from '@material-ui/icons/OpenInNew'
|
import OpenInNew from '@material-ui/icons/OpenInNew'
|
||||||
import { withStyles } from '@material-ui/core/styles'
|
import { withStyles } from '@material-ui/core/styles'
|
||||||
|
@ -19,6 +19,7 @@ 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, getHumanFriendlyToken } from '~/logic/tokens/store/actions/fetchTokens'
|
import { getStandardTokenContract, getHumanFriendlyToken } from '~/logic/tokens/store/actions/fetchTokens'
|
||||||
|
import { estimateApprovalTxGasCosts } from '~/logic/safe/transactions/gasNew'
|
||||||
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
|
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
|
||||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||||
import { TX_NOTIFICATION_TYPES } from '~/logic/safe/transactions'
|
import { TX_NOTIFICATION_TYPES } from '~/logic/safe/transactions'
|
||||||
|
@ -59,10 +60,42 @@ const ReviewTx = ({
|
||||||
enqueueSnackbar,
|
enqueueSnackbar,
|
||||||
closeSnackbar,
|
closeSnackbar,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const submitTx = async () => {
|
const [gasCosts, setGasCosts] = useState<string>('0.0')
|
||||||
const web3 = getWeb3()
|
|
||||||
const isSendingETH = isEther(tx.token.symbol)
|
const isSendingETH = isEther(tx.token.symbol)
|
||||||
const txRecipient = isSendingETH ? tx.recipientAddress : tx.token.address
|
const txRecipient = isSendingETH ? tx.recipientAddress : tx.token.address
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let isCurrent = true
|
||||||
|
const estimateGas = async () => {
|
||||||
|
const web3 = getWeb3()
|
||||||
|
const { fromWei, toBN } = web3.utils
|
||||||
|
let txData = EMPTY_DATA
|
||||||
|
|
||||||
|
if (!isSendingETH) {
|
||||||
|
const StandardToken = await getStandardTokenContract()
|
||||||
|
const tokenInstance = await StandardToken.at(tx.token.address)
|
||||||
|
|
||||||
|
txData = tokenInstance.contract.methods.transfer(tx.recipientAddress, 0).encodeABI()
|
||||||
|
}
|
||||||
|
|
||||||
|
const estimatedGasCosts = await estimateApprovalTxGasCosts(safeAddress, txRecipient, txData)
|
||||||
|
console.log({ estimatedGasCosts })
|
||||||
|
const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether')
|
||||||
|
const roundedGasCosts = parseFloat(gasCostsAsEth).toFixed(3)
|
||||||
|
if (isCurrent) {
|
||||||
|
setGasCosts(roundedGasCosts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
estimateGas()
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
isCurrent = false
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const submitTx = async () => {
|
||||||
|
const web3 = getWeb3()
|
||||||
let txData = EMPTY_DATA
|
let txData = EMPTY_DATA
|
||||||
let txAmount = web3.utils.toWei(tx.amount, 'ether')
|
let txAmount = web3.utils.toWei(tx.amount, 'ether')
|
||||||
|
|
||||||
|
@ -106,12 +139,7 @@ const ReviewTx = ({
|
||||||
</Row>
|
</Row>
|
||||||
<Hairline />
|
<Hairline />
|
||||||
<Block className={classes.container}>
|
<Block className={classes.container}>
|
||||||
<SafeInfo
|
<SafeInfo safeAddress={safeAddress} etherScanLink={etherScanLink} safeName={safeName} ethBalance={ethBalance} />
|
||||||
safeAddress={safeAddress}
|
|
||||||
etherScanLink={etherScanLink}
|
|
||||||
safeName={safeName}
|
|
||||||
ethBalance={ethBalance}
|
|
||||||
/>
|
|
||||||
<Row margin="md">
|
<Row margin="md">
|
||||||
<Col xs={1}>
|
<Col xs={1}>
|
||||||
<img src={ArrowDown} alt="Arrow Down" style={{ marginLeft: '8px' }} />
|
<img src={ArrowDown} alt="Arrow Down" style={{ marginLeft: '8px' }} />
|
||||||
|
@ -152,6 +180,9 @@ const ReviewTx = ({
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
</Row>
|
</Row>
|
||||||
</Block>
|
</Block>
|
||||||
|
<Row>
|
||||||
|
<Paragraph>{`Gas costs: ${gasCosts}`}</Paragraph>
|
||||||
|
</Row>
|
||||||
<Hairline style={{ position: 'absolute', bottom: 85 }} />
|
<Hairline style={{ position: 'absolute', bottom: 85 }} />
|
||||||
<Row align="center" className={classes.buttonRow}>
|
<Row align="center" className={classes.buttonRow}>
|
||||||
<Button minWidth={140} onClick={() => setActiveScreen('sendFunds')}>
|
<Button minWidth={140} onClick={() => setActiveScreen('sendFunds')}>
|
||||||
|
|
Loading…
Reference in New Issue