Gas estimations for approving TX wip, fix notifications reducer which led to infinite loop during HMR

This commit is contained in:
Mikhail Mikheev 2019-10-10 18:25:33 +04:00
parent ee483a98e4
commit de16a0cdec
7 changed files with 51 additions and 15 deletions

View File

@ -1,11 +1,17 @@
// @flow
import React, { Component } from 'react'
import { Component } from 'react'
import { List } from 'immutable'
import { connect } from 'react-redux'
import { withSnackbar } from 'notistack'
import actions from './actions'
import { type Notification } from '~/logic/notifications/store/models/notification'
import actions, {type Actions } from './actions'
import selector from './selector'
class Notifier extends Component {
type Props = Actions & {
notifications: List<Notification>,
}
class Notifier extends Component<Props> {
displayed = []
shouldComponentUpdate({ notifications: newSnacks = [] }) {

View File

@ -29,7 +29,5 @@ export default handleActions<NotificationReducerState, *>(
return state.delete(key)
},
},
Map({
notifications: Map(),
}),
Map(),
)

View File

@ -5,7 +5,7 @@ import { type GlobalState } from '~/store'
import { NOTIFICATIONS_REDUCER_ID } from '~/logic/notifications/store/reducer/notifications'
import { type Notification } from '~/logic/notifications/store/models/notification'
export const notificationsMapSelector = (
const notificationsMapSelector = (
state: GlobalState,
): Map<string, Notification> => state[NOTIFICATIONS_REDUCER_ID]

View File

@ -1,16 +1,17 @@
// @flow
import GnosisSafeSol from '@gnosis.pm/safe-contracts/build/contracts/GnosisSafe.json'
import { List } from 'immutable'
import { type Confirmation } from '~/routes/safe/store/models/confirmation'
import { getWeb3, getAccountFrom } from '~/logic/wallets/getWeb3'
import { calculateGasOf, calculateGasPrice } from '~/logic/wallets/ethTransactions'
import { ZERO_ADDRESS } from '~/logic/wallets/ethAddresses'
import { type Transaction } from '~/routes/safe/store/models/transaction'
import { CALL } from '.'
export const estimateTxGasCosts = async (
safeAddress: string,
to: string,
data: string,
tx?: Transaction,
confirmations?: List<Confirmation>,
): Promise<number> => {
try {
const web3 = getWeb3()
@ -19,12 +20,12 @@ export const estimateTxGasCosts = async (
const nonce = await safeInstance.methods.nonce().call()
const threshold = await safeInstance.methods.getThreshold().call()
const isExecution = (tx && tx.confirmations.size) || threshold === '1'
const isExecution = (confirmations && confirmations.size) || threshold === '1'
let txData
if (isExecution) {
// https://gnosis-safe.readthedocs.io/en/latest/contracts/signatures.html#pre-validated-signatures
const signatures = tx
const signatures = confirmations
|| `0x000000000000000000000000${from.replace(
'0x',
'',

View File

@ -1,5 +1,5 @@
// @flow
import React, { useState } from 'react'
import React, { useState, useEffect } from 'react'
import Close from '@material-ui/icons/Close'
import IconButton from '@material-ui/core/IconButton'
import { withStyles } from '@material-ui/core/styles'
@ -13,6 +13,9 @@ import Row from '~/components/layout/Row'
import Bold from '~/components/layout/Bold'
import Block from '~/components/layout/Block'
import Paragraph from '~/components/layout/Paragraph'
import { getWeb3 } from '~/logic/wallets/getWeb3'
import { estimateTxGasCosts } from '~/logic/safe/transactions/gasNew'
import { formatAmount } from '~/logic/tokens/utils/formatAmount'
import { TX_NOTIFICATION_TYPES } from '~/logic/safe/transactions'
import { type Transaction } from '~/routes/safe/store/models/transaction'
import { styles } from './style'
@ -62,9 +65,32 @@ const ApproveTxModal = ({
closeSnackbar,
}: Props) => {
const [approveAndExecute, setApproveAndExecute] = useState<boolean>(true)
const [gasCosts, setGasCosts] = useState<string>('< 0.001')
const { title, description } = getModalTitleAndDescription(thresholdReached)
const oneConfirmationLeft = tx.confirmations.size + 1 === threshold
useEffect(() => {
let isCurrent = true
const estimateGas = async () => {
const web3 = getWeb3()
const { fromWei, toBN } = web3.utils
const estimatedGasCosts = await estimateTxGasCosts(safeAddress, tx.recipient, tx.data, tx.confirmations)
const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether')
const formattedGasCosts = formatAmount(gasCostsAsEth)
if (isCurrent) {
setGasCosts(formattedGasCosts)
}
}
estimateGas()
return () => {
isCurrent = false
}
}, [approveAndExecute])
const handleExecuteCheckbox = () => setApproveAndExecute((prevApproveAndExecute) => !prevApproveAndExecute)
const approveTx = () => {
@ -112,6 +138,11 @@ const ApproveTxModal = ({
</>
)}
</Row>
<Row>
<Paragraph>
{`You're about to ${approveAndExecute ? 'execute' : 'approve'} a transaction and will have to confirm it with your currently connected wallet. Make sure you have ${gasCosts} (fee price) ETH in this wallet to fund this confirmation.`}
</Paragraph>
</Row>
</Block>
<Row align="center" className={classes.buttonRow}>
<Button minWidth={140} minHeight={42} onClick={onClose}>

View File

@ -10,7 +10,7 @@ export type SafeProps = {
address: string,
threshold: number,
owners: List<Owner>,
balances: Map<string, string>,
balances?: Map<string, string>,
activeTokens: Set<string>,
ethBalance?: string,
}
@ -21,7 +21,7 @@ const SafeRecord: RecordFactory<SafeProps> = Record({
threshold: 0,
ethBalance: 0,
owners: List([]),
activeTokens: new Set([]),
activeTokens: new Set(),
balances: Map({}),
})

View File

@ -15,7 +15,7 @@ import provider, { PROVIDER_REDUCER_ID, type State as ProviderState } from '~/lo
import tokens, { TOKEN_REDUCER_ID, type State as TokensState } from '~/logic/tokens/store/reducer/tokens'
import notifications, {
NOTIFICATIONS_REDUCER_ID,
type State as NotificationsState,
type NotificationReducerState as NotificationsState,
} from '~/logic/notifications/store/reducer/notifications'
export const history = createBrowserHistory()