MetaMetrics: Identify 'number_of_tokens' user trait (#14427)

* MetaMetrics: identify number_of_tokens

* MetaMetrics: update number_of_tokens
do not filter by unique addresses.
Each token contract x chain id combo is a unique contract

* MetaMetrics: update MetaMetricsTraits @typedef
- add number_of_tokens

* MetaMetrics: clean up number_of_tokens

* MetaMetrics: alphabetize in test
feature/default_network_editable
Ariella Vu 3 years ago committed by GitHub
parent e7bb8e2663
commit 21e54f4717
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      app/scripts/controllers/metametrics.js
  2. 37
      app/scripts/controllers/metametrics.test.js
  3. 5
      shared/constants/metametrics.js

@ -557,6 +557,7 @@ export default class MetaMetricsController {
[TRAITS.NUMBER_OF_NFT_COLLECTIONS]: this._getNumberOfNFtCollection( [TRAITS.NUMBER_OF_NFT_COLLECTIONS]: this._getNumberOfNFtCollection(
metamaskState, metamaskState,
), ),
[TRAITS.NUMBER_OF_TOKENS]: this._getNumberOfTokens(metamaskState),
[TRAITS.OPENSEA_API_ENABLED]: metamaskState.openSeaEnabled, [TRAITS.OPENSEA_API_ENABLED]: metamaskState.openSeaEnabled,
[TRAITS.THREE_BOX_ENABLED]: metamaskState.threeBoxSyncingAllowed, [TRAITS.THREE_BOX_ENABLED]: metamaskState.threeBoxSyncingAllowed,
}; };
@ -619,6 +620,19 @@ export default class MetaMetricsController {
return unique.length; return unique.length;
} }
/**
* @param {object} metamaskState
* @returns number of unique token addresses
*/
_getNumberOfTokens(metamaskState) {
return Object.values(metamaskState.allTokens).reduce(
(result, accountsByChain) => {
return result + sum(Object.values(accountsByChain).map(size));
},
0,
);
}
/** /**
* Calls segment.identify with given user traits * Calls segment.identify with given user traits
* *

@ -611,6 +611,34 @@ describe('MetaMetricsController', function () {
describe('_buildUserTraitsObject', function () { describe('_buildUserTraitsObject', function () {
it('should return full user traits object on first call', function () { it('should return full user traits object on first call', function () {
const MOCK_ALL_TOKENS = {
'0x1': {
'0x1235ce91d74254f29d4609f25932fe6d97bf4842': [
{
address: '0xd2cea331e5f5d8ee9fb1055c297795937645de91',
},
{
address: '0xabc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9',
},
],
'0xe364b0f9d1879e53e8183055c9d7dd2b7375d86b': [
{
address: '0xd2cea331e5f5d8ee9fb1055c297795937645de91',
},
],
},
'0x4': {
'0x1235ce91d74254f29d4609f25932fe6d97bf4842': [
{
address: '0xd2cea331e5f5d8ee9fb1055c297795937645de91',
},
{
address: '0x12317F958D2ee523a2206206994597C13D831ec7',
},
],
},
};
const metaMetricsController = getMetaMetricsController(); const metaMetricsController = getMetaMetricsController();
const traits = metaMetricsController._buildUserTraitsObject({ const traits = metaMetricsController._buildUserTraitsObject({
addressBook: { addressBook: {
@ -643,6 +671,7 @@ describe('MetaMetricsController', function () {
], ],
}, },
}, },
allTokens: MOCK_ALL_TOKENS,
frequentRpcListDetail: [ frequentRpcListDetail: [
{ chainId: MAINNET_CHAIN_ID }, { chainId: MAINNET_CHAIN_ID },
{ chainId: ROPSTEN_CHAIN_ID }, { chainId: ROPSTEN_CHAIN_ID },
@ -661,6 +690,7 @@ describe('MetaMetricsController', function () {
[TRAITS.NFT_AUTODETECTION_ENABLED]: false, [TRAITS.NFT_AUTODETECTION_ENABLED]: false,
[TRAITS.NUMBER_OF_ACCOUNTS]: 2, [TRAITS.NUMBER_OF_ACCOUNTS]: 2,
[TRAITS.NUMBER_OF_NFT_COLLECTIONS]: 3, [TRAITS.NUMBER_OF_NFT_COLLECTIONS]: 3,
[TRAITS.NUMBER_OF_TOKENS]: 5,
[TRAITS.OPENSEA_API_ENABLED]: true, [TRAITS.OPENSEA_API_ENABLED]: true,
[TRAITS.THREE_BOX_ENABLED]: false, [TRAITS.THREE_BOX_ENABLED]: false,
}); });
@ -673,6 +703,7 @@ describe('MetaMetricsController', function () {
[MAINNET_CHAIN_ID]: [{ address: '0x' }], [MAINNET_CHAIN_ID]: [{ address: '0x' }],
[ROPSTEN_CHAIN_ID]: [{ address: '0x' }, { address: '0x0' }], [ROPSTEN_CHAIN_ID]: [{ address: '0x' }, { address: '0x0' }],
}, },
allTokens: {},
frequentRpcListDetail: [ frequentRpcListDetail: [
{ chainId: MAINNET_CHAIN_ID }, { chainId: MAINNET_CHAIN_ID },
{ chainId: ROPSTEN_CHAIN_ID }, { chainId: ROPSTEN_CHAIN_ID },
@ -689,6 +720,9 @@ describe('MetaMetricsController', function () {
[MAINNET_CHAIN_ID]: [{ address: '0x' }, { address: '0x1' }], [MAINNET_CHAIN_ID]: [{ address: '0x' }, { address: '0x1' }],
[ROPSTEN_CHAIN_ID]: [{ address: '0x' }, { address: '0x0' }], [ROPSTEN_CHAIN_ID]: [{ address: '0x' }, { address: '0x0' }],
}, },
allTokens: {
'0x1': { '0xabcde': [{ '0x12345': { address: '0xtestAddress' } }] },
},
frequentRpcListDetail: [ frequentRpcListDetail: [
{ chainId: MAINNET_CHAIN_ID }, { chainId: MAINNET_CHAIN_ID },
{ chainId: ROPSTEN_CHAIN_ID }, { chainId: ROPSTEN_CHAIN_ID },
@ -703,6 +737,7 @@ describe('MetaMetricsController', function () {
assert.deepEqual(updatedTraits, { assert.deepEqual(updatedTraits, {
[TRAITS.ADDRESS_BOOK_ENTRIES]: 4, [TRAITS.ADDRESS_BOOK_ENTRIES]: 4,
[TRAITS.NUMBER_OF_ACCOUNTS]: 3, [TRAITS.NUMBER_OF_ACCOUNTS]: 3,
[TRAITS.NUMBER_OF_TOKENS]: 1,
[TRAITS.OPENSEA_API_ENABLED]: false, [TRAITS.OPENSEA_API_ENABLED]: false,
}); });
}); });
@ -714,6 +749,7 @@ describe('MetaMetricsController', function () {
[MAINNET_CHAIN_ID]: [{ address: '0x' }], [MAINNET_CHAIN_ID]: [{ address: '0x' }],
[ROPSTEN_CHAIN_ID]: [{ address: '0x' }, { address: '0x0' }], [ROPSTEN_CHAIN_ID]: [{ address: '0x' }, { address: '0x0' }],
}, },
allTokens: {},
frequentRpcListDetail: [ frequentRpcListDetail: [
{ chainId: MAINNET_CHAIN_ID }, { chainId: MAINNET_CHAIN_ID },
{ chainId: ROPSTEN_CHAIN_ID }, { chainId: ROPSTEN_CHAIN_ID },
@ -730,6 +766,7 @@ describe('MetaMetricsController', function () {
[MAINNET_CHAIN_ID]: [{ address: '0x' }], [MAINNET_CHAIN_ID]: [{ address: '0x' }],
[ROPSTEN_CHAIN_ID]: [{ address: '0x' }, { address: '0x0' }], [ROPSTEN_CHAIN_ID]: [{ address: '0x' }, { address: '0x0' }],
}, },
allTokens: {},
frequentRpcListDetail: [ frequentRpcListDetail: [
{ chainId: MAINNET_CHAIN_ID }, { chainId: MAINNET_CHAIN_ID },
{ chainId: ROPSTEN_CHAIN_ID }, { chainId: ROPSTEN_CHAIN_ID },

@ -170,6 +170,8 @@
* change, we identify the new number_of_accounts trait * change, we identify the new number_of_accounts trait
* @property {'number_of_nft_collections'} NUMBER_OF_NFT_COLLECTIONS - user * @property {'number_of_nft_collections'} NUMBER_OF_NFT_COLLECTIONS - user
* trait for number of unique NFT addresses * trait for number of unique 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 * @property {'opensea_api_enabled'} OPENSEA_API_ENABLED - when the OpenSea API is enabled
* we identify the opensea_api_enabled trait * we identify the opensea_api_enabled trait
* @property {'three_box_enabled'} THREE_BOX_ENABLED - when 3box feature is * @property {'three_box_enabled'} THREE_BOX_ENABLED - when 3box feature is
@ -188,6 +190,7 @@ export const TRAITS = {
NFT_AUTODETECTION_ENABLED: 'nft_autodetection_enabled', NFT_AUTODETECTION_ENABLED: 'nft_autodetection_enabled',
NUMBER_OF_ACCOUNTS: 'number_of_accounts', NUMBER_OF_ACCOUNTS: 'number_of_accounts',
NUMBER_OF_NFT_COLLECTIONS: 'number_of_nft_collections', NUMBER_OF_NFT_COLLECTIONS: 'number_of_nft_collections',
NUMBER_OF_TOKENS: 'number_of_tokens',
OPENSEA_API_ENABLED: 'opensea_api_enabled', OPENSEA_API_ENABLED: 'opensea_api_enabled',
THREE_BOX_ENABLED: 'three_box_enabled', THREE_BOX_ENABLED: 'three_box_enabled',
}; };
@ -206,6 +209,8 @@ export const TRAITS = {
* of identities(accounts) added to the user's MetaMask. * of identities(accounts) added to the user's MetaMask.
* @property {number} [number_of_nft_collections] - A number representing the * @property {number} [number_of_nft_collections] - A number representing the
* amount of different NFT collections the user possesses an NFT from. * amount of different NFT collections the user possesses an NFT from.
* @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 * @property {boolean} [opensea_api_enabled] - does the user have the OpenSea
* API enabled? * API enabled?
* @property {boolean} [three_box_enabled] - does the user have 3box sync * @property {boolean} [three_box_enabled] - does the user have 3box sync

Loading…
Cancel
Save