gas calculations wip
This commit is contained in:
parent
b0a7b649a1
commit
2eb09c6398
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
// @flow
|
||||
|
||||
export * from './estimateTxGas'
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue