mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 01:47:00 +01:00
Adding metrics events for EIP-1559 V2 flow (#13329)
This commit is contained in:
parent
a5b114c4f9
commit
cc1861a34e
@ -1570,6 +1570,8 @@ export default class TransactionController extends EventEmitter {
|
||||
network,
|
||||
type,
|
||||
eip_1559_version: eip1559Version,
|
||||
gas_edit_type: 'none',
|
||||
gas_edit_attempted: 'none',
|
||||
};
|
||||
|
||||
const sensitiveProperties = {
|
||||
|
@ -1610,6 +1610,8 @@ describe('Transaction Controller', function () {
|
||||
properties: {
|
||||
chain_id: '0x2a',
|
||||
eip_1559_version: '0',
|
||||
gas_edit_attempted: 'none',
|
||||
gas_edit_type: 'none',
|
||||
network: '42',
|
||||
referrer: 'metamask',
|
||||
source: 'user',
|
||||
@ -1683,6 +1685,8 @@ describe('Transaction Controller', function () {
|
||||
properties: {
|
||||
chain_id: '0x2a',
|
||||
eip_1559_version: '0',
|
||||
gas_edit_attempted: 'none',
|
||||
gas_edit_type: 'none',
|
||||
network: '42',
|
||||
referrer: 'metamask',
|
||||
source: 'user',
|
||||
@ -1766,6 +1770,8 @@ describe('Transaction Controller', function () {
|
||||
properties: {
|
||||
chain_id: '0x2a',
|
||||
eip_1559_version: '0',
|
||||
gas_edit_attempted: 'none',
|
||||
gas_edit_type: 'none',
|
||||
network: '42',
|
||||
referrer: 'other',
|
||||
source: 'dapp',
|
||||
@ -1841,6 +1847,8 @@ describe('Transaction Controller', function () {
|
||||
properties: {
|
||||
chain_id: '0x2a',
|
||||
eip_1559_version: '0',
|
||||
gas_edit_attempted: 'none',
|
||||
gas_edit_type: 'none',
|
||||
network: '42',
|
||||
referrer: 'other',
|
||||
source: 'dapp',
|
||||
@ -1916,6 +1924,8 @@ describe('Transaction Controller', function () {
|
||||
properties: {
|
||||
chain_id: '0x2a',
|
||||
eip_1559_version: '0',
|
||||
gas_edit_attempted: 'none',
|
||||
gas_edit_type: 'none',
|
||||
network: '42',
|
||||
referrer: 'other',
|
||||
source: 'dapp',
|
||||
@ -1977,6 +1987,8 @@ describe('Transaction Controller', function () {
|
||||
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
||||
chain_id: '0x2a',
|
||||
eip_1559_version: '0',
|
||||
gas_edit_attempted: 'none',
|
||||
gas_edit_type: 'none',
|
||||
},
|
||||
sensitiveProperties: {
|
||||
baz: 3.0,
|
||||
@ -2040,6 +2052,8 @@ describe('Transaction Controller', function () {
|
||||
properties: {
|
||||
chain_id: '0x2a',
|
||||
eip_1559_version: '1',
|
||||
gas_edit_attempted: 'none',
|
||||
gas_edit_type: 'none',
|
||||
network: '42',
|
||||
referrer: 'other',
|
||||
source: 'dapp',
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
|
||||
import { useTransactionEventFragment } from '../../../../hooks/useTransactionEventFragment';
|
||||
import { EDIT_GAS_MODES } from '../../../../../shared/constants/gas';
|
||||
import Box from '../../../ui/box';
|
||||
import Typography from '../../../ui/typography';
|
||||
@ -27,8 +28,8 @@ const AdvancedGasFeeDefaults = () => {
|
||||
maxPriorityFeePerGas,
|
||||
} = useAdvancedGasFeePopoverContext();
|
||||
const advancedGasFeeValues = useSelector(getAdvancedGasFeeValues);
|
||||
const { updateTransactionEventFragment } = useTransactionEventFragment();
|
||||
const { editGasMode } = useGasFeeContext();
|
||||
|
||||
const [isDefaultSettingsSelected, setDefaultSettingsSelected] = useState(
|
||||
Boolean(advancedGasFeeValues) &&
|
||||
advancedGasFeeValues.maxBaseFee === maxBaseFee &&
|
||||
@ -47,6 +48,12 @@ const AdvancedGasFeeDefaults = () => {
|
||||
if (isDefaultSettingsSelected) {
|
||||
dispatch(setAdvancedGasFee(null));
|
||||
setDefaultSettingsSelected(false);
|
||||
updateTransactionEventFragment({
|
||||
properties: {
|
||||
advanced_gas_defaults_updated_maxbasefee: null,
|
||||
advanced_gas_defaults_updated_priorityfee: null,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
dispatch(
|
||||
setAdvancedGasFee({
|
||||
@ -54,7 +61,12 @@ const AdvancedGasFeeDefaults = () => {
|
||||
priorityFee: maxPriorityFeePerGas,
|
||||
}),
|
||||
);
|
||||
setDefaultSettingsSelected(true);
|
||||
updateTransactionEventFragment({
|
||||
properties: {
|
||||
advanced_gas_defaults_updated_maxbasefee: maxBaseFee,
|
||||
advanced_gas_defaults_updated_priorityfee: maxPriorityFeePerGas,
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -25,6 +25,7 @@ jest.mock('../../../../store/actions', () => ({
|
||||
addPollingTokenToAppState: jest.fn(),
|
||||
removePollingTokenFromAppState: jest.fn(),
|
||||
setAdvancedGasFee: jest.fn(),
|
||||
updateEventFragment: jest.fn(),
|
||||
}));
|
||||
|
||||
const render = (defaultGasParams, contextParams) => {
|
||||
|
@ -1,16 +1,18 @@
|
||||
import React from 'react';
|
||||
|
||||
import { PRIORITY_LEVELS } from '../../../../../shared/constants/gas';
|
||||
import { decGWEIToHexWEI } from '../../../../../shared/modules/conversion.utils';
|
||||
import { useTransactionModalContext } from '../../../../contexts/transaction-modal';
|
||||
import { useGasFeeContext } from '../../../../contexts/gasFee';
|
||||
import { useTransactionEventFragment } from '../../../../hooks/useTransactionEventFragment';
|
||||
import Button from '../../../ui/button';
|
||||
import I18nValue from '../../../ui/i18n-value';
|
||||
|
||||
import { useAdvancedGasFeePopoverContext } from '../context';
|
||||
import { decGWEIToHexWEI } from '../../../../../shared/modules/conversion.utils';
|
||||
|
||||
const AdvancedGasFeeSaveButton = () => {
|
||||
const { closeAllModals } = useTransactionModalContext();
|
||||
const { updateTransactionEventFragment } = useTransactionEventFragment();
|
||||
const { updateTransaction } = useGasFeeContext();
|
||||
const {
|
||||
gasLimit,
|
||||
@ -26,6 +28,11 @@ const AdvancedGasFeeSaveButton = () => {
|
||||
maxPriorityFeePerGas: decGWEIToHexWEI(maxPriorityFeePerGas),
|
||||
gasLimit,
|
||||
});
|
||||
updateTransactionEventFragment({
|
||||
properties: {
|
||||
gas_edit_type: 'advanced',
|
||||
},
|
||||
});
|
||||
closeAllModals();
|
||||
};
|
||||
|
||||
|
@ -62,7 +62,7 @@ const CancelSpeedupPopover = () => {
|
||||
updateTransactionUsingEstimate(PRIORITY_LEVELS.MEDIUM);
|
||||
return;
|
||||
}
|
||||
updateTransactionToTenPercentIncreasedGasFee();
|
||||
updateTransactionToTenPercentIncreasedGasFee(true);
|
||||
}, [
|
||||
appIsLoading,
|
||||
currentModal,
|
||||
|
@ -9,6 +9,7 @@ import { COLORS, TYPOGRAPHY } from '../../../helpers/constants/design-system';
|
||||
import { PRIORITY_LEVEL_ICON_MAP } from '../../../helpers/constants/gas';
|
||||
import { useGasFeeContext } from '../../../contexts/gasFee';
|
||||
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||
import { useTransactionEventFragment } from '../../../hooks/useTransactionEventFragment';
|
||||
import { useTransactionModalContext } from '../../../contexts/transaction-modal';
|
||||
import InfoTooltip from '../../ui/info-tooltip/info-tooltip';
|
||||
import Typography from '../../ui/typography/typography';
|
||||
@ -25,6 +26,7 @@ export default function EditGasFeeButton({ userAcknowledgedGasMissing }) {
|
||||
supportsEIP1559V2,
|
||||
transaction,
|
||||
} = useGasFeeContext();
|
||||
const { updateTransactionEventFragment } = useTransactionEventFragment();
|
||||
const { openModal } = useTransactionModalContext();
|
||||
const editEnabled =
|
||||
!hasSimulationError || userAcknowledgedGasMissing === true;
|
||||
@ -46,12 +48,23 @@ export default function EditGasFeeButton({ userAcknowledgedGasMissing }) {
|
||||
title = 'tenPercentIncreased';
|
||||
}
|
||||
|
||||
const openEditGasFeeModal = () => {
|
||||
updateTransactionEventFragment({
|
||||
gas_edit_attempted: 'basic',
|
||||
});
|
||||
openModal('editGasFee');
|
||||
};
|
||||
|
||||
const openAdvancedGasFeeModal = () => {
|
||||
updateTransactionEventFragment({
|
||||
gas_edit_attempted: 'advanced',
|
||||
});
|
||||
openModal('advancedGasFee');
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="edit-gas-fee-button">
|
||||
<button
|
||||
onClick={() => openModal('editGasFee')}
|
||||
data-testid="edit-gas-fee-button"
|
||||
>
|
||||
<button onClick={openEditGasFeeModal} data-testid="edit-gas-fee-button">
|
||||
{icon && (
|
||||
<span className="edit-gas-fee-button__icon">
|
||||
{PRIORITY_LEVEL_ICON_MAP[icon]}
|
||||
@ -61,7 +74,7 @@ export default function EditGasFeeButton({ userAcknowledgedGasMissing }) {
|
||||
<i className="fas fa-chevron-right asset-list-item__chevron-right" />
|
||||
</button>
|
||||
{estimateUsed === 'custom' && (
|
||||
<button onClick={() => openModal('advancedGasFee')}>{t('edit')}</button>
|
||||
<button onClick={openAdvancedGasFeeModal}>{t('edit')}</button>
|
||||
)}
|
||||
{estimateUsed === 'dappSuggested' && (
|
||||
<InfoTooltip
|
||||
|
@ -11,12 +11,13 @@ import { PRIMARY } from '../../../../helpers/constants/common';
|
||||
import { toHumanReadableTime } from '../../../../helpers/utils/util';
|
||||
import { useGasFeeContext } from '../../../../contexts/gasFee';
|
||||
import { useI18nContext } from '../../../../hooks/useI18nContext';
|
||||
import { useTransactionEventFragment } from '../../../../hooks/useTransactionEventFragment';
|
||||
import { useTransactionModalContext } from '../../../../contexts/transaction-modal';
|
||||
import EditGasToolTip from '../edit-gas-tooltip/edit-gas-tooltip';
|
||||
import I18nValue from '../../../ui/i18n-value';
|
||||
import InfoTooltip from '../../../ui/info-tooltip';
|
||||
import LoadingHeartBeat from '../../../ui/loading-heartbeat';
|
||||
import UserPreferencedCurrencyDisplay from '../../user-preferenced-currency-display';
|
||||
import EditGasToolTip from '../edit-gas-tooltip/edit-gas-tooltip';
|
||||
|
||||
import { useGasItemFeeDetails } from './useGasItemFeeDetails';
|
||||
|
||||
@ -48,6 +49,7 @@ const EditGasItem = ({ priorityLevel }) => {
|
||||
updateTransactionUsingEstimate,
|
||||
transaction,
|
||||
} = useGasFeeContext();
|
||||
const { updateTransactionEventFragment } = useTransactionEventFragment();
|
||||
const t = useI18nContext();
|
||||
const { closeModal, openModal } = useTransactionModalContext();
|
||||
const { dappSuggestedGasFees } = transaction;
|
||||
@ -72,8 +74,19 @@ const EditGasItem = ({ priorityLevel }) => {
|
||||
|
||||
const onOptionSelect = () => {
|
||||
if (priorityLevel === PRIORITY_LEVELS.CUSTOM) {
|
||||
updateTransactionEventFragment({
|
||||
properties: {
|
||||
gas_edit_attempted: 'advanced',
|
||||
},
|
||||
});
|
||||
openModal('advancedGasFee');
|
||||
} else {
|
||||
updateTransactionEventFragment({
|
||||
properties: {
|
||||
gas_edit_type: 'basic',
|
||||
},
|
||||
});
|
||||
|
||||
closeModal('editGasFee');
|
||||
|
||||
if (priorityLevel === PRIORITY_LEVELS.TEN_PERCENT_INCREASED) {
|
||||
|
@ -296,7 +296,7 @@ const TransactionListItem = (props) => {
|
||||
transaction={transactionGroup.primaryTransaction}
|
||||
editGasMode={editGasMode}
|
||||
>
|
||||
<TransactionModalContextProvider captureEventEnabled={false}>
|
||||
<TransactionModalContextProvider>
|
||||
<TransactionListItemInner {...props} setEditGasMode={setEditGasMode} />
|
||||
{supportsEIP1559V2 && (
|
||||
<>
|
||||
|
@ -1,40 +1,10 @@
|
||||
import React, { createContext, useContext, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { TRANSACTION_TYPES } from '../../shared/constants/transaction';
|
||||
import { getMethodName } from '../helpers/utils/metrics';
|
||||
import { useGasFeeContext } from './gasFee';
|
||||
import { MetaMetricsContext } from './metametrics';
|
||||
|
||||
export const TransactionModalContext = createContext({});
|
||||
|
||||
export const TransactionModalContextProvider = ({
|
||||
actionKey,
|
||||
children,
|
||||
methodData,
|
||||
captureEventEnabled = true,
|
||||
}) => {
|
||||
export const TransactionModalContextProvider = ({ children }) => {
|
||||
const [openModals, setOpenModals] = useState([]);
|
||||
const metricsEvent = useContext(MetaMetricsContext);
|
||||
const { transaction: { origin } = {} } = useGasFeeContext();
|
||||
|
||||
const captureEvent = () => {
|
||||
metricsEvent({
|
||||
eventOpts: {
|
||||
category: 'Transactions',
|
||||
action: 'Confirm Screen',
|
||||
name: 'User clicks "Edit" on gas',
|
||||
},
|
||||
customVariables: {
|
||||
recipientKnown: null,
|
||||
functionType:
|
||||
actionKey ||
|
||||
getMethodName(methodData?.name) ||
|
||||
TRANSACTION_TYPES.CONTRACT_INTERACTION,
|
||||
origin,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const closeModal = (modalName) => {
|
||||
const index = openModals.indexOf(modalName);
|
||||
@ -54,7 +24,6 @@ export const TransactionModalContextProvider = ({
|
||||
if (openModals.includes(modalName)) {
|
||||
return;
|
||||
}
|
||||
captureEventEnabled && captureEvent();
|
||||
const modals = [...openModals];
|
||||
modals.push(modalName);
|
||||
setOpenModals(modals);
|
||||
@ -80,8 +49,5 @@ export function useTransactionModalContext() {
|
||||
}
|
||||
|
||||
TransactionModalContextProvider.propTypes = {
|
||||
actionKey: PropTypes.string,
|
||||
children: PropTypes.node.isRequired,
|
||||
methodData: PropTypes.object,
|
||||
captureEventEnabled: PropTypes.bool,
|
||||
};
|
||||
|
@ -79,7 +79,7 @@ describe('useMaxPriorityFeePerGasInput', () => {
|
||||
expect(mock).toHaveBeenCalledTimes(1);
|
||||
expect(mock).toHaveBeenCalledWith({
|
||||
txParams: {
|
||||
estimateSuggested: 'medium',
|
||||
estimateSuggested: 'tenPercentIncreased',
|
||||
estimateUsed: 'tenPercentIncreased',
|
||||
gas: '5208',
|
||||
gasLimit: '5208',
|
||||
|
@ -49,11 +49,17 @@ export const useTransactionFunctions = ({
|
||||
}, [editGasMode, transaction?.previousGas, transaction?.txParams]);
|
||||
|
||||
const updateTransaction = useCallback(
|
||||
({ estimateUsed, gasLimit, maxFeePerGas, maxPriorityFeePerGas }) => {
|
||||
({
|
||||
estimateUsed,
|
||||
gasLimit,
|
||||
maxFeePerGas,
|
||||
maxPriorityFeePerGas,
|
||||
estimateSuggested,
|
||||
}) => {
|
||||
const newGasSettings = {
|
||||
gas: decimalToHex(gasLimit || gasLimitValue),
|
||||
gasLimit: decimalToHex(gasLimit || gasLimitValue),
|
||||
estimateSuggested: defaultEstimateToUse,
|
||||
estimateSuggested: estimateSuggested || defaultEstimateToUse,
|
||||
estimateUsed,
|
||||
};
|
||||
if (maxFeePerGas) {
|
||||
@ -111,17 +117,23 @@ export const useTransactionFunctions = ({
|
||||
);
|
||||
}, [dispatch, estimatedBaseFee, transaction]);
|
||||
|
||||
const updateTransactionToTenPercentIncreasedGasFee = useCallback(() => {
|
||||
const { gas: gasLimit, maxFeePerGas, maxPriorityFeePerGas } =
|
||||
transaction.previousGas || transaction.txParams;
|
||||
const updateTransactionToTenPercentIncreasedGasFee = useCallback(
|
||||
(initTransaction = false) => {
|
||||
const { gas: gasLimit, maxFeePerGas, maxPriorityFeePerGas } =
|
||||
transaction.previousGas || transaction.txParams;
|
||||
|
||||
updateTransaction({
|
||||
estimateUsed: PRIORITY_LEVELS.TEN_PERCENT_INCREASED,
|
||||
gasLimit,
|
||||
maxFeePerGas: addTenPercentAndRound(maxFeePerGas),
|
||||
maxPriorityFeePerGas: addTenPercentAndRound(maxPriorityFeePerGas),
|
||||
});
|
||||
}, [transaction, updateTransaction]);
|
||||
updateTransaction({
|
||||
estimateSuggested: initTransaction
|
||||
? defaultEstimateToUse
|
||||
: PRIORITY_LEVELS.TEN_PERCENT_INCREASED,
|
||||
estimateUsed: PRIORITY_LEVELS.TEN_PERCENT_INCREASED,
|
||||
gasLimit,
|
||||
maxFeePerGas: addTenPercentAndRound(maxFeePerGas),
|
||||
maxPriorityFeePerGas: addTenPercentAndRound(maxPriorityFeePerGas),
|
||||
});
|
||||
},
|
||||
[defaultEstimateToUse, transaction, updateTransaction],
|
||||
);
|
||||
|
||||
const updateTransactionUsingEstimate = useCallback(
|
||||
(gasFeeEstimateToUse) => {
|
||||
|
@ -18,7 +18,7 @@ import { useMetaMetricsContext } from './useMetricEvent';
|
||||
* @param {Object} fragmentOptions
|
||||
* @returns
|
||||
*/
|
||||
export function useEventFragment(existingId, fragmentOptions) {
|
||||
export function useEventFragment(existingId, fragmentOptions = {}) {
|
||||
// To prevent overcalling the createEventFragment background method a ref
|
||||
// is used to store a boolean value of whether we have already called the
|
||||
// method.
|
||||
|
22
ui/hooks/useTransactionEventFragment.js
Normal file
22
ui/hooks/useTransactionEventFragment.js
Normal file
@ -0,0 +1,22 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { useGasFeeContext } from '../contexts/gasFee';
|
||||
import { updateEventFragment } from '../store/actions';
|
||||
|
||||
export const useTransactionEventFragment = () => {
|
||||
const { transaction } = useGasFeeContext();
|
||||
|
||||
const updateTransactionEventFragment = useCallback(
|
||||
(params) => {
|
||||
if (!transaction) {
|
||||
return;
|
||||
}
|
||||
updateEventFragment(`transaction-added-${transaction.id}`, params);
|
||||
},
|
||||
[transaction],
|
||||
);
|
||||
|
||||
return {
|
||||
updateTransactionEventFragment,
|
||||
};
|
||||
};
|
@ -180,7 +180,7 @@ export default function ConfirmApprove() {
|
||||
showAccountInHeader
|
||||
title={tokensText}
|
||||
contentComponent={
|
||||
<TransactionModalContextProvider captureEventEnabled={false}>
|
||||
<TransactionModalContextProvider>
|
||||
<ConfirmApproveContent
|
||||
decimals={decimals}
|
||||
siteImage={siteImage}
|
||||
|
@ -980,7 +980,6 @@ export default class ConfirmTransactionBase extends Component {
|
||||
render() {
|
||||
const { t } = this.context;
|
||||
const {
|
||||
actionKey,
|
||||
fromName,
|
||||
fromAddress,
|
||||
toName,
|
||||
@ -1046,10 +1045,7 @@ export default class ConfirmTransactionBase extends Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<TransactionModalContextProvider
|
||||
actionKey={actionKey}
|
||||
methodData={methodData}
|
||||
>
|
||||
<TransactionModalContextProvider>
|
||||
<ConfirmPageContainer
|
||||
fromName={fromName}
|
||||
fromAddress={fromAddress}
|
||||
|
@ -695,7 +695,7 @@ export default function ViewQuote() {
|
||||
minimumGasLimit={usedGasLimit}
|
||||
transaction={transaction}
|
||||
>
|
||||
<TransactionModalContextProvider captureEventEnabled={false}>
|
||||
<TransactionModalContextProvider>
|
||||
<div className="view-quote">
|
||||
<div
|
||||
className={classnames('view-quote__content', {
|
||||
|
Loading…
Reference in New Issue
Block a user