From 922ebd57cbd4aa72c5872b89730d61972b939efc Mon Sep 17 00:00:00 2001 From: Brad Decker Date: Wed, 13 Apr 2022 11:46:49 -0500 Subject: [PATCH] track address book usage (#14382) * track address book usage * Update app/scripts/controllers/metametrics.js Co-authored-by: Ariella Vu <20778143+digiwand@users.noreply.github.com> * Update shared/constants/metametrics.js Co-authored-by: Ariella Vu <20778143+digiwand@users.noreply.github.com> Co-authored-by: Ariella Vu <20778143+digiwand@users.noreply.github.com> --- app/scripts/controllers/metametrics.js | 16 +++++++- app/scripts/controllers/metametrics.test.js | 22 +++++++++++ shared/constants/metametrics.js | 41 ++++++++++++++++----- 3 files changed, 68 insertions(+), 11 deletions(-) diff --git a/app/scripts/controllers/metametrics.js b/app/scripts/controllers/metametrics.js index 4cc3ed69e..65fa46c83 100644 --- a/app/scripts/controllers/metametrics.js +++ b/app/scripts/controllers/metametrics.js @@ -1,4 +1,4 @@ -import { isEqual, merge, omit, omitBy, pickBy } from 'lodash'; +import { isEqual, merge, omit, omitBy, pickBy, size, sum } from 'lodash'; import { ObservableStore } from '@metamask/obs-store'; import { bufferToHex, keccak } from 'ethereumjs-util'; import { generateUUID } from 'pubnub'; @@ -31,6 +31,7 @@ const exceptionsToFilter = { * @typedef {import('../../../shared/constants/metametrics').MetaMetricsPagePayload} MetaMetricsPagePayload * @typedef {import('../../../shared/constants/metametrics').MetaMetricsPageOptions} MetaMetricsPageOptions * @typedef {import('../../../shared/constants/metametrics').MetaMetricsEventFragment} MetaMetricsEventFragment + * @typedef {import('../../../shared/constants/metametrics').MetaMetricsTraits} MetaMetricsTraits */ /** @@ -531,8 +532,21 @@ export default class MetaMetricsController { }; } + /** + * This method generates the MetaMetrics user traits object, omitting any + * traits that have not changed since the last invocation of this method. + * + * @param {object} metamaskState - Full metamask state object. + * @returns {MetaMetricsTraits | null} traits that have changed since last update + */ _buildUserTraitsObject(metamaskState) { + /** + * @type {MetaMetricsTraits} + */ const currentTraits = { + [TRAITS.ADDRESS_BOOK_ENTRIES]: sum( + Object.values(metamaskState.addressBook).map(size), + ), [TRAITS.LEDGER_CONNECTION_TYPE]: metamaskState.ledgerTransportType, [TRAITS.NUMBER_OF_ACCOUNTS]: Object.values(metamaskState.identities) .length, diff --git a/app/scripts/controllers/metametrics.test.js b/app/scripts/controllers/metametrics.test.js index 81ea8e0ed..0cf82af71 100644 --- a/app/scripts/controllers/metametrics.test.js +++ b/app/scripts/controllers/metametrics.test.js @@ -646,9 +646,14 @@ describe('MetaMetricsController', function () { }, }, threeBoxSyncingAllowed: false, + addressBook: { + [MAINNET_CHAIN_ID]: [{ address: '0x' }], + [ROPSTEN_CHAIN_ID]: [{ address: '0x' }, { address: '0x0' }], + }, }); assert.deepEqual(traits, { + [TRAITS.ADDRESS_BOOK_ENTRIES]: 3, [TRAITS.LEDGER_CONNECTION_TYPE]: 'web-hid', [TRAITS.NETWORKS_ADDED]: [MAINNET_CHAIN_ID, ROPSTEN_CHAIN_ID], [TRAITS.NUMBER_OF_ACCOUNTS]: 2, @@ -667,6 +672,10 @@ describe('MetaMetricsController', function () { ledgerTransportType: 'web-hid', identities: [{}, {}], threeBoxSyncingAllowed: false, + addressBook: { + [MAINNET_CHAIN_ID]: [{ address: '0x' }], + [ROPSTEN_CHAIN_ID]: [{ address: '0x' }, { address: '0x0' }], + }, }); const updatedTraits = metaMetricsController._buildUserTraitsObject({ @@ -677,9 +686,14 @@ describe('MetaMetricsController', function () { ledgerTransportType: 'web-hid', identities: [{}, {}, {}], threeBoxSyncingAllowed: false, + addressBook: { + [MAINNET_CHAIN_ID]: [{ address: '0x' }, { address: '0x1' }], + [ROPSTEN_CHAIN_ID]: [{ address: '0x' }, { address: '0x0' }], + }, }); assert.deepEqual(updatedTraits, { + [TRAITS.ADDRESS_BOOK_ENTRIES]: 4, [TRAITS.NUMBER_OF_ACCOUNTS]: 3, }); }); @@ -694,6 +708,10 @@ describe('MetaMetricsController', function () { ledgerTransportType: 'web-hid', identities: [{}, {}], threeBoxSyncingAllowed: false, + addressBook: { + [MAINNET_CHAIN_ID]: [{ address: '0x' }], + [ROPSTEN_CHAIN_ID]: [{ address: '0x' }, { address: '0x0' }], + }, }); const updatedTraits = metaMetricsController._buildUserTraitsObject({ @@ -704,6 +722,10 @@ describe('MetaMetricsController', function () { ledgerTransportType: 'web-hid', identities: [{}, {}], threeBoxSyncingAllowed: false, + addressBook: { + [MAINNET_CHAIN_ID]: [{ address: '0x' }], + [ROPSTEN_CHAIN_ID]: [{ address: '0x' }, { address: '0x0' }], + }, }); assert.equal(updatedTraits, null); diff --git a/shared/constants/metametrics.js b/shared/constants/metametrics.js index 8291f4860..28c6076f3 100644 --- a/shared/constants/metametrics.js +++ b/shared/constants/metametrics.js @@ -156,16 +156,20 @@ /** * @typedef {Object} Traits - * @property {string} [LEDGER_CONNECTION_TYPE] - when ledger live connnection - * type is changed we identify the ledger_connection_type trait - * @property {string} [NETWORKS_ADDED] - when user modifies networks we - * identify the networks_added trait - * @property {string} [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 {string} [THREE_BOX_ENABLED] - when 3box feature is toggled we - * identify the 3box_enabled trait + * @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 {'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 {'three_box_enabled'} THREE_BOX_ENABLED - when 3box feature is + * toggled we identify the 3box_enabled trait */ /** @@ -174,6 +178,7 @@ */ export const TRAITS = { + ADDRESS_BOOK_ENTRIES: 'address_book_entries', LEDGER_CONNECTION_TYPE: 'ledger_connection_type', NETWORKS_ADDED: 'networks_added', NUMBER_OF_ACCOUNTS: 'number_of_accounts', @@ -181,6 +186,22 @@ export const TRAITS = { THREE_BOX_ENABLED: 'three_box_enabled', }; +/** + * @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 {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 {boolean} [three_box_enabled] - does the user have 3box sync + * enabled? + */ + // Mixpanel converts the zero address value to a truly anonymous event, which // speeds up reporting export const METAMETRICS_ANONYMOUS_ID = '0x0000000000000000';