gas calculations wip

This commit is contained in:
mmv 2019-05-21 19:04:52 +04:00
parent b0a7b649a1
commit 2eb09c6398
8 changed files with 91 additions and 20 deletions

View File

@ -10,7 +10,7 @@ const devConfig = {
[TX_SERVICE_HOST]: 'http://localhost:8000/api/v1/',
[ENABLED_TX_SERVICE_REMOVAL_SENDER]: false,
[SIGNATURES_VIA_METAMASK]: false,
[RELAY_API_URL]: 'https://safe-relay.staging.gnosisdev.com/api/v1/',
[RELAY_API_URL]: 'https://safe-relay.staging.gnosisdev.com/api/v1',
}
export default devConfig

View File

@ -10,7 +10,7 @@ const prodConfig = {
[TX_SERVICE_HOST]: 'https://safe-transaction-history.dev.gnosisdev.com/api/v1/',
[ENABLED_TX_SERVICE_REMOVAL_SENDER]: false,
[SIGNATURES_VIA_METAMASK]: false,
[RELAY_API_URL]: 'https://safe-relay.staging.gnosisdev.com/api/v1/',
[RELAY_API_URL]: 'https://safe-relay.staging.gnosisdev.com/api/v1',
}
export default prodConfig

View File

@ -10,7 +10,7 @@ const testConfig = {
[TX_SERVICE_HOST]: 'http://localhost:8000/api/v1/',
[ENABLED_TX_SERVICE_REMOVAL_SENDER]: false,
[SIGNATURES_VIA_METAMASK]: false,
[RELAY_API_URL]: 'https://safe-relay.staging.gnosisdev.com/api/v1/',
[RELAY_API_URL]: 'https://safe-relay.staging.gnosisdev.com/api/v1',
}
export default testConfig

View File

@ -0,0 +1,17 @@
// @flow
import axios from 'axios'
import { getRelayUrl } from '~/config/index'
export const estimateTxGas = (safeAddress: string, to: string, value: string, data, operation = 0) => {
const apiUrl = getRelayUrl()
const url = `${apiUrl}/safes/${safeAddress}/transactions/estimate/`
// const estimationValue = isTokenTransfer(tx.data) ? '0' : value.toString(10)
return axios.post(url, {
safe: safeAddress,
to,
data: '0x',
value,
operation,
})
}

View File

@ -0,0 +1,3 @@
// @flow
export * from './estimateTxGas'

View File

@ -3,6 +3,7 @@ import { getWeb3 } from '~/logic/wallets/getWeb3'
import { BigNumber } from 'bignumber.js'
import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
import { getSignaturesFrom } from '~/utils/storage/signatures'
import { getSafeEthereumInstance } from './safeFrontendOperations';
const estimateDataGasCosts = (data) => {
const reducer = (accumulator, currentValue) => {
@ -63,7 +64,12 @@ export const generateTxGasEstimateFrom = async (
operation: number,
) => {
try {
const estimateData = safe.contract.methods.requiredTxGas(to, valueInWei, data, operation).encodeABI()
let safeInstance = safe
if (!safeInstance) {
safeInstance = await getSafeEthereumInstance(safeAddress)
}
const estimateData = safeInstance.contract.methods.requiredTxGas(to, valueInWei, data, operation).encodeABI()
const estimateResponse = await getWeb3().eth.call({
to: safeAddress,
from: safeAddress,
@ -72,11 +78,11 @@ export const generateTxGasEstimateFrom = async (
const txGasEstimate = new BigNumber(estimateResponse.substring(138), 16)
// Add 10k else we will fail in case of nested calls
return Promise.resolve(txGasEstimate.toNumber() + 10000)
return txGasEstimate.toNumber() + 10000
} catch (error) {
// eslint-disable-next-line
console.log('Error calculating tx gas estimation ' + error)
return Promise.resolve(0)
return 0
}
}

View File

@ -1,7 +1,6 @@
// @flow
import React from 'react'
import { List } from 'immutable'
import { OnChange } from 'react-final-form-listeners'
import { withStyles } from '@material-ui/core/styles'
import MenuItem from '@material-ui/core/MenuItem'
import ListItemIcon from '@material-ui/core/ListItemIcon'
@ -18,7 +17,6 @@ import { selectedTokenStyles, selectStyles } from './style'
type SelectFieldProps = {
tokens: List<Token>,
classes: Object,
onTokenChange: Function,
}
type SelectedTokenProps = {
@ -49,7 +47,7 @@ const SelectedToken = ({ token, classes }: SelectedTokenProps) => (
const SelectedTokenStyled = withStyles(selectedTokenStyles)(SelectedToken)
const TokenSelectField = ({ tokens, onTokenChange, classes }: SelectFieldProps) => (
const TokenSelectField = ({ tokens, classes }: SelectFieldProps) => (
<Field
name="token"
component={SelectField}
@ -67,11 +65,6 @@ const TokenSelectField = ({ tokens, onTokenChange, classes }: SelectFieldProps)
<ListItemText primary={token.name} secondary={`${token.balance} ${token.symbol}`} />
</MenuItem>
))}
<OnChange name="token">
{() => {
onTokenChange()
}}
</OnChange>
</Field>
)

View File

@ -1,7 +1,9 @@
// @flow
import * as React from 'react'
import React, { useState } from 'react'
import { List } from 'immutable'
import { BigNumber } from 'bignumber.js'
import { withStyles } from '@material-ui/core/styles'
import { OnChange } from 'react-final-form-listeners'
import Close from '@material-ui/icons/Close'
import InputAdornment from '@material-ui/core/InputAdornment'
import IconButton from '@material-ui/core/IconButton'
@ -13,11 +15,21 @@ import Block from '~/components/layout/Block'
import Hairline from '~/components/layout/Hairline'
import ButtonLink from '~/components/layout/ButtonLink'
import Field from '~/components/forms/Field'
import Bold from '~/components/layout/Bold'
import TextField from '~/components/forms/TextField'
import { getWeb3 } from '~/logic/wallets/getWeb3'
import { type Token } from '~/logic/tokens/store/model/token'
import { composeValidators, required, mustBeEthereumAddress } from '~/components/forms/validator'
import {
composeValidators,
required,
mustBeEthereumAddress,
mustBeFloat,
maxValue,
greaterThan,
} from '~/components/forms/validator'
import TokenSelectField from '~/routes/safe/components/Balances/SendModal/screens/SendFunds/TokenSelectField'
import SafeInfo from '~/routes/safe/components/Balances/SendModal/screens/SendFunds/SafeInfo'
import { generateTxGasEstimateFrom } from '~/logic/safe/safeTxSignerEIP712'
import ArrowDown from './assets/arrow-down.svg'
import { styles } from './style'
@ -31,9 +43,12 @@ type Props = {
tokens: List<Token>,
}
const web3 = getWeb3()
const SendFunds = ({
classes, onClose, safeAddress, etherScanLink, safeName, ethBalance, tokens,
}: Props) => {
const [txFee, setTxFee] = useState(0)
const handleSubmit = () => {}
const formMutators = {
setMax: (args, state, utils) => {
@ -71,7 +86,13 @@ const SendFunds = ({
{(...args) => {
const formState = args[2]
const mutators = args[3]
const { token } = formState.values
const { token, recipientAddress, amount } = formState.values
const estimateFee = async () => {
const valueInWei = web3.utils.toWei(amount, 'ether')
const fee = await generateTxGasEstimateFrom(null, safeAddress, '0x', recipientAddress, valueInWei, 0)
setTxFee(fee)
}
return (
<React.Fragment>
@ -90,7 +111,7 @@ const SendFunds = ({
</Row>
<Row margin="sm">
<Col>
<TokenSelectField tokens={tokens} onTokenChange={mutators.onTokenChange} />
<TokenSelectField tokens={tokens} />
</Col>
</Row>
<Row margin="xs">
@ -103,13 +124,18 @@ const SendFunds = ({
</ButtonLink>
</Col>
</Row>
<Row>
<Row margin="md">
<Col>
<Field
name="amount"
component={TextField}
type="text"
validate={composeValidators(required)}
validate={composeValidators(
required,
mustBeFloat,
greaterThan(0),
maxValue(token && token.balance),
)}
placeholder="Amount*"
text="Amount*"
className={classes.addressInput}
@ -119,6 +145,32 @@ const SendFunds = ({
}
}
/>
<OnChange name="amount">
{() => {
estimateFee()
}}
</OnChange>
<OnChange name="token">
{() => {
mutators.onTokenChange()
}}
</OnChange>
</Col>
</Row>
<Row margin="xs">
<Col>
<Paragraph size="md" color="disabled" style={{ letterSpacing: '-0.5px' }} noMargin>
Fee
</Paragraph>
</Col>
</Row>
<Row>
<Col layout="column">
<Bold>
{web3.utils.fromWei(web3.utils.toBN(txFee), 'ether')}
{' '}
ETH
</Bold>
</Col>
</Row>
</React.Fragment>