From 1304ec7af5ff49a63e01274d8c8651cfbcd9a661 Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Mon, 3 Apr 2023 09:31:04 -0600 Subject: [PATCH] Convert shared/constants/metametrics to TS (#18353) We want to convert NetworkController to TypeScript in order to be able to compare differences in the controller between in this repo and the core repo. To do this, however, we need to convert the dependencies of the controller to TypeScript. As a part of this effort, this commit converts `shared/constants/metametrics` to TypeScript. Note that simple objects have been largely replaced with enums. There are some cases where I even split up some of these objects into multiple enums. Co-authored-by: Mark Stacey --- app/scripts/background.js | 24 +- app/scripts/controllers/detect-tokens.js | 9 +- app/scripts/controllers/metametrics.js | 50 +- app/scripts/controllers/metametrics.test.js | 46 +- .../controllers/network/network-controller.js | 4 +- .../network/network-controller.test.js | 28 +- app/scripts/controllers/sign.test.ts | 4 +- app/scripts/controllers/sign.ts | 4 +- app/scripts/controllers/transactions/index.js | 14 +- .../controllers/transactions/index.test.js | 41 +- .../lib/createRPCMethodTrackingMiddleware.js | 76 +-- .../createRPCMethodTrackingMiddleware.test.js | 40 +- app/scripts/lib/decrypt-message-manager.js | 4 +- .../lib/encryption-public-key-manager.js | 4 +- .../handlers/add-ethereum-chain.js | 4 +- .../handlers/log-web3-shim-usage.js | 4 +- app/scripts/metamask-controller.js | 23 +- shared/constants/metametrics.js | 482 ------------- shared/constants/metametrics.ts | 642 ++++++++++++++++++ .../account-menu/account-menu.component.js | 41 +- ui/components/app/add-network/add-network.js | 5 +- .../app/app-header/app-header.component.js | 13 +- .../app/asset-list-item/asset-list-item.js | 4 +- ui/components/app/asset-list/asset-list.js | 9 +- .../detected-tokens-link.js | 11 +- .../confirm-page-container.component.js | 9 +- .../desktop-enable-button.component.js | 6 +- .../detected-token-selection-popover.js | 11 +- .../app/detected-token/detected-token.js | 19 +- .../app/dropdowns/network-dropdown.js | 12 +- .../import-token-link.component.js | 9 +- .../app/menu-bar/account-options-menu.js | 24 +- ui/components/app/menu-bar/menu-bar.js | 9 +- .../account-details-modal.component.js | 18 +- .../confirm-remove-account.component.js | 4 +- .../export-private-key-modal.component.js | 35 +- .../permission-page-container.component.js | 4 +- .../signature-request.component.js | 6 +- .../transaction-activity-log.component.js | 4 +- ...transaction-list-item-details.component.js | 10 +- .../transaction-list-item.component.js | 6 +- .../app/wallet-overview/eth-overview.js | 31 +- .../app/wallet-overview/token-overview.js | 31 +- .../account-list-item-menu.js | 16 +- .../account-list-menu/account-list-menu.js | 28 +- .../detected-token-banner.js | 12 +- .../multichain/global-menu/global-menu.js | 34 +- .../multichain-import-token-link.js | 9 +- ui/contexts/metametrics.js | 7 +- ui/ducks/swaps/swaps.js | 12 +- ui/pages/add-nft/add-nft.js | 9 +- ui/pages/asset/components/native-asset.js | 4 +- ui/pages/asset/components/token-asset.js | 4 +- .../confirm-add-suggested-token.js | 12 +- .../confirm-decrypt-message.component.js | 8 +- ...confirm-encryption-public-key.component.js | 6 +- .../confirm-import-token.js | 14 +- .../confirm-transaction-base.component.js | 8 +- .../connect-hardware/account-list.js | 4 +- .../create-account/connect-hardware/index.js | 18 +- .../connect-hardware/select-hardware.js | 30 +- .../import-account/import-account.js | 19 +- .../create-account/new-account.component.js | 18 +- .../desktop-error/render-desktop-error.js | 4 +- ui/pages/error/error.component.js | 14 +- .../home/beta/beta-home-footer.component.js | 14 +- .../home/flask/flask-home-footer.component.js | 14 +- ui/pages/home/home.component.js | 12 +- ui/pages/keychains/restore-vault.js | 4 +- ui/pages/keychains/reveal-seed.js | 36 +- .../create-password/create-password.js | 9 +- .../creation-successful.js | 9 +- .../onboarding-flow/import-srp/import-srp.js | 10 +- .../metametrics/metametrics.js | 14 +- ui/pages/onboarding-flow/onboarding-flow.js | 11 +- .../pin-extension/pin-extension.js | 9 +- .../privacy-settings/privacy-settings.js | 9 +- .../confirm-recovery-phrase.js | 10 +- .../recovery-phrase/review-recovery-phrase.js | 14 +- .../secure-your-wallet/secure-your-wallet.js | 17 +- .../skip-srp-backup-popover.js | 15 +- ui/pages/onboarding-flow/welcome/welcome.js | 17 +- ui/pages/send/gas-display/gas-display.js | 9 +- .../amount-max-button/amount-max-button.js | 4 +- .../send-asset-row.component.js | 4 +- .../send/send-footer/send-footer.component.js | 6 +- ui/pages/send/send.js | 4 +- .../advanced-tab/advanced-tab.component.js | 9 +- .../experimental-tab.component.js | 8 +- .../settings/info-tab/info-tab.component.js | 22 +- .../networks-form/networks-form.js | 6 +- .../security-tab/security-tab.component.js | 22 +- .../settings-tab/settings-tab.component.js | 4 +- .../awaiting-signatures.js | 4 +- ui/pages/swaps/awaiting-swap/awaiting-swap.js | 16 +- ui/pages/swaps/build-quote/build-quote.js | 16 +- .../swaps/create-new-swap/create-new-swap.js | 4 +- .../dropdown-search-list.js | 6 +- ui/pages/swaps/fee-card/fee-card.js | 4 +- ui/pages/swaps/index.js | 6 +- .../loading-swaps-quotes.js | 4 +- .../item-list/item-list.component.js | 4 +- .../smart-transaction-status.js | 6 +- .../view-on-block-explorer.js | 12 +- ui/pages/swaps/view-quote/view-quote.js | 12 +- ui/pages/unlock-page/unlock-page.component.js | 20 +- ui/store/action-queue/index.ts | 9 +- ui/store/actions.test.js | 6 +- ui/store/actions.ts | 4 +- 109 files changed, 1462 insertions(+), 1117 deletions(-) delete mode 100644 shared/constants/metametrics.js create mode 100644 shared/constants/metametrics.ts diff --git a/app/scripts/background.js b/app/scripts/background.js index 2fdca5a16..9e7f65d0d 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -24,11 +24,11 @@ import { } from '../../shared/constants/app'; import { SECOND } from '../../shared/constants/time'; import { - REJECT_NOTFICIATION_CLOSE, - REJECT_NOTFICIATION_CLOSE_SIG, - EVENT, - EVENT_NAMES, - TRAITS, + REJECT_NOTIFICATION_CLOSE, + REJECT_NOTIFICATION_CLOSE_SIG, + MetaMetricsEventCategory, + MetaMetricsEventName, + MetaMetricsUserTrait, } from '../../shared/constants/metametrics'; import { checkForLastErrorAndLog } from '../../shared/modules/browser-runtime.utils'; import { isManifestV3 } from '../../shared/modules/mv3.utils'; @@ -738,13 +738,13 @@ export function setupController(initState, initLangCode, overrides) { ).forEach((txId) => controller.txController.txStateManager.setTxStatusRejected(txId), ); - controller.signController.rejectUnapproved(REJECT_NOTFICIATION_CLOSE_SIG); + controller.signController.rejectUnapproved(REJECT_NOTIFICATION_CLOSE_SIG); controller.decryptMessageManager.messages .filter((msg) => msg.status === 'unapproved') .forEach((tx) => controller.decryptMessageManager.rejectMsg( tx.id, - REJECT_NOTFICIATION_CLOSE, + REJECT_NOTIFICATION_CLOSE, ), ); controller.encryptionPublicKeyManager.messages @@ -752,7 +752,7 @@ export function setupController(initState, initLangCode, overrides) { .forEach((tx) => controller.encryptionPublicKeyManager.rejectMsg( tx.id, - REJECT_NOTFICIATION_CLOSE, + REJECT_NOTIFICATION_CLOSE, ), ); @@ -848,11 +848,13 @@ async function openPopup() { const addAppInstalledEvent = () => { if (controller) { controller.metaMetricsController.updateTraits({ - [TRAITS.INSTALL_DATE_EXT]: new Date().toISOString().split('T')[0], // yyyy-mm-dd + [MetaMetricsUserTrait.InstallDateExt]: new Date() + .toISOString() + .split('T')[0], // yyyy-mm-dd }); controller.metaMetricsController.addEventBeforeMetricsOptIn({ - category: EVENT.CATEGORIES.APP, - event: EVENT_NAMES.APP_INSTALLED, + category: MetaMetricsEventCategory.App, + event: MetaMetricsEventName.AppInstalled, properties: {}, }); return; diff --git a/app/scripts/controllers/detect-tokens.js b/app/scripts/controllers/detect-tokens.js index a53bee096..2b23dd71b 100644 --- a/app/scripts/controllers/detect-tokens.js +++ b/app/scripts/controllers/detect-tokens.js @@ -8,7 +8,10 @@ import { AssetType, TokenStandard, } from '../../../shared/constants/transaction'; -import { EVENT, EVENT_NAMES } from '../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../shared/constants/metametrics'; // By default, poll every 3 minutes const DEFAULT_INTERVAL = MINUTE * 3; @@ -167,8 +170,8 @@ export default class DetectTokensController { if (tokensWithBalance.length > 0) { this._trackMetaMetricsEvent({ - event: EVENT_NAMES.TOKEN_DETECTED, - category: EVENT.CATEGORIES.WALLET, + event: MetaMetricsEventName.TokenDetected, + category: MetaMetricsEventCategory.Wallet, properties: { tokens: eventTokensDetails, token_standard: TokenStandard.ERC20, diff --git a/app/scripts/controllers/metametrics.js b/app/scripts/controllers/metametrics.js index a949f3cc7..c433b3f5e 100644 --- a/app/scripts/controllers/metametrics.js +++ b/app/scripts/controllers/metametrics.js @@ -15,7 +15,7 @@ import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../shared/constants/app'; import { METAMETRICS_ANONYMOUS_ID, METAMETRICS_BACKGROUND_PAGE_OBJECT, - TRAITS, + MetaMetricsUserTrait, } from '../../../shared/constants/metametrics'; import { SECOND } from '../../../shared/constants/time'; import { isManifestV3 } from '../../../shared/modules/mv3.utils'; @@ -692,38 +692,44 @@ export default class MetaMetricsController { const { traits, previousUserTraits } = this.store.getState(); /** @type {MetaMetricsTraits} */ const currentTraits = { - [TRAITS.ADDRESS_BOOK_ENTRIES]: sum( + [MetaMetricsUserTrait.AddressBookEntries]: sum( Object.values(metamaskState.addressBook).map(size), ), - [TRAITS.INSTALL_DATE_EXT]: traits[TRAITS.INSTALL_DATE_EXT] || '', - [TRAITS.LEDGER_CONNECTION_TYPE]: metamaskState.ledgerTransportType, - [TRAITS.NETWORKS_ADDED]: Object.values( + [MetaMetricsUserTrait.InstallDateExt]: + traits[MetaMetricsUserTrait.InstallDateExt] || '', + [MetaMetricsUserTrait.LedgerConnectionType]: + metamaskState.ledgerTransportType, + [MetaMetricsUserTrait.NetworksAdded]: Object.values( metamaskState.networkConfigurations, ).map((networkConfiguration) => networkConfiguration.chainId), - [TRAITS.NETWORKS_WITHOUT_TICKER]: Object.values( + [MetaMetricsUserTrait.NetworksWithoutTicker]: Object.values( metamaskState.networkConfigurations, ) .filter(({ ticker }) => !ticker) .map(({ chainId }) => chainId), - [TRAITS.NFT_AUTODETECTION_ENABLED]: metamaskState.useNftDetection, - [TRAITS.NUMBER_OF_ACCOUNTS]: Object.values(metamaskState.identities) - .length, - [TRAITS.NUMBER_OF_NFT_COLLECTIONS]: this._getAllUniqueNFTAddressesLength( + [MetaMetricsUserTrait.NftAutodetectionEnabled]: + metamaskState.useNftDetection, + [MetaMetricsUserTrait.NumberOfAccounts]: Object.values( + metamaskState.identities, + ).length, + [MetaMetricsUserTrait.NumberOfNftCollections]: + this._getAllUniqueNFTAddressesLength(metamaskState.allNfts), + [MetaMetricsUserTrait.NumberOfNfts]: this._getAllNFTsFlattened( metamaskState.allNfts, - ), - [TRAITS.NUMBER_OF_NFTS]: this._getAllNFTsFlattened(metamaskState.allNfts) - .length, - [TRAITS.NUMBER_OF_TOKENS]: this._getNumberOfTokens(metamaskState), - [TRAITS.OPENSEA_API_ENABLED]: metamaskState.openSeaEnabled, - [TRAITS.THREE_BOX_ENABLED]: false, // deprecated, hard-coded as false - [TRAITS.THEME]: metamaskState.theme || 'default', - [TRAITS.TOKEN_DETECTION_ENABLED]: metamaskState.useTokenDetection, + ).length, + [MetaMetricsUserTrait.NumberOfTokens]: + this._getNumberOfTokens(metamaskState), + [MetaMetricsUserTrait.OpenseaApiEnabled]: metamaskState.openSeaEnabled, + [MetaMetricsUserTrait.ThreeBoxEnabled]: false, // deprecated, hard-coded as false + [MetaMetricsUserTrait.Theme]: metamaskState.theme || 'default', + [MetaMetricsUserTrait.TokenDetectionEnabled]: + metamaskState.useTokenDetection, ///: BEGIN:ONLY_INCLUDE_IN(flask) - [TRAITS.DESKTOP_ENABLED]: metamaskState.desktopEnabled || false, + [MetaMetricsUserTrait.DesktopEnabled]: + metamaskState.desktopEnabled || false, ///: END:ONLY_INCLUDE_IN - [TRAITS.SECURITY_PROVIDERS]: metamaskState.transactionSecurityCheckEnabled - ? ['opensea'] - : [], + [MetaMetricsUserTrait.SecurityProviders]: + metamaskState.transactionSecurityCheckEnabled ? ['opensea'] : [], }; if (!previousUserTraits) { diff --git a/app/scripts/controllers/metametrics.test.js b/app/scripts/controllers/metametrics.test.js index 18535c1d7..dbd0e56c8 100644 --- a/app/scripts/controllers/metametrics.test.js +++ b/app/scripts/controllers/metametrics.test.js @@ -5,7 +5,7 @@ import { createSegmentMock } from '../lib/segment'; import { METAMETRICS_ANONYMOUS_ID, METAMETRICS_BACKGROUND_PAGE_OBJECT, - TRAITS, + MetaMetricsUserTrait, } from '../../../shared/constants/metametrics'; import waitUntilCalled from '../../../test/lib/wait-until-called'; import { @@ -953,22 +953,26 @@ describe('MetaMetricsController', function () { }); assert.deepEqual(traits, { - [TRAITS.ADDRESS_BOOK_ENTRIES]: 3, - [TRAITS.INSTALL_DATE_EXT]: '', - [TRAITS.LEDGER_CONNECTION_TYPE]: 'web-hid', - [TRAITS.NETWORKS_ADDED]: [CHAIN_IDS.MAINNET, CHAIN_IDS.GOERLI, '0xaf'], - [TRAITS.NETWORKS_WITHOUT_TICKER]: ['0xaf'], - [TRAITS.NFT_AUTODETECTION_ENABLED]: false, - [TRAITS.NUMBER_OF_ACCOUNTS]: 2, - [TRAITS.NUMBER_OF_NFT_COLLECTIONS]: 3, - [TRAITS.NUMBER_OF_NFTS]: 4, - [TRAITS.NUMBER_OF_TOKENS]: 5, - [TRAITS.OPENSEA_API_ENABLED]: true, - [TRAITS.THREE_BOX_ENABLED]: false, - [TRAITS.THEME]: 'default', - [TRAITS.TOKEN_DETECTION_ENABLED]: true, - [TRAITS.DESKTOP_ENABLED]: false, - [TRAITS.SECURITY_PROVIDERS]: [], + [MetaMetricsUserTrait.AddressBookEntries]: 3, + [MetaMetricsUserTrait.InstallDateExt]: '', + [MetaMetricsUserTrait.LedgerConnectionType]: 'web-hid', + [MetaMetricsUserTrait.NetworksAdded]: [ + CHAIN_IDS.MAINNET, + CHAIN_IDS.GOERLI, + '0xaf', + ], + [MetaMetricsUserTrait.NetworksWithoutTicker]: ['0xaf'], + [MetaMetricsUserTrait.NftAutodetectionEnabled]: false, + [MetaMetricsUserTrait.NumberOfAccounts]: 2, + [MetaMetricsUserTrait.NumberOfNftCollections]: 3, + [MetaMetricsUserTrait.NumberOfNfts]: 4, + [MetaMetricsUserTrait.NumberOfTokens]: 5, + [MetaMetricsUserTrait.OpenseaApiEnabled]: true, + [MetaMetricsUserTrait.ThreeBoxEnabled]: false, + [MetaMetricsUserTrait.Theme]: 'default', + [MetaMetricsUserTrait.TokenDetectionEnabled]: true, + [MetaMetricsUserTrait.DesktopEnabled]: false, + [MetaMetricsUserTrait.SecurityProviders]: [], }); }); @@ -1015,10 +1019,10 @@ describe('MetaMetricsController', function () { }); assert.deepEqual(updatedTraits, { - [TRAITS.ADDRESS_BOOK_ENTRIES]: 4, - [TRAITS.NUMBER_OF_ACCOUNTS]: 3, - [TRAITS.NUMBER_OF_TOKENS]: 1, - [TRAITS.OPENSEA_API_ENABLED]: false, + [MetaMetricsUserTrait.AddressBookEntries]: 4, + [MetaMetricsUserTrait.NumberOfAccounts]: 3, + [MetaMetricsUserTrait.NumberOfTokens]: 1, + [MetaMetricsUserTrait.OpenseaApiEnabled]: false, }); }); diff --git a/app/scripts/controllers/network/network-controller.js b/app/scripts/controllers/network/network-controller.js index ca48d85c4..ad8ded74b 100644 --- a/app/scripts/controllers/network/network-controller.js +++ b/app/scripts/controllers/network/network-controller.js @@ -26,7 +26,7 @@ import { isPrefixedFormattedHexString, isSafeChainId, } from '../../../../shared/modules/network.utils'; -import { EVENT } from '../../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../../shared/constants/metametrics'; import { createNetworkClient } from './create-network-client'; /** @@ -645,7 +645,7 @@ export default class NetworkController extends EventEmitter { if (!oldNetworkConfigurationId) { this._trackMetaMetricsEvent({ event: 'Custom Network Added', - category: EVENT.CATEGORIES.NETWORK, + category: MetaMetricsEventCategory.Network, referrer: { url: referrer, }, diff --git a/app/scripts/controllers/network/network-controller.test.js b/app/scripts/controllers/network/network-controller.test.js index e8684179e..a58c563a8 100644 --- a/app/scripts/controllers/network/network-controller.test.js +++ b/app/scripts/controllers/network/network-controller.test.js @@ -5,7 +5,7 @@ import nock from 'nock'; import sinon from 'sinon'; import { ControllerMessenger } from '@metamask/base-controller'; import { BUILT_IN_NETWORKS } from '../../../../shared/constants/network'; -import { EVENT } from '../../../../shared/constants/metametrics'; +import { MetaMetricsNetworkEventSource } from '../../../../shared/constants/metametrics'; import NetworkController from './network-controller'; jest.mock('uuid', () => { @@ -6991,7 +6991,7 @@ describe('NetworkController', () => { }, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }, ), ).toThrow( @@ -7015,7 +7015,7 @@ describe('NetworkController', () => { }, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }, ), ).toThrow( @@ -7038,7 +7038,7 @@ describe('NetworkController', () => { }, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }, ), ).toThrow( @@ -7062,7 +7062,7 @@ describe('NetworkController', () => { }, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }, ), ).toThrow(new Error('rpcUrl must be a valid URL')); @@ -7081,7 +7081,7 @@ describe('NetworkController', () => { }, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }, ), ).toThrow( @@ -7126,7 +7126,7 @@ describe('NetworkController', () => { controller.upsertNetworkConfiguration(rpcUrlNetwork, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }); expect( @@ -7164,7 +7164,7 @@ describe('NetworkController', () => { controller.upsertNetworkConfiguration(rpcUrlNetwork, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }); expect( @@ -7213,7 +7213,7 @@ describe('NetworkController', () => { controller.upsertNetworkConfiguration(rpcUrlNetwork, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }); expect( @@ -7262,7 +7262,7 @@ describe('NetworkController', () => { }; controller.upsertNetworkConfiguration(updatedConfiguration, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }); expect( Object.values(controller.store.getState().networkConfigurations), @@ -7315,7 +7315,7 @@ describe('NetworkController', () => { }, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }, ); @@ -7375,7 +7375,7 @@ describe('NetworkController', () => { controller.upsertNetworkConfiguration(rpcUrlNetwork, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }); expect(controller.store.getState().provider).toStrictEqual( @@ -7424,7 +7424,7 @@ describe('NetworkController', () => { controller.upsertNetworkConfiguration(rpcUrlNetwork, { setActive: true, referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }); expect(controller.store.getState().provider).toStrictEqual({ @@ -7473,7 +7473,7 @@ describe('NetworkController', () => { controller.upsertNetworkConfiguration(newNetworkConfiguration, { referrer: 'https://test-dapp.com', - source: EVENT.SOURCE.NETWORK.DAPP, + source: MetaMetricsNetworkEventSource.Dapp, }); expect( diff --git a/app/scripts/controllers/sign.test.ts b/app/scripts/controllers/sign.test.ts index 9363583fb..7212df2ae 100644 --- a/app/scripts/controllers/sign.test.ts +++ b/app/scripts/controllers/sign.test.ts @@ -7,7 +7,7 @@ import { AbstractMessage, OriginalRequest, } from '@metamask/message-manager/dist/AbstractMessageManager'; -import { EVENT } from '../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../shared/constants/metametrics'; import { detectSIWE } from '../../../shared/modules/siwe'; import SignController, { SignControllerMessenger, @@ -270,7 +270,7 @@ describe('SignController', () => { expect(metricsEventMock).toHaveBeenCalledTimes(6); expect(metricsEventMock).toHaveBeenLastCalledWith({ event: 'Test Reason', - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, properties: { action: 'Sign Request', type: messageMock.type, diff --git a/app/scripts/controllers/sign.ts b/app/scripts/controllers/sign.ts index 13157d502..afaeaa499 100644 --- a/app/scripts/controllers/sign.ts +++ b/app/scripts/controllers/sign.ts @@ -32,7 +32,7 @@ import { AddApprovalRequest, RejectRequest, } from '@metamask/approval-controller'; -import { EVENT } from '../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../shared/constants/metametrics'; import { detectSIWE } from '../../../shared/modules/siwe'; import PreferencesController from './preferences'; @@ -510,7 +510,7 @@ export default class SignController extends BaseControllerV2< this._metricsEvent({ event: reason, - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, properties: { action: 'Sign Request', type: message.type, diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js index a98ee441d..8d0cddd6e 100644 --- a/app/scripts/controllers/transactions/index.js +++ b/app/scripts/controllers/transactions/index.js @@ -39,7 +39,7 @@ import { hexWEIToDecGWEI, } from '../../../../shared/modules/conversion.utils'; import { isSwapsDefaultTokenAddress } from '../../../../shared/modules/swaps.utils'; -import { EVENT } from '../../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../../shared/constants/metametrics'; import { HARDFORKS, CHAIN_ID_TO_GAS_LIMIT_BUFFER_MAP, @@ -2027,7 +2027,7 @@ export default class TransactionController extends EventEmitter { this._trackMetaMetricsEvent({ event: 'Swap Failed', sensitiveProperties: { ...txMeta.swapMetaData }, - category: EVENT.CATEGORIES.SWAPS, + category: MetaMetricsEventCategory.Swaps, }); } else { const tokensReceived = getSwapsTokensReceivedFromTxMeta( @@ -2062,7 +2062,7 @@ export default class TransactionController extends EventEmitter { this._trackMetaMetricsEvent({ event: 'Swap Completed', - category: EVENT.CATEGORIES.SWAPS, + category: MetaMetricsEventCategory.Swaps, sensitiveProperties: { ...txMeta.swapMetaData, token_to_amount_received: tokensReceived, @@ -2414,7 +2414,7 @@ export default class TransactionController extends EventEmitter { // occur. case TransactionMetaMetricsEvent.added: this.createEventFragment({ - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, initialEvent: TransactionMetaMetricsEvent.added, successEvent: TransactionMetaMetricsEvent.approved, failureEvent: TransactionMetaMetricsEvent.rejected, @@ -2436,7 +2436,7 @@ export default class TransactionController extends EventEmitter { case TransactionMetaMetricsEvent.approved: case TransactionMetaMetricsEvent.rejected: this.createEventFragment({ - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, successEvent: TransactionMetaMetricsEvent.approved, failureEvent: TransactionMetaMetricsEvent.rejected, properties, @@ -2458,7 +2458,7 @@ export default class TransactionController extends EventEmitter { // properties to the transaction event. case TransactionMetaMetricsEvent.submitted: this.createEventFragment({ - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, initialEvent: TransactionMetaMetricsEvent.submitted, successEvent: TransactionMetaMetricsEvent.finalized, properties, @@ -2478,7 +2478,7 @@ export default class TransactionController extends EventEmitter { // fragment does not exist. case TransactionMetaMetricsEvent.finalized: this.createEventFragment({ - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, successEvent: TransactionMetaMetricsEvent.finalized, properties, sensitiveProperties, diff --git a/app/scripts/controllers/transactions/index.test.js b/app/scripts/controllers/transactions/index.test.js index 99b2cd4b1..c16f1fa2c 100644 --- a/app/scripts/controllers/transactions/index.test.js +++ b/app/scripts/controllers/transactions/index.test.js @@ -10,7 +10,10 @@ import { getTestAccounts, } from '../../../../test/stub/provider'; import mockEstimates from '../../../../test/data/mock-estimates.json'; -import { EVENT } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsTransactionEventSource, +} from '../../../../shared/constants/metametrics'; import { TransactionStatus, TransactionType, @@ -1772,7 +1775,7 @@ describe('Transaction Controller', function () { successEvent: 'Transaction Approved', failureEvent: 'Transaction Rejected', uniqueIdentifier: 'transaction-added-1', - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, persist: true, properties: { chain_id: '0x5', @@ -1781,7 +1784,7 @@ describe('Transaction Controller', function () { gas_edit_type: 'none', network: '5', referrer: ORIGIN_METAMASK, - source: EVENT.SOURCE.TRANSACTION.USER, + source: MetaMetricsTransactionEventSource.User, transaction_type: TransactionType.simpleSend, account_type: 'MetaMask', asset_type: AssetType.native, @@ -1859,7 +1862,7 @@ describe('Transaction Controller', function () { initialEvent: 'Transaction Submitted', successEvent: 'Transaction Finalized', uniqueIdentifier: 'transaction-submitted-1', - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, persist: true, properties: { chain_id: '0x5', @@ -1868,7 +1871,7 @@ describe('Transaction Controller', function () { gas_edit_type: 'none', network: '5', referrer: ORIGIN_METAMASK, - source: EVENT.SOURCE.TRANSACTION.USER, + source: MetaMetricsTransactionEventSource.User, transaction_type: TransactionType.simpleSend, account_type: 'MetaMask', asset_type: AssetType.native, @@ -1958,7 +1961,7 @@ describe('Transaction Controller', function () { successEvent: 'Transaction Approved', failureEvent: 'Transaction Rejected', uniqueIdentifier: 'transaction-added-1', - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, persist: true, properties: { chain_id: '0x5', @@ -1967,7 +1970,7 @@ describe('Transaction Controller', function () { gas_edit_type: 'none', network: '5', referrer: 'other', - source: EVENT.SOURCE.TRANSACTION.DAPP, + source: MetaMetricsTransactionEventSource.Dapp, transaction_type: TransactionType.simpleSend, account_type: 'MetaMask', asset_type: AssetType.native, @@ -2047,7 +2050,7 @@ describe('Transaction Controller', function () { initialEvent: 'Transaction Submitted', successEvent: 'Transaction Finalized', uniqueIdentifier: 'transaction-submitted-1', - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, persist: true, properties: { chain_id: '0x5', @@ -2056,7 +2059,7 @@ describe('Transaction Controller', function () { gas_edit_type: 'none', network: '5', referrer: 'other', - source: EVENT.SOURCE.TRANSACTION.DAPP, + source: MetaMetricsTransactionEventSource.Dapp, transaction_type: TransactionType.simpleSend, account_type: 'MetaMask', asset_type: AssetType.native, @@ -2138,7 +2141,7 @@ describe('Transaction Controller', function () { successEvent: 'Transaction Approved', failureEvent: 'Transaction Rejected', uniqueIdentifier: 'transaction-added-1', - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, persist: true, properties: { chain_id: '0x5', @@ -2147,7 +2150,7 @@ describe('Transaction Controller', function () { gas_edit_type: 'none', network: '5', referrer: 'other', - source: EVENT.SOURCE.TRANSACTION.DAPP, + source: MetaMetricsTransactionEventSource.Dapp, transaction_type: TransactionType.simpleSend, account_type: 'MetaMask', asset_type: AssetType.native, @@ -2211,11 +2214,11 @@ describe('Transaction Controller', function () { failureEvent: 'Transaction Rejected', uniqueIdentifier: 'transaction-added-1', persist: true, - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, properties: { network: '5', referrer: 'other', - source: EVENT.SOURCE.TRANSACTION.DAPP, + source: MetaMetricsTransactionEventSource.Dapp, transaction_type: TransactionType.simpleSend, chain_id: '0x5', eip_1559_version: '0', @@ -2285,11 +2288,11 @@ describe('Transaction Controller', function () { failureEvent: 'Transaction Rejected', uniqueIdentifier: 'transaction-added-1', persist: true, - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, properties: { network: '5', referrer: 'other', - source: EVENT.SOURCE.TRANSACTION.DAPP, + source: MetaMetricsTransactionEventSource.Dapp, transaction_type: TransactionType.simpleSend, chain_id: '0x5', eip_1559_version: '0', @@ -2359,11 +2362,11 @@ describe('Transaction Controller', function () { failureEvent: 'Transaction Rejected', uniqueIdentifier: 'transaction-added-1', persist: true, - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, properties: { network: '5', referrer: 'other', - source: EVENT.SOURCE.TRANSACTION.DAPP, + source: MetaMetricsTransactionEventSource.Dapp, transaction_type: TransactionType.simpleSend, chain_id: '0x5', eip_1559_version: '0', @@ -2441,7 +2444,7 @@ describe('Transaction Controller', function () { failureEvent: 'Transaction Rejected', uniqueIdentifier: 'transaction-added-1', persist: true, - category: EVENT.CATEGORIES.TRANSACTIONS, + category: MetaMetricsEventCategory.Transactions, properties: { chain_id: '0x5', eip_1559_version: '2', @@ -2449,7 +2452,7 @@ describe('Transaction Controller', function () { gas_edit_type: 'none', network: '5', referrer: 'other', - source: EVENT.SOURCE.TRANSACTION.DAPP, + source: MetaMetricsTransactionEventSource.Dapp, transaction_type: TransactionType.simpleSend, account_type: 'MetaMask', asset_type: AssetType.native, diff --git a/app/scripts/lib/createRPCMethodTrackingMiddleware.js b/app/scripts/lib/createRPCMethodTrackingMiddleware.js index cec5b3308..cd3b9720a 100644 --- a/app/scripts/lib/createRPCMethodTrackingMiddleware.js +++ b/app/scripts/lib/createRPCMethodTrackingMiddleware.js @@ -4,9 +4,9 @@ import { TransactionStatus } from '../../../shared/constants/transaction'; import { SECOND } from '../../../shared/constants/time'; import { detectSIWE } from '../../../shared/modules/siwe'; import { - EVENT, - EVENT_NAMES, - METAMETRIC_KEY_OPT, + MetaMetricsEventCategory, + MetaMetricsEventName, + MetaMetricsEventUiCustomization, } from '../../../shared/constants/metametrics'; /** @@ -46,50 +46,50 @@ const RATE_LIMIT_MAP = { */ const EVENT_NAME_MAP = { [MESSAGE_TYPE.ETH_SIGN]: { - APPROVED: EVENT_NAMES.SIGNATURE_APPROVED, - FAILED: EVENT_NAMES.SIGNATURE_FAILED, - REJECTED: EVENT_NAMES.SIGNATURE_REJECTED, - REQUESTED: EVENT_NAMES.SIGNATURE_REQUESTED, + APPROVED: MetaMetricsEventName.SignatureApproved, + FAILED: MetaMetricsEventName.SignatureFailed, + REJECTED: MetaMetricsEventName.SignatureRejected, + REQUESTED: MetaMetricsEventName.SignatureRequested, }, [MESSAGE_TYPE.ETH_SIGN_TYPED_DATA]: { - APPROVED: EVENT_NAMES.SIGNATURE_APPROVED, - REJECTED: EVENT_NAMES.SIGNATURE_REJECTED, - REQUESTED: EVENT_NAMES.SIGNATURE_REQUESTED, + APPROVED: MetaMetricsEventName.SignatureApproved, + REJECTED: MetaMetricsEventName.SignatureRejected, + REQUESTED: MetaMetricsEventName.SignatureRequested, }, [MESSAGE_TYPE.ETH_SIGN_TYPED_DATA_V3]: { - APPROVED: EVENT_NAMES.SIGNATURE_APPROVED, - REJECTED: EVENT_NAMES.SIGNATURE_REJECTED, - REQUESTED: EVENT_NAMES.SIGNATURE_REQUESTED, + APPROVED: MetaMetricsEventName.SignatureApproved, + REJECTED: MetaMetricsEventName.SignatureRejected, + REQUESTED: MetaMetricsEventName.SignatureRequested, }, [MESSAGE_TYPE.ETH_SIGN_TYPED_DATA_V4]: { - APPROVED: EVENT_NAMES.SIGNATURE_APPROVED, - REJECTED: EVENT_NAMES.SIGNATURE_REJECTED, - REQUESTED: EVENT_NAMES.SIGNATURE_REQUESTED, + APPROVED: MetaMetricsEventName.SignatureApproved, + REJECTED: MetaMetricsEventName.SignatureRejected, + REQUESTED: MetaMetricsEventName.SignatureRequested, }, [MESSAGE_TYPE.PERSONAL_SIGN]: { - APPROVED: EVENT_NAMES.SIGNATURE_APPROVED, - REJECTED: EVENT_NAMES.SIGNATURE_REJECTED, - REQUESTED: EVENT_NAMES.SIGNATURE_REQUESTED, + APPROVED: MetaMetricsEventName.SignatureApproved, + REJECTED: MetaMetricsEventName.SignatureRejected, + REQUESTED: MetaMetricsEventName.SignatureRequested, }, [MESSAGE_TYPE.ETH_DECRYPT]: { - APPROVED: EVENT_NAMES.DECRYPTION_APPROVED, - REJECTED: EVENT_NAMES.DECRYPTION_REJECTED, - REQUESTED: EVENT_NAMES.DECRYPTION_REQUESTED, + APPROVED: MetaMetricsEventName.DecryptionApproved, + REJECTED: MetaMetricsEventName.DecryptionRejected, + REQUESTED: MetaMetricsEventName.DecryptionRequested, }, [MESSAGE_TYPE.ETH_GET_ENCRYPTION_PUBLIC_KEY]: { - APPROVED: EVENT_NAMES.ENCRYPTION_PUBLIC_KEY_APPROVED, - REJECTED: EVENT_NAMES.ENCRYPTION_PUBLIC_KEY_REJECTED, - REQUESTED: EVENT_NAMES.ENCRYPTION_PUBLIC_KEY_REQUESTED, + APPROVED: MetaMetricsEventName.EncryptionPublicKeyApproved, + REJECTED: MetaMetricsEventName.EncryptionPublicKeyRejected, + REQUESTED: MetaMetricsEventName.EncryptionPublicKeyRequested, }, [MESSAGE_TYPE.ETH_REQUEST_ACCOUNTS]: { - APPROVED: EVENT_NAMES.PERMISSIONS_APPROVED, - REJECTED: EVENT_NAMES.PERMISSIONS_REJECTED, - REQUESTED: EVENT_NAMES.PERMISSIONS_REQUESTED, + APPROVED: MetaMetricsEventName.PermissionsApproved, + REJECTED: MetaMetricsEventName.PermissionsRejected, + REQUESTED: MetaMetricsEventName.PermissionsRequested, }, [MESSAGE_TYPE.WALLET_REQUEST_PERMISSIONS]: { - APPROVED: EVENT_NAMES.PERMISSIONS_APPROVED, - REJECTED: EVENT_NAMES.PERMISSIONS_REJECTED, - REQUESTED: EVENT_NAMES.PERMISSIONS_REQUESTED, + APPROVED: MetaMetricsEventName.PermissionsApproved, + REJECTED: MetaMetricsEventName.PermissionsRejected, + REQUESTED: MetaMetricsEventName.PermissionsRequested, }, }; @@ -162,9 +162,9 @@ export default function createRPCMethodTrackingMiddleware({ // 'Provider Method Called'. const event = eventType ? eventType.REQUESTED - : EVENT_NAMES.PROVIDER_METHOD_CALLED; + : MetaMetricsEventName.ProviderMethodCalled; - if (event === EVENT_NAMES.SIGNATURE_REQUESTED) { + if (event === MetaMetricsEventName.SignatureRequested) { eventProperties.signature_type = method; const data = req?.params?.[0]; @@ -190,11 +190,11 @@ export default function createRPCMethodTrackingMiddleware({ if (securityProviderResponse?.flagAsDangerous === 1) { eventProperties.ui_customizations = [ - METAMETRIC_KEY_OPT.ui_customizations.flaggedAsMalicious, + MetaMetricsEventUiCustomization.FlaggedAsMalicious, ]; } else if (securityProviderResponse?.flagAsDangerous === 2) { eventProperties.ui_customizations = [ - METAMETRIC_KEY_OPT.ui_customizations.flaggedAsSafetyUnknown, + MetaMetricsEventUiCustomization.FlaggedAsSafetyUnknown, ]; } @@ -203,7 +203,7 @@ export default function createRPCMethodTrackingMiddleware({ if (isSIWEMessage) { eventProperties.ui_customizations = ( eventProperties.ui_customizations || [] - ).concat(METAMETRIC_KEY_OPT.ui_customizations.SIWE); + ).concat(MetaMetricsEventUiCustomization.Siwe); } } } catch (e) { @@ -217,7 +217,7 @@ export default function createRPCMethodTrackingMiddleware({ trackEvent({ event, - category: EVENT.CATEGORIES.INPAGE_PROVIDER, + category: MetaMetricsEventCategory.InpageProvider, referrer: { url: origin, }, @@ -253,7 +253,7 @@ export default function createRPCMethodTrackingMiddleware({ trackEvent({ event, - category: EVENT.CATEGORIES.INPAGE_PROVIDER, + category: MetaMetricsEventCategory.InpageProvider, referrer: { url: origin, }, diff --git a/app/scripts/lib/createRPCMethodTrackingMiddleware.test.js b/app/scripts/lib/createRPCMethodTrackingMiddleware.test.js index 5be404f43..342fd320a 100644 --- a/app/scripts/lib/createRPCMethodTrackingMiddleware.test.js +++ b/app/scripts/lib/createRPCMethodTrackingMiddleware.test.js @@ -1,8 +1,8 @@ import { errorCodes } from 'eth-rpc-errors'; import { MESSAGE_TYPE } from '../../../shared/constants/app'; import { - EVENT_NAMES, - METAMETRIC_KEY_OPT, + MetaMetricsEventName, + MetaMetricsEventUiCustomization, } from '../../../shared/constants/metametrics'; import { SECOND } from '../../../shared/constants/time'; import { detectSIWE } from '../../../shared/modules/siwe'; @@ -111,7 +111,7 @@ describe('createRPCMethodTrackingMiddleware', () => { metricsState.participateInMetaMetrics = true; }); - it(`should immediately track a ${EVENT_NAMES.SIGNATURE_REQUESTED} event`, async () => { + it(`should immediately track a ${MetaMetricsEventName.SignatureRequested} event`, async () => { const req = { method: MESSAGE_TYPE.ETH_SIGN, origin: 'some.dapp', @@ -125,7 +125,7 @@ describe('createRPCMethodTrackingMiddleware', () => { expect(trackEvent).toHaveBeenCalledTimes(1); expect(trackEvent.mock.calls[0][0]).toMatchObject({ category: 'inpage_provider', - event: EVENT_NAMES.SIGNATURE_REQUESTED, + event: MetaMetricsEventName.SignatureRequested, properties: { signature_type: MESSAGE_TYPE.ETH_SIGN, }, @@ -133,7 +133,7 @@ describe('createRPCMethodTrackingMiddleware', () => { }); }); - it(`should track a ${EVENT_NAMES.SIGNATURE_APPROVED} event if the user approves`, async () => { + it(`should track a ${MetaMetricsEventName.SignatureApproved} event if the user approves`, async () => { const req = { method: MESSAGE_TYPE.ETH_SIGN_TYPED_DATA_V4, origin: 'some.dapp', @@ -148,7 +148,7 @@ describe('createRPCMethodTrackingMiddleware', () => { expect(trackEvent).toHaveBeenCalledTimes(2); expect(trackEvent.mock.calls[1][0]).toMatchObject({ category: 'inpage_provider', - event: EVENT_NAMES.SIGNATURE_APPROVED, + event: MetaMetricsEventName.SignatureApproved, properties: { signature_type: MESSAGE_TYPE.ETH_SIGN_TYPED_DATA_V4, }, @@ -156,7 +156,7 @@ describe('createRPCMethodTrackingMiddleware', () => { }); }); - it(`should track a ${EVENT_NAMES.SIGNATURE_REJECTED} event if the user approves`, async () => { + it(`should track a ${MetaMetricsEventName.SignatureRejected} event if the user approves`, async () => { const req = { method: MESSAGE_TYPE.PERSONAL_SIGN, origin: 'some.dapp', @@ -171,7 +171,7 @@ describe('createRPCMethodTrackingMiddleware', () => { expect(trackEvent).toHaveBeenCalledTimes(2); expect(trackEvent.mock.calls[1][0]).toMatchObject({ category: 'inpage_provider', - event: EVENT_NAMES.SIGNATURE_REJECTED, + event: MetaMetricsEventName.SignatureRejected, properties: { signature_type: MESSAGE_TYPE.PERSONAL_SIGN, }, @@ -179,7 +179,7 @@ describe('createRPCMethodTrackingMiddleware', () => { }); }); - it(`should track a ${EVENT_NAMES.PERMISSIONS_APPROVED} event if the user approves`, async () => { + it(`should track a ${MetaMetricsEventName.PermissionsApproved} event if the user approves`, async () => { const req = { method: MESSAGE_TYPE.ETH_REQUEST_ACCOUNTS, origin: 'some.dapp', @@ -192,7 +192,7 @@ describe('createRPCMethodTrackingMiddleware', () => { expect(trackEvent).toHaveBeenCalledTimes(2); expect(trackEvent.mock.calls[1][0]).toMatchObject({ category: 'inpage_provider', - event: EVENT_NAMES.PERMISSIONS_APPROVED, + event: MetaMetricsEventName.PermissionsApproved, properties: { method: MESSAGE_TYPE.ETH_REQUEST_ACCOUNTS }, referrer: { url: 'some.dapp' }, }); @@ -261,17 +261,17 @@ describe('createRPCMethodTrackingMiddleware', () => { expect(trackEvent.mock.calls[1][0]).toMatchObject({ category: 'inpage_provider', - event: EVENT_NAMES.SIGNATURE_APPROVED, + event: MetaMetricsEventName.SignatureApproved, properties: { signature_type: MESSAGE_TYPE.PERSONAL_SIGN, - ui_customizations: [METAMETRIC_KEY_OPT.ui_customizations.SIWE], + ui_customizations: [MetaMetricsEventUiCustomization.Siwe], }, referrer: { url: 'some.dapp' }, }); }); describe(`when '${MESSAGE_TYPE.ETH_SIGN}' is disabled in advanced settings`, () => { - it(`should track ${EVENT_NAMES.SIGNATURE_FAILED} and include error property`, async () => { + it(`should track ${MetaMetricsEventName.SignatureFailed} and include error property`, async () => { const mockError = { code: errorCodes.rpc.methodNotFound }; const req = { method: MESSAGE_TYPE.ETH_SIGN, @@ -289,7 +289,7 @@ describe('createRPCMethodTrackingMiddleware', () => { expect(trackEvent.mock.calls[1][0]).toMatchObject({ category: 'inpage_provider', - event: EVENT_NAMES.SIGNATURE_FAILED, + event: MetaMetricsEventName.SignatureFailed, properties: { signature_type: MESSAGE_TYPE.ETH_SIGN, error: mockError, @@ -300,7 +300,7 @@ describe('createRPCMethodTrackingMiddleware', () => { }); describe('when request is flagged as safe by security provider', () => { - it(`should immediately track a ${EVENT_NAMES.SIGNATURE_REQUESTED} event`, async () => { + it(`should immediately track a ${MetaMetricsEventName.SignatureRequested} event`, async () => { const req = { method: MESSAGE_TYPE.ETH_SIGN, origin: 'some.dapp', @@ -315,7 +315,7 @@ describe('createRPCMethodTrackingMiddleware', () => { expect(trackEvent).toHaveBeenCalledTimes(1); expect(trackEvent.mock.calls[0][0]).toMatchObject({ category: 'inpage_provider', - event: EVENT_NAMES.SIGNATURE_REQUESTED, + event: MetaMetricsEventName.SignatureRequested, properties: { signature_type: MESSAGE_TYPE.ETH_SIGN, }, @@ -329,7 +329,7 @@ describe('createRPCMethodTrackingMiddleware', () => { flagAsDangerous = 1; }); - it(`should immediately track a ${EVENT_NAMES.SIGNATURE_REQUESTED} event which is flagged as malicious`, async () => { + it(`should immediately track a ${MetaMetricsEventName.SignatureRequested} event which is flagged as malicious`, async () => { const req = { method: MESSAGE_TYPE.ETH_SIGN, origin: 'some.dapp', @@ -344,7 +344,7 @@ describe('createRPCMethodTrackingMiddleware', () => { expect(trackEvent).toHaveBeenCalledTimes(1); expect(trackEvent.mock.calls[0][0]).toMatchObject({ category: 'inpage_provider', - event: EVENT_NAMES.SIGNATURE_REQUESTED, + event: MetaMetricsEventName.SignatureRequested, properties: { signature_type: MESSAGE_TYPE.ETH_SIGN, ui_customizations: ['flagged_as_malicious'], @@ -359,7 +359,7 @@ describe('createRPCMethodTrackingMiddleware', () => { flagAsDangerous = 2; }); - it(`should immediately track a ${EVENT_NAMES.SIGNATURE_REQUESTED} event which is flagged as safety unknown`, async () => { + it(`should immediately track a ${MetaMetricsEventName.SignatureRequested} event which is flagged as safety unknown`, async () => { const req = { method: MESSAGE_TYPE.ETH_SIGN, origin: 'some.dapp', @@ -374,7 +374,7 @@ describe('createRPCMethodTrackingMiddleware', () => { expect(trackEvent).toHaveBeenCalledTimes(1); expect(trackEvent.mock.calls[0][0]).toMatchObject({ category: 'inpage_provider', - event: EVENT_NAMES.SIGNATURE_REQUESTED, + event: MetaMetricsEventName.SignatureRequested, properties: { signature_type: MESSAGE_TYPE.ETH_SIGN, ui_customizations: ['flagged_as_safety_unknown'], diff --git a/app/scripts/lib/decrypt-message-manager.js b/app/scripts/lib/decrypt-message-manager.js index 197b66763..9249c907e 100644 --- a/app/scripts/lib/decrypt-message-manager.js +++ b/app/scripts/lib/decrypt-message-manager.js @@ -4,7 +4,7 @@ import { bufferToHex } from 'ethereumjs-util'; import { ethErrors } from 'eth-rpc-errors'; import log from 'loglevel'; import { MESSAGE_TYPE } from '../../../shared/constants/app'; -import { EVENT } from '../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../shared/constants/metametrics'; import { METAMASK_CONTROLLER_EVENTS } from '../metamask-controller'; import createId from '../../../shared/modules/random-id'; import { stripHexPrefix } from '../../../shared/modules/hexstring-utils'; @@ -237,7 +237,7 @@ export default class DecryptMessageManager extends EventEmitter { if (reason) { this.metricsEvent({ event: reason, - category: EVENT.CATEGORIES.MESSAGES, + category: MetaMetricsEventCategory.Messages, properties: { action: 'Decrypt Message Request', }, diff --git a/app/scripts/lib/encryption-public-key-manager.js b/app/scripts/lib/encryption-public-key-manager.js index 6230c9224..9791e0378 100644 --- a/app/scripts/lib/encryption-public-key-manager.js +++ b/app/scripts/lib/encryption-public-key-manager.js @@ -3,7 +3,7 @@ import { ObservableStore } from '@metamask/obs-store'; import { ethErrors } from 'eth-rpc-errors'; import log from 'loglevel'; import { MESSAGE_TYPE } from '../../../shared/constants/app'; -import { EVENT } from '../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../shared/constants/metametrics'; import { METAMASK_CONTROLLER_EVENTS } from '../metamask-controller'; import createId from '../../../shared/modules/random-id'; @@ -225,7 +225,7 @@ export default class EncryptionPublicKeyManager extends EventEmitter { if (reason) { this.metricsEvent({ event: reason, - category: EVENT.CATEGORIES.MESSAGES, + category: MetaMetricsEventCategory.Messages, properties: { action: 'Encryption public key Request', }, diff --git a/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js b/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js index b35fe1e5c..f63412b61 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js @@ -9,7 +9,7 @@ import { isPrefixedFormattedHexString, isSafeChainId, } from '../../../../../shared/modules/network.utils'; -import { EVENT } from '../../../../../shared/constants/metametrics'; +import { MetaMetricsNetworkEventSource } from '../../../../../shared/constants/metametrics'; const addEthereumChain = { methodNames: [MESSAGE_TYPE.ADD_ETHEREUM_CHAIN], @@ -262,7 +262,7 @@ async function addEthereumChainHandler( rpcUrl: firstValidRPCUrl, ticker, }, - { source: EVENT.SOURCE.NETWORK.DAPP, referrer: origin }, + { source: MetaMetricsNetworkEventSource.Dapp, referrer: origin }, ); // Once the network has been added, the requested is considered successful diff --git a/app/scripts/lib/rpc-method-middleware/handlers/log-web3-shim-usage.js b/app/scripts/lib/rpc-method-middleware/handlers/log-web3-shim-usage.js index b829e16fa..5ea476a4f 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/log-web3-shim-usage.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/log-web3-shim-usage.js @@ -1,5 +1,5 @@ import { MESSAGE_TYPE } from '../../../../../shared/constants/app'; -import { EVENT } from '../../../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../../../shared/constants/metametrics'; /** * This RPC method is called by the inpage provider whenever it detects the @@ -49,7 +49,7 @@ function logWeb3ShimUsageHandler( sendMetrics( { event: `Website Accessed window.web3 Shim`, - category: EVENT.CATEGORIES.INPAGE_PROVIDER, + category: MetaMetricsEventCategory.InpageProvider, referrer: { url: origin, }, diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 93670073d..c1b050b3b 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -104,7 +104,10 @@ import { ///: END:ONLY_INCLUDE_IN POLLING_TOKEN_ENVIRONMENT_TYPES, } from '../../shared/constants/app'; -import { EVENT, EVENT_NAMES } from '../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../shared/constants/metametrics'; import { getTokenIdParam, @@ -399,8 +402,8 @@ export default class MetamaskController extends EventEmitter { ), onNftAdded: ({ address, symbol, tokenId, standard, source }) => this.metaMetricsController.trackEvent({ - event: EVENT_NAMES.NFT_ADDED, - category: EVENT.CATEGORIES.WALLET, + event: MetaMetricsEventName.NftAdded, + category: MetaMetricsEventCategory.Wallet, properties: { token_contract_address: address, token_symbol: symbol, @@ -1069,7 +1072,7 @@ export default class MetamaskController extends EventEmitter { this.metaMetricsController.trackEvent( { event: 'Tx Status Update: On-Chain Failure', - category: EVENT.CATEGORIES.BACKGROUND, + category: MetaMetricsEventCategory.Background, properties: { action: 'Transactions', errorMessage: txMeta.simulationFails?.reason, @@ -1196,8 +1199,8 @@ export default class MetamaskController extends EventEmitter { const { serviceWorkerLastActiveTime } = this.appStateController.store.getState(); const metametricsPayload = { - category: EVENT.SOURCE.SERVICE_WORKERS, - event: EVENT_NAMES.SERVICE_WORKER_RESTARTED, + category: MetaMetricsEventCategory.ServiceWorkers, + event: MetaMetricsEventName.ServiceWorkerRestarted, properties: { service_worker_restarted_time: Date.now() - serviceWorkerLastActiveTime, @@ -1619,7 +1622,7 @@ export default class MetamaskController extends EventEmitter { (truncatedSnap) => { this.metaMetricsController.trackEvent({ event: 'Snap Installed', - category: EVENT.CATEGORIES.SNAPS, + category: MetaMetricsEventCategory.Snaps, properties: { snap_id: truncatedSnap.id, version: truncatedSnap.version, @@ -1633,7 +1636,7 @@ export default class MetamaskController extends EventEmitter { (newSnap, oldVersion) => { this.metaMetricsController.trackEvent({ event: 'Snap Updated', - category: EVENT.CATEGORIES.SNAPS, + category: MetaMetricsEventCategory.Snaps, properties: { snap_id: newSnap.id, old_version: oldVersion, @@ -3540,8 +3543,8 @@ export default class MetamaskController extends EventEmitter { if (usePhishDetect && phishingTestResponse?.result) { this.sendPhishingWarning(connectionStream, hostname); this.metaMetricsController.trackEvent({ - event: EVENT_NAMES.PHISHING_PAGE_DISPLAYED, - category: EVENT.CATEGORIES.PHISHING, + event: MetaMetricsEventName.PhishingPageDisplayed, + category: MetaMetricsEventCategory.Phishing, properties: { url: hostname, }, diff --git a/shared/constants/metametrics.js b/shared/constants/metametrics.js deleted file mode 100644 index 1eeb0a314..000000000 --- a/shared/constants/metametrics.js +++ /dev/null @@ -1,482 +0,0 @@ -// Type Imports -/** - * @typedef {import('../../shared/constants/app').EnvironmentType} EnvironmentType - */ - -// Type Declarations -/** - * Used to attach context of where the user was at in the application when the - * event was triggered. Also included as full details of the current page in - * page events. - * - * @typedef {object} MetaMetricsPageObject - * @property {string} [path] - the path of the current page (e.g /home) - * @property {string} [title] - the title of the current page (e.g 'home') - * @property {string} [url] - the fully qualified url of the current page - */ - -/** - * For metamask, this is the dapp that triggered an interaction - * - * @typedef {object} MetaMetricsReferrerObject - * @property {string} [url] - the origin of the dapp issuing the - * notification - */ - -/** - * We attach context to every meta metrics event that help to qualify our - * analytics. This type has all optional values because it represents a - * returned object from a method call. Ideally app and userAgent are - * defined on every event. This is confirmed in the getTrackMetaMetricsEvent - * function, but still provides the consumer a way to override these values if - * necessary. - * - * @typedef {object} MetaMetricsContext - * @property {object} app - Application metadata. - * @property {string} app.name - the name of the application tracking the event - * @property {string} app.version - the version of the application - * @property {string} userAgent - the useragent string of the user - * @property {MetaMetricsPageObject} [page] - an object representing details of - * the current page - * @property {MetaMetricsReferrerObject} [referrer] - for metamask, this is the - * dapp that triggered an interaction - */ - -/** - * @typedef {object} MetaMetricsEventPayload - * @property {string} event - event name to track - * @property {string} category - category to associate event to - * @property {number} [actionId] - Action id to deduplicate event requests from - * the UI - * @property {string} [environmentType] - The type of environment this event - * occurred in. Defaults to the background process type - * @property {object} [properties] - object of custom values to track, keys - * in this object must be in snake_case - * @property {object} [sensitiveProperties] - Object of sensitive values to - * track. Keys in this object must be in snake_case. These properties will be - * sent in an additional event that excludes the user's metaMetricsId - * @property {number} [revenue] - amount of currency that event creates in - * revenue for MetaMask - * @property {string} [currency] - ISO 4127 format currency for events with - * revenue, defaults to US dollars - * @property {number} [value] - Abstract business "value" attributable to - * customers who trigger this event - * @property {MetaMetricsPageObject} [page] - the page/route that the event - * occurred on - * @property {MetaMetricsReferrerObject} [referrer] - the origin of the dapp - * that triggered the event - */ - -/** - * @typedef {object} MetaMetricsEventOptions - * @property {boolean} [isOptIn] - happened during opt in/out workflow - * @property {boolean} [flushImmediately] - When true will automatically flush - * the segment queue after tracking the event. Recommended if the result of - * tracking the event must be known before UI transition or update - * @property {boolean} [excludeMetaMetricsId] - whether to exclude the user's - * metametrics id for anonymity - * @property {string} [metaMetricsId] - an override for the metaMetricsId in - * the event one is created as part of an asynchronous workflow, such as - * awaiting the result of the metametrics opt-in function that generates the - * user's metametrics id - * @property {boolean} [matomoEvent] - is this event a holdover from matomo - * that needs further migration? when true, sends the data to a special - * segment source that marks the event data as not conforming to our schema - */ - -/** - * @typedef {object} MetaMetricsEventFragment - * @property {string} successEvent - The event name to fire when the fragment - * is closed in an affirmative action. - * @property {string} [failureEvent] - The event name to fire when the fragment - * is closed with a rejection. - * @property {string} [initialEvent] - An event name to fire immediately upon - * fragment creation. This is useful for building funnels in mixpanel and for - * reduction of code duplication. - * @property {string} category - the event category to use for both the success - * and failure events - * @property {boolean} [persist] - Should this fragment be persisted in - * state and progressed after the extension is locked and unlocked. - * @property {number} [timeout] - Time in seconds the event should be persisted - * for. After the timeout the fragment will be closed as abandoned. if not - * supplied the fragment is stored indefinitely. - * @property {number} [lastUpdated] - Date.now() when the fragment was last - * updated. Used to determine if the timeout has expired and the fragment - * should be closed. - * @property {object} [properties] - Object of custom values to track, keys in - * this object must be in snake_case. - * @property {object} [sensitiveProperties] - Object of sensitive values to - * track. Keys in this object must be in snake_case. These properties will be - * sent in an additional event that excludes the user's metaMetricsId - * @property {number} [revenue] - amount of currency that event creates in - * revenue for MetaMask if fragment is successful. - * @property {string} [currency] - ISO 4127 format currency for events with - * revenue, defaults to US dollars - * @property {number} [value] - Abstract business "value" attributable to - * customers who successfully complete this fragment - * @property {MetaMetricsPageObject} [page] - the page/route that the event - * occurred on - * @property {MetaMetricsReferrerObject} [referrer] - the origin of the dapp - * that initiated the event fragment. - * @property {string} [uniqueIdentifier] - optional argument to override the - * automatic generation of UUID for the event fragment. This is useful when - * tracking events for subsystems that already generate UUIDs so to avoid - * unnecessary lookups and reduce accidental duplication. - */ - -/** - * Represents the shape of data sent to the segment.track method. - * - * @typedef {object} SegmentEventPayload - * @property {string} [userId] - The metametrics id for the user - * @property {string} [anonymousId] - An anonymousId that is used to track - * sensitive data while preserving anonymity. - * @property {string} event - name of the event to track - * @property {object} properties - properties to attach to the event - * @property {MetaMetricsContext} context - the context the event occurred in - */ - -/** - * @typedef {object} MetaMetricsPagePayload - * @property {string} name - The name of the page that was viewed - * @property {object} [params] - The variadic parts of the page url - * example (route: `/asset/:asset`, path: `/asset/ETH`) - * params: { asset: 'ETH' } - * @property {EnvironmentType} environmentType - the environment type that the - * page was viewed in - * @property {MetaMetricsPageObject} [page] - the details of the page - * @property {MetaMetricsReferrerObject} [referrer] - dapp that triggered the page - * view - */ - -/** - * @typedef {object} MetaMetricsPageOptions - * @property {boolean} [isOptInPath] - is the current path one of the pages in - * the onboarding workflow? If true and participateInMetaMetrics is null track - * the page view - */ - -/** - * @typedef {object} Traits - * @property {'address_book_entries'} ADDRESS_BOOK_ENTRIES - When the user - * adds or modifies addresses in address book the address_book_entries trait - * is identified. - * @property {'ledger_connection_type'} LEDGER_CONNECTION_TYPE - when ledger - * live connnection type is changed we identify the ledger_connection_type - * trait - * @property {'networks_added'} NETWORKS_ADDED - when user modifies networks - * we identify the networks_added trait - * @property {'networks_without_ticker'} NETWORKS_WITHOUT_TICKER - when user - * modifies networks we identify the networks_without_ticker trait for - * networks without a ticker. - * @property {'nft_autodetection_enabled'} NFT_AUTODETECTION_ENABLED - when Autodetect NFTs - * feature is toggled we identify the nft_autodetection_enabled trait - * @property {'number_of_accounts'} NUMBER_OF_ACCOUNTS - when identities - * change, we identify the new number_of_accounts trait - * @property {'number_of_nft_collections'} NUMBER_OF_NFT_COLLECTIONS - user - * trait for number of unique NFT addresses - * @property {'number_of_nfts'} NUMBER_OF_NFTS - user trait for number of all NFT addresses - * @property {'number_of_tokens'} NUMBER_OF_TOKENS - when the number of tokens change, we - * identify the new number_of_tokens trait - * @property {'opensea_api_enabled'} OPENSEA_API_ENABLED - when the OpenSea API is enabled - * we identify the opensea_api_enabled trait - * @property {'three_box_enabled'} THREE_BOX_ENABLED - When 3Box feature is - * toggled we identify the 3box_enabled trait. This trait has been deprecated. - * @property {'theme'} THEME - when the user's theme changes we identify the theme trait - * @property {'token_detection_enabled'} TOKEN_DETECTION_ENABLED - when token detection feature is toggled we - * identify the token_detection_enabled trait - * @property {'install_date_ext'} INSTALL_DATE_EXT - when the user installed the extension - * @property {'desktop_enabled'} [DESKTOP_ENABLED] - optional / does the user have desktop enabled? - * @property {'security_providers'} SECURITY_PROVIDERS - when security provider feature is toggled we - * identify the security_providers trait - */ - -/** - * - * @type {Traits} - */ - -export const TRAITS = { - ADDRESS_BOOK_ENTRIES: 'address_book_entries', - INSTALL_DATE_EXT: 'install_date_ext', - LEDGER_CONNECTION_TYPE: 'ledger_connection_type', - NETWORKS_ADDED: 'networks_added', - NETWORKS_WITHOUT_TICKER: 'networks_without_ticker', - NFT_AUTODETECTION_ENABLED: 'nft_autodetection_enabled', - NUMBER_OF_ACCOUNTS: 'number_of_accounts', - NUMBER_OF_NFT_COLLECTIONS: 'number_of_nft_collections', - NUMBER_OF_NFTS: 'number_of_nfts', - NUMBER_OF_TOKENS: 'number_of_tokens', - OPENSEA_API_ENABLED: 'opensea_api_enabled', - THEME: 'theme', - THREE_BOX_ENABLED: 'three_box_enabled', - TOKEN_DETECTION_ENABLED: 'token_detection_enabled', - DESKTOP_ENABLED: 'desktop_enabled', - SECURITY_PROVIDERS: 'security_providers', -}; - -/** - * @typedef {object} MetaMetricsTraits - * @property {number} [address_book_entries] - The number of entries in the - * user's address book. - * @property {'ledgerLive' | 'webhid' | 'u2f'} [ledger_connection_type] - the - * type of ledger connection set by user preference. - * @property {Array} [networks_added] - An array consisting of chainIds - * that indicate the networks a user has added to their MetaMask. - * @property {Array} [networks_without_ticker] - An array consisting of - * chainIds that indicate the networks added by the user that do not have a - * ticker. - * @property {number} [nft_autodetection_enabled] - does the user have the - * use collection/nft detection enabled? - * @property {number} [number_of_accounts] - A number representing the number - * of identities(accounts) added to the user's MetaMask. - * @property {number} [number_of_nft_collections] - A number representing the - * amount of different NFT collections the user possesses an NFT from. - * @property {number} [number_of_nfts] - A number representing the - * amount of all NFTs the user possesses across all networks and accounts. - * @property {number} [number_of_tokens] - The total number of token contracts - * the user has across all networks and accounts. - * @property {boolean} [opensea_api_enabled] - does the user have the OpenSea - * API enabled? - * @property {boolean} [three_box_enabled] - Does the user have 3box sync - * enabled? (deprecated) - * @property {string} [theme] - which theme the user has selected - * @property {boolean} [token_detection_enabled] - does the user have token detection is enabled? - * @property {boolean} [desktop_enabled] - optional / does the user have desktop enabled? - * @property {Array} [security_providers] - whether security provider feature toggle is on or off - */ - -// Mixpanel converts the zero address value to a truly anonymous event, which -// speeds up reporting -export const METAMETRICS_ANONYMOUS_ID = '0x0000000000000000'; - -/** - * This object is used to identify events that are triggered by the background - * process. - * - * @type {MetaMetricsPageObject} - */ -export const METAMETRICS_BACKGROUND_PAGE_OBJECT = { - path: '/background-process', - title: 'Background Process', - url: '/background-process', -}; - -/** - * @typedef {object} SegmentInterface - * @property {SegmentEventPayload[]} queue - A queue of events to be sent when - * the flushAt limit has been reached, or flushInterval occurs - * @property {() => void} flush - Immediately flush the queue, resetting it to - * an empty array and sending the pending events to Segment - * @property {( - * payload: SegmentEventPayload, - * callback: (err?: Error) => void - * ) => void} track - Track an event with Segment, using the internal batching - * mechanism to optimize network requests - * @property {(payload: object) => void} page - Track a page view with Segment - * @property {() => void} identify - Identify an anonymous user. We do not - * currently use this method. - */ - -export const REJECT_NOTFICIATION_CLOSE = 'Cancel Via Notification Close'; -export const REJECT_NOTFICIATION_CLOSE_SIG = - 'Cancel Sig Request Via Notification Close'; - -/** - * EVENTS - */ - -export const EVENT_NAMES = { - ACCOUNT_ADDED: 'Account Added', - ACCOUNT_ADD_SELECTED: 'Account Add Selected', - ACCOUNT_ADD_FAILED: 'Account Add Failed', - ACCOUNT_PASSWORD_CREATED: 'Account Password Created', - ACCOUNT_RESET: 'Account Reset', - APP_INSTALLED: 'App Installed', - APP_UNLOCKED: 'App Unlocked', - APP_UNLOCKED_FAILED: 'App Unlocked Failed', - APP_WINDOW_EXPANDED: 'App Window Expanded', - BRIDGE_LINK_CLICKED: 'Bridge Link Clicked', - DECRYPTION_APPROVED: 'Decryption Approved', - DECRYPTION_REJECTED: 'Decryption Rejected', - DECRYPTION_REQUESTED: 'Decryption Requested', - ENCRYPTION_PUBLIC_KEY_APPROVED: 'Encryption Approved', - ENCRYPTION_PUBLIC_KEY_REJECTED: 'Encryption Rejected', - ENCRYPTION_PUBLIC_KEY_REQUESTED: 'Encryption Requested', - EXTERNAL_LINK_CLICKED: 'External Link Clicked', - KEY_EXPORT_SELECTED: 'Key Export Selected', - KEY_EXPORT_REQUESTED: 'Key Export Requested', - KEY_EXPORT_FAILED: 'Key Export Failed', - KEY_EXPORT_CANCELED: 'Key Export Canceled', - KEY_EXPORT_REVEALED: 'Key Material Revealed', - KEY_EXPORT_COPIED: 'Key Material Copied', - KEY_TOKEN_DETECTION_SELECTED: 'Key Token Detection Selected', - KEY_GLOBAL_SECURITY_TOGGLE_SELECTED: 'Key Global Security/Privacy Settings', - KEY_BALANCE_TOKEN_PRICE_CHECKER: - 'Key Show Balance and Token Price Checker Settings', - KEY_GAS_FEE_ESTIMATION_BUY_SWAP_TOKENS: - 'Key Show Gas Fee Estimation, Buy Crypto and Swap Tokens', - KEY_AUTO_DETECT_TOKENS: 'Key Autodetect tokens', - KEY_BATCH_ACCOUNT_BALANCE_REQUESTS: 'Key Batch account balance requests', - METRICS_OPT_IN: 'Metrics Opt In', - METRICS_OPT_OUT: 'Metrics Opt Out', - NAV_ACCOUNT_MENU_OPENED: 'Account Menu Opened', - NAV_ACCOUNT_DETAILS_OPENED: 'Account Details Opened', - NAV_CONNECTED_SITES_OPENED: 'Connected Sites Opened', - NAV_MAIN_MENU_OPENED: 'Main Menu Opened', - NAV_NETWORK_MENU_OPENED: 'Network Menu Opened', - NAV_SETTINGS_OPENED: 'Settings Opened', - NAV_ACCOUNT_SWITCHED: 'Account Switched', - NAV_NETWORK_SWITCHED: 'Network Switched', - NAV_BUY_BUTTON_CLICKED: 'Buy Button Clicked', - NAV_SEND_BUTTON_CLICKED: 'Send Button Clicked', - NAV_SWAP_BUTTON_CLICKED: 'Swap Button Clicked', - SRP_TO_CONFIRM_BACKUP: 'SRP Backup Confirm Displayed', - WALLET_SETUP_STARTED: 'Wallet Setup Selected', - WALLET_SETUP_CANCELED: 'Wallet Setup Canceled', - WALLET_SETUP_FAILED: 'Wallet Setup Failed', - WALLET_CREATED: 'Wallet Created', - NFT_ADDED: 'NFT Added', - ONRAMP_PROVIDER_SELECTED: 'On-ramp Provider Selected', - PERMISSIONS_APPROVED: 'Permissions Approved', - PERMISSIONS_REJECTED: 'Permissions Rejected', - PERMISSIONS_REQUESTED: 'Permissions Requested', - PHISHING_PAGE_DISPLAYED: 'Phishing Page Displayed', - PORTFOLIO_LINK_CLICKED: 'Portfolio Link Clicked', - PUBLIC_ADDRESS_COPIED: 'Public Address Copied', - PROVIDER_METHOD_CALLED: 'Provider Method Called', - SIGNATURE_APPROVED: 'Signature Approved', - SIGNATURE_FAILED: 'Signature Failed', - SIGNATURE_REJECTED: 'Signature Rejected', - SIGNATURE_REQUESTED: 'Signature Requested', - TOKEN_IMPORT_BUTTON_CLICKED: 'Import Token Button Clicked', - TOKEN_SCREEN_OPENED: 'Token Screen Opened', - SUPPORT_LINK_CLICKED: 'Support Link Clicked', - TOKEN_ADDED: 'Token Added', - TOKEN_DETECTED: 'Token Detected', - TOKEN_HIDDEN: 'Token Hidden', - TOKEN_IMPORT_CANCELED: 'Token Import Canceled', - TOKEN_IMPORT_CLICKED: 'Token Import Clicked', - ONBOARDING_WELCOME: 'App Installed', - ONBOARDING_WALLET_CREATION_STARTED: 'Wallet Setup Selected', - ONBOARDING_WALLET_IMPORT_STARTED: 'Wallet Import Started', - ONBOARDING_WALLET_CREATION_ATTEMPTED: 'Wallet Password Created', - ONBOARDING_WALLET_SECURITY_STARTED: 'SRP Backup Selected', - ONBOARDING_WALLET_SECURITY_SKIP_INITIATED: 'SRP Skip Backup Selected', - ONBOARDING_WALLET_SECURITY_SKIP_CONFIRMED: 'SRP Backup Skipped', - ONBOARDING_WALLET_SECURITY_SKIP_CANCELED: 'SRP Skip Backup Canceled', - ONBOARDING_WALLET_SECURITY_PHRASE_REVEALED: 'SRP Revealed', - ONBOARDING_WALLET_SECURITY_PHRASE_WRITTEN_DOWN: 'SRP Backup Confirm Display', - ONBOARDING_WALLET_SECURITY_PHRASE_CONFIRMED: 'SRP Backup Confirmed', - ONBOARDING_WALLET_CREATION_COMPLETE: 'Wallet Created', - ONBOARDING_WALLET_SETUP_COMPLETE: 'Application Opened', - ONBOARDING_WALLET_ADVANCED_SETTINGS: 'Settings Updated', - ONBOARDING_WALLET_IMPORT_ATTEMPTED: 'Wallet Import Attempted', - ONBOARDING_WALLET_VIDEO_PLAY: 'SRP Intro Video Played', - ONBOARDING_TWITTER_CLICK: 'External Link Clicked', - SERVICE_WORKER_RESTARTED: 'Service Worker Restarted', -}; - -export const EVENT = { - ACCOUNT_TYPES: { - DEFAULT: 'metamask', - IMPORTED: 'imported', - HARDWARE: 'hardware', - }, - ACCOUNT_IMPORT_TYPES: { - JSON: 'json', - PRIVATE_KEY: 'private_key', - SRP: 'srp', - }, - CATEGORIES: { - ACCOUNTS: 'Accounts', - APP: 'App', - AUTH: 'Auth', - BACKGROUND: 'Background', - ERROR: 'Error', - FOOTER: 'Footer', - HOME: 'Home', - INPAGE_PROVIDER: 'inpage_provider', - KEYS: 'Keys', - MESSAGES: 'Messages', - NAVIGATION: 'Navigation', - NETWORK: 'Network', - ONBOARDING: 'Onboarding', - PHISHING: 'Phishing', - RETENTION: 'Retention', - SETTINGS: 'Settings', - SNAPS: 'Snaps', - SWAPS: 'Swaps', - TRANSACTIONS: 'Transactions', - WALLET: 'Wallet', - DESKTOP: 'Desktop', - }, - EXTERNAL_LINK_TYPES: { - TRANSACTION_BLOCK_EXPLORER: 'Transaction Block Explorer', - BLOCK_EXPLORER: 'Block Explorer', - ACCOUNT_TRACKER: 'Account Tracker', - TOKEN_TRACKER: 'Token Tracker', - }, - KEY_TYPES: { - PKEY: 'private_key', - SRP: 'srp', - }, - ONRAMP_PROVIDER_TYPES: { - COINBASE: 'coinbase', - MOONPAY: 'moonpay', - WYRE: 'wyre', - TRANSAK: 'transak', - SELF_DEPOSIT: 'direct_deposit', - }, - SOURCE: { - NETWORK: { - CUSTOM_NETWORK_FORM: 'custom_network_form', - POPULAR_NETWORK_LIST: 'popular_network_list', - DAPP: 'dapp', - }, - SWAPS: { - MAIN_VIEW: 'Main View', - TOKEN_VIEW: 'Token View', - }, - TOKEN: { - CUSTOM: 'custom', - DAPP: 'dapp', - DETECTED: 'detected', - LIST: 'list', - }, - TRANSACTION: { - DAPP: 'dapp', - USER: 'user', - }, - SERVICE_WORKERS: 'service_workers', - }, - LOCATION: { - TOKEN_DETAILS: 'token_details', - TOKEN_DETECTION: 'token_detection', - TOKEN_MENU: 'token_menu', - }, -}; - -// Values below (e.g. 'location') can be used in the "properties" -// tracking object as keys, e.g. { location: 'Home' } -export const CONTEXT_PROPS = { - PAGE_TITLE: 'location', -}; - -/** - * These types correspond to the keys in the METAMETRIC_KEY_OPT object - */ -export const METAMETRIC_KEY = { - UI_CUSTOMIZATIONS: `ui_customizations`, -}; - -/** - * This object maps a METAMETRIC_KEY to an object of possible options - */ -export const METAMETRIC_KEY_OPT = { - [METAMETRIC_KEY.UI_CUSTOMIZATIONS]: { - flaggedAsMalicious: 'flagged_as_malicious', - flaggedAsSafetyUnknown: 'flagged_as_safety_unknown', - SIWE: 'sign_in_with_ethereum', - }, -}; diff --git a/shared/constants/metametrics.ts b/shared/constants/metametrics.ts new file mode 100644 index 000000000..03626ff61 --- /dev/null +++ b/shared/constants/metametrics.ts @@ -0,0 +1,642 @@ +import type { EnvironmentType } from './app'; +import { LedgerTransportTypes } from './hardware-wallets'; + +/** + * Used to attach context of where the user was at in the application when the + * event was triggered. Also included as full details of the current page in + * page events. + */ +export type MetaMetricsPageObject = { + /** + * The path of the current page (e.g. "/home"). + */ + path?: string; + /** + * The title of the current page (e.g. "home"). + */ + title?: string; + /** + * The fully qualified URL of the current page. + */ + url?: string; +}; + +/** + * The dapp that triggered an interaction (MetaMask only). + */ +export type MetaMetricsReferrerObject = { + /** + * The origin of the dapp issuing the notification. + */ + url?: string; +}; + +/** + * We attach context to every meta metrics event that help to qualify our + * analytics. This type has all optional values because it represents a + * returned object from a method call. Ideally app and userAgent are + * defined on every event. This is confirmed in the getTrackMetaMetricsEvent + * function, but still provides the consumer a way to override these values if + * necessary. + */ +type MetaMetricsContext = { + /** + * Application metadata. + */ + app: { + /** + * The name of the application tracking the event. + */ + name: string; + /** + * The version of the application. + */ + version: string; + }; + /** + * The user agent of the application. + */ + userAgent: string; + /** + * An object representing details of the current page. + */ + page?: MetaMetricsPageObject; + /** + * The dapp that triggered an interaction (MetaMask only). + */ + referrer?: MetaMetricsReferrerObject; +}; + +export type MetaMetricsEventPayload = { + /** + * The event name to track. + */ + event: string; + /** + * The category to associate the event to. + */ + category: string; + /** + * The action ID to deduplicate event requests from the UI. + */ + actionId?: number; + /** + * The type of environment this event occurred in. Defaults to the background + * process type. + */ + environmentType?: string; + /** + * Custom values to track. Keys in this object must be `snake_case`. + */ + properties?: object; + /** + * Sensitive values to track. These properties will be sent in an additional + * event that excludes the user's `metaMetricsId`. Keys in this object must be + * in `snake_case`. + */ + sensitiveProperties?: object; + /** + * Amount of currency that the event creates in revenue for MetaMask. + */ + revenue?: number; + /** + * ISO-4127-formatted currency for events with revenue. Defaults to US + * dollars. + */ + currency?: string; + /** + * Abstract business "value" attributable to customers who trigger this event. + */ + value?: number; + /** + * The page/route that the event occurred on. + */ + page?: MetaMetricsPageObject; + /** + * The origin of the dapp that triggered this event. + */ + referrer?: MetaMetricsReferrerObject; +}; + +export type MetaMetricsEventOptions = { + /** + * Whether or not the event happened during the opt-in workflow. + */ + isOptIn?: boolean; + /** + * Whether the segment queue should be flushed after tracking the event. + * Recommended if the result of tracking the event must be known before UI + * transition or update. + */ + flushImmediately?: boolean; + /** + * Whether to exclude the user's `metaMetricsId` for anonymity. + */ + excludeMetaMetricsId?: boolean; + /** + * An override for the `metaMetricsId` in the event (no pun intended) one is + * created as a part of an asynchronous workflow, such as awaiting the result + * of the MetaMetrics opt-in function that generates the user's + * `metaMetricsId`. + */ + metaMetricsId?: string; + /** + * Is this event a holdover from Matomo that needs further migration? When + * true, sends the data to a special Segment source that marks the event data + * as not conforming to our schema. + */ + matomoEvent?: boolean; +}; + +export type MetaMetricsEventFragment = { + /** + * The event name to fire when the fragment is closed in an affirmative action. + */ + successEvent: string; + /** + * The event name to fire when the fragment is closed with a rejection. + */ + failureEvent?: string; + /** + * An event name to fire immediately upon fragment creation. This is useful + * for building funnels in mixpanel and for reduction of code duplication. + */ + initialEvent?: string; + /** + * The event category to use for both the success and failure events. + */ + category: string; + /** + * Should this fragment be persisted in state and progressed after the + * extension is locked and unlocked. + */ + persist?: boolean; + /** + * Time in seconds the event should be persisted for. After the timeout the + * fragment will be closed as abandoned. If not supplied the fragment is + * stored indefinitely. + */ + timeout?: number; + /** + * `Date.now()` when the fragment was last updated. Used to determine if the + * timeout has expired and the fragment should be closed. + */ + lastUpdated?: number; + /** + * Custom values to track. Keys in this object must be `snake_case`. + */ + properties?: object; + /** + * Sensitive values to track. These properties will be sent in an additional + * event that excludes the user's `metaMetricsId`. Keys in this object must be + * in `snake_case`. + */ + sensitiveProperties?: object; + /** + * Amount of currency that the event creates in revenue for MetaMask. + */ + revenue?: number; + /** + * ISO-4127-formatted currency for events with revenue. Defaults to US + * dollars. + */ + currency?: string; + /** + * Abstract business "value" attributable to customers who trigger this event. + */ + value?: number; + /** + * The page/route that the event occurred on. + */ + page?: MetaMetricsPageObject; + /** + * The origin of the dapp that triggered this event. + */ + referrer?: MetaMetricsReferrerObject; + /** + * Overrides the automatic generation of UUID for the event fragment. This is + * useful when tracking events for subsystems that already generate UUIDs so + * to avoid unnecessary lookups and reduce accidental duplication. + */ + uniqueIdentifier?: string; +}; + +/** + * Data sent to the `segment.track` method. + */ +export type SegmentEventPayload = { + /** + * The MetaMetrics id for the user. + */ + userId?: string; + /** + * An anonymous ID that is used to track sensitive data while preserving + * anonymity. + */ + anonymousId?: string; + /** + * The name of the event to track. + */ + event: string; + /** + * Properties to attach to the event. + */ + properties: object; + /** + * The context the event occurred in. + */ + context: MetaMetricsContext; +}; + +/** + * Data sent to MetaMetrics for page views. + */ +export type MetaMetricsPagePayload = { + /** + * The name of the page that was viewed. + */ + name: string; + /** + * The variadic parts of the page URL. + * + * Example: If the route is `/asset/:asset` and the path is `/asset/ETH`, + * the `params` property would be `{ asset: 'ETH' }`. + */ + params?: object; + /** + * The environment type that the page was viewed in. + */ + environmentType: EnvironmentType; + /** + * The details of the page. + */ + page?: MetaMetricsPageObject; + /** + * The dapp that triggered the page view. + */ + referrer?: MetaMetricsReferrerObject; +}; + +export type MetaMetricsPageOptions = { + /** + * Is the current path one of the pages in the onboarding workflow? (If this + * is true and participateInMetaMetrics is null, then the page view will be + * tracked.) + */ + isOptInPath?: boolean; +}; + +/** + * Data sent to MetaMetrics for user traits. + */ +export type MetaMetricsUserTraits = { + /** + * The number of entries in the user's address book. + */ + address_book_entries?: number; + /** + * The type of ledger connection set by user preference. + */ + ledger_connection_type?: LedgerTransportTypes; + /** + * An array consisting of chain IDs that represent the networks added by the + * user. + */ + networks_added?: string[]; + /** + * An array consisting of chain IDs that represent the networks added by the + * user that do not have a ticker. + */ + networks_without_ticker?: string[]; + /** + * Does the user have the Autodetect NFTs feature enabled? + */ + nft_autodetection_enabled?: number; + /** + * A number representing the number of identities (accounts) added to the + * user's wallet. + */ + number_of_accounts?: number; + /** + * A number representing the amount of NFT collections from which the user + * possesses NFTs. + */ + number_of_nft_collections?: number; + /** + * A number representing the amount of all NFTs the user possesses across all + * networks and accounts. + */ + number_of_nfts?: number; + /** + * The total number of token contracts the user has across all networks and + * accounts. + */ + number_of_tokens?: number; + /** + * Does the user have the OpenSea API enabled? + */ + opensea_api_enabled?: boolean; + /** + * Does the user have 3Box sync enabled? + * + * @deprecated + */ + three_box_enabled?: boolean; + /** + * Which theme the user has selected. + */ + theme?: string; + /** + * Does the user have token detection enabled? + */ + token_detection_enabled?: boolean; + /** + * Does the user have desktop enabled? + */ + desktop_enabled?: boolean; + /** + * Whether the security provider feature has been enabled. + */ + security_providers?: string[]; +}; + +export enum MetaMetricsUserTrait { + /** + * Identified when the user adds or modifies addresses in the address book. + */ + AddressBookEntries = 'address_book_entries', + /** + * Identified when the user installed the extension. + */ + InstallDateExt = 'install_date_ext', + /** + * Identified when the Ledger Live connection type is changed. + */ + LedgerConnectionType = 'ledger_connection_type', + /** + * Identified when the user modifies networks. + */ + NetworksAdded = 'networks_added', + /** + * Identified when the user modifies networks that lack a ticker. + */ + NetworksWithoutTicker = 'networks_without_ticker', + /** + * Identified when the "Autodetect NFTs" feature is toggled. + */ + NftAutodetectionEnabled = 'nft_autodetection_enabled', + /** + * Identified when identities change. + */ + NumberOfAccounts = 'number_of_accounts', + /** + * The number of unique NFT addresses. + */ + NumberOfNftCollections = 'number_of_nft_collections', + /** + * Identified when the number of NFTs owned by the user changes. + */ + NumberOfNfts = 'number_of_nfts', + /** + * Identified when the number of tokens change. + */ + NumberOfTokens = 'number_of_tokens', + /** + * Identified when the OpenSea API is enabled. + */ + OpenSeaApiEnabled = 'opensea_api_enabled', + /** + * Identified when the user's theme changes. + */ + Theme = 'theme', + /** + * Identified when the 3Box feature is toggled. + * + * @deprecated + */ + ThreeBoxEnabled = 'three_box_enabled', + /** + * Identified when the token detection feature is toggled. + */ + TokenDetectionEnabled = 'token_detection_enabled', + /** + * Identified when the user enables desktop. + */ + DesktopEnabled = 'desktop_enabled', + /** + * Identified when the security provider feature is enabled. + */ + SecurityProviders = 'security_providers', +} + +/** + * Mixpanel converts the zero address value to a truly anonymous event, which + * speeds up reporting + */ +export const METAMETRICS_ANONYMOUS_ID = '0x0000000000000000'; + +/** + * Used to identify events that are triggered by the background process. + */ +export const METAMETRICS_BACKGROUND_PAGE_OBJECT: MetaMetricsPageObject = { + path: '/background-process', + title: 'Background Process', + url: '/background-process', +}; + +export const REJECT_NOTIFICATION_CLOSE = 'Cancel Via Notification Close'; + +export const REJECT_NOTIFICATION_CLOSE_SIG = + 'Cancel Sig Request Via Notification Close'; + +export enum MetaMetricsEventName { + AccountAdded = 'Account Added', + AccountAddSelected = 'Account Add Selected', + AccountAddFailed = 'Account Add Failed', + AccountPasswordCreated = 'Account Password Created', + AccountReset = 'Account Reset', + AppInstalled = 'App Installed', + AppUnlocked = 'App Unlocked', + AppUnlockedFailed = 'App Unlocked Failed', + AppWindowExpanded = 'App Window Expanded', + BridgeLinkClicked = 'Bridge Link Clicked', + DecryptionApproved = 'Decryption Approved', + DecryptionRejected = 'Decryption Rejected', + DecryptionRequested = 'Decryption Requested', + EncryptionPublicKeyApproved = 'Encryption Approved', + EncryptionPublicKeyRejected = 'Encryption Rejected', + EncryptionPublicKeyRequested = 'Encryption Requested', + ExternalLinkClicked = 'External Link Clicked', + KeyExportSelected = 'Key Export Selected', + KeyExportRequested = 'Key Export Requested', + KeyExportFailed = 'Key Export Failed', + KeyExportCanceled = 'Key Export Canceled', + KeyExportRevealed = 'Key Material Revealed', + KeyExportCopied = 'Key Material Copied', + KeyTokenDetectionSelected = 'Key Token Detection Selected', + KeyGlobalSecurityToggleSelected = 'Key Global Security/Privacy Settings', + KeyBalanceTokenPriceChecker = 'Key Show Balance and Token Price Checker Settings', + KeyGasFeeEstimationBuySwapTokens = 'Key Show Gas Fee Estimation, Buy Crypto and Swap Tokens', + KeyAutoDetectTokens = 'Key Autodetect tokens', + KeyBatchAccountBalanceRequests = 'Key Batch account balance requests', + MetricsOptIn = 'Metrics Opt In', + MetricsOptOut = 'Metrics Opt Out', + NavAccountMenuOpened = 'Account Menu Opened', + NavAccountDetailsOpened = 'Account Details Opened', + NavConnectedSitesOpened = 'Connected Sites Opened', + NavMainMenuOpened = 'Main Menu Opened', + NavNetworkMenuOpened = 'Network Menu Opened', + NavSettingsOpened = 'Settings Opened', + NavAccountSwitched = 'Account Switched', + NavNetworkSwitched = 'Network Switched', + NavBuyButtonClicked = 'Buy Button Clicked', + NavSendButtonClicked = 'Send Button Clicked', + NavSwapButtonClicked = 'Swap Button Clicked', + SrpToConfirmBackup = 'SRP Backup Confirm Displayed', + WalletSetupStarted = 'Wallet Setup Selected', + WalletSetupCanceled = 'Wallet Setup Canceled', + WalletSetupFailed = 'Wallet Setup Failed', + WalletCreated = 'Wallet Created', + NftAdded = 'NFT Added', + OnrampProviderSelected = 'On-ramp Provider Selected', + PermissionsApproved = 'Permissions Approved', + PermissionsRejected = 'Permissions Rejected', + PermissionsRequested = 'Permissions Requested', + PhishingPageDisplayed = 'Phishing Page Displayed', + PortfolioLinkClicked = 'Portfolio Link Clicked', + PublicAddressCopied = 'Public Address Copied', + ProviderMethodCalled = 'Provider Method Called', + SignatureApproved = 'Signature Approved', + SignatureFailed = 'Signature Failed', + SignatureRejected = 'Signature Rejected', + SignatureRequested = 'Signature Requested', + TokenImportButtonClicked = 'Import Token Button Clicked', + TokenScreenOpened = 'Token Screen Opened', + SupportLinkClicked = 'Support Link Clicked', + TokenAdded = 'Token Added', + TokenDetected = 'Token Detected', + TokenHidden = 'Token Hidden', + TokenImportCanceled = 'Token Import Canceled', + TokenImportClicked = 'Token Import Clicked', + OnboardingWelcome = 'App Installed', + OnboardingWalletCreationStarted = 'Wallet Setup Selected', + OnboardingWalletImportStarted = 'Wallet Import Started', + OnboardingWalletCreationAttempted = 'Wallet Password Created', + OnboardingWalletSecurityStarted = 'SRP Backup Selected', + OnboardingWalletSecuritySkipInitiated = 'SRP Skip Backup Selected', + OnboardingWalletSecuritySkipConfirmed = 'SRP Backup Skipped', + OnboardingWalletSecuritySkipCanceled = 'SRP Skip Backup Canceled', + OnboardingWalletSecurityPhraseRevealed = 'SRP Revealed', + OnboardingWalletSecurityPhraseWrittenDown = 'SRP Backup Confirm Display', + OnboardingWalletSecurityPhraseConfirmed = 'SRP Backup Confirmed', + OnboardingWalletCreationComplete = 'Wallet Created', + OnboardingWalletSetupComplete = 'Application Opened', + OnboardingWalletAdvancedSettings = 'Settings Updated', + OnboardingWalletImportAttempted = 'Wallet Import Attempted', + OnboardingWalletVideoPlay = 'SRP Intro Video Played', + OnboardingTwitterClick = 'External Link Clicked', + ServiceWorkerRestarted = 'Service Worker Restarted', +} + +export enum MetaMetricsEventAccountType { + Default = 'metamask', + Imported = 'imported', + Hardware = 'hardware', +} + +export enum MetaMetricsEventAccountImportType { + Json = 'json', + PrivateKey = 'private_key', + Srp = 'srp', +} + +export enum MetaMetricsEventCategory { + Accounts = 'Accounts', + App = 'App', + Auth = 'Auth', + Background = 'Background', + // The TypeScript ESLint rule is incorrectly marking this line. + /* eslint-disable-next-line @typescript-eslint/no-shadow */ + Error = 'Error', + Footer = 'Footer', + Home = 'Home', + InpageProvider = 'inpage_provider', + Keys = 'Keys', + Messages = 'Messages', + Navigation = 'Navigation', + Network = 'Network', + Onboarding = 'Onboarding', + Phishing = 'Phishing', + Retention = 'Retention', + Settings = 'Settings', + Snaps = 'Snaps', + Swaps = 'Swaps', + Transactions = 'Transactions', + Wallet = 'Wallet', + Desktop = 'Desktop', + ServiceWorkers = 'service_workers', +} + +export enum MetaMetricsEventLinkType { + TransactionBlockExplorer = 'Transaction Block Explorer', + BlockExplorer = 'Block Explorer', + AccountTracker = 'Account Tracker', + TokenTracker = 'Token Tracker', +} + +export enum MetaMetricsEventKeyType { + Pkey = 'private_key', + Srp = 'srp', +} + +// NOTE: This doesn't seem to be used at all +export enum MetaMetricsEventOnrampProviderType { + Coinbase = 'coinbase', + Moonpay = 'moonpay', + Wyre = 'wyre', + Transak = 'transak', + SelfDeposit = 'direct_deposit', +} + +export enum MetaMetricsNetworkEventSource { + CustomNetworkForm = 'custom_network_form', + PopularNetworkList = 'popular_network_list', + Dapp = 'dapp', +} + +export enum MetaMetricsSwapsEventSource { + MainView = 'Main View', + TokenView = 'Token View', +} + +export enum MetaMetricsTokenEventSource { + Custom = 'custom', + Dapp = 'dapp', + Detected = 'detected', + List = 'list', +} + +export enum MetaMetricsTransactionEventSource { + Dapp = 'dapp', + User = 'user', +} + +export enum MetaMetricsEventLocation { + TokenDetails = 'token_details', + TokenDetection = 'token_detection', + TokenMenu = 'token_menu', +} + +export enum MetaMetricsEventUiCustomization { + FlaggedAsMalicious = 'flagged_as_malicious', + FlaggedAsSafetyUnknown = 'flagged_as_safety_unknown', + Siwe = 'sign_in_with_ethereum', +} + +/** + * Values that can used in the "properties" tracking object as keys, e.g. `{ + * location: 'Home' }`. + */ +export enum MetaMetricsContextProp { + PageTitle = 'location', +} diff --git a/ui/components/app/account-menu/account-menu.component.js b/ui/components/app/account-menu/account-menu.component.js index c27788402..c20b83e5c 100644 --- a/ui/components/app/account-menu/account-menu.component.js +++ b/ui/components/app/account-menu/account-menu.component.js @@ -6,9 +6,10 @@ import InputAdornment from '@material-ui/core/InputAdornment'; import classnames from 'classnames'; import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app'; import { - EVENT, - EVENT_NAMES, - CONTEXT_PROPS, + MetaMetricsContextProp, + MetaMetricsEventAccountType, + MetaMetricsEventCategory, + MetaMetricsEventName, } from '../../../../shared/constants/metametrics'; import { getEnvironmentType } from '../../../../app/scripts/lib/util'; import Identicon from '../../ui/identicon'; @@ -209,8 +210,8 @@ export default class AccountMenu extends Component { className="account-menu__account account-menu__item--clickable" onClick={() => { this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, - event: EVENT_NAMES.NAV_ACCOUNT_SWITCHED, + category: MetaMetricsEventCategory.Navigation, + event: MetaMetricsEventName.NavAccountSwitched, properties: { location: 'Main Menu', }, @@ -360,10 +361,10 @@ export default class AccountMenu extends Component { onClick={() => { toggleAccountMenu(); trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, - event: EVENT_NAMES.ACCOUNT_ADD_SELECTED, + category: MetaMetricsEventCategory.Navigation, + event: MetaMetricsEventName.AccountAddSelected, properties: { - account_type: EVENT.ACCOUNT_TYPES.DEFAULT, + account_type: MetaMetricsEventAccountType.Default, location: 'Main Menu', }, }); @@ -378,10 +379,10 @@ export default class AccountMenu extends Component { onClick={() => { toggleAccountMenu(); trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, - event: EVENT_NAMES.ACCOUNT_ADD_SELECTED, + category: MetaMetricsEventCategory.Navigation, + event: MetaMetricsEventName.AccountAddSelected, properties: { - account_type: EVENT.ACCOUNT_TYPES.IMPORTED, + account_type: MetaMetricsEventAccountType.Imported, location: 'Main Menu', }, }); @@ -396,10 +397,10 @@ export default class AccountMenu extends Component { onClick={() => { toggleAccountMenu(); trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, - event: EVENT_NAMES.ACCOUNT_ADD_SELECTED, + category: MetaMetricsEventCategory.Navigation, + event: MetaMetricsEventName.AccountAddSelected, properties: { - account_type: EVENT.ACCOUNT_TYPES.HARDWARE, + account_type: MetaMetricsEventAccountType.Hardware, location: 'Main Menu', }, }); @@ -446,14 +447,16 @@ export default class AccountMenu extends Component { onClick={() => { trackEvent( { - category: EVENT.CATEGORIES.NAVIGATION, - event: EVENT_NAMES.SUPPORT_LINK_CLICKED, + category: MetaMetricsEventCategory.Navigation, + event: MetaMetricsEventName.SupportLinkClicked, properties: { url: supportLink, }, }, { - contextPropsIntoEventProperties: [CONTEXT_PROPS.PAGE_TITLE], + contextPropsIntoEventProperties: [ + MetaMetricsContextProp.PageTitle, + ], }, ); global.platform.openTab({ url: supportLink }); @@ -472,8 +475,8 @@ export default class AccountMenu extends Component { toggleAccountMenu(); history.push(SETTINGS_ROUTE); this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, - event: EVENT_NAMES.NAV_SETTINGS_OPENED, + category: MetaMetricsEventCategory.Navigation, + event: MetaMetricsEventName.NavSettingsOpened, properties: { location: 'Main Menu', }, diff --git a/ui/components/app/add-network/add-network.js b/ui/components/app/add-network/add-network.js index 816d1e92c..48eaa711d 100644 --- a/ui/components/app/add-network/add-network.js +++ b/ui/components/app/add-network/add-network.js @@ -37,7 +37,7 @@ import { ADD_NETWORK_ROUTE } from '../../../helpers/constants/routes'; import { getEnvironmentType } from '../../../../app/scripts/lib/util'; import ZENDESK_URLS from '../../../helpers/constants/zendesk-url'; import { Icon, ICON_NAMES, ICON_SIZES, Text } from '../../component-library'; -import { EVENT } from '../../../../shared/constants/metametrics'; +import { MetaMetricsNetworkEventSource } from '../../../../shared/constants/metametrics'; const AddNetwork = () => { const t = useContext(I18nContext); @@ -267,7 +267,8 @@ const AddNetwork = () => { imageUrl: item.rpcPrefs?.imageUrl, chainName: item.nickname, referrer: ORIGIN_METAMASK, - source: EVENT.SOURCE.NETWORK.POPULAR_NETWORK_LIST, + source: + MetaMetricsNetworkEventSource.PopularNetworkList, }, }), ); diff --git a/ui/components/app/app-header/app-header.component.js b/ui/components/app/app-header/app-header.component.js index e7178a56f..248dda89f 100644 --- a/ui/components/app/app-header/app-header.component.js +++ b/ui/components/app/app-header/app-header.component.js @@ -4,7 +4,10 @@ import classnames from 'classnames'; import Identicon from '../../ui/identicon'; import MetaFoxLogo from '../../ui/metafox-logo'; import { DEFAULT_ROUTE } from '../../../helpers/constants/routes'; -import { EVENT, EVENT_NAMES } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; import NetworkDisplay from '../network-display'; ///: BEGIN:ONLY_INCLUDE_IN(beta) @@ -57,8 +60,8 @@ export default class AppHeader extends PureComponent { if (networkDropdownOpen === false) { this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, - event: EVENT_NAMES.NAV_NETWORK_MENU_OPENED, + category: MetaMetricsEventCategory.Navigation, + event: MetaMetricsEventName.NavNetworkMenuOpened, properties: {}, }); showNetworkDropdown(); @@ -90,8 +93,8 @@ export default class AppHeader extends PureComponent { if (!disabled) { !isAccountMenuOpen && this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, - event: EVENT_NAMES.NAV_MAIN_MENU_OPENED, + category: MetaMetricsEventCategory.Navigation, + event: MetaMetricsEventName.NavMainMenuOpened, properties: {}, }); toggleAccountMenu(); diff --git a/ui/components/app/asset-list-item/asset-list-item.js b/ui/components/app/asset-list-item/asset-list-item.js index c25682355..a5cc5051f 100644 --- a/ui/components/app/asset-list-item/asset-list-item.js +++ b/ui/components/app/asset-list-item/asset-list-item.js @@ -13,7 +13,7 @@ import { startNewDraftTransaction } from '../../../ducks/send'; import { SEND_ROUTE } from '../../../helpers/constants/routes'; import { Color, SEVERITIES } from '../../../helpers/constants/design-system'; import { INVALID_ASSET_TYPE } from '../../../helpers/constants/error-keys'; -import { EVENT } from '../../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../../shared/constants/metametrics'; import { AssetType } from '../../../../shared/constants/transaction'; import { MetaMetricsContext } from '../../../contexts/metametrics'; import { Icon, ICON_NAMES, ICON_SIZES } from '../../component-library'; @@ -68,7 +68,7 @@ const AssetListItem = ({ e.stopPropagation(); trackEvent({ event: 'Clicked Send: Token', - category: EVENT.CATEGORIES.NAVIGATION, + category: MetaMetricsEventCategory.Navigation, properties: { action: 'Home', legacy_event: true, diff --git a/ui/components/app/asset-list/asset-list.js b/ui/components/app/asset-list/asset-list.js index e83606e8b..5e305dcf9 100644 --- a/ui/components/app/asset-list/asset-list.js +++ b/ui/components/app/asset-list/asset-list.js @@ -24,7 +24,10 @@ import { } from '../../../helpers/constants/design-system'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { MetaMetricsContext } from '../../../contexts/metametrics'; -import { EVENT, EVENT_NAMES } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; import DetectedToken from '../detected-token/detected-token'; import { DetectedTokensBanner, @@ -110,8 +113,8 @@ const AssetList = ({ onClickAsset }) => { onTokenClick={(tokenAddress) => { onClickAsset(tokenAddress); trackEvent({ - event: EVENT_NAMES.TOKEN_SCREEN_OPENED, - category: EVENT.CATEGORIES.NAVIGATION, + event: MetaMetricsEventName.TokenScreenOpened, + category: MetaMetricsEventCategory.Navigation, properties: { token_symbol: primaryCurrencyProperties.suffix, location: 'Home', diff --git a/ui/components/app/asset-list/detetcted-tokens-link/detected-tokens-link.js b/ui/components/app/asset-list/detetcted-tokens-link/detected-tokens-link.js index adad64e95..9c9ef6230 100644 --- a/ui/components/app/asset-list/detetcted-tokens-link/detected-tokens-link.js +++ b/ui/components/app/asset-list/detetcted-tokens-link/detected-tokens-link.js @@ -9,8 +9,9 @@ import { useI18nContext } from '../../../../hooks/useI18nContext'; import { getDetectedTokensInCurrentNetwork } from '../../../../selectors'; import { MetaMetricsContext } from '../../../../contexts/metametrics'; import { - EVENT, - EVENT_NAMES, + MetaMetricsEventCategory, + MetaMetricsEventName, + MetaMetricsTokenEventSource, } from '../../../../../shared/constants/metametrics'; const DetectedTokensLink = ({ className = '', setShowDetectedTokens }) => { @@ -25,10 +26,10 @@ const DetectedTokensLink = ({ className = '', setShowDetectedTokens }) => { const onClick = () => { setShowDetectedTokens(true); trackEvent({ - event: EVENT_NAMES.TOKEN_IMPORT_CLICKED, - category: EVENT.CATEGORIES.WALLET, + event: MetaMetricsEventName.TokenImportClicked, + category: MetaMetricsEventCategory.Wallet, properties: { - source: EVENT.SOURCE.TOKEN.DETECTED, + source: MetaMetricsTokenEventSource.Detected, tokens: detectedTokensDetails, }, }); diff --git a/ui/components/app/confirm-page-container/confirm-page-container.component.js b/ui/components/app/confirm-page-container/confirm-page-container.component.js index aa12f0cf5..1c9b74d6a 100644 --- a/ui/components/app/confirm-page-container/confirm-page-container.component.js +++ b/ui/components/app/confirm-page-container/confirm-page-container.component.js @@ -44,7 +44,10 @@ import { } from '../../../selectors'; import useRamps from '../../../hooks/experiences/useRamps'; import { MetaMetricsContext } from '../../../contexts/metametrics'; -import { EVENT, EVENT_NAMES } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; import { ConfirmPageContainerHeader, ConfirmPageContainerContent, @@ -250,8 +253,8 @@ const ConfirmPageContainer = (props) => { onClick={() => { openBuyCryptoInPdapp(); trackEvent({ - event: EVENT_NAMES.NAV_BUY_BUTTON_CLICKED, - category: EVENT.CATEGORIES.NAVIGATION, + event: MetaMetricsEventName.NavBuyButtonClicked, + category: MetaMetricsEventCategory.Navigation, properties: { location: 'Transaction Confirmation', text: 'Buy', diff --git a/ui/components/app/desktop-enable-button/desktop-enable-button.component.js b/ui/components/app/desktop-enable-button/desktop-enable-button.component.js index 52099e738..650e13e60 100644 --- a/ui/components/app/desktop-enable-button/desktop-enable-button.component.js +++ b/ui/components/app/desktop-enable-button/desktop-enable-button.component.js @@ -20,7 +20,7 @@ import { } from '../../../store/actions'; import { SECOND } from '../../../../shared/constants/time'; import { MetaMetricsContext } from '../../../contexts/metametrics'; -import { EVENT } from '../../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../../shared/constants/metametrics'; const DESKTOP_ERROR_DESKTOP_OUTDATED_ROUTE = `${DESKTOP_ERROR_ROUTE}/${EXTENSION_ERROR_PAGE_TYPES.DESKTOP_OUTDATED}`; const DESKTOP_ERROR_EXTENSION_OUTDATED_ROUTE = `${DESKTOP_ERROR_ROUTE}/${EXTENSION_ERROR_PAGE_TYPES.EXTENSION_OUTDATED}`; @@ -45,7 +45,7 @@ export default function DesktopEnableButton() { await disableDesktop(); setDesktopEnabled(false); trackEvent({ - category: EVENT.CATEGORIES.DESKTOP, + category: MetaMetricsEventCategory.Desktop, event: DESKTOP_UPDATE_SETTINGS_EVENT, properties: { desktop_enabled: false, @@ -90,7 +90,7 @@ export default function DesktopEnableButton() { } trackEvent({ - category: EVENT.CATEGORIES.DESKTOP, + category: MetaMetricsEventCategory.Desktop, event: 'Desktop Button Clicked', properties: { button_action: 'Enable MetaMask Desktop', diff --git a/ui/components/app/detected-token/detected-token-selection-popover/detected-token-selection-popover.js b/ui/components/app/detected-token/detected-token-selection-popover/detected-token-selection-popover.js index a72664086..4ae5204fc 100644 --- a/ui/components/app/detected-token/detected-token-selection-popover/detected-token-selection-popover.js +++ b/ui/components/app/detected-token/detected-token-selection-popover/detected-token-selection-popover.js @@ -5,8 +5,9 @@ import { useSelector } from 'react-redux'; import { useI18nContext } from '../../../../hooks/useI18nContext'; import { MetaMetricsContext } from '../../../../contexts/metametrics'; import { - EVENT, - EVENT_NAMES, + MetaMetricsEventCategory, + MetaMetricsEventName, + MetaMetricsTokenEventSource, } from '../../../../../shared/constants/metametrics'; import { getDetectedTokensInCurrentNetwork } from '../../../../selectors'; @@ -40,10 +41,10 @@ const DetectedTokenSelectionPopover = ({ ({ address, symbol }) => `${symbol} - ${address}`, ); trackEvent({ - event: EVENT_NAMES.TOKEN_IMPORT_CANCELED, - category: EVENT.CATEGORIES.WALLET, + event: MetaMetricsEventName.TokenImportCanceled, + category: MetaMetricsEventCategory.Wallet, properties: { - source: EVENT.SOURCE.TOKEN.DETECTED, + source: MetaMetricsTokenEventSource.Detected, tokens: eventTokensDetails, }, }); diff --git a/ui/components/app/detected-token/detected-token.js b/ui/components/app/detected-token/detected-token.js index feadbab24..02484563b 100644 --- a/ui/components/app/detected-token/detected-token.js +++ b/ui/components/app/detected-token/detected-token.js @@ -15,7 +15,12 @@ import { AssetType, TokenStandard, } from '../../../../shared/constants/transaction'; -import { EVENT, EVENT_NAMES } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventLocation, + MetaMetricsEventName, + MetaMetricsTokenEventSource, +} from '../../../../shared/constants/metametrics'; import DetectedTokenSelectionPopover from './detected-token-selection-popover/detected-token-selection-popover'; import DetectedTokenIgnoredPopover from './detected-token-ignored-popover/detected-token-ignored-popover'; @@ -58,13 +63,13 @@ const DetectedToken = ({ setShowDetectedTokens }) => { const importSelectedTokens = async (selectedTokens) => { selectedTokens.forEach((importedToken) => { trackEvent({ - event: EVENT_NAMES.TOKEN_ADDED, - category: EVENT.CATEGORIES.WALLET, + event: MetaMetricsEventName.TokenAdded, + category: MetaMetricsEventCategory.Wallet, sensitiveProperties: { token_symbol: importedToken.symbol, token_contract_address: importedToken.address, token_decimal_precision: importedToken.decimals, - source: EVENT.SOURCE.TOKEN.DETECTED, + source: MetaMetricsTokenEventSource.Detected, token_standard: TokenStandard.ERC20, asset_type: AssetType.token, }, @@ -86,11 +91,11 @@ const DetectedToken = ({ setShowDetectedTokens }) => { ({ symbol, address }) => `${symbol} - ${address}`, ); trackEvent({ - event: EVENT_NAMES.TOKEN_HIDDEN, - category: EVENT.CATEGORIES.WALLET, + event: MetaMetricsEventName.TokenHidden, + category: MetaMetricsEventCategory.Wallet, sensitiveProperties: { tokens: tokensDetailsList, - location: EVENT.LOCATION.TOKEN_DETECTION, + location: MetaMetricsEventLocation.TokenDetection, token_standard: TokenStandard.ERC20, asset_type: AssetType.token, }, diff --git a/ui/components/app/dropdowns/network-dropdown.js b/ui/components/app/dropdowns/network-dropdown.js index c40ccc79d..d101e5769 100644 --- a/ui/components/app/dropdowns/network-dropdown.js +++ b/ui/components/app/dropdowns/network-dropdown.js @@ -23,7 +23,11 @@ import { IconColor, Size } from '../../../helpers/constants/design-system'; import { getShowTestNetworks } from '../../../selectors'; import { getEnvironmentType } from '../../../../app/scripts/lib/util'; import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app'; -import { EVENT, EVENT_NAMES } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, + MetaMetricsNetworkEventSource, +} from '../../../../shared/constants/metametrics'; import { ADD_POPULAR_CUSTOM_NETWORK, ADVANCED_ROUTE, @@ -127,8 +131,8 @@ class NetworkDropdown extends Component { const { trackEvent } = this.context; trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, - event: EVENT_NAMES.NAV_NETWORK_SWITCHED, + category: MetaMetricsEventCategory.Navigation, + event: MetaMetricsEventName.NavNetworkSwitched, properties: { from_network: providerType, to_network: newProviderType, @@ -320,7 +324,7 @@ class NetworkDropdown extends Component { }, { setActive: true, - source: EVENT.SOURCE.NETWORK.CUSTOM_NETWORK_FORM, + source: MetaMetricsNetworkEventSource.CustomNetworkForm, }, ); } diff --git a/ui/components/app/import-token-link/import-token-link.component.js b/ui/components/app/import-token-link/import-token-link.component.js index 6f5e93a1b..cf7ebae1f 100644 --- a/ui/components/app/import-token-link/import-token-link.component.js +++ b/ui/components/app/import-token-link/import-token-link.component.js @@ -8,7 +8,10 @@ import Box from '../../ui/box/box'; import { TEXT_ALIGN } from '../../../helpers/constants/design-system'; import { detectNewTokens } from '../../../store/actions'; import { MetaMetricsContext } from '../../../contexts/metametrics'; -import { EVENT, EVENT_NAMES } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; import { getIsTokenDetectionSupported, getIsTokenDetectionInactiveOnMainnet, @@ -51,8 +54,8 @@ export default function ImportTokenLink() { onClick={() => { history.push(IMPORT_TOKEN_ROUTE); trackEvent({ - event: EVENT_NAMES.TOKEN_IMPORT_BUTTON_CLICKED, - category: EVENT.CATEGORIES.NAVIGATION, + event: MetaMetricsEventName.TokenImportButtonClicked, + category: MetaMetricsEventCategory.Navigation, properties: { location: 'Home', }, diff --git a/ui/components/app/menu-bar/account-options-menu.js b/ui/components/app/menu-bar/account-options-menu.js index deeb4e0a3..b5469687b 100644 --- a/ui/components/app/menu-bar/account-options-menu.js +++ b/ui/components/app/menu-bar/account-options-menu.js @@ -22,7 +22,11 @@ import { useI18nContext } from '../../../hooks/useI18nContext'; import { getEnvironmentType } from '../../../../app/scripts/lib/util'; import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../shared/constants/app'; import { KeyringType } from '../../../../shared/constants/keyring'; -import { EVENT, EVENT_NAMES } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventLinkType, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; import { MetaMetricsContext } from '../../../contexts/metametrics'; import { ICON_NAMES } from '../../component-library'; @@ -50,10 +54,10 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { const openBlockExplorer = () => { trackEvent({ - event: EVENT_NAMES.EXTERNAL_LINK_CLICKED, - category: EVENT.CATEGORIES.NAVIGATION, + event: MetaMetricsEventName.ExternalLinkClicked, + category: MetaMetricsEventCategory.Navigation, properties: { - link_type: EVENT.EXTERNAL_LINK_TYPES.ACCOUNT_TRACKER, + link_type: MetaMetricsEventLinkType.AccountTracker, location: 'Account Options', url_domain: getURLHostName(addressLink), }, @@ -96,8 +100,8 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { { trackEvent({ - event: EVENT_NAMES.APP_WINDOW_EXPANDED, - category: EVENT.CATEGORIES.NAVIGATION, + event: MetaMetricsEventName.AppWindowExpanded, + category: MetaMetricsEventCategory.Navigation, properties: { location: 'Account Options', }, @@ -115,8 +119,8 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { onClick={() => { dispatch(showModal({ name: 'ACCOUNT_DETAILS' })); trackEvent({ - event: EVENT_NAMES.NAV_ACCOUNT_DETAILS_OPENED, - category: EVENT.CATEGORIES.NAVIGATION, + event: MetaMetricsEventName.NavAccountDetailsOpened, + category: MetaMetricsEventCategory.Navigation, properties: { location: 'Account Options', }, @@ -131,8 +135,8 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { data-testid="account-options-menu__connected-sites" onClick={() => { trackEvent({ - event: EVENT_NAMES.NAV_CONNECTED_SITES_OPENED, - category: EVENT.CATEGORIES.NAVIGATION, + event: MetaMetricsEventName.NavConnectedSitesOpened, + category: MetaMetricsEventCategory.Navigation, properties: { location: 'Account Options', }, diff --git a/ui/components/app/menu-bar/menu-bar.js b/ui/components/app/menu-bar/menu-bar.js index 3ddc301af..99afdf1c6 100644 --- a/ui/components/app/menu-bar/menu-bar.js +++ b/ui/components/app/menu-bar/menu-bar.js @@ -6,7 +6,10 @@ import SelectedAccount from '../selected-account'; import ConnectedStatusIndicator from '../connected-status-indicator'; import { getEnvironmentType } from '../../../../app/scripts/lib/util'; import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app'; -import { EVENT, EVENT_NAMES } from '../../../../shared/constants/metametrics'; +import { + MetaMetricsEventCategory, + MetaMetricsEventName, +} from '../../../../shared/constants/metametrics'; import { CONNECTED_ACCOUNTS_ROUTE } from '../../../helpers/constants/routes'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { getOriginOfCurrentTab } from '../../../selectors'; @@ -44,8 +47,8 @@ export default function MenuBar() { ariaLabel={t('accountOptions')} onClick={() => { trackEvent({ - event: EVENT_NAMES.NAV_ACCOUNT_MENU_OPENED, - category: EVENT.CATEGORIES.NAVIGATION, + event: MetaMetricsEventName.NavAccountMenuOpened, + category: MetaMetricsEventCategory.Navigation, properties: { location: 'Home', }, diff --git a/ui/components/app/modals/account-details-modal/account-details-modal.component.js b/ui/components/app/modals/account-details-modal/account-details-modal.component.js index 189b18fbc..f1ad623c6 100644 --- a/ui/components/app/modals/account-details-modal/account-details-modal.component.js +++ b/ui/components/app/modals/account-details-modal/account-details-modal.component.js @@ -9,8 +9,10 @@ import Button from '../../../ui/button'; import { getURLHostName } from '../../../../helpers/utils/util'; import { isHardwareKeyring } from '../../../../helpers/utils/hardware'; import { - EVENT, - EVENT_NAMES, + MetaMetricsEventCategory, + MetaMetricsEventLinkType, + MetaMetricsEventKeyType, + MetaMetricsEventName, } from '../../../../../shared/constants/metametrics'; import { NETWORKS_ROUTE } from '../../../../helpers/constants/routes'; @@ -65,10 +67,10 @@ export default class AccountDetailsModal extends Component { const openBlockExplorer = () => { const accountLink = getAccountLink(address, chainId, rpcPrefs); this.context.trackEvent({ - category: EVENT.CATEGORIES.NAVIGATION, - event: EVENT_NAMES.EXTERNAL_LINK_CLICKED, + category: MetaMetricsEventCategory.Navigation, + event: MetaMetricsEventName.ExternalLinkClicked, properties: { - link_type: EVENT.EXTERNAL_LINK_TYPES.ACCOUNT_TRACKER, + link_type: MetaMetricsEventLinkType.AccountTracker, location: 'Account Details Modal', url_domain: getURLHostName(accountLink), }, @@ -115,10 +117,10 @@ export default class AccountDetailsModal extends Component { className="account-details-modal__button" onClick={() => { this.context.trackEvent({ - category: EVENT.CATEGORIES.ACCOUNTS, - event: EVENT_NAMES.KEY_EXPORT_SELECTED, + category: MetaMetricsEventCategory.Accounts, + event: MetaMetricsEventName.KeyExportSelected, properties: { - key_type: EVENT.KEY_TYPES.PKEY, + key_type: MetaMetricsEventKeyType.Pkey, location: 'Account Details Modal', }, }); diff --git a/ui/components/app/modals/confirm-remove-account/confirm-remove-account.component.js b/ui/components/app/modals/confirm-remove-account/confirm-remove-account.component.js index 4d1faea86..e8d8c25cd 100644 --- a/ui/components/app/modals/confirm-remove-account/confirm-remove-account.component.js +++ b/ui/components/app/modals/confirm-remove-account/confirm-remove-account.component.js @@ -4,7 +4,7 @@ import { getAccountLink } from '@metamask/etherscan-link'; import Modal from '../../modal'; import { addressSummary, getURLHostName } from '../../../../helpers/utils/util'; import Identicon from '../../../ui/identicon'; -import { EVENT } from '../../../../../shared/constants/metametrics'; +import { MetaMetricsEventCategory } from '../../../../../shared/constants/metametrics'; import ZENDESK_URLS from '../../../../helpers/constants/zendesk-url'; export default class ConfirmRemoveAccount extends Component { @@ -62,7 +62,7 @@ export default class ConfirmRemoveAccount extends Component { rpcPrefs, ); this.context.trackEvent({ - category: EVENT.CATEGORIES.ACCOUNTS, + category: MetaMetricsEventCategory.Accounts, event: 'Clicked Block Explorer Link', properties: { link_type: 'Account Tracker', diff --git a/ui/components/app/modals/export-private-key-modal/export-private-key-modal.component.js b/ui/components/app/modals/export-private-key-modal/export-private-key-modal.component.js index fcd2dde85..81e0dfc4c 100644 --- a/ui/components/app/modals/export-private-key-modal/export-private-key-modal.component.js +++ b/ui/components/app/modals/export-private-key-modal/export-private-key-modal.component.js @@ -10,8 +10,9 @@ import { stripHexPrefix, } from '../../../../../shared/modules/hexstring-utils'; import { - EVENT, - EVENT_NAMES, + MetaMetricsEventCategory, + MetaMetricsEventKeyType, + MetaMetricsEventName, } from '../../../../../shared/constants/metametrics'; export default class ExportPrivateKeyModal extends Component { @@ -53,10 +54,10 @@ export default class ExportPrivateKeyModal extends Component { exportAccount(password, address) .then((privateKey) => { this.context.trackEvent({ - category: EVENT.CATEGORIES.KEYS, - event: EVENT_NAMES.KEY_EXPORT_REVEALED, + category: MetaMetricsEventCategory.Keys, + event: MetaMetricsEventName.KeyExportRevealed, properties: { - key_type: EVENT.KEY_TYPES.PKEY, + key_type: MetaMetricsEventKeyType.Pkey, }, }); @@ -67,10 +68,10 @@ export default class ExportPrivateKeyModal extends Component { }) .catch((e) => { this.context.trackEvent({ - category: EVENT.CATEGORIES.KEYS, - event: EVENT_NAMES.KEY_EXPORT_FAILED, + category: MetaMetricsEventCategory.Keys, + event: MetaMetricsEventName.KeyExportFailed, properties: { - key_type: EVENT.KEY_TYPES.PKEY, + key_type: MetaMetricsEventKeyType.Pkey, reason: 'incorrect_password', }, }); @@ -108,10 +109,10 @@ export default class ExportPrivateKeyModal extends Component { onClick={() => { copyToClipboard(plainKey); this.context.trackEvent({ - category: EVENT.CATEGORIES.KEYS, - event: EVENT_NAMES.KEY_EXPORT_COPIED, + category: MetaMetricsEventCategory.Keys, + event: MetaMetricsEventName.KeyExportCopied, properties: { - key_type: EVENT.KEY_TYPES.PKEY, + key_type: MetaMetricsEventKeyType.Pkey, copy_method: 'clipboard', }, }); @@ -132,10 +133,10 @@ export default class ExportPrivateKeyModal extends Component { className="export-private-key-modal__button export-private-key-modal__button--cancel" onClick={() => { this.context.trackEvent({ - category: EVENT.CATEGORIES.KEYS, - event: EVENT_NAMES.KEY_EXPORT_CANCELED, + category: MetaMetricsEventCategory.Keys, + event: MetaMetricsEventName.KeyExportCanceled, properties: { - key_type: EVENT.KEY_TYPES.PKEY, + key_type: MetaMetricsEventKeyType.Pkey, }, }); hideModal(); @@ -159,10 +160,10 @@ export default class ExportPrivateKeyModal extends Component {