Add gas costs to custom tx, add etherscan/copy btns to send funds flow

This commit is contained in:
Mikhail Mikheev 2019-10-09 16:47:05 +04:00
parent 4d25c04410
commit 769f16401a
8 changed files with 68 additions and 67 deletions

View File

@ -1,6 +1,6 @@
// @flow // @flow
import * as React from 'react'
import classNames from 'classnames/bind' import classNames from 'classnames/bind'
import React from 'react'
import { capitalize } from '~/utils/css' import { capitalize } from '~/utils/css'
import styles from './index.scss' import styles from './index.scss'

View File

@ -1,23 +1,17 @@
// @flow // @flow
import React from 'react' import React from 'react'
import OpenInNew from '@material-ui/icons/OpenInNew' import { makeStyles } from '@material-ui/core/styles'
import { withStyles } from '@material-ui/core/styles'
import Row from '~/components/layout/Row' import Row from '~/components/layout/Row'
import Col from '~/components/layout/Col' import Col from '~/components/layout/Col'
import Paragraph from '~/components/layout/Paragraph' import Paragraph from '~/components/layout/Paragraph'
import Link from '~/components/layout/Link' import EtherscanBtn from '~/components/EtherscanBtn'
import CopyBtn from '~/components/CopyBtn'
import Bold from '~/components/layout/Bold' import Bold from '~/components/layout/Bold'
import Block from '~/components/layout/Block' import Block from '~/components/layout/Block'
import Identicon from '~/components/Identicon' import Identicon from '~/components/Identicon'
import { copyToClipboard } from '~/utils/clipboard' import { xs, border } from '~/theme/variables'
import { secondary, xs, border } from '~/theme/variables'
const openIconStyle = { const useStyles = makeStyles({
height: '16px',
color: secondary,
}
const styles = () => ({
balanceContainer: { balanceContainer: {
fontSize: '12px', fontSize: '12px',
lineHeight: 1.08, lineHeight: 1.08,
@ -28,20 +22,22 @@ const styles = () => ({
marginTop: xs, marginTop: xs,
borderRadius: '3px', borderRadius: '3px',
}, },
address: {
marginRight: xs,
},
}) })
type Props = { type Props = {
classes: Object,
safeAddress: string, safeAddress: string,
etherScanLink: string,
safeName: string, safeName: string,
ethBalance: string, ethBalance: string,
} }
const SafeInfo = (props: Props) => { const SafeInfo = (props: Props) => {
const { const {
safeAddress, safeName, etherScanLink, ethBalance, classes, safeAddress, safeName, ethBalance,
} = props } = props
const classes = useStyles()
return ( return (
<Row margin="md"> <Row margin="md">
@ -52,21 +48,18 @@ const SafeInfo = (props: Props) => {
<Paragraph weight="bolder" noMargin style={{ lineHeight: 1 }}> <Paragraph weight="bolder" noMargin style={{ lineHeight: 1 }}>
{safeName} {safeName}
</Paragraph> </Paragraph>
<Paragraph weight="bolder" onClick={copyToClipboard} noMargin> <Block justify="left">
<Paragraph weight="bolder" className={classes.address} noMargin>
{safeAddress} {safeAddress}
<Link to={etherScanLink} target="_blank">
<OpenInNew style={openIconStyle} />
</Link>
</Paragraph> </Paragraph>
<CopyBtn content={safeAddress} />
<EtherscanBtn type="address" value={safeAddress} />
</Block>
<Block className={classes.balanceContainer}> <Block className={classes.balanceContainer}>
<Paragraph noMargin> <Paragraph noMargin>
Balance: Balance:
{' '} {' '}
<Bold> <Bold>{`${ethBalance} ETH`}</Bold>
{ethBalance}
{' '}
ETH
</Bold>
</Paragraph> </Paragraph>
</Block> </Block>
</Col> </Col>
@ -74,4 +67,4 @@ const SafeInfo = (props: Props) => {
) )
} }
export default withStyles(styles)(SafeInfo) export default SafeInfo

View File

@ -113,7 +113,6 @@ const Send = ({
<SendFunds <SendFunds
onClose={onClose} onClose={onClose}
safeAddress={safeAddress} safeAddress={safeAddress}
etherScanLink={etherScanLink}
safeName={safeName} safeName={safeName}
ethBalance={ethBalance} ethBalance={ethBalance}
tokens={tokens} tokens={tokens}
@ -128,7 +127,6 @@ const Send = ({
onClose={onClose} onClose={onClose}
setActiveScreen={setActiveScreen} setActiveScreen={setActiveScreen}
safeAddress={safeAddress} safeAddress={safeAddress}
etherScanLink={etherScanLink}
safeName={safeName} safeName={safeName}
ethBalance={ethBalance} ethBalance={ethBalance}
createTransaction={createTransaction} createTransaction={createTransaction}
@ -138,7 +136,6 @@ const Send = ({
<SendCustomTx <SendCustomTx
onClose={onClose} onClose={onClose}
safeAddress={safeAddress} safeAddress={safeAddress}
etherScanLink={etherScanLink}
safeName={safeName} safeName={safeName}
ethBalance={ethBalance} ethBalance={ethBalance}
onSubmit={handleCustomTxCreation} onSubmit={handleCustomTxCreation}

View File

@ -1,5 +1,5 @@
// @flow // @flow
import React from 'react' import React, { useState, useEffect } from 'react'
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'
import Close from '@material-ui/icons/Close' import Close from '@material-ui/icons/Close'
@ -17,9 +17,11 @@ import Hairline from '~/components/layout/Hairline'
import { copyToClipboard } from '~/utils/clipboard' import { copyToClipboard } from '~/utils/clipboard'
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 { estimateApprovalTxGasCosts } from '~/logic/safe/transactions/gasNew'
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'
import { getEthAsToken } from '~/logic/tokens/utils/tokenHelpers' import { getEthAsToken } from '~/logic/tokens/utils/tokenHelpers'
import { formatAmount } from '~/logic/tokens/utils/formatAmount'
import ArrowDown from '../assets/arrow-down.svg' import ArrowDown from '../assets/arrow-down.svg'
import { secondary } from '~/theme/variables' import { secondary } from '~/theme/variables'
import { styles } from './style' import { styles } from './style'
@ -56,10 +58,33 @@ const ReviewCustomTx = ({
enqueueSnackbar, enqueueSnackbar,
closeSnackbar, closeSnackbar,
}: Props) => { }: Props) => {
const [gasCosts, setGasCosts] = useState<string>('< 0.001')
useEffect(() => {
let isCurrent = true
const estimateGas = async () => {
const web3 = getWeb3()
const { fromWei, toBN } = web3.utils
const estimatedGasCosts = await estimateApprovalTxGasCosts(safeAddress, tx.recipientAddress, tx.data.trim())
const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether')
const formattedGasCosts = formatAmount(gasCostsAsEth)
if (isCurrent) {
setGasCosts(formattedGasCosts)
}
}
estimateGas()
return () => {
isCurrent = false
}
}, [])
const submitTx = async () => { const submitTx = async () => {
const web3 = getWeb3() const web3 = getWeb3()
const txRecipient = tx.recipientAddress const txRecipient = tx.recipientAddress
const txData = tx.data const txData = tx.data.trim()
const txValue = tx.value ? web3.utils.toWei(tx.value, 'ether') : 0 const txValue = tx.value ? web3.utils.toWei(tx.value, 'ether') : 0
createTransaction( createTransaction(
@ -125,7 +150,7 @@ const ReviewCustomTx = ({
</Paragraph> </Paragraph>
</Row> </Row>
<Row margin="md" align="center"> <Row margin="md" align="center">
<Img src={getEthAsToken().logoUri} height={28} alt="Ether" onError={setImageToPlaceholder} /> <Img src={getEthAsToken('0').logoUri} height={28} alt="Ether" onError={setImageToPlaceholder} />
<Paragraph size="md" noMargin className={classes.value}> <Paragraph size="md" noMargin className={classes.value}>
{tx.value || 0} {tx.value || 0}
{' ETH'} {' ETH'}
@ -143,6 +168,11 @@ const ReviewCustomTx = ({
</Row> </Row>
</Col> </Col>
</Row> </Row>
<Row>
<Paragraph>
{`You're about to create 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> </Block>
<Hairline /> <Hairline />
<Row align="center" className={classes.buttonRow}> <Row align="center" className={classes.buttonRow}>

View File

@ -1,20 +1,19 @@
// @flow // @flow
import React, { useEffect, useState } 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 { withStyles } from '@material-ui/core/styles' import { withStyles } from '@material-ui/core/styles'
import Close from '@material-ui/icons/Close' import Close from '@material-ui/icons/Close'
import IconButton from '@material-ui/core/IconButton' import IconButton from '@material-ui/core/IconButton'
import { withSnackbar } from 'notistack' import { withSnackbar } from 'notistack'
import Paragraph from '~/components/layout/Paragraph' import Paragraph from '~/components/layout/Paragraph'
import Row from '~/components/layout/Row' import Row from '~/components/layout/Row'
import Link from '~/components/layout/Link'
import Col from '~/components/layout/Col' import Col from '~/components/layout/Col'
import Button from '~/components/layout/Button' import Button from '~/components/layout/Button'
import Img from '~/components/layout/Img' import Img from '~/components/layout/Img'
import Block from '~/components/layout/Block' import Block from '~/components/layout/Block'
import EtherscanBtn from '~/components/EtherscanBtn'
import CopyBtn from '~/components/CopyBtn'
import Identicon from '~/components/Identicon' import Identicon from '~/components/Identicon'
import { copyToClipboard } from '~/utils/clipboard'
import Hairline from '~/components/layout/Hairline' 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'
@ -24,7 +23,6 @@ import { EMPTY_DATA } from '~/logic/wallets/ethTransactions'
import { formatAmount } from '~/logic/tokens/utils/formatAmount' import { formatAmount } from '~/logic/tokens/utils/formatAmount'
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'
import { secondary } from '~/theme/variables'
import { isEther } from '~/logic/tokens/utils/tokenHelpers' import { isEther } from '~/logic/tokens/utils/tokenHelpers'
import ArrowDown from '../assets/arrow-down.svg' import ArrowDown from '../assets/arrow-down.svg'
import { styles } from './style' import { styles } from './style'
@ -34,7 +32,6 @@ type Props = {
setActiveScreen: Function, setActiveScreen: Function,
classes: Object, classes: Object,
safeAddress: string, safeAddress: string,
etherScanLink: string,
safeName: string, safeName: string,
ethBalance: string, ethBalance: string,
tx: Object, tx: Object,
@ -43,17 +40,11 @@ type Props = {
closeSnackbar: Function, closeSnackbar: Function,
} }
const openIconStyle = {
height: '16px',
color: secondary,
}
const ReviewTx = ({ const ReviewTx = ({
onClose, onClose,
setActiveScreen, setActiveScreen,
classes, classes,
safeAddress, safeAddress,
etherScanLink,
safeName, safeName,
ethBalance, ethBalance,
tx, tx,
@ -139,7 +130,7 @@ const ReviewTx = ({
</Row> </Row>
<Hairline /> <Hairline />
<Block className={classes.container}> <Block className={classes.container}>
<SafeInfo safeAddress={safeAddress} etherScanLink={etherScanLink} safeName={safeName} ethBalance={ethBalance} /> <SafeInfo safeAddress={safeAddress} 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' }} />
@ -158,12 +149,13 @@ const ReviewTx = ({
<Identicon address={tx.recipientAddress} diameter={32} /> <Identicon address={tx.recipientAddress} diameter={32} />
</Col> </Col>
<Col xs={11} layout="column"> <Col xs={11} layout="column">
<Paragraph weight="bolder" onClick={copyToClipboard} noMargin> <Block justify="left">
<Paragraph weight="bolder" className={classes.address} noMargin>
{tx.recipientAddress} {tx.recipientAddress}
<Link to={etherScanLink} target="_blank">
<OpenInNew style={openIconStyle} />
</Link>
</Paragraph> </Paragraph>
<CopyBtn content={tx.recipientAddress} />
<EtherscanBtn type="address" value={tx.recipientAddress} />
</Block>
</Col> </Col>
</Row> </Row>
<Row margin="xs"> <Row margin="xs">

View File

@ -29,6 +29,9 @@ export const styles = () => ({
amount: { amount: {
marginLeft: sm, marginLeft: sm,
}, },
address: {
marginRight: sm,
},
buttonRow: { buttonRow: {
height: '84px', height: '84px',
justifyContent: 'center', justifyContent: 'center',

View File

@ -30,7 +30,6 @@ type Props = {
onClose: () => void, onClose: () => void,
classes: Object, classes: Object,
safeAddress: string, safeAddress: string,
etherScanLink: string,
safeName: string, safeName: string,
ethBalance: string, ethBalance: string,
onSubmit: Function, onSubmit: Function,
@ -41,7 +40,6 @@ const SendCustomTx = ({
classes, classes,
onClose, onClose,
safeAddress, safeAddress,
etherScanLink,
safeName, safeName,
ethBalance, ethBalance,
onSubmit, onSubmit,
@ -101,12 +99,7 @@ const SendCustomTx = ({
return ( return (
<> <>
<Block className={classes.formContainer}> <Block className={classes.formContainer}>
<SafeInfo <SafeInfo safeAddress={safeAddress} 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' }} />

View File

@ -33,7 +33,6 @@ type Props = {
onClose: () => void, onClose: () => void,
classes: Object, classes: Object,
safeAddress: string, safeAddress: string,
etherScanLink: string,
safeName: string, safeName: string,
ethBalance: string, ethBalance: string,
selectedToken: string, selectedToken: string,
@ -60,7 +59,6 @@ const SendFunds = ({
classes, classes,
onClose, onClose,
safeAddress, safeAddress,
etherScanLink,
safeName, safeName,
ethBalance, ethBalance,
tokens, tokens,
@ -114,12 +112,7 @@ const SendFunds = ({
return ( return (
<> <>
<Block className={classes.formContainer}> <Block className={classes.formContainer}>
<SafeInfo <SafeInfo safeAddress={safeAddress} 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' }} />