1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-22 17:33:23 +01:00

Adding metrics events for EIP-1559 V2 flow (#13329)

This commit is contained in:
Jyoti Puri 2022-02-01 23:23:03 +05:30 committed by GitHub
parent a5b114c4f9
commit cc1861a34e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 125 additions and 67 deletions

View File

@ -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 = {

View File

@ -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',

View File

@ -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,
},
});
}
};

View File

@ -25,6 +25,7 @@ jest.mock('../../../../store/actions', () => ({
addPollingTokenToAppState: jest.fn(),
removePollingTokenFromAppState: jest.fn(),
setAdvancedGasFee: jest.fn(),
updateEventFragment: jest.fn(),
}));
const render = (defaultGasParams, contextParams) => {

View File

@ -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();
};

View File

@ -62,7 +62,7 @@ const CancelSpeedupPopover = () => {
updateTransactionUsingEstimate(PRIORITY_LEVELS.MEDIUM);
return;
}
updateTransactionToTenPercentIncreasedGasFee();
updateTransactionToTenPercentIncreasedGasFee(true);
}, [
appIsLoading,
currentModal,

View File

@ -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

View File

@ -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) {

View File

@ -296,7 +296,7 @@ const TransactionListItem = (props) => {
transaction={transactionGroup.primaryTransaction}
editGasMode={editGasMode}
>
<TransactionModalContextProvider captureEventEnabled={false}>
<TransactionModalContextProvider>
<TransactionListItemInner {...props} setEditGasMode={setEditGasMode} />
{supportsEIP1559V2 && (
<>

View File

@ -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,
};

View File

@ -79,7 +79,7 @@ describe('useMaxPriorityFeePerGasInput', () => {
expect(mock).toHaveBeenCalledTimes(1);
expect(mock).toHaveBeenCalledWith({
txParams: {
estimateSuggested: 'medium',
estimateSuggested: 'tenPercentIncreased',
estimateUsed: 'tenPercentIncreased',
gas: '5208',
gasLimit: '5208',

View File

@ -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) => {

View File

@ -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.

View 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,
};
};

View File

@ -180,7 +180,7 @@ export default function ConfirmApprove() {
showAccountInHeader
title={tokensText}
contentComponent={
<TransactionModalContextProvider captureEventEnabled={false}>
<TransactionModalContextProvider>
<ConfirmApproveContent
decimals={decimals}
siteImage={siteImage}

View File

@ -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}

View File

@ -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', {