Add gas costs to custom tx, add etherscan/copy btns to send funds flow
This commit is contained in:
parent
4d25c04410
commit
769f16401a
|
@ -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'
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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}>
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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' }} />
|
||||||
|
|
|
@ -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' }} />
|
||||||
|
|
Loading…
Reference in New Issue