Update calculateGasPrice to fetch from config (#1517)
* Update calculateGasPrice to fetch from config * Remove unused gas estimation function * Remove unused gasCost estimate function * Add gasParameter to gasPriceOracle
This commit is contained in:
parent
c9e9fe8ca6
commit
5f3a9ef1a9
|
@ -1,5 +1,5 @@
|
|||
import networks from 'src/config/networks'
|
||||
import { EnvironmentSettings, ETHEREUM_NETWORK, NetworkSettings, SafeFeatures, Wallets } from 'src/config/networks/network.d'
|
||||
import { EnvironmentSettings, ETHEREUM_NETWORK, NetworkSettings, SafeFeatures, Wallets, GasPriceOracle } from 'src/config/networks/network.d'
|
||||
import { APP_ENV, ETHERSCAN_API_KEY, GOOGLE_ANALYTICS_ID, INFURA_TOKEN, NETWORK, NODE_ENV } from 'src/utils/constants'
|
||||
import { ensureOnce } from 'src/utils/singleton'
|
||||
import memoize from 'lodash.memoize'
|
||||
|
@ -63,6 +63,10 @@ export const getRelayUrl = (): string | undefined => getConfig()?.relayApiUrl
|
|||
|
||||
export const getGnosisSafeAppsUrl = (): string => getConfig()?.safeAppsUrl
|
||||
|
||||
export const getGasPrice = (): number | undefined => getConfig()?.gasPrice
|
||||
|
||||
export const getGasPriceOracle = (): GasPriceOracle | undefined => getConfig()?.gasPriceOracle
|
||||
|
||||
export const getRpcServiceUrl = (): string => {
|
||||
const usesInfuraRPC = [ETHEREUM_NETWORK.MAINNET, ETHEREUM_NETWORK.RINKEBY].includes(getNetworkId())
|
||||
|
||||
|
|
|
@ -5,7 +5,10 @@ const baseConfig: EnvironmentSettings = {
|
|||
txServiceUrl: 'http://localhost:8000/api/v1',
|
||||
relayApiUrl: 'https://safe-relay.staging.gnosisdev.com/api/v1',
|
||||
safeAppsUrl: 'http://localhost:3002',
|
||||
gasPriceOracleUrl: 'https://ethgasstation.info/json/ethgasAPI.json',
|
||||
gasPriceOracle: {
|
||||
url: 'https://ethgasstation.info/json/ethgasAPI.json',
|
||||
gasParameter: 'average',
|
||||
},
|
||||
rpcServiceUrl: 'http://localhost:4447',
|
||||
networkExplorerName: 'Etherscan',
|
||||
networkExplorerUrl: 'https://rinkeby.etherscan.io',
|
||||
|
|
|
@ -4,7 +4,10 @@ import { EnvironmentSettings, ETHEREUM_NETWORK, NetworkConfig } from 'src/config
|
|||
const baseConfig: EnvironmentSettings = {
|
||||
txServiceUrl: 'https://safe-transaction.mainnet.staging.gnosisdev.com/api/v1',
|
||||
safeAppsUrl: 'https://safe-apps.dev.gnosisdev.com',
|
||||
gasPriceOracleUrl: 'https://ethgasstation.info/json/ethgasAPI.json',
|
||||
gasPriceOracle: {
|
||||
url: 'https://ethgasstation.info/json/ethgasAPI.json',
|
||||
gasParameter: 'average',
|
||||
},
|
||||
rpcServiceUrl: 'https://mainnet.infura.io:443/v3',
|
||||
networkExplorerName: 'Etherscan',
|
||||
networkExplorerUrl: 'https://etherscan.io',
|
||||
|
|
|
@ -64,14 +64,20 @@ export type SafeFeatures = FEATURES[]
|
|||
|
||||
export type Wallets = WALLETS[]
|
||||
|
||||
export type GasPriceOracle = {
|
||||
url: string
|
||||
// Different gas api providers can use a different name to reflect different gas levels based on tx speed
|
||||
// For example in ethGasStation for ETHEREUM_MAINNET = safeLow | average | fast
|
||||
gasParameter: string
|
||||
}
|
||||
|
||||
type GasPrice = {
|
||||
gasPrice: number
|
||||
gasPriceOracleUrl?: string
|
||||
gasPriceOracle?: GasPriceOracle
|
||||
} | {
|
||||
gasPrice?: number
|
||||
// for infura there's a REST API Token required stored in: `REACT_APP_INFURA_TOKEN`
|
||||
gasPriceOracleUrl: string
|
||||
gasPriceOracle: GasPriceOracle
|
||||
}
|
||||
|
||||
export type EnvironmentSettings = GasPrice & {
|
||||
|
|
|
@ -4,7 +4,10 @@ import { EnvironmentSettings, ETHEREUM_NETWORK, NetworkConfig } from 'src/config
|
|||
const baseConfig: EnvironmentSettings = {
|
||||
txServiceUrl: 'https://safe-transaction.staging.gnosisdev.com/api/v1',
|
||||
safeAppsUrl: 'https://safe-apps.dev.gnosisdev.com',
|
||||
gasPriceOracleUrl: 'https://ethgasstation.info/json/ethgasAPI.json',
|
||||
gasPriceOracle: {
|
||||
url: 'https://ethgasstation.info/json/ethgasAPI.json',
|
||||
gasParameter: 'average',
|
||||
},
|
||||
rpcServiceUrl: 'https://rinkeby.infura.io:443/v3',
|
||||
networkExplorerName: 'Etherscan',
|
||||
networkExplorerUrl: 'https://rinkeby.etherscan.io',
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
import axios from 'axios'
|
||||
|
||||
import { getRelayUrl } from 'src/config/index'
|
||||
|
||||
export const estimateTxGas = (safeAddress, to, value, 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,
|
||||
})
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
export * from './estimateTxGas'
|
|
@ -16,7 +16,7 @@ import {
|
|||
saveTxToHistory,
|
||||
tryOffchainSigning,
|
||||
} from 'src/logic/safe/transactions'
|
||||
import { estimateSafeTxGas } from 'src/logic/safe/transactions/gasNew'
|
||||
import { estimateSafeTxGas } from 'src/logic/safe/transactions/gas'
|
||||
import { getCurrentSafeVersion } from 'src/logic/safe/utils/safeVersion'
|
||||
import { ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses'
|
||||
import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions'
|
||||
|
|
|
@ -1,36 +1,168 @@
|
|||
import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts'
|
||||
import GnosisSafeSol from '@gnosis.pm/safe-contracts/build/contracts/GnosisSafe.json'
|
||||
import { BigNumber } from 'bignumber.js'
|
||||
import { AbiItem } from 'web3-utils'
|
||||
|
||||
export const calculateTxFee = async (safe, safeAddress, from, data, to, valueInWei, operation) => {
|
||||
import { CALL } from '.'
|
||||
|
||||
import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts'
|
||||
import { generateSignaturesFromTxConfirmations } from 'src/logic/safe/safeTxSigner'
|
||||
import { Transaction } from 'src/logic/safe/store/models/types/transaction'
|
||||
import { ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses'
|
||||
import { EMPTY_DATA, calculateGasOf, calculateGasPrice } from 'src/logic/wallets/ethTransactions'
|
||||
import { getAccountFrom, getWeb3 } from 'src/logic/wallets/getWeb3'
|
||||
import { GnosisSafe } from 'src/types/contracts/GnosisSafe.d'
|
||||
|
||||
const estimateDataGasCosts = (data: string): number => {
|
||||
const reducer = (accumulator, currentValue) => {
|
||||
if (currentValue === EMPTY_DATA) {
|
||||
return accumulator + 0
|
||||
}
|
||||
|
||||
if (currentValue === '00') {
|
||||
return accumulator + 4
|
||||
}
|
||||
|
||||
return accumulator + 16
|
||||
}
|
||||
|
||||
return data.match(/.{2}/g)?.reduce(reducer, 0)
|
||||
}
|
||||
|
||||
export const estimateTxGasCosts = async (
|
||||
safeAddress: string,
|
||||
to: string,
|
||||
data: string,
|
||||
tx?: Transaction,
|
||||
preApprovingOwner?: string,
|
||||
): Promise<number> => {
|
||||
try {
|
||||
const web3 = getWeb3()
|
||||
const from = await getAccountFrom(web3)
|
||||
|
||||
if (!from) {
|
||||
return 0
|
||||
}
|
||||
|
||||
const safeInstance = (new web3.eth.Contract(GnosisSafeSol.abi as AbiItem[], safeAddress) as unknown) as GnosisSafe
|
||||
const nonce = await safeInstance.methods.nonce().call()
|
||||
const threshold = await safeInstance.methods.getThreshold().call()
|
||||
const isExecution = tx?.confirmations.size === Number(threshold) || !!preApprovingOwner || threshold === '1'
|
||||
|
||||
let txData
|
||||
if (isExecution) {
|
||||
// https://docs.gnosis.io/safe/docs/docs5/#pre-validated-signatures
|
||||
const signatures = tx?.confirmations
|
||||
? generateSignaturesFromTxConfirmations(tx.confirmations, preApprovingOwner)
|
||||
: `0x000000000000000000000000${from.replace(
|
||||
'0x',
|
||||
'',
|
||||
)}000000000000000000000000000000000000000000000000000000000000000001`
|
||||
txData = await safeInstance.methods
|
||||
.execTransaction(
|
||||
to,
|
||||
tx?.value || 0,
|
||||
data,
|
||||
CALL,
|
||||
tx?.safeTxGas || 0,
|
||||
0,
|
||||
0,
|
||||
ZERO_ADDRESS,
|
||||
ZERO_ADDRESS,
|
||||
signatures,
|
||||
)
|
||||
.encodeABI()
|
||||
} else {
|
||||
const txHash = await safeInstance.methods
|
||||
.getTransactionHash(to, tx?.value || 0, data, CALL, 0, 0, 0, ZERO_ADDRESS, ZERO_ADDRESS, nonce)
|
||||
.call({
|
||||
from,
|
||||
})
|
||||
txData = await safeInstance.methods.approveHash(txHash).encodeABI()
|
||||
}
|
||||
|
||||
const gas = await calculateGasOf(txData, from, safeAddress)
|
||||
const gasPrice = await calculateGasPrice()
|
||||
|
||||
return gas * parseInt(gasPrice, 10)
|
||||
} catch (err) {
|
||||
console.error('Error while estimating transaction execution gas costs:')
|
||||
console.error(err)
|
||||
|
||||
return 10000
|
||||
}
|
||||
}
|
||||
|
||||
export const estimateSafeTxGas = async (
|
||||
safe: GnosisSafe | undefined,
|
||||
safeAddress: string,
|
||||
data: string,
|
||||
to: string,
|
||||
valueInWei: string,
|
||||
operation: number,
|
||||
): Promise<number> => {
|
||||
try {
|
||||
let safeInstance = safe
|
||||
if (!safeInstance) {
|
||||
safeInstance = await getGnosisSafeInstanceAt(safeAddress)
|
||||
}
|
||||
|
||||
// https://docs.gnosis.io/safe/docs/docs5/#pre-validated-signatures
|
||||
const sigs = `0x000000000000000000000000${from.replace(
|
||||
'0x',
|
||||
'',
|
||||
)}000000000000000000000000000000000000000000000000000000000000000001`
|
||||
const web3 = await getWeb3()
|
||||
const estimateData = safeInstance.methods.requiredTxGas(to, valueInWei, data, operation).encodeABI()
|
||||
const estimateResponse = await web3.eth.call({
|
||||
to: safeAddress,
|
||||
from: safeAddress,
|
||||
data: estimateData,
|
||||
})
|
||||
const txGasEstimation = new BigNumber(estimateResponse.substring(138), 16).toNumber() + 10000
|
||||
|
||||
// we get gas limit from this call, then it needs to be multiplied by the gas price
|
||||
// https://safe-relay.gnosis.pm/api/v1/gas-station/
|
||||
// https://safe-relay.rinkeby.gnosis.pm/api/v1/about/
|
||||
const estimate = await safeInstance.execTransaction.estimateGas(
|
||||
to,
|
||||
valueInWei,
|
||||
data,
|
||||
operation,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
'0x0000000000000000000000000000000000000000',
|
||||
'0x0000000000000000000000000000000000000000',
|
||||
sigs,
|
||||
{ from: '0xbc2BB26a6d821e69A38016f3858561a1D80d4182' },
|
||||
// 21000 - additional gas costs (e.g. base tx costs, transfer costs)
|
||||
const dataGasEstimation = estimateDataGasCosts(estimateData) + 21000
|
||||
const additionalGasBatches = [10000, 20000, 40000, 80000, 160000, 320000, 640000, 1280000, 2560000, 5120000]
|
||||
|
||||
const batch = new web3.BatchRequest()
|
||||
const estimationRequests = additionalGasBatches.map(
|
||||
(additionalGas) =>
|
||||
new Promise((resolve) => {
|
||||
// there are no type definitions for .request, so for now ts-ignore is there
|
||||
// Issue link: https://github.com/ethereum/web3.js/issues/3144
|
||||
// eslint-disable-next-line
|
||||
// @ts-ignore
|
||||
const request = web3.eth.call.request(
|
||||
{
|
||||
to: safeAddress,
|
||||
from: safeAddress,
|
||||
data: estimateData,
|
||||
gasPrice: 0,
|
||||
gasLimit: txGasEstimation + dataGasEstimation + additionalGas,
|
||||
},
|
||||
(error, res) => {
|
||||
// res.data check is for OpenEthereum/Parity revert messages format
|
||||
const isOpenEthereumRevertMsg = res && typeof res.data === 'string'
|
||||
|
||||
const isEstimationSuccessful =
|
||||
!error &&
|
||||
((typeof res === 'string' && res !== '0x') || (isOpenEthereumRevertMsg && res.data.slice(9) !== '0x'))
|
||||
|
||||
resolve({
|
||||
success: isEstimationSuccessful,
|
||||
estimation: txGasEstimation + additionalGas,
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
return estimate
|
||||
batch.add(request)
|
||||
}),
|
||||
)
|
||||
batch.execute()
|
||||
|
||||
const estimationResponses = await Promise.all(estimationRequests)
|
||||
const firstSuccessfulRequest: any = estimationResponses.find((res: any) => res.success)
|
||||
|
||||
if (firstSuccessfulRequest) {
|
||||
return firstSuccessfulRequest.estimation
|
||||
}
|
||||
|
||||
return 0
|
||||
} catch (error) {
|
||||
console.error('Error calculating tx gas estimation', error)
|
||||
return 0
|
||||
|
|
|
@ -1,170 +0,0 @@
|
|||
import GnosisSafeSol from '@gnosis.pm/safe-contracts/build/contracts/GnosisSafe.json'
|
||||
import { BigNumber } from 'bignumber.js'
|
||||
import { AbiItem } from 'web3-utils'
|
||||
|
||||
import { CALL } from '.'
|
||||
|
||||
import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts'
|
||||
import { generateSignaturesFromTxConfirmations } from 'src/logic/safe/safeTxSigner'
|
||||
import { Transaction } from 'src/logic/safe/store/models/types/transaction'
|
||||
import { ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses'
|
||||
import { EMPTY_DATA, calculateGasOf, calculateGasPrice } from 'src/logic/wallets/ethTransactions'
|
||||
import { getAccountFrom, getWeb3 } from 'src/logic/wallets/getWeb3'
|
||||
import { GnosisSafe } from 'src/types/contracts/GnosisSafe.d'
|
||||
|
||||
const estimateDataGasCosts = (data: string): number => {
|
||||
const reducer = (accumulator, currentValue) => {
|
||||
if (currentValue === EMPTY_DATA) {
|
||||
return accumulator + 0
|
||||
}
|
||||
|
||||
if (currentValue === '00') {
|
||||
return accumulator + 4
|
||||
}
|
||||
|
||||
return accumulator + 16
|
||||
}
|
||||
|
||||
return data.match(/.{2}/g)?.reduce(reducer, 0)
|
||||
}
|
||||
|
||||
export const estimateTxGasCosts = async (
|
||||
safeAddress: string,
|
||||
to: string,
|
||||
data: string,
|
||||
tx?: Transaction,
|
||||
preApprovingOwner?: string,
|
||||
): Promise<number> => {
|
||||
try {
|
||||
const web3 = getWeb3()
|
||||
const from = await getAccountFrom(web3)
|
||||
|
||||
if (!from) {
|
||||
return 0
|
||||
}
|
||||
|
||||
const safeInstance = (new web3.eth.Contract(GnosisSafeSol.abi as AbiItem[], safeAddress) as unknown) as GnosisSafe
|
||||
const nonce = await safeInstance.methods.nonce().call()
|
||||
const threshold = await safeInstance.methods.getThreshold().call()
|
||||
const isExecution = tx?.confirmations.size === Number(threshold) || !!preApprovingOwner || threshold === '1'
|
||||
|
||||
let txData
|
||||
if (isExecution) {
|
||||
// https://docs.gnosis.io/safe/docs/docs5/#pre-validated-signatures
|
||||
const signatures = tx?.confirmations
|
||||
? generateSignaturesFromTxConfirmations(tx.confirmations, preApprovingOwner)
|
||||
: `0x000000000000000000000000${from.replace(
|
||||
'0x',
|
||||
'',
|
||||
)}000000000000000000000000000000000000000000000000000000000000000001`
|
||||
txData = await safeInstance.methods
|
||||
.execTransaction(
|
||||
to,
|
||||
tx?.value || 0,
|
||||
data,
|
||||
CALL,
|
||||
tx?.safeTxGas || 0,
|
||||
0,
|
||||
0,
|
||||
ZERO_ADDRESS,
|
||||
ZERO_ADDRESS,
|
||||
signatures,
|
||||
)
|
||||
.encodeABI()
|
||||
} else {
|
||||
const txHash = await safeInstance.methods
|
||||
.getTransactionHash(to, tx?.value || 0, data, CALL, 0, 0, 0, ZERO_ADDRESS, ZERO_ADDRESS, nonce)
|
||||
.call({
|
||||
from,
|
||||
})
|
||||
txData = await safeInstance.methods.approveHash(txHash).encodeABI()
|
||||
}
|
||||
|
||||
const gas = await calculateGasOf(txData, from, safeAddress)
|
||||
const gasPrice = await calculateGasPrice()
|
||||
|
||||
return gas * parseInt(gasPrice, 10)
|
||||
} catch (err) {
|
||||
console.error('Error while estimating transaction execution gas costs:')
|
||||
console.error(err)
|
||||
|
||||
return 10000
|
||||
}
|
||||
}
|
||||
|
||||
export const estimateSafeTxGas = async (
|
||||
safe: GnosisSafe | undefined,
|
||||
safeAddress: string,
|
||||
data: string,
|
||||
to: string,
|
||||
valueInWei: string,
|
||||
operation: number,
|
||||
): Promise<number> => {
|
||||
try {
|
||||
let safeInstance = safe
|
||||
if (!safeInstance) {
|
||||
safeInstance = await getGnosisSafeInstanceAt(safeAddress)
|
||||
}
|
||||
|
||||
const web3 = await getWeb3()
|
||||
const estimateData = safeInstance.methods.requiredTxGas(to, valueInWei, data, operation).encodeABI()
|
||||
const estimateResponse = await web3.eth.call({
|
||||
to: safeAddress,
|
||||
from: safeAddress,
|
||||
data: estimateData,
|
||||
})
|
||||
const txGasEstimation = new BigNumber(estimateResponse.substring(138), 16).toNumber() + 10000
|
||||
|
||||
// 21000 - additional gas costs (e.g. base tx costs, transfer costs)
|
||||
const dataGasEstimation = estimateDataGasCosts(estimateData) + 21000
|
||||
const additionalGasBatches = [10000, 20000, 40000, 80000, 160000, 320000, 640000, 1280000, 2560000, 5120000]
|
||||
|
||||
const batch = new web3.BatchRequest()
|
||||
const estimationRequests = additionalGasBatches.map(
|
||||
(additionalGas) =>
|
||||
new Promise((resolve) => {
|
||||
// there are no type definitions for .request, so for now ts-ignore is there
|
||||
// Issue link: https://github.com/ethereum/web3.js/issues/3144
|
||||
// eslint-disable-next-line
|
||||
// @ts-ignore
|
||||
const request = web3.eth.call.request(
|
||||
{
|
||||
to: safeAddress,
|
||||
from: safeAddress,
|
||||
data: estimateData,
|
||||
gasPrice: 0,
|
||||
gasLimit: txGasEstimation + dataGasEstimation + additionalGas,
|
||||
},
|
||||
(error, res) => {
|
||||
// res.data check is for OpenEthereum/Parity revert messages format
|
||||
const isOpenEthereumRevertMsg = res && typeof res.data === 'string'
|
||||
|
||||
const isEstimationSuccessful =
|
||||
!error &&
|
||||
((typeof res === 'string' && res !== '0x') || (isOpenEthereumRevertMsg && res.data.slice(9) !== '0x'))
|
||||
|
||||
resolve({
|
||||
success: isEstimationSuccessful,
|
||||
estimation: txGasEstimation + additionalGas,
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
batch.add(request)
|
||||
}),
|
||||
)
|
||||
batch.execute()
|
||||
|
||||
const estimationResponses = await Promise.all(estimationRequests)
|
||||
const firstSuccessfulRequest: any = estimationResponses.find((res: any) => res.success)
|
||||
|
||||
if (firstSuccessfulRequest) {
|
||||
return firstSuccessfulRequest.estimation
|
||||
}
|
||||
|
||||
return 0
|
||||
} catch (error) {
|
||||
console.error('Error calculating tx gas estimation', error)
|
||||
return 0
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
export * from './gas'
|
||||
export * from './send'
|
||||
export * from './offchainSigner'
|
||||
export * from './txHistory'
|
||||
|
|
|
@ -2,6 +2,7 @@ import axios from 'axios'
|
|||
import { BigNumber } from 'bignumber.js'
|
||||
|
||||
import { getWeb3, web3ReadOnly } from 'src/logic/wallets/getWeb3'
|
||||
import { getGasPrice, getGasPriceOracle } from 'src/config'
|
||||
|
||||
// const MAINNET_NETWORK = 1
|
||||
export const EMPTY_DATA = '0x'
|
||||
|
@ -26,7 +27,7 @@ export const checkReceiptStatus = async (hash) => {
|
|||
return Promise.resolve()
|
||||
}
|
||||
|
||||
export const calculateGasPrice = async () => {
|
||||
export const calculateGasPrice = async (): Promise<string> => {
|
||||
/*
|
||||
const web3 = getWeb3()
|
||||
const { network } = web3.version
|
||||
|
@ -41,11 +42,23 @@ export const calculateGasPrice = async () => {
|
|||
return '20000000000'
|
||||
}
|
||||
|
||||
const url = 'https://ethgasstation.info/json/ethgasAPI.json'
|
||||
// const errMsg = 'Error querying gas station'
|
||||
const gasPrice = getGasPrice()
|
||||
const gasPriceOracle = getGasPriceOracle()
|
||||
|
||||
if (gasPrice) {
|
||||
// Fixed gas price in configuration. xDai uses this approach
|
||||
return new BigNumber(gasPrice).toString()
|
||||
} else if (gasPriceOracle) {
|
||||
const { url, gasParameter } = gasPriceOracle
|
||||
|
||||
// Fetch from gas price provider
|
||||
const { data } = await axios.get(url)
|
||||
|
||||
return new BigNumber(data.average).multipliedBy(1e8).toString()
|
||||
return new BigNumber(data[gasParameter]).multipliedBy(1e8).toString()
|
||||
} else {
|
||||
const errorMsg = 'gasPrice or gasPriceOracle not set in config'
|
||||
return Promise.reject(errorMsg)
|
||||
}
|
||||
}
|
||||
|
||||
export const calculateGasOf = async (data, from, to) => {
|
||||
|
|
|
@ -20,7 +20,7 @@ import createTransaction from 'src/logic/safe/store/actions/createTransaction'
|
|||
import { MULTI_SEND_ADDRESS } from 'src/logic/contracts/safeContracts'
|
||||
import { DELEGATE_CALL, TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions'
|
||||
import { encodeMultiSendCall } from 'src/logic/safe/transactions/multisend'
|
||||
import { estimateSafeTxGas } from 'src/logic/safe/transactions/gasNew'
|
||||
import { estimateSafeTxGas } from 'src/logic/safe/transactions/gas'
|
||||
|
||||
import GasEstimationInfo from './GasEstimationInfo'
|
||||
import { getNetworkInfo } from 'src/config'
|
||||
|
|
|
@ -14,7 +14,7 @@ import Paragraph from 'src/components/layout/Paragraph'
|
|||
import Row from 'src/components/layout/Row'
|
||||
import { AbiItemExtended } from 'src/logic/contractInteraction/sources/ABIService'
|
||||
import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions'
|
||||
import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew'
|
||||
import { estimateTxGasCosts } from 'src/logic/safe/transactions/gas'
|
||||
import { formatAmount } from 'src/logic/tokens/utils/formatAmount'
|
||||
import { getEthAsToken } from 'src/logic/tokens/utils/tokenHelpers'
|
||||
import { styles } from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/style'
|
||||
|
|
|
@ -19,7 +19,7 @@ import Row from 'src/components/layout/Row'
|
|||
import createTransaction from 'src/logic/safe/store/actions/createTransaction'
|
||||
import { safeSelector } from 'src/logic/safe/store/selectors'
|
||||
import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions'
|
||||
import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew'
|
||||
import { estimateTxGasCosts } from 'src/logic/safe/transactions/gas'
|
||||
import { formatAmount } from 'src/logic/tokens/utils/formatAmount'
|
||||
import { getEthAsToken } from 'src/logic/tokens/utils/tokenHelpers'
|
||||
import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo'
|
||||
|
|
|
@ -20,7 +20,7 @@ import { nftTokensSelector } from 'src/logic/collectibles/store/selectors'
|
|||
import createTransaction from 'src/logic/safe/store/actions/createTransaction'
|
||||
import { safeSelector } from 'src/logic/safe/store/selectors'
|
||||
import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions'
|
||||
import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew'
|
||||
import { estimateTxGasCosts } from 'src/logic/safe/transactions/gas'
|
||||
import {
|
||||
containsMethodByHash,
|
||||
getERC721TokenContract,
|
||||
|
|
|
@ -21,7 +21,7 @@ import Row from 'src/components/layout/Row'
|
|||
import createTransaction from 'src/logic/safe/store/actions/createTransaction'
|
||||
import { safeSelector } from 'src/logic/safe/store/selectors'
|
||||
import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions'
|
||||
import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew'
|
||||
import { estimateTxGasCosts } from 'src/logic/safe/transactions/gas'
|
||||
import { getHumanFriendlyToken } from 'src/logic/tokens/store/actions/fetchTokens'
|
||||
import { formatAmount } from 'src/logic/tokens/utils/formatAmount'
|
||||
import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions'
|
||||
|
|
|
@ -17,7 +17,7 @@ import Paragraph from 'src/components/layout/Paragraph'
|
|||
import Row from 'src/components/layout/Row'
|
||||
import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts'
|
||||
import { safeNameSelector, safeOwnersSelector, safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors'
|
||||
import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew'
|
||||
import { estimateTxGasCosts } from 'src/logic/safe/transactions/gas'
|
||||
import { formatAmount } from 'src/logic/tokens/utils/formatAmount'
|
||||
|
||||
import { styles } from './style'
|
||||
|
|
|
@ -17,7 +17,7 @@ import Paragraph from 'src/components/layout/Paragraph'
|
|||
import Row from 'src/components/layout/Row'
|
||||
import { getGnosisSafeInstanceAt, SENTINEL_ADDRESS } from 'src/logic/contracts/safeContracts'
|
||||
import { safeNameSelector, safeOwnersSelector, safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors'
|
||||
import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew'
|
||||
import { estimateTxGasCosts } from 'src/logic/safe/transactions/gas'
|
||||
import { formatAmount } from 'src/logic/tokens/utils/formatAmount'
|
||||
|
||||
import { styles } from './style'
|
||||
|
|
|
@ -22,7 +22,7 @@ import {
|
|||
safeParamAddressFromStateSelector,
|
||||
safeThresholdSelector,
|
||||
} from 'src/logic/safe/store/selectors'
|
||||
import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew'
|
||||
import { estimateTxGasCosts } from 'src/logic/safe/transactions/gas'
|
||||
import { formatAmount } from 'src/logic/tokens/utils/formatAmount'
|
||||
|
||||
import { styles } from './style'
|
||||
|
|
|
@ -18,7 +18,7 @@ import Hairline from 'src/components/layout/Hairline'
|
|||
import Paragraph from 'src/components/layout/Paragraph'
|
||||
import Row from 'src/components/layout/Row'
|
||||
import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts'
|
||||
import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew'
|
||||
import { estimateTxGasCosts } from 'src/logic/safe/transactions/gas'
|
||||
import { formatAmount } from 'src/logic/tokens/utils/formatAmount'
|
||||
|
||||
const THRESHOLD_FIELD_NAME = 'threshold'
|
||||
|
|
|
@ -18,7 +18,7 @@ import Hairline from 'src/components/layout/Hairline'
|
|||
import Paragraph from 'src/components/layout/Paragraph'
|
||||
import Row from 'src/components/layout/Row'
|
||||
import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions'
|
||||
import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew'
|
||||
import { estimateTxGasCosts } from 'src/logic/safe/transactions/gas'
|
||||
import { formatAmount } from 'src/logic/tokens/utils/formatAmount'
|
||||
import { userAccountSelector } from 'src/logic/wallets/store/selectors'
|
||||
import processTransaction from 'src/logic/safe/store/actions/processTransaction'
|
||||
|
|
|
@ -16,7 +16,7 @@ import Hairline from 'src/components/layout/Hairline'
|
|||
import Paragraph from 'src/components/layout/Paragraph'
|
||||
import Row from 'src/components/layout/Row'
|
||||
import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions'
|
||||
import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew'
|
||||
import { estimateTxGasCosts } from 'src/logic/safe/transactions/gas'
|
||||
import { formatAmount } from 'src/logic/tokens/utils/formatAmount'
|
||||
import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions'
|
||||
import createTransaction from 'src/logic/safe/store/actions/createTransaction'
|
||||
|
|
Loading…
Reference in New Issue