mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Changes in edit link on confirm transaction page (#12567)
This commit is contained in:
parent
189e5c0a17
commit
39cb29d5b5
app/_locales/en
ui
components/app/transaction-detail
hooks/gasFeeInput
@ -549,6 +549,9 @@
|
|||||||
"currentlyUnavailable": {
|
"currentlyUnavailable": {
|
||||||
"message": "Unavailable on this network"
|
"message": "Unavailable on this network"
|
||||||
},
|
},
|
||||||
|
"custom": {
|
||||||
|
"message": "Advanced"
|
||||||
|
},
|
||||||
"customGas": {
|
"customGas": {
|
||||||
"message": "Customize Gas"
|
"message": "Customize Gas"
|
||||||
},
|
},
|
||||||
@ -561,6 +564,13 @@
|
|||||||
"customToken": {
|
"customToken": {
|
||||||
"message": "Custom Token"
|
"message": "Custom Token"
|
||||||
},
|
},
|
||||||
|
"dappSuggested": {
|
||||||
|
"message": "Site suggested"
|
||||||
|
},
|
||||||
|
"dappSuggestedTooltip": {
|
||||||
|
"message": "$1 has recommended this price.",
|
||||||
|
"description": "$1 represents the Dapp's origin"
|
||||||
|
},
|
||||||
"data": {
|
"data": {
|
||||||
"message": "Data"
|
"message": "Data"
|
||||||
},
|
},
|
||||||
@ -1015,6 +1025,9 @@
|
|||||||
"gasPriceInfoTooltipContent": {
|
"gasPriceInfoTooltipContent": {
|
||||||
"message": "Gas price specifies the amount of Ether you are willing to pay for each unit of gas."
|
"message": "Gas price specifies the amount of Ether you are willing to pay for each unit of gas."
|
||||||
},
|
},
|
||||||
|
"gasPriceLabel": {
|
||||||
|
"message": "Gas price"
|
||||||
|
},
|
||||||
"gasTimingMinutes": {
|
"gasTimingMinutes": {
|
||||||
"message": "$1 minutes",
|
"message": "$1 minutes",
|
||||||
"description": "$1 represents a number of minutes"
|
"description": "$1 represents a number of minutes"
|
||||||
@ -1113,6 +1126,9 @@
|
|||||||
"hideZeroBalanceTokens": {
|
"hideZeroBalanceTokens": {
|
||||||
"message": "Hide Tokens Without Balance"
|
"message": "Hide Tokens Without Balance"
|
||||||
},
|
},
|
||||||
|
"high": {
|
||||||
|
"message": "Aggressive"
|
||||||
|
},
|
||||||
"history": {
|
"history": {
|
||||||
"message": "History"
|
"message": "History"
|
||||||
},
|
},
|
||||||
@ -1349,6 +1365,9 @@
|
|||||||
"lockTimeTooGreat": {
|
"lockTimeTooGreat": {
|
||||||
"message": "Lock time is too great"
|
"message": "Lock time is too great"
|
||||||
},
|
},
|
||||||
|
"low": {
|
||||||
|
"message": "Low"
|
||||||
|
},
|
||||||
"lowPriorityMessage": {
|
"lowPriorityMessage": {
|
||||||
"message": "Future transactions will queue after this one. This price was last seen was some time ago."
|
"message": "Future transactions will queue after this one. This price was last seen was some time ago."
|
||||||
},
|
},
|
||||||
@ -1365,12 +1384,18 @@
|
|||||||
"max": {
|
"max": {
|
||||||
"message": "Max"
|
"message": "Max"
|
||||||
},
|
},
|
||||||
|
"maxBaseFee": {
|
||||||
|
"message": "Max base fee"
|
||||||
|
},
|
||||||
"maxFee": {
|
"maxFee": {
|
||||||
"message": "Max fee"
|
"message": "Max fee"
|
||||||
},
|
},
|
||||||
"maxPriorityFee": {
|
"maxPriorityFee": {
|
||||||
"message": "Max priority fee"
|
"message": "Max priority fee"
|
||||||
},
|
},
|
||||||
|
"medium": {
|
||||||
|
"message": "Market"
|
||||||
|
},
|
||||||
"memo": {
|
"memo": {
|
||||||
"message": "memo"
|
"message": "memo"
|
||||||
},
|
},
|
||||||
|
@ -15,4 +15,55 @@
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-edit-V2 {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
justify-content: flex-end;
|
||||||
|
padding-top: 20px;
|
||||||
|
|
||||||
|
button {
|
||||||
|
@include H7;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
color: $primary-1;
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
padding-inline-end: 0;
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
color: $primary-1;
|
||||||
|
margin-right: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__icon {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__label {
|
||||||
|
font-size: 12px;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-tooltip {
|
||||||
|
align-self: center;
|
||||||
|
margin-left: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__tooltip {
|
||||||
|
p {
|
||||||
|
color: $Grey-500;
|
||||||
|
}
|
||||||
|
|
||||||
|
b {
|
||||||
|
color: $neutral-black;
|
||||||
|
display: inline-block;
|
||||||
|
min-width: 60%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,94 @@ import React, { useContext } from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import { I18nContext } from '../../../contexts/i18n';
|
import { I18nContext } from '../../../contexts/i18n';
|
||||||
|
import { useGasFeeContext } from '../../../contexts/gasFee';
|
||||||
|
import InfoTooltip from '../../ui/info-tooltip/info-tooltip';
|
||||||
|
import Typography from '../../ui/typography/typography';
|
||||||
|
|
||||||
import TransactionDetailItem from '../transaction-detail-item/transaction-detail-item.component';
|
import TransactionDetailItem from '../transaction-detail-item/transaction-detail-item.component';
|
||||||
|
import { COLORS } from '../../../helpers/constants/design-system';
|
||||||
|
|
||||||
|
const GasLevelIconMap = {
|
||||||
|
low: '🐢',
|
||||||
|
medium: '🦊',
|
||||||
|
high: '🦍',
|
||||||
|
dappSuggested: '🌐',
|
||||||
|
custom: '⚙',
|
||||||
|
};
|
||||||
|
|
||||||
export default function TransactionDetail({ rows = [], onEdit }) {
|
export default function TransactionDetail({ rows = [], onEdit }) {
|
||||||
|
// eslint-disable-next-line prefer-destructuring
|
||||||
|
const EIP_1559_V2 = process.env.EIP_1559_V2;
|
||||||
|
|
||||||
const t = useContext(I18nContext);
|
const t = useContext(I18nContext);
|
||||||
|
const {
|
||||||
|
estimateToUse,
|
||||||
|
gasLimit,
|
||||||
|
gasPrice,
|
||||||
|
isUsingDappSuggestedGasFees,
|
||||||
|
maxFeePerGas,
|
||||||
|
maxPriorityFeePerGas,
|
||||||
|
transaction,
|
||||||
|
supportsEIP1559,
|
||||||
|
} = useGasFeeContext();
|
||||||
|
const estimateUsed = isUsingDappSuggestedGasFees
|
||||||
|
? 'dappSuggested'
|
||||||
|
: estimateToUse;
|
||||||
|
|
||||||
|
if (EIP_1559_V2 && estimateUsed) {
|
||||||
|
return (
|
||||||
|
<div className="transaction-detail">
|
||||||
|
<div className="transaction-detail-edit-V2">
|
||||||
|
<button onClick={onEdit}>
|
||||||
|
<span className="transaction-detail-edit-V2__icon">
|
||||||
|
{`${GasLevelIconMap[estimateUsed]} `}
|
||||||
|
</span>
|
||||||
|
<span className="transaction-detail-edit-V2__label">
|
||||||
|
{t(estimateUsed)}
|
||||||
|
</span>
|
||||||
|
<i className="fas fa-chevron-right asset-list-item__chevron-right" />
|
||||||
|
</button>
|
||||||
|
{estimateUsed === 'custom' && onEdit && (
|
||||||
|
<button onClick={onEdit}>{t('edit')}</button>
|
||||||
|
)}
|
||||||
|
{estimateUsed === 'dappSuggested' && (
|
||||||
|
<InfoTooltip
|
||||||
|
contentText={
|
||||||
|
<div className="transaction-detail-edit-V2__tooltip">
|
||||||
|
<Typography fontSize="12px" color={COLORS.GREY}>
|
||||||
|
{t('dappSuggestedTooltip', [transaction.origin])}
|
||||||
|
</Typography>
|
||||||
|
{supportsEIP1559 ? (
|
||||||
|
<>
|
||||||
|
<Typography fontSize="12px">
|
||||||
|
<b>{t('maxBaseFee')}</b>
|
||||||
|
{maxFeePerGas}
|
||||||
|
</Typography>
|
||||||
|
<Typography fontSize="12px">
|
||||||
|
<b>{t('maxPriorityFee')}</b>
|
||||||
|
{maxPriorityFeePerGas}
|
||||||
|
</Typography>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<Typography fontSize="12px">
|
||||||
|
<b>{t('gasPriceLabel')}</b>
|
||||||
|
{gasPrice}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
<Typography fontSize="12px">
|
||||||
|
<b>{t('gasLimit')}</b>
|
||||||
|
{gasLimit}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
position="top"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="transaction-detail-rows">{rows}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="transaction-detail">
|
<div className="transaction-detail">
|
||||||
|
@ -0,0 +1,94 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { screen } from '@testing-library/react';
|
||||||
|
|
||||||
|
import { ETH } from '../../../helpers/constants/common';
|
||||||
|
import { GasFeeContextProvider } from '../../../contexts/gasFee';
|
||||||
|
import { renderWithProvider } from '../../../../test/jest';
|
||||||
|
import configureStore from '../../../store/store';
|
||||||
|
|
||||||
|
import TransactionDetail from './transaction-detail.component';
|
||||||
|
|
||||||
|
jest.mock('../../../store/actions', () => ({
|
||||||
|
disconnectGasFeeEstimatePoller: jest.fn(),
|
||||||
|
getGasFeeEstimatesAndStartPolling: jest
|
||||||
|
.fn()
|
||||||
|
.mockImplementation(() => Promise.resolve()),
|
||||||
|
addPollingTokenToAppState: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const render = (props) => {
|
||||||
|
const store = configureStore({
|
||||||
|
metamask: {
|
||||||
|
nativeCurrency: ETH,
|
||||||
|
preferences: {
|
||||||
|
useNativeCurrencyAsPrimaryCurrency: true,
|
||||||
|
},
|
||||||
|
provider: {},
|
||||||
|
cachedBalances: {},
|
||||||
|
accounts: {
|
||||||
|
'0xAddress': {
|
||||||
|
address: '0xAddress',
|
||||||
|
balance: '0x176e5b6f173ebe66',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
selectedAddress: '0xAddress',
|
||||||
|
featureFlags: { advancedInlineGas: true },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return renderWithProvider(
|
||||||
|
<GasFeeContextProvider {...props}>
|
||||||
|
<TransactionDetail
|
||||||
|
onEdit={() => {
|
||||||
|
console.log('on edit');
|
||||||
|
}}
|
||||||
|
rows={[]}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</GasFeeContextProvider>,
|
||||||
|
store,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('TransactionDetail', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env.EIP_1559_V2 = true;
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
process.env.EIP_1559_V2 = false;
|
||||||
|
});
|
||||||
|
it('should render edit link with text low if low gas estimates are selected', () => {
|
||||||
|
render({ transaction: { userFeeLevel: 'low' } });
|
||||||
|
expect(screen.queryByText('🐢')).toBeInTheDocument();
|
||||||
|
expect(screen.queryByText('Low')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
it('should render edit link with text markey if medium gas estimates are selected', () => {
|
||||||
|
render({ transaction: { userFeeLevel: 'medium' } });
|
||||||
|
expect(screen.queryByText('🦊')).toBeInTheDocument();
|
||||||
|
expect(screen.queryByText('Market')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
it('should render edit link with text agressive if high gas estimates are selected', () => {
|
||||||
|
render({ transaction: { userFeeLevel: 'high' } });
|
||||||
|
expect(screen.queryByText('🦍')).toBeInTheDocument();
|
||||||
|
expect(screen.queryByText('Aggressive')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
it('should render edit link with text Site suggested if site suggested estimated are used', () => {
|
||||||
|
render({
|
||||||
|
transaction: {
|
||||||
|
dappSuggestedGasFees: { maxFeePerGas: 1, maxPriorityFeePerGas: 1 },
|
||||||
|
txParams: { maxFeePerGas: 1, maxPriorityFeePerGas: 1 },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(screen.queryByText('🌐')).toBeInTheDocument();
|
||||||
|
expect(screen.queryByText('Site suggested')).toBeInTheDocument();
|
||||||
|
expect(document.getElementsByClassName('info-tooltip')).toHaveLength(1);
|
||||||
|
});
|
||||||
|
it('should render edit link with text advance if custom gas estimates are used', () => {
|
||||||
|
render({
|
||||||
|
defaultEstimateToUse: 'custom',
|
||||||
|
});
|
||||||
|
expect(screen.queryByText('⚙')).toBeInTheDocument();
|
||||||
|
expect(screen.queryByText('Advanced')).toBeInTheDocument();
|
||||||
|
expect(screen.queryByText('Edit')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
@ -1,15 +1,19 @@
|
|||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
|
|
||||||
import { getAdvancedInlineGasShown } from '../../selectors';
|
|
||||||
import { hexToDecimal } from '../../helpers/utils/conversions.util';
|
|
||||||
import {
|
import {
|
||||||
CUSTOM_GAS_ESTIMATE,
|
CUSTOM_GAS_ESTIMATE,
|
||||||
GAS_RECOMMENDATIONS,
|
GAS_RECOMMENDATIONS,
|
||||||
EDIT_GAS_MODES,
|
EDIT_GAS_MODES,
|
||||||
} from '../../../shared/constants/gas';
|
} from '../../../shared/constants/gas';
|
||||||
import { GAS_FORM_ERRORS } from '../../helpers/constants/gas';
|
import { GAS_FORM_ERRORS } from '../../helpers/constants/gas';
|
||||||
|
import { areDappSuggestedAndTxParamGasFeesTheSame } from '../../helpers/utils/confirm-tx.util';
|
||||||
|
import {
|
||||||
|
checkNetworkAndAccountSupports1559,
|
||||||
|
getAdvancedInlineGasShown,
|
||||||
|
} from '../../selectors';
|
||||||
|
import { hexToDecimal } from '../../helpers/utils/conversions.util';
|
||||||
|
import { isLegacyTransaction } from '../../helpers/utils/transactions.util';
|
||||||
import { useGasFeeEstimates } from '../useGasFeeEstimates';
|
import { useGasFeeEstimates } from '../useGasFeeEstimates';
|
||||||
|
|
||||||
import { useGasFeeErrors } from './useGasFeeErrors';
|
import { useGasFeeErrors } from './useGasFeeErrors';
|
||||||
@ -69,6 +73,10 @@ export function useGasFeeInputs(
|
|||||||
minimumGasLimit = '0x5208',
|
minimumGasLimit = '0x5208',
|
||||||
editGasMode = EDIT_GAS_MODES.MODIFY_IN_PLACE,
|
editGasMode = EDIT_GAS_MODES.MODIFY_IN_PLACE,
|
||||||
) {
|
) {
|
||||||
|
const supportsEIP1559 =
|
||||||
|
useSelector(checkNetworkAndAccountSupports1559) &&
|
||||||
|
!isLegacyTransaction(transaction?.txParams);
|
||||||
|
|
||||||
// We need the gas estimates from the GasFeeController in the background.
|
// We need the gas estimates from the GasFeeController in the background.
|
||||||
// Calling this hooks initiates polling for new gas estimates and returns the
|
// Calling this hooks initiates polling for new gas estimates and returns the
|
||||||
// current estimate.
|
// current estimate.
|
||||||
@ -92,6 +100,13 @@ export function useGasFeeInputs(
|
|||||||
return defaultEstimateToUse;
|
return defaultEstimateToUse;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const [
|
||||||
|
isUsingDappSuggestedGasFees,
|
||||||
|
setIsUsingDappSuggestedGasFees,
|
||||||
|
] = useState(() =>
|
||||||
|
Boolean(areDappSuggestedAndTxParamGasFeesTheSame(transaction)),
|
||||||
|
);
|
||||||
|
|
||||||
const [gasLimit, setGasLimit] = useState(
|
const [gasLimit, setGasLimit] = useState(
|
||||||
Number(hexToDecimal(transaction?.txParams?.gas ?? '0x0')),
|
Number(hexToDecimal(transaction?.txParams?.gas ?? '0x0')),
|
||||||
);
|
);
|
||||||
@ -193,6 +208,7 @@ export function useGasFeeInputs(
|
|||||||
setMaxPriorityFeePerGas(null);
|
setMaxPriorityFeePerGas(null);
|
||||||
setGasPrice(null);
|
setGasPrice(null);
|
||||||
setGasPriceHasBeenManuallySet(false);
|
setGasPriceHasBeenManuallySet(false);
|
||||||
|
setIsUsingDappSuggestedGasFees(false);
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
setInternalEstimateToUse,
|
setInternalEstimateToUse,
|
||||||
@ -201,6 +217,7 @@ export function useGasFeeInputs(
|
|||||||
setMaxPriorityFeePerGas,
|
setMaxPriorityFeePerGas,
|
||||||
setGasPrice,
|
setGasPrice,
|
||||||
setGasPriceHasBeenManuallySet,
|
setGasPriceHasBeenManuallySet,
|
||||||
|
setIsUsingDappSuggestedGasFees,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -228,6 +245,7 @@ export function useGasFeeInputs(
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
transaction,
|
||||||
maxFeePerGas,
|
maxFeePerGas,
|
||||||
maxFeePerGasFiat,
|
maxFeePerGasFiat,
|
||||||
setMaxFeePerGas,
|
setMaxFeePerGas,
|
||||||
@ -245,6 +263,7 @@ export function useGasFeeInputs(
|
|||||||
estimatedMaximumNative,
|
estimatedMaximumNative,
|
||||||
estimatedMinimumNative,
|
estimatedMinimumNative,
|
||||||
isGasEstimatesLoading,
|
isGasEstimatesLoading,
|
||||||
|
isUsingDappSuggestedGasFees,
|
||||||
gasFeeEstimates,
|
gasFeeEstimates,
|
||||||
gasEstimateType,
|
gasEstimateType,
|
||||||
estimatedGasFeeTimeBounds,
|
estimatedGasFeeTimeBounds,
|
||||||
@ -256,5 +275,6 @@ export function useGasFeeInputs(
|
|||||||
gasErrors,
|
gasErrors,
|
||||||
gasWarnings,
|
gasWarnings,
|
||||||
hasGasErrors,
|
hasGasErrors,
|
||||||
|
supportsEIP1559,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user