Review spending cap screen (#15919)
parent
d97b9c7eef
commit
a993509afc
@ -0,0 +1,241 @@ |
||||
import React, { useContext } from 'react'; |
||||
import PropTypes from 'prop-types'; |
||||
import classnames from 'classnames'; |
||||
import Box from '../../ui/box/box'; |
||||
import Button from '../../ui/button'; |
||||
import EditGasFeeButton from '../edit-gas-fee-button/edit-gas-fee-button'; |
||||
import Typography from '../../ui/typography/typography'; |
||||
import { |
||||
ALIGN_ITEMS, |
||||
BLOCK_SIZES, |
||||
COLORS, |
||||
DISPLAY, |
||||
FLEX_DIRECTION, |
||||
FONT_WEIGHT, |
||||
JUSTIFY_CONTENT, |
||||
TEXT_ALIGN, |
||||
TYPOGRAPHY, |
||||
} from '../../../helpers/constants/design-system'; |
||||
import { I18nContext } from '../../../../.storybook/i18n'; |
||||
import GasDetailsItem from '../gas-details-item/gas-details-item'; |
||||
import MultiLayerFeeMessage from '../multilayer-fee-message/multi-layer-fee-message'; |
||||
import { formatCurrency } from '../../../helpers/utils/confirm-tx.util'; |
||||
|
||||
export default function ApproveContentCard({ |
||||
showHeader = true, |
||||
symbol, |
||||
title, |
||||
showEdit, |
||||
showAdvanceGasFeeOptions = false, |
||||
onEditClick, |
||||
footer, |
||||
noBorder, |
||||
supportsEIP1559V2, |
||||
renderTransactionDetailsContent, |
||||
renderDataContent, |
||||
isMultiLayerFeeNetwork, |
||||
ethTransactionTotal, |
||||
nativeCurrency, |
||||
fullTxData, |
||||
hexTransactionTotal, |
||||
fiatTransactionTotal, |
||||
currentCurrency, |
||||
isSetApproveForAll, |
||||
isApprovalOrRejection, |
||||
data, |
||||
}) { |
||||
const t = useContext(I18nContext); |
||||
|
||||
return ( |
||||
<Box |
||||
className={classnames({ |
||||
'approve-content-card-container__card': !noBorder, |
||||
'approve-content-card-container__card--no-border': noBorder, |
||||
})} |
||||
> |
||||
{showHeader && ( |
||||
<Box |
||||
display={DISPLAY.FLEX} |
||||
flexDirection={FLEX_DIRECTION.ROW} |
||||
alignItems={ALIGN_ITEMS.CENTER} |
||||
justifyContent={JUSTIFY_CONTENT.FLEX_END} |
||||
className="approve-content-card-container__card-header" |
||||
> |
||||
{supportsEIP1559V2 && title === t('transactionFee') ? null : ( |
||||
<> |
||||
<Box className="approve-content-card-container__card-header__symbol"> |
||||
{symbol} |
||||
</Box> |
||||
<Box |
||||
marginLeft={4} |
||||
className="approve-content-card-container__card-header__title" |
||||
> |
||||
<Typography |
||||
variant={TYPOGRAPHY.H6} |
||||
fontWeight={FONT_WEIGHT.BOLD} |
||||
> |
||||
{title} |
||||
</Typography> |
||||
</Box> |
||||
</> |
||||
)} |
||||
{showEdit && (!showAdvanceGasFeeOptions || !supportsEIP1559V2) && ( |
||||
<Box width={BLOCK_SIZES.ONE_SIXTH}> |
||||
<Button type="link" onClick={() => onEditClick()}> |
||||
<Typography |
||||
variant={TYPOGRAPHY.H7} |
||||
color={COLORS.PRIMARY_DEFAULT} |
||||
> |
||||
{t('edit')} |
||||
</Typography> |
||||
</Button> |
||||
</Box> |
||||
)} |
||||
{showEdit && showAdvanceGasFeeOptions && supportsEIP1559V2 && ( |
||||
<EditGasFeeButton /> |
||||
)} |
||||
</Box> |
||||
)} |
||||
<Box |
||||
marginTop={1} |
||||
marginBottom={3} |
||||
className="approve-content-card-container__card-content" |
||||
> |
||||
{renderTransactionDetailsContent && |
||||
(!isMultiLayerFeeNetwork && supportsEIP1559V2 ? ( |
||||
<GasDetailsItem /> |
||||
) : ( |
||||
<Box |
||||
display={DISPLAY.FLEX} |
||||
flexDirection={FLEX_DIRECTION.ROW} |
||||
justifyContent={JUSTIFY_CONTENT.SPACE_BETWEEN} |
||||
> |
||||
{isMultiLayerFeeNetwork ? ( |
||||
<Box |
||||
display={DISPLAY.FLEX} |
||||
flexDirection={FLEX_DIRECTION.COLUMN} |
||||
className="approve-content-card-container__transaction-details-extra-content" |
||||
> |
||||
<Box |
||||
display={DISPLAY.FLEX} |
||||
justifyContent={JUSTIFY_CONTENT.SPACE_BETWEEN} |
||||
> |
||||
<Typography |
||||
variant={TYPOGRAPHY.H6} |
||||
fontWeight={FONT_WEIGHT.NORMAL} |
||||
color={COLORS.TEXT_MUTED} |
||||
> |
||||
<span>{t('transactionDetailLayer2GasHeading')}</span> |
||||
{`${ethTransactionTotal} ${nativeCurrency}`} |
||||
</Typography> |
||||
</Box> |
||||
<MultiLayerFeeMessage |
||||
transaction={fullTxData} |
||||
layer2fee={hexTransactionTotal} |
||||
nativeCurrency={nativeCurrency} |
||||
plainStyle |
||||
/> |
||||
</Box> |
||||
) : ( |
||||
<> |
||||
<Box> |
||||
<Typography |
||||
variant={TYPOGRAPHY.H7} |
||||
color={COLORS.TEXT_ALTERNATIVE} |
||||
> |
||||
{t('feeAssociatedRequest')} |
||||
</Typography> |
||||
</Box> |
||||
<Box |
||||
display={DISPLAY.FLEX} |
||||
flexDirection={FLEX_DIRECTION.COLUMN} |
||||
alignItems={ALIGN_ITEMS.FLEX_END} |
||||
textAlign={TEXT_ALIGN.RIGHT} |
||||
> |
||||
<Box> |
||||
<Typography |
||||
variant={TYPOGRAPHY.H4} |
||||
fontWeight={FONT_WEIGHT.BOLD} |
||||
color={COLORS.TEXT_DEFAULT} |
||||
> |
||||
{formatCurrency(fiatTransactionTotal, currentCurrency)} |
||||
</Typography> |
||||
</Box> |
||||
<Box> |
||||
<Typography |
||||
variant={TYPOGRAPHY.H6} |
||||
fontWeight={FONT_WEIGHT.NORMAL} |
||||
color={COLORS.TEXT_MUTED} |
||||
> |
||||
{`${ethTransactionTotal} ${nativeCurrency}`} |
||||
</Typography> |
||||
</Box> |
||||
</Box> |
||||
</> |
||||
)} |
||||
</Box> |
||||
))} |
||||
{renderDataContent && ( |
||||
<Box display={DISPLAY.FLEX} flexDirection={FLEX_DIRECTION.COLUMN}> |
||||
<Box> |
||||
<Typography |
||||
variant={TYPOGRAPHY.H7} |
||||
color={COLORS.TEXT_ALTERNATIVE} |
||||
> |
||||
{isSetApproveForAll |
||||
? t('functionSetApprovalForAll') |
||||
: t('functionApprove')} |
||||
</Typography> |
||||
</Box> |
||||
{isSetApproveForAll && isApprovalOrRejection !== undefined ? ( |
||||
<Box> |
||||
<Typography |
||||
variant={TYPOGRAPHY.H7} |
||||
color={COLORS.TEXT_ALTERNATIVE} |
||||
> |
||||
{`${t('parameters')}: ${isApprovalOrRejection}`} |
||||
</Typography> |
||||
</Box> |
||||
) : null} |
||||
<Box |
||||
marginRight={4} |
||||
className="approve-content-card-container__data__data-block" |
||||
> |
||||
<Typography |
||||
variant={TYPOGRAPHY.H7} |
||||
color={COLORS.TEXT_ALTERNATIVE} |
||||
> |
||||
{data} |
||||
</Typography> |
||||
</Box> |
||||
</Box> |
||||
)} |
||||
</Box> |
||||
{footer} |
||||
</Box> |
||||
); |
||||
} |
||||
|
||||
ApproveContentCard.propTypes = { |
||||
showHeader: PropTypes.bool, |
||||
symbol: PropTypes.node, |
||||
title: PropTypes.string, |
||||
showEdit: PropTypes.bool, |
||||
showAdvanceGasFeeOptions: PropTypes.bool, |
||||
onEditClick: PropTypes.func, |
||||
footer: PropTypes.node, |
||||
noBorder: PropTypes.bool, |
||||
supportsEIP1559V2: PropTypes.bool, |
||||
renderTransactionDetailsContent: PropTypes.bool, |
||||
renderDataContent: PropTypes.bool, |
||||
isMultiLayerFeeNetwork: PropTypes.bool, |
||||
ethTransactionTotal: PropTypes.string, |
||||
nativeCurrency: PropTypes.string, |
||||
fullTxData: PropTypes.object, |
||||
hexTransactionTotal: PropTypes.string, |
||||
fiatTransactionTotal: PropTypes.string, |
||||
currentCurrency: PropTypes.string, |
||||
isSetApproveForAll: PropTypes.bool, |
||||
isApprovalOrRejection: PropTypes.bool, |
||||
data: PropTypes.string, |
||||
}; |
@ -0,0 +1 @@ |
||||
export { default } from './approve-content-card'; |
@ -0,0 +1,51 @@ |
||||
.approve-content-card-container { |
||||
&__card, |
||||
&__card--no-border { |
||||
border-bottom: 1px solid var(--color-border-default); |
||||
position: relative; |
||||
padding-inline-start: 24px; |
||||
padding-inline-end: 24px; |
||||
} |
||||
|
||||
&__card--no-border { |
||||
border-bottom: none; |
||||
} |
||||
|
||||
&__card-header { |
||||
position: relative; |
||||
|
||||
&__symbol { |
||||
width: auto; |
||||
} |
||||
|
||||
&__symbol--aligned { |
||||
width: 100%; |
||||
} |
||||
|
||||
&__title { |
||||
width: 100%; |
||||
} |
||||
|
||||
&__title--aligned { |
||||
margin-inline-start: 27px; |
||||
position: absolute; |
||||
width: auto; |
||||
} |
||||
} |
||||
|
||||
&__card-content--aligned { |
||||
margin-inline-start: 42px; |
||||
} |
||||
|
||||
&__transaction-details-extra-content { |
||||
width: 100%; |
||||
} |
||||
|
||||
&__data { |
||||
width: 100%; |
||||
|
||||
&__data-block { |
||||
overflow-wrap: break-word; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1 @@ |
||||
export { default } from './token-allowance'; |
@ -0,0 +1,41 @@ |
||||
.token-allowance-container { |
||||
&__icon-display-content { |
||||
width: fit-content; |
||||
height: 40px; |
||||
box-sizing: border-box; |
||||
border-radius: 100px; |
||||
position: relative; |
||||
|
||||
&__siteimage-identicon { |
||||
width: 24px; |
||||
height: 24px; |
||||
box-shadow: none; |
||||
background: none; |
||||
} |
||||
} |
||||
|
||||
a.token-allowance-container__verify-link { |
||||
width: fit-content; |
||||
margin-inline-start: 96px; |
||||
margin-inline-end: 96px; |
||||
padding: 0; |
||||
} |
||||
|
||||
a.token-allowance-container__view-details { |
||||
width: fit-content; |
||||
margin-inline-start: 108px; |
||||
margin-inline-end: 108px; |
||||
} |
||||
|
||||
&__card-wrapper { |
||||
width: 100%; |
||||
} |
||||
|
||||
&__data { |
||||
width: 100%; |
||||
} |
||||
|
||||
&__full-tx-content { |
||||
max-width: 100%; |
||||
} |
||||
} |
@ -0,0 +1,437 @@ |
||||
import React, { useState, useContext } from 'react'; |
||||
import { useDispatch, useSelector } from 'react-redux'; |
||||
import { useHistory } from 'react-router-dom'; |
||||
import PropTypes from 'prop-types'; |
||||
import Box from '../../components/ui/box/box'; |
||||
import NetworkAccountBalanceHeader from '../../components/app/network-account-balance-header/network-account-balance-header'; |
||||
import UrlIcon from '../../components/ui/url-icon/url-icon'; |
||||
import Typography from '../../components/ui/typography/typography'; |
||||
import { |
||||
ALIGN_ITEMS, |
||||
BORDER_STYLE, |
||||
COLORS, |
||||
DISPLAY, |
||||
FLEX_DIRECTION, |
||||
FONT_WEIGHT, |
||||
JUSTIFY_CONTENT, |
||||
TEXT_ALIGN, |
||||
TYPOGRAPHY, |
||||
} from '../../helpers/constants/design-system'; |
||||
import { I18nContext } from '../../contexts/i18n'; |
||||
import ContractTokenValues from '../../components/ui/contract-token-values/contract-token-values'; |
||||
import Button from '../../components/ui/button'; |
||||
import ReviewSpendingCap from '../../components/ui/review-spending-cap/review-spending-cap'; |
||||
import { PageContainerFooter } from '../../components/ui/page-container'; |
||||
import ContractDetailsModal from '../../components/app/modals/contract-details-modal/contract-details-modal'; |
||||
import { |
||||
getCurrentAccountWithSendEtherInfo, |
||||
getNetworkIdentifier, |
||||
transactionFeeSelector, |
||||
getKnownMethodData, |
||||
getRpcPrefsForCurrentProvider, |
||||
} from '../../selectors'; |
||||
import { NETWORK_TO_NAME_MAP } from '../../../shared/constants/network'; |
||||
import { |
||||
cancelTx, |
||||
updateAndApproveTx, |
||||
updateCustomNonce, |
||||
} from '../../store/actions'; |
||||
import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck'; |
||||
import { getMostRecentOverviewPage } from '../../ducks/history/history'; |
||||
import ApproveContentCard from '../../components/app/approve-content-card/approve-content-card'; |
||||
|
||||
export default function TokenAllowance({ |
||||
origin, |
||||
siteImage, |
||||
showCustomizeGasModal, |
||||
useNonceField, |
||||
currentCurrency, |
||||
nativeCurrency, |
||||
ethTransactionTotal, |
||||
fiatTransactionTotal, |
||||
hexTransactionTotal, |
||||
txData, |
||||
isMultiLayerFeeNetwork, |
||||
supportsEIP1559V2, |
||||
userAddress, |
||||
tokenAddress, |
||||
data, |
||||
isSetApproveForAll, |
||||
isApprovalOrRejection, |
||||
customTxParamsData, |
||||
dappProposedTokenAmount, |
||||
currentTokenBalance, |
||||
toAddress, |
||||
tokenSymbol, |
||||
}) { |
||||
const t = useContext(I18nContext); |
||||
const dispatch = useDispatch(); |
||||
const history = useHistory(); |
||||
const mostRecentOverviewPage = useSelector(getMostRecentOverviewPage); |
||||
|
||||
const [showContractDetails, setShowContractDetails] = useState(false); |
||||
const [showFullTxDetails, setShowFullTxDetails] = useState(false); |
||||
const [isFirstPage, setIsFirstPage] = useState(false); |
||||
|
||||
const currentAccount = useSelector(getCurrentAccountWithSendEtherInfo); |
||||
const networkIdentifier = useSelector(getNetworkIdentifier); |
||||
const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider); |
||||
|
||||
let fullTxData = { ...txData }; |
||||
|
||||
if (customTxParamsData) { |
||||
fullTxData = { |
||||
...fullTxData, |
||||
txParams: { |
||||
...fullTxData.txParams, |
||||
data: customTxParamsData, |
||||
}, |
||||
}; |
||||
} |
||||
|
||||
const fee = useSelector((state) => transactionFeeSelector(state, fullTxData)); |
||||
const methodData = useSelector((state) => getKnownMethodData(state, data)); |
||||
|
||||
const networkName = |
||||
NETWORK_TO_NAME_MAP[fullTxData.chainId] || networkIdentifier; |
||||
|
||||
const customNonceValue = ''; |
||||
const customNonceMerge = (transactionData) => |
||||
customNonceValue |
||||
? { |
||||
...transactionData, |
||||
customNonceValue, |
||||
} |
||||
: transactionData; |
||||
|
||||
const handleReject = () => { |
||||
dispatch(cancelTx(fullTxData)).then(() => { |
||||
dispatch(clearConfirmTransaction()); |
||||
dispatch(updateCustomNonce('')); |
||||
history.push(mostRecentOverviewPage); |
||||
}); |
||||
}; |
||||
|
||||
const handleApprove = () => { |
||||
const { name } = methodData; |
||||
|
||||
if (fee.gasEstimationObject.baseFeePerGas) { |
||||
fullTxData.estimatedBaseFee = fee.gasEstimationObject.baseFeePerGas; |
||||
} |
||||
|
||||
if (name) { |
||||
fullTxData.contractMethodName = name; |
||||
} |
||||
|
||||
if (dappProposedTokenAmount) { |
||||
fullTxData.dappProposedTokenAmount = dappProposedTokenAmount; |
||||
fullTxData.originalApprovalAmount = dappProposedTokenAmount; |
||||
} |
||||
|
||||
if (currentTokenBalance) { |
||||
fullTxData.currentTokenBalance = currentTokenBalance; |
||||
} |
||||
|
||||
dispatch(updateAndApproveTx(customNonceMerge(fullTxData))).then(() => { |
||||
dispatch(clearConfirmTransaction()); |
||||
dispatch(updateCustomNonce('')); |
||||
history.push(mostRecentOverviewPage); |
||||
}); |
||||
}; |
||||
|
||||
return ( |
||||
<Box className="token-allowance-container page-container"> |
||||
<Box |
||||
paddingLeft={4} |
||||
paddingRight={4} |
||||
alignItems={ALIGN_ITEMS.CENTER} |
||||
display={DISPLAY.FLEX} |
||||
flexDirection={FLEX_DIRECTION.ROW} |
||||
justifyContent={JUSTIFY_CONTENT.SPACE_BETWEEN} |
||||
> |
||||
<Box> |
||||
{!isFirstPage && ( |
||||
<Button type="inline" onClick={() => setIsFirstPage(true)}> |
||||
<Typography |
||||
variant={TYPOGRAPHY.H6} |
||||
color={COLORS.TEXT_MUTED} |
||||
fontWeight={FONT_WEIGHT.BOLD} |
||||
> |
||||
{'<'} {t('back')} |
||||
</Typography> |
||||
</Button> |
||||
)} |
||||
</Box> |
||||
<Box textAlign={TEXT_ALIGN.END}> |
||||
<Typography |
||||
variant={TYPOGRAPHY.H7} |
||||
color={COLORS.TEXT_MUTED} |
||||
fontWeight={FONT_WEIGHT.BOLD} |
||||
> |
||||
{isFirstPage ? 1 : 2} {t('ofTextNofM')} 2 |
||||
</Typography> |
||||
</Box> |
||||
</Box> |
||||
<NetworkAccountBalanceHeader |
||||
networkName={networkName} |
||||
accountName={currentAccount.name} |
||||
accountBalance={currentTokenBalance} |
||||
tokenName={tokenSymbol} |
||||
accountAddress={userAddress} |
||||
/> |
||||
<Box |
||||
display={DISPLAY.FLEX} |
||||
flexDirection={FLEX_DIRECTION.ROW} |
||||
justifyContent={JUSTIFY_CONTENT.CENTER} |
||||
> |
||||
<Box |
||||
display={DISPLAY.FLEX} |
||||
alignItems={ALIGN_ITEMS.CENTER} |
||||
marginTop={6} |
||||
marginRight={12} |
||||
marginBottom={8} |
||||
marginLeft={12} |
||||
paddingTop={2} |
||||
paddingRight={4} |
||||
paddingBottom={2} |
||||
paddingLeft={2} |
||||
borderColor={COLORS.BORDER_MUTED} |
||||
borderStyle={BORDER_STYLE.SOLID} |
||||
borderWidth={1} |
||||
className="token-allowance-container__icon-display-content" |
||||
> |
||||
<UrlIcon |
||||
className="token-allowance-container__icon-display-content__siteimage-identicon" |
||||
fallbackClassName="token-allowance-container__icon-display-content__siteimage-identicon" |
||||
name={origin} |
||||
url={siteImage} |
||||
/> |
||||
<Typography |
||||
variant={TYPOGRAPHY.H6} |
||||
fontWeight={FONT_WEIGHT.NORMAL} |
||||
color={COLORS.TEXT_ALTERNATIVE} |
||||
boxProps={{ marginLeft: 1, marginTop: 2 }} |
||||
> |
||||
{origin} |
||||
</Typography> |
||||
</Box> |
||||
</Box> |
||||
<Box marginBottom={5}> |
||||
<Typography |
||||
variant={TYPOGRAPHY.H3} |
||||
fontWeight={FONT_WEIGHT.BOLD} |
||||
align={TEXT_ALIGN.CENTER} |
||||
> |
||||
{isFirstPage ? t('setSpendingCap') : t('reviewSpendingCap')} |
||||
</Typography> |
||||
</Box> |
||||
<Box> |
||||
<ContractTokenValues |
||||
tokenName={tokenSymbol} |
||||
address={tokenAddress} |
||||
chainId={fullTxData.chainId} |
||||
rpcPrefs={rpcPrefs} |
||||
/> |
||||
</Box> |
||||
<Box |
||||
marginTop={1} |
||||
display={DISPLAY.FLEX} |
||||
flexDirection={FLEX_DIRECTION.ROW} |
||||
justifyContent={JUSTIFY_CONTENT.CENTER} |
||||
> |
||||
<Button |
||||
type="link" |
||||
onClick={() => setShowContractDetails(true)} |
||||
className="token-allowance-container__verify-link" |
||||
> |
||||
<Typography variant={TYPOGRAPHY.H6} color={COLORS.PRIMARY_DEFAULT}> |
||||
{t('verifyContractDetails')} |
||||
</Typography> |
||||
</Button> |
||||
</Box> |
||||
<Box margin={[4, 4, 3, 4]}> |
||||
<ReviewSpendingCap |
||||
tokenName={tokenSymbol} |
||||
currentTokenBalance={parseFloat(currentTokenBalance)} |
||||
tokenValue={10} |
||||
onEdit={() => setIsFirstPage(true)} |
||||
/> |
||||
</Box> |
||||
{!isFirstPage && ( |
||||
<Box className="token-allowance-container__card-wrapper"> |
||||
<ApproveContentCard |
||||
symbol={<i className="fa fa-tag" />} |
||||
title={t('transactionFee')} |
||||
showEdit |
||||
showAdvanceGasFeeOptions |
||||
onEditClick={showCustomizeGasModal} |
||||
renderTransactionDetailsContent |
||||
noBorder={useNonceField || !showFullTxDetails} |
||||
supportsEIP1559V2={supportsEIP1559V2} |
||||
isMultiLayerFeeNetwork={isMultiLayerFeeNetwork} |
||||
ethTransactionTotal={ethTransactionTotal} |
||||
nativeCurrency={nativeCurrency} |
||||
fullTxData={fullTxData} |
||||
hexTransactionTotal={hexTransactionTotal} |
||||
fiatTransactionTotal={fiatTransactionTotal} |
||||
currentCurrency={currentCurrency} |
||||
/> |
||||
</Box> |
||||
)} |
||||
<Box |
||||
display={DISPLAY.FLEX} |
||||
flexDirection={FLEX_DIRECTION.ROW} |
||||
justifyContent={JUSTIFY_CONTENT.CENTER} |
||||
> |
||||
<Button |
||||
type="link" |
||||
onClick={() => setShowFullTxDetails(!showFullTxDetails)} |
||||
className="token-allowance-container__view-details" |
||||
> |
||||
<Typography |
||||
variant={TYPOGRAPHY.H6} |
||||
color={COLORS.PRIMARY_DEFAULT} |
||||
marginRight={1} |
||||
> |
||||
{t('viewDetails')} |
||||
</Typography> |
||||
{showFullTxDetails ? ( |
||||
<i className="fa fa-sm fa-angle-up" /> |
||||
) : ( |
||||
<i className="fa fa-sm fa-angle-down" /> |
||||
)} |
||||
</Button> |
||||
</Box> |
||||
{showFullTxDetails ? ( |
||||
<Box |
||||
display={DISPLAY.FLEX} |
||||
flexDirection={FLEX_DIRECTION.COLUMN} |
||||
alignItems={ALIGN_ITEMS.CENTER} |
||||
className="token-allowance-container__full-tx-content" |
||||
> |
||||
<Box className="token-allowance-container__data"> |
||||
<ApproveContentCard |
||||
symbol={<i className="fa fa-file" />} |
||||
title={t('data')} |
||||
renderDataContent |
||||
noBorder |
||||
supportsEIP1559V2={supportsEIP1559V2} |
||||
isSetApproveForAll={isSetApproveForAll} |
||||
isApprovalOrRejection={isApprovalOrRejection} |
||||
data={data} |
||||
/> |
||||
</Box> |
||||
</Box> |
||||
) : null} |
||||
<PageContainerFooter |
||||
cancelText={t('reject')} |
||||
submitText={isFirstPage ? t('next') : t('approveButtonText')} |
||||
onCancel={() => handleReject()} |
||||
onSubmit={() => (isFirstPage ? setIsFirstPage(false) : handleApprove())} |
||||
/> |
||||
{showContractDetails && ( |
||||
<ContractDetailsModal |
||||
tokenName={tokenSymbol} |
||||
onClose={() => setShowContractDetails(false)} |
||||
tokenAddress={tokenAddress} |
||||
toAddress={toAddress} |
||||
chainId={fullTxData.chainId} |
||||
rpcPrefs={rpcPrefs} |
||||
origin={origin} |
||||
siteImage={siteImage} |
||||
/> |
||||
)} |
||||
</Box> |
||||
); |
||||
} |
||||
|
||||
TokenAllowance.propTypes = { |
||||
/** |
||||
* Dapp URL |
||||
*/ |
||||
origin: PropTypes.string, |
||||
/** |
||||
* Dapp image |
||||
*/ |
||||
siteImage: PropTypes.string, |
||||
/** |
||||
* Function that is supposed to open the customized gas modal |
||||
*/ |
||||
showCustomizeGasModal: PropTypes.func, |
||||
/** |
||||
* Whether nonce field should be used or not |
||||
*/ |
||||
useNonceField: PropTypes.bool, |
||||
/** |
||||
* Current fiat currency (e.g. USD) |
||||
*/ |
||||
currentCurrency: PropTypes.string, |
||||
/** |
||||
* Current native currency (e.g. RopstenETH) |
||||
*/ |
||||
nativeCurrency: PropTypes.string, |
||||
/** |
||||
* Total sum of the transaction in native currency |
||||
*/ |
||||
ethTransactionTotal: PropTypes.string, |
||||
/** |
||||
* Total sum of the transaction in fiat currency |
||||
*/ |
||||
fiatTransactionTotal: PropTypes.string, |
||||
/** |
||||
* Total sum of the transaction converted to hex value |
||||
*/ |
||||
hexTransactionTotal: PropTypes.string, |
||||
/** |
||||
* Current transaction |
||||
*/ |
||||
txData: PropTypes.object, |
||||
/** |
||||
* Is multi-layer fee network or not |
||||
*/ |
||||
isMultiLayerFeeNetwork: PropTypes.bool, |
||||
/** |
||||
* Is the enhanced gas fee enabled or not |
||||
*/ |
||||
supportsEIP1559V2: PropTypes.bool, |
||||
/** |
||||
* User's address |
||||
*/ |
||||
userAddress: PropTypes.string, |
||||
/** |
||||
* Address of the token that is waiting to be allowed |
||||
*/ |
||||
tokenAddress: PropTypes.string, |
||||
/** |
||||
* Current transaction data |
||||
*/ |
||||
data: PropTypes.string, |
||||
/** |
||||
* Is set approve for all or not |
||||
*/ |
||||
isSetApproveForAll: PropTypes.bool, |
||||
/** |
||||
* Whether a current set approval for all transaction will approve or revoke access |
||||
*/ |
||||
isApprovalOrRejection: PropTypes.bool, |
||||
/** |
||||
* Custom transaction parameters data made by the user (fees) |
||||
*/ |
||||
customTxParamsData: PropTypes.object, |
||||
/** |
||||
* Token amount proposed by the Dapp |
||||
*/ |
||||
dappProposedTokenAmount: PropTypes.string, |
||||
/** |
||||
* Token balance of the current account |
||||
*/ |
||||
currentTokenBalance: PropTypes.string, |
||||
/** |
||||
* Contract address requesting spending cap |
||||
*/ |
||||
toAddress: PropTypes.string, |
||||
/** |
||||
* Symbol of the token that is waiting to be allowed |
||||
*/ |
||||
tokenSymbol: PropTypes.string, |
||||
}; |
@ -0,0 +1,201 @@ |
||||
import React from 'react'; |
||||
import TokenAllowance from './token-allowance'; |
||||
|
||||
export default { |
||||
title: 'Pages/TokenAllowance', |
||||
id: __filename, |
||||
argTypes: { |
||||
origin: { |
||||
control: 'text', |
||||
}, |
||||
siteImage: { |
||||
control: 'text', |
||||
}, |
||||
showCustomizeGasModal: { |
||||
action: 'showCustomizeGasModal', |
||||
}, |
||||
useNonceField: { |
||||
control: 'boolean', |
||||
}, |
||||
currentCurrency: { |
||||
control: 'text', |
||||
}, |
||||
nativeCurrency: { |
||||
control: 'text', |
||||
}, |
||||
ethTransactionTotal: { |
||||
control: 'text', |
||||
}, |
||||
fiatTransactionTotal: { |
||||
control: 'text', |
||||
}, |
||||
hexTransactionTotal: { |
||||
control: 'text', |
||||
}, |
||||
isMultiLayerFeeNetwork: { |
||||
control: 'text', |
||||
}, |
||||
supportsEIP1559V2: { |
||||
control: 'boolean', |
||||
}, |
||||
userAddress: { |
||||
control: 'text', |
||||
}, |
||||
tokenAddress: { |
||||
control: 'text', |
||||
}, |
||||
data: { |
||||
control: 'text', |
||||
}, |
||||
isSetApproveForAll: { |
||||
control: 'boolean', |
||||
}, |
||||
setApproveForAllArg: { |
||||
control: 'boolean', |
||||
}, |
||||
customTxParamsData: { |
||||
control: 'object', |
||||
}, |
||||
dappProposedTokenAmount: { |
||||
control: 'text', |
||||
}, |
||||
currentTokenBalance: { |
||||
control: 'text', |
||||
}, |
||||
toAddress: { |
||||
control: 'text', |
||||
}, |
||||
tokenSymbol: { |
||||
control: 'text', |
||||
}, |
||||
txData: { |
||||
control: 'object', |
||||
}, |
||||
}, |
||||
args: { |
||||
origin: 'https://metamask.github.io', |
||||
siteImage: 'https://metamask.github.io/test-dapp/metamask-fox.svg', |
||||
useNonceField: false, |
||||
currentCurrency: 'usd', |
||||
nativeCurrency: 'RopstenETH', |
||||
ethTransactionTotal: '0.0012', |
||||
fiatTransactionTotal: '1.6', |
||||
hexTransactionTotal: '0x44364c5bb0000', |
||||
isMultiLayerFeeNetwork: false, |
||||
supportsEIP1559V2: false, |
||||
userAddress: '0xdd34b35ca1de17dfcdc07f79ff1f8f94868c40a1', |
||||
tokenAddress: '0x55797717b9947b31306f4aac7ad1365c6e3923bd', |
||||
data: '0x095ea7b30000000000000000000000009bc5baf874d2da8d216ae9f137804184ee5afef40000000000000000000000000000000000000000000000000000000000011170', |
||||
isSetApproveForAll: false, |
||||
setApproveForAllArg: false, |
||||
customTxParamsData: {}, |
||||
dappProposedTokenAmount: '7', |
||||
currentTokenBalance: '10', |
||||
toAddress: '0x9bc5baf874d2da8d216ae9f137804184ee5afef4', |
||||
tokenSymbol: 'TST', |
||||
txData: { |
||||
id: 3049568294499567, |
||||
time: 1664449552289, |
||||
status: 'unapproved', |
||||
metamaskNetworkId: '3', |
||||
originalGasEstimate: '0xea60', |
||||
userEditedGasLimit: false, |
||||
chainId: '0x3', |
||||
loadingDefaults: false, |
||||
dappSuggestedGasFees: { |
||||
gasPrice: '0x4a817c800', |
||||
gas: '0xea60', |
||||
}, |
||||
sendFlowHistory: [], |
||||
txParams: { |
||||
from: '0xdd34b35ca1de17dfcdc07f79ff1f8f94868c40a1', |
||||
to: '0x55797717b9947b31306f4aac7ad1365c6e3923bd', |
||||
value: '0x0', |
||||
data: '0x095ea7b30000000000000000000000009bc5baf874d2da8d216ae9f137804184ee5afef40000000000000000000000000000000000000000000000000000000000011170', |
||||
gas: '0xea60', |
||||
maxFeePerGas: '0x4a817c800', |
||||
maxPriorityFeePerGas: '0x4a817c800', |
||||
}, |
||||
origin: 'https://metamask.github.io', |
||||
type: 'approve', |
||||
history: [ |
||||
{ |
||||
id: 3049568294499567, |
||||
time: 1664449552289, |
||||
status: 'unapproved', |
||||
metamaskNetworkId: '3', |
||||
originalGasEstimate: '0xea60', |
||||
userEditedGasLimit: false, |
||||
chainId: '0x3', |
||||
loadingDefaults: true, |
||||
dappSuggestedGasFees: { |
||||
gasPrice: '0x4a817c800', |
||||
gas: '0xea60', |
||||
}, |
||||
sendFlowHistory: [], |
||||
txParams: { |
||||
from: '0xdd34b35ca1de17dfcdc07f79ff1f8f94868c40a1', |
||||
to: '0x55797717b9947b31306f4aac7ad1365c6e3923bd', |
||||
value: '0x0', |
||||
data: '0x095ea7b30000000000000000000000009bc5baf874d2da8d216ae9f137804184ee5afef40000000000000000000000000000000000000000000000000000000000011170', |
||||
gas: '0xea60', |
||||
gasPrice: '0x4a817c800', |
||||
}, |
||||
origin: 'https://metamask.github.io', |
||||
type: 'approve', |
||||
}, |
||||
[ |
||||
{ |
||||
op: 'remove', |
||||
path: '/txParams/gasPrice', |
||||
note: 'Added new unapproved transaction.', |
||||
timestamp: 1664449553939, |
||||
}, |
||||
{ |
||||
op: 'add', |
||||
path: '/txParams/maxFeePerGas', |
||||
value: '0x4a817c800', |
||||
}, |
||||
{ |
||||
op: 'add', |
||||
path: '/txParams/maxPriorityFeePerGas', |
||||
value: '0x4a817c800', |
||||
}, |
||||
{ |
||||
op: 'replace', |
||||
path: '/loadingDefaults', |
||||
value: false, |
||||
}, |
||||
{ |
||||
op: 'add', |
||||
path: '/userFeeLevel', |
||||
value: 'custom', |
||||
}, |
||||
{ |
||||
op: 'add', |
||||
path: '/defaultGasEstimates', |
||||
value: { |
||||
estimateType: 'custom', |
||||
gas: '0xea60', |
||||
maxFeePerGas: '0x4a817c800', |
||||
maxPriorityFeePerGas: '0x4a817c800', |
||||
}, |
||||
}, |
||||
], |
||||
], |
||||
userFeeLevel: 'custom', |
||||
defaultGasEstimates: { |
||||
estimateType: 'custom', |
||||
gas: '0xea60', |
||||
maxFeePerGas: '0x4a817c800', |
||||
maxPriorityFeePerGas: '0x4a817c800', |
||||
}, |
||||
}, |
||||
}, |
||||
}; |
||||
|
||||
export const DefaultStory = (args) => { |
||||
return <TokenAllowance {...args} />; |
||||
}; |
||||
|
||||
DefaultStory.storyName = 'Default'; |
Loading…
Reference in new issue