Token allowance screen updated (#16157)

feature/default_network_editable
Filip Sekulic 2 years ago committed by GitHub
parent 0336a3c006
commit 17c1fef9be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      app/_locales/en/messages.json
  2. 63
      ui/components/app/approve-content-card/approve-content-card.js
  3. 196
      ui/components/app/approve-content-card/approve-content-card.stories.js
  4. 64
      ui/components/app/custom-spending-cap/custom-spending-cap.js
  5. 4
      ui/components/app/custom-spending-cap/custom-spending-cap.stories.js
  6. 7
      ui/components/app/custom-spending-cap/index.scss
  7. 10
      ui/ducks/app/app.js
  8. 4
      ui/pages/confirm-approve/confirm-approve.js
  9. 96
      ui/pages/token-allowance/token-allowance.js
  10. 6
      ui/pages/token-allowance/token-allowance.stories.js
  11. 4
      ui/selectors/selectors.js
  12. 3
      ui/store/actionConstants.js

@ -2931,6 +2931,9 @@
"message": "By revoking permission, the following $1 will no longer be able to access your $2", "message": "By revoking permission, the following $1 will no longer be able to access your $2",
"description": "$1 is either key 'account' or 'contract', and $2 is either a string or link of a given token symbol or name" "description": "$1 is either key 'account' or 'contract', and $2 is either a string or link of a given token symbol or name"
}, },
"revokeSpendingCap": {
"message": "Revoke spending cap for your"
},
"revokeSpendingCapTooltipText": { "revokeSpendingCapTooltipText": {
"message": "This contract will be unable to spend any more of your current or future tokens." "message": "This contract will be unable to spend any more of your current or future tokens."
}, },

@ -217,25 +217,88 @@ export default function ApproveContentCard({
} }
ApproveContentCard.propTypes = { ApproveContentCard.propTypes = {
/**
* Whether to show header including icon, transaction fee text and edit button
*/
showHeader: PropTypes.bool, showHeader: PropTypes.bool,
/**
* Symbol icon
*/
symbol: PropTypes.node, symbol: PropTypes.node,
/**
* Title to be included in the header
*/
title: PropTypes.string, title: PropTypes.string,
/**
* Whether to show edit button or not
*/
showEdit: PropTypes.bool, showEdit: PropTypes.bool,
/**
* Whether to show advanced gas fee options or not
*/
showAdvanceGasFeeOptions: PropTypes.bool, showAdvanceGasFeeOptions: PropTypes.bool,
/**
* Should open customize gas modal when edit button is clicked
*/
onEditClick: PropTypes.func, onEditClick: PropTypes.func,
/**
* Footer to be shown
*/
footer: PropTypes.node, footer: PropTypes.node,
/**
* Whether to include border-bottom or not
*/
noBorder: PropTypes.bool, noBorder: PropTypes.bool,
/**
* Is enhanced gas fee enabled or not
*/
supportsEIP1559V2: PropTypes.bool, supportsEIP1559V2: PropTypes.bool,
/**
* Whether to render transaction details content or not
*/
renderTransactionDetailsContent: PropTypes.bool, renderTransactionDetailsContent: PropTypes.bool,
/**
* Whether to render data content or not
*/
renderDataContent: PropTypes.bool, renderDataContent: PropTypes.bool,
/**
* Is multi-layer fee network or not
*/
isMultiLayerFeeNetwork: PropTypes.bool, isMultiLayerFeeNetwork: PropTypes.bool,
/**
* Total sum of the transaction in native currency
*/
ethTransactionTotal: PropTypes.string, ethTransactionTotal: PropTypes.string,
/**
* Current native currency
*/
nativeCurrency: PropTypes.string, nativeCurrency: PropTypes.string,
/**
* Current transaction
*/
fullTxData: PropTypes.object, fullTxData: PropTypes.object,
/**
* Total sum of the transaction converted to hex value
*/
hexTransactionTotal: PropTypes.string, hexTransactionTotal: PropTypes.string,
/**
* Total sum of the transaction in fiat currency
*/
fiatTransactionTotal: PropTypes.string, fiatTransactionTotal: PropTypes.string,
/**
* Current fiat currency
*/
currentCurrency: PropTypes.string, currentCurrency: PropTypes.string,
/**
* Is set approve for all or not
*/
isSetApproveForAll: PropTypes.bool, isSetApproveForAll: PropTypes.bool,
/**
* Whether a current set approval for all transaction will approve or revoke access
*/
isApprovalOrRejection: PropTypes.bool, isApprovalOrRejection: PropTypes.bool,
/**
* Current transaction data
*/
data: PropTypes.string, data: PropTypes.string,
}; };

@ -0,0 +1,196 @@
import React from 'react';
import ApproveContentCard from './approve-content-card';
export default {
title: 'Components/App/ApproveContentCard',
id: __filename,
argTypes: {
showHeader: {
control: 'boolean',
},
symbol: {
control: 'array',
},
title: {
control: 'text',
},
showEdit: {
control: 'boolean',
},
showAdvanceGasFeeOptions: {
control: 'boolean',
},
footer: {
control: 'array',
},
noBorder: {
control: 'boolean',
},
supportsEIP1559V2: {
control: 'boolean',
},
renderTransactionDetailsContent: {
control: 'boolean',
},
renderDataContent: {
control: 'boolean',
},
isMultiLayerFeeNetwork: {
control: 'boolean',
},
ethTransactionTotal: {
control: 'text',
},
nativeCurrency: {
control: 'text',
},
fullTxData: {
control: 'object',
},
hexTransactionTotal: {
control: 'text',
},
fiatTransactionTotal: {
control: 'text',
},
currentCurrency: {
control: 'text',
},
isSetApproveForAll: {
control: 'boolean',
},
isApprovalOrRejection: {
control: 'boolean',
},
data: {
control: 'text',
},
onEditClick: {
control: 'onEditClick',
},
},
args: {
showHeader: true,
symbol: <i className="fa fa-tag" />,
title: 'Transaction fee',
showEdit: true,
showAdvanceGasFeeOptions: true,
noBorder: true,
supportsEIP1559V2: false,
renderTransactionDetailsContent: true,
renderDataContent: false,
isMultiLayerFeeNetwork: false,
ethTransactionTotal: '0.0012',
nativeCurrency: 'GoerliETH',
hexTransactionTotal: '0x44364c5bb0000',
fiatTransactionTotal: '1.54',
currentCurrency: 'usd',
isSetApproveForAll: false,
isApprovalOrRejection: false,
data: '',
fullTxData: {
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 <ApproveContentCard {...args} />;
};
DefaultStory.storyName = 'Default';

@ -1,4 +1,5 @@
import React, { useState, useContext } from 'react'; import React, { useState, useContext, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { I18nContext } from '../../../contexts/i18n'; import { I18nContext } from '../../../contexts/i18n';
import Box from '../../ui/box'; import Box from '../../ui/box';
@ -15,6 +16,8 @@ import {
JUSTIFY_CONTENT, JUSTIFY_CONTENT,
SIZES, SIZES,
} from '../../../helpers/constants/design-system'; } from '../../../helpers/constants/design-system';
import { getCustomTokenAmount } from '../../../selectors';
import { setCustomTokenAmount } from '../../../ducks/app/app';
import { CustomSpendingCapTooltip } from './custom-spending-cap-tooltip'; import { CustomSpendingCapTooltip } from './custom-spending-cap-tooltip';
export default function CustomSpendingCap({ export default function CustomSpendingCap({
@ -22,12 +25,17 @@ export default function CustomSpendingCap({
currentTokenBalance, currentTokenBalance,
dappProposedValue, dappProposedValue,
siteOrigin, siteOrigin,
onEdit, passTheErrorText,
}) { }) {
const t = useContext(I18nContext); const t = useContext(I18nContext);
const [value, setValue] = useState(''); const dispatch = useDispatch();
const [customSpendingCapText, setCustomSpendingCapText] = useState('');
const value = useSelector(getCustomTokenAmount);
const [error, setError] = useState(''); const [error, setError] = useState('');
const [showUseDefaultButton, setShowUseDefaultButton] = useState(
value !== String(dappProposedValue) && true,
);
const inputLogicEmptyStateText = t('inputLogicEmptyState'); const inputLogicEmptyStateText = t('inputLogicEmptyState');
const getInputTextLogic = (inputNumber) => { const getInputTextLogic = (inputNumber) => {
@ -57,6 +65,10 @@ export default function CustomSpendingCap({
}; };
}; };
const [customSpendingCapText, setCustomSpendingCapText] = useState(
getInputTextLogic(value).description,
);
const handleChange = (valueInput) => { const handleChange = (valueInput) => {
let spendingCapError = ''; let spendingCapError = '';
const inputTextLogic = getInputTextLogic(valueInput); const inputTextLogic = getInputTextLogic(valueInput);
@ -71,9 +83,19 @@ export default function CustomSpendingCap({
setError(''); setError('');
} }
setValue(valueInput); dispatch(setCustomTokenAmount(String(valueInput)));
}; };
useEffect(() => {
if (value !== String(dappProposedValue)) {
setShowUseDefaultButton(true);
}
}, [value, dappProposedValue]);
useEffect(() => {
passTheErrorText(error);
}, [error, passTheErrorText]);
const chooseTooltipContentText = const chooseTooltipContentText =
value > currentTokenBalance value > currentTokenBalance
? t('warningTooltipText', [ ? t('warningTooltipText', [
@ -100,7 +122,6 @@ export default function CustomSpendingCap({
onClick={(e) => { onClick={(e) => {
e.preventDefault(); e.preventDefault();
handleChange(currentTokenBalance); handleChange(currentTokenBalance);
setValue(currentTokenBalance);
}} }}
> >
{t('max')} {t('max')}
@ -131,6 +152,7 @@ export default function CustomSpendingCap({
} }
> >
<FormField <FormField
numeric
dataTestId="custom-spending-cap-input" dataTestId="custom-spending-cap-input"
autoFocus autoFocus
wrappingLabelProps={{ as: 'div' }} wrappingLabelProps={{ as: 'div' }}
@ -151,21 +173,19 @@ export default function CustomSpendingCap({
error={error} error={error}
value={value} value={value}
titleDetail={ titleDetail={
<button showUseDefaultButton && (
className="custom-spending-cap__input--button" <button
type="link" className="custom-spending-cap__input--button"
onClick={(e) => { type="link"
e.preventDefault(); onClick={(e) => {
if (value <= currentTokenBalance || error) { e.preventDefault();
setShowUseDefaultButton(false);
handleChange(dappProposedValue); handleChange(dappProposedValue);
setValue(dappProposedValue); }}
} else { >
onEdit(); {t('useDefault')}
} </button>
}} )
>
{value > currentTokenBalance ? t('edit') : t('useDefault')}
</button>
} }
titleDetailWrapperProps={{ marginBottom: 2, marginRight: 0 }} titleDetailWrapperProps={{ marginBottom: 2, marginRight: 0 }}
allowDecimals allowDecimals
@ -202,7 +222,7 @@ CustomSpendingCap.propTypes = {
*/ */
siteOrigin: PropTypes.string, siteOrigin: PropTypes.string,
/** /**
* onClick handler for the Edit link * Parent component's callback function passed in order to get the error text
*/ */
onEdit: PropTypes.func, passTheErrorText: PropTypes.func,
}; };

@ -17,8 +17,8 @@ export default {
siteOrigin: { siteOrigin: {
control: { type: 'text' }, control: { type: 'text' },
}, },
onEdit: { passTheErrorText: {
action: 'onEdit', action: 'passTheErrorText',
}, },
}, },
args: { args: {

@ -21,6 +21,7 @@
position: absolute; position: absolute;
margin-top: 55px; margin-top: 55px;
margin-inline-start: -75px; margin-inline-start: -75px;
z-index: 1;
} }
} }
@ -28,4 +29,10 @@
color: var(--color-error-default); color: var(--color-error-default);
padding-inline-end: 60px; padding-inline-end: 60px;
} }
input[type='number']::-webkit-inner-spin-button,
input[type='number']:hover::-webkit-inner-spin-button {
-webkit-appearance: none;
display: none;
}
} }

@ -58,6 +58,7 @@ export default function reduceApp(state = {}, action) {
newTokensImported: '', newTokensImported: '',
newCustomNetworkAdded: {}, newCustomNetworkAdded: {},
onboardedInThisUISession: false, onboardedInThisUISession: false,
customTokenAmount: '',
...state, ...state,
}; };
@ -401,6 +402,11 @@ export default function reduceApp(state = {}, action) {
...appState, ...appState,
onboardedInThisUISession: action.value, onboardedInThisUISession: action.value,
}; };
case actionConstants.SET_CUSTOM_TOKEN_AMOUNT:
return {
...appState,
customTokenAmount: action.value,
};
default: default:
return appState; return appState;
} }
@ -463,3 +469,7 @@ export function setNewCustomNetworkAdded(value) {
export function setOnBoardedInThisUISession(value) { export function setOnBoardedInThisUISession(value) {
return { type: actionConstants.ONBOARDED_IN_THIS_UI_SESSION, value }; return { type: actionConstants.ONBOARDED_IN_THIS_UI_SESSION, value };
} }
export function setCustomTokenAmount(value) {
return { type: actionConstants.SET_CUSTOM_TOKEN_AMOUNT, value };
}

@ -180,14 +180,14 @@ export default function ConfirmApprove({
supportsEIP1559V2={supportsEIP1559V2} supportsEIP1559V2={supportsEIP1559V2}
userAddress={userAddress} userAddress={userAddress}
tokenAddress={tokenAddress} tokenAddress={tokenAddress}
data={customData || transactionData} data={transactionData}
isSetApproveForAll={isSetApproveForAll} isSetApproveForAll={isSetApproveForAll}
isApprovalOrRejection={isApprovalOrRejection} isApprovalOrRejection={isApprovalOrRejection}
customTxParamsData={customData}
dappProposedTokenAmount={tokenAmount} dappProposedTokenAmount={tokenAmount}
currentTokenBalance={tokenBalance} currentTokenBalance={tokenBalance}
toAddress={toAddress} toAddress={toAddress}
tokenSymbol={tokenSymbol} tokenSymbol={tokenSymbol}
decimals={decimals}
/> />
{showCustomizeGasPopover && !supportsEIP1559V2 && ( {showCustomizeGasPopover && !supportsEIP1559V2 && (
<EditGasPopover <EditGasPopover

@ -29,6 +29,7 @@ import {
transactionFeeSelector, transactionFeeSelector,
getKnownMethodData, getKnownMethodData,
getRpcPrefsForCurrentProvider, getRpcPrefsForCurrentProvider,
getCustomTokenAmount,
} from '../../selectors'; } from '../../selectors';
import { NETWORK_TO_NAME_MAP } from '../../../shared/constants/network'; import { NETWORK_TO_NAME_MAP } from '../../../shared/constants/network';
import { import {
@ -39,6 +40,10 @@ import {
import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck'; import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck';
import { getMostRecentOverviewPage } from '../../ducks/history/history'; import { getMostRecentOverviewPage } from '../../ducks/history/history';
import ApproveContentCard from '../../components/app/approve-content-card/approve-content-card'; import ApproveContentCard from '../../components/app/approve-content-card/approve-content-card';
import CustomSpendingCap from '../../components/app/custom-spending-cap/custom-spending-cap';
import Dialog from '../../components/ui/dialog';
import { useGasFeeContext } from '../../contexts/gasFee';
import { getCustomTxParamsData } from '../confirm-approve/confirm-approve.util';
export default function TokenAllowance({ export default function TokenAllowance({
origin, origin,
@ -58,7 +63,7 @@ export default function TokenAllowance({
data, data,
isSetApproveForAll, isSetApproveForAll,
isApprovalOrRejection, isApprovalOrRejection,
customTxParamsData, decimals,
dappProposedTokenAmount, dappProposedTokenAmount,
currentTokenBalance, currentTokenBalance,
toAddress, toAddress,
@ -71,11 +76,22 @@ export default function TokenAllowance({
const [showContractDetails, setShowContractDetails] = useState(false); const [showContractDetails, setShowContractDetails] = useState(false);
const [showFullTxDetails, setShowFullTxDetails] = useState(false); const [showFullTxDetails, setShowFullTxDetails] = useState(false);
const [isFirstPage, setIsFirstPage] = useState(false); const [isFirstPage, setIsFirstPage] = useState(true);
const [errorText, setErrorText] = useState('');
const currentAccount = useSelector(getCurrentAccountWithSendEtherInfo); const currentAccount = useSelector(getCurrentAccountWithSendEtherInfo);
const networkIdentifier = useSelector(getNetworkIdentifier); const networkIdentifier = useSelector(getNetworkIdentifier);
const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider); const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider);
const customTokenAmount = useSelector(getCustomTokenAmount);
const customPermissionAmount = customTokenAmount.toString();
const customTxParamsData = customTokenAmount
? getCustomTxParamsData(data, {
customPermissionAmount,
decimals,
})
: null;
let fullTxData = { ...txData }; let fullTxData = { ...txData };
@ -92,6 +108,13 @@ export default function TokenAllowance({
const fee = useSelector((state) => transactionFeeSelector(state, fullTxData)); const fee = useSelector((state) => transactionFeeSelector(state, fullTxData));
const methodData = useSelector((state) => getKnownMethodData(state, data)); const methodData = useSelector((state) => getKnownMethodData(state, data));
const { balanceError } = useGasFeeContext();
const disableNextButton =
isFirstPage && (customTokenAmount === '' || errorText !== '');
const disableApproveButton = !isFirstPage && balanceError;
const networkName = const networkName =
NETWORK_TO_NAME_MAP[fullTxData.chainId] || networkIdentifier; NETWORK_TO_NAME_MAP[fullTxData.chainId] || networkIdentifier;
@ -105,9 +128,10 @@ export default function TokenAllowance({
: transactionData; : transactionData;
const handleReject = () => { const handleReject = () => {
dispatch(updateCustomNonce(''));
dispatch(cancelTx(fullTxData)).then(() => { dispatch(cancelTx(fullTxData)).then(() => {
dispatch(clearConfirmTransaction()); dispatch(clearConfirmTransaction());
dispatch(updateCustomNonce(''));
history.push(mostRecentOverviewPage); history.push(mostRecentOverviewPage);
}); });
}; };
@ -128,17 +152,35 @@ export default function TokenAllowance({
fullTxData.originalApprovalAmount = dappProposedTokenAmount; fullTxData.originalApprovalAmount = dappProposedTokenAmount;
} }
if (customTokenAmount) {
fullTxData.customTokenAmount = customTokenAmount;
fullTxData.finalApprovalAmount = customTokenAmount;
} else if (dappProposedTokenAmount !== undefined) {
fullTxData.finalApprovalAmount = dappProposedTokenAmount;
}
if (currentTokenBalance) { if (currentTokenBalance) {
fullTxData.currentTokenBalance = currentTokenBalance; fullTxData.currentTokenBalance = currentTokenBalance;
} }
dispatch(updateCustomNonce(''));
dispatch(updateAndApproveTx(customNonceMerge(fullTxData))).then(() => { dispatch(updateAndApproveTx(customNonceMerge(fullTxData))).then(() => {
dispatch(clearConfirmTransaction()); dispatch(clearConfirmTransaction());
dispatch(updateCustomNonce(''));
history.push(mostRecentOverviewPage); history.push(mostRecentOverviewPage);
}); });
}; };
const handleNextClick = () => {
setShowFullTxDetails(false);
setIsFirstPage(false);
};
const handleBackClick = () => {
setShowFullTxDetails(false);
setIsFirstPage(true);
};
return ( return (
<Box className="token-allowance-container page-container"> <Box className="token-allowance-container page-container">
<Box <Box
@ -151,7 +193,7 @@ export default function TokenAllowance({
> >
<Box> <Box>
{!isFirstPage && ( {!isFirstPage && (
<Button type="inline" onClick={() => setIsFirstPage(true)}> <Button type="inline" onClick={() => handleBackClick()}>
<Typography <Typography
variant={TYPOGRAPHY.H6} variant={TYPOGRAPHY.H6}
color={COLORS.TEXT_MUTED} color={COLORS.TEXT_MUTED}
@ -217,13 +259,17 @@ export default function TokenAllowance({
</Typography> </Typography>
</Box> </Box>
</Box> </Box>
<Box marginBottom={5}> <Box marginBottom={5} marginLeft={4} marginRight={4}>
<Typography <Typography
variant={TYPOGRAPHY.H3} variant={TYPOGRAPHY.H3}
fontWeight={FONT_WEIGHT.BOLD} fontWeight={FONT_WEIGHT.BOLD}
align={TEXT_ALIGN.CENTER} align={TEXT_ALIGN.CENTER}
> >
{isFirstPage ? t('setSpendingCap') : t('reviewSpendingCap')} {isFirstPage && t('setSpendingCap')}
{!isFirstPage &&
(customTokenAmount === 0
? t('revokeSpendingCap')
: t('reviewSpendingCap'))}
</Typography> </Typography>
</Box> </Box>
<Box> <Box>
@ -251,13 +297,28 @@ export default function TokenAllowance({
</Button> </Button>
</Box> </Box>
<Box margin={[4, 4, 3, 4]}> <Box margin={[4, 4, 3, 4]}>
<ReviewSpendingCap {isFirstPage ? (
tokenName={tokenSymbol} <CustomSpendingCap
currentTokenBalance={parseFloat(currentTokenBalance)} tokenName={tokenSymbol}
tokenValue={10} currentTokenBalance={parseFloat(currentTokenBalance)}
onEdit={() => setIsFirstPage(true)} dappProposedValue={parseFloat(dappProposedTokenAmount)}
/> siteOrigin={origin}
passTheErrorText={(value) => setErrorText(value)}
/>
) : (
<ReviewSpendingCap
tokenName={tokenSymbol}
currentTokenBalance={parseFloat(currentTokenBalance)}
tokenValue={parseFloat(customTokenAmount)}
onEdit={() => handleBackClick()}
/>
)}
</Box> </Box>
{!isFirstPage && balanceError && (
<Dialog type="error" className="send__error-dialog">
{t('insufficientFundsForGas')}
</Dialog>
)}
{!isFirstPage && ( {!isFirstPage && (
<Box className="token-allowance-container__card-wrapper"> <Box className="token-allowance-container__card-wrapper">
<ApproveContentCard <ApproveContentCard
@ -319,7 +380,7 @@ export default function TokenAllowance({
supportsEIP1559V2={supportsEIP1559V2} supportsEIP1559V2={supportsEIP1559V2}
isSetApproveForAll={isSetApproveForAll} isSetApproveForAll={isSetApproveForAll}
isApprovalOrRejection={isApprovalOrRejection} isApprovalOrRejection={isApprovalOrRejection}
data={data} data={customTxParamsData || data}
/> />
</Box> </Box>
</Box> </Box>
@ -328,7 +389,8 @@ export default function TokenAllowance({
cancelText={t('reject')} cancelText={t('reject')}
submitText={isFirstPage ? t('next') : t('approveButtonText')} submitText={isFirstPage ? t('next') : t('approveButtonText')}
onCancel={() => handleReject()} onCancel={() => handleReject()}
onSubmit={() => (isFirstPage ? setIsFirstPage(false) : handleApprove())} onSubmit={() => (isFirstPage ? handleNextClick() : handleApprove())}
disabled={disableNextButton || disableApproveButton}
/> />
{showContractDetails && ( {showContractDetails && (
<ContractDetailsModal <ContractDetailsModal
@ -416,9 +478,9 @@ TokenAllowance.propTypes = {
*/ */
isApprovalOrRejection: PropTypes.bool, isApprovalOrRejection: PropTypes.bool,
/** /**
* Custom transaction parameters data made by the user (fees) * Number of decimals
*/ */
customTxParamsData: PropTypes.object, decimals: PropTypes.string,
/** /**
* Token amount proposed by the Dapp * Token amount proposed by the Dapp
*/ */

@ -53,8 +53,8 @@ export default {
setApproveForAllArg: { setApproveForAllArg: {
control: 'boolean', control: 'boolean',
}, },
customTxParamsData: { decimals: {
control: 'object', control: 'text',
}, },
dappProposedTokenAmount: { dappProposedTokenAmount: {
control: 'text', control: 'text',
@ -88,7 +88,7 @@ export default {
data: '0x095ea7b30000000000000000000000009bc5baf874d2da8d216ae9f137804184ee5afef40000000000000000000000000000000000000000000000000000000000011170', data: '0x095ea7b30000000000000000000000009bc5baf874d2da8d216ae9f137804184ee5afef40000000000000000000000000000000000000000000000000000000000011170',
isSetApproveForAll: false, isSetApproveForAll: false,
setApproveForAllArg: false, setApproveForAllArg: false,
customTxParamsData: {}, decimals: '4',
dappProposedTokenAmount: '7', dappProposedTokenAmount: '7',
currentTokenBalance: '10', currentTokenBalance: '10',
toAddress: '0x9bc5baf874d2da8d216ae9f137804184ee5afef4', toAddress: '0x9bc5baf874d2da8d216ae9f137804184ee5afef4',

@ -1307,3 +1307,7 @@ export function getShouldShowSeedPhraseReminder(state) {
dismissSeedBackUpReminder === false dismissSeedBackUpReminder === false
); );
} }
export function getCustomTokenAmount(state) {
return state.appState.customTokenAmount;
}

@ -120,3 +120,6 @@ export const TOGGLE_CURRENCY_INPUT_SWITCH = 'TOGGLE_CURRENCY_INPUT_SWITCH';
// Token detection v2 // Token detection v2
export const SET_NEW_TOKENS_IMPORTED = 'SET_NEW_TOKENS_IMPORTED'; export const SET_NEW_TOKENS_IMPORTED = 'SET_NEW_TOKENS_IMPORTED';
// Token allowance
export const SET_CUSTOM_TOKEN_AMOUNT = 'SET_CUSTOM_TOKEN_AMOUNT';

Loading…
Cancel
Save