Skip to content

Commit

Permalink
Merge MetamaskState defined in metametrics-controller into `initi…
Browse files Browse the repository at this point in the history
…alMetamaskState`
  • Loading branch information
MajorLift committed Nov 27, 2024
1 parent e7cc0eb commit 25a6496
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 82 deletions.
137 changes: 59 additions & 78 deletions app/scripts/controllers/metametrics-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import {
} from 'lodash';
import { bufferToHex, keccak } from 'ethereumjs-util';
import { v4 as uuidv4 } from 'uuid';
import { NameControllerState, NameType } from '@metamask/name-controller';
import { AccountsControllerState } from '@metamask/accounts-controller';
import { NameType } from '@metamask/name-controller';
import {
getErrorMessage,
Hex,
Expand All @@ -23,22 +22,17 @@ import {
NetworkControllerGetNetworkClientByIdAction,
NetworkControllerGetStateAction,
NetworkControllerNetworkDidChangeEvent,
NetworkState,
} from '@metamask/network-controller';
import { Browser } from 'webextension-polyfill';
import {
Nft,
NftControllerState,
TokensControllerState,
} from '@metamask/assets-controllers';
import { Nft } from '@metamask/assets-controllers';
import { captureException as sentryCaptureException } from '@sentry/browser';
import {
BaseController,
ControllerGetStateAction,
ControllerStateChangeEvent,
RestrictedControllerMessenger,
} from '@metamask/base-controller';
import { AddressBookControllerState } from '@metamask/address-book-controller';
import type { MemStoreControllersComposedState } from '../metamask-controller-stores';
import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../shared/constants/app';
import {
METAMETRICS_ANONYMOUS_ID,
Expand All @@ -65,7 +59,6 @@ import {
AnonymousTransactionMetaMetricsEvent,
TransactionMetaMetricsEvent,
} from '../../../shared/constants/transaction';
import { LedgerTransportTypes } from '../../../shared/constants/hardware-wallets';
import Analytics from '../lib/segment/analytics';

///: BEGIN:ONLY_INCLUDE_IF(build-main)
Expand Down Expand Up @@ -144,39 +137,6 @@ const exceptionsToFilter: Record<string, boolean> = {
*/
type SegmentEventType = 'identify' | 'track' | 'page';

// TODO: Complete MetaMaskState by adding the full state definition and relocate it after the background is converted to TypeScript.
export type MetaMaskState = {
ledgerTransportType: LedgerTransportTypes;
networkConfigurationsByChainId: NetworkState['networkConfigurationsByChainId'];
internalAccounts: AccountsControllerState['internalAccounts'];
allNfts: NftControllerState['allNfts'];
allTokens: TokensControllerState['allTokens'];
theme: string;
participateInMetaMetrics: boolean;
dataCollectionForMarketing: boolean;
ShowNativeTokenAsMainBalance: boolean;
useNftDetection: PreferencesControllerState['useNftDetection'];
openSeaEnabled: PreferencesControllerState['openSeaEnabled'];
securityAlertsEnabled: PreferencesControllerState['securityAlertsEnabled'];
useTokenDetection: PreferencesControllerState['useTokenDetection'];
tokenSortConfig: PreferencesControllerState['preferences']['tokenSortConfig'];
names: NameControllerState['names'];
security_providers: string[];
addressBook: AddressBookControllerState['addressBook'];
currentCurrency: string;
preferences: {
privacyMode: PreferencesControllerState['preferences']['privacyMode'];
tokenNetworkFilter: string[];
};
///: BEGIN:ONLY_INCLUDE_IF(build-mmi)
custodyAccountDetails: {
[address: string]: {
custodianName: string;
};
};
///: END:ONLY_INCLUDE_IF
};

/**
* {@link MetaMetricsController}'s metadata.
*
Expand Down Expand Up @@ -1004,7 +964,7 @@ export default class MetaMetricsController extends BaseController<
}
}

handleMetaMaskStateUpdate(newState: MetaMaskState): void {
handleMetaMaskStateUpdate(newState: MemStoreControllersComposedState): void {
const userTraits = this._buildUserTraitsObject(newState);
if (userTraits) {
this.identify(userTraits);
Expand Down Expand Up @@ -1169,73 +1129,85 @@ export default class MetaMetricsController extends BaseController<
* @returns traits that have changed since last update
*/
_buildUserTraitsObject(
metamaskState: MetaMaskState,
metamaskState: MemStoreControllersComposedState,
): Partial<MetaMetricsUserTraits> | null {
///: BEGIN:ONLY_INCLUDE_IF(build-mmi)
const mmiAccountAddress =
metamaskState.custodyAccountDetails &&
Object.keys(metamaskState.custodyAccountDetails).length
? Object.keys(metamaskState.custodyAccountDetails)[0]
metamaskState.CustodyController.custodyAccountDetails &&
Object.keys(metamaskState.CustodyController.custodyAccountDetails).length
? Object.keys(metamaskState.CustodyController.custodyAccountDetails)[0]
: null;
///: END:ONLY_INCLUDE_IF
const { traits, previousUserTraits } = this.state;

const currentTraits = {
[MetaMetricsUserTrait.AddressBookEntries]: sum(
Object.values(metamaskState.addressBook).map(size),
Object.values(metamaskState.AddressBookController.addressBook).map(
size,
),
),
[MetaMetricsUserTrait.InstallDateExt]:
traits[MetaMetricsUserTrait.InstallDateExt] || '',
[MetaMetricsUserTrait.LedgerConnectionType]:
metamaskState.ledgerTransportType,
metamaskState.PreferencesController.ledgerTransportType,
[MetaMetricsUserTrait.NetworksAdded]: Object.values(
metamaskState.networkConfigurationsByChainId,
metamaskState.NetworkController.networkConfigurationsByChainId,
).map((networkConfiguration) => networkConfiguration.chainId),
[MetaMetricsUserTrait.NetworksWithoutTicker]: Object.values(
metamaskState.networkConfigurationsByChainId,
metamaskState.NetworkController.networkConfigurationsByChainId,
)
.filter(({ nativeCurrency }) => !nativeCurrency)
.map(({ chainId }) => chainId),
[MetaMetricsUserTrait.NftAutodetectionEnabled]:
metamaskState.useNftDetection,
metamaskState.PreferencesController.useNftDetection,
[MetaMetricsUserTrait.NumberOfAccounts]: Object.values(
metamaskState.internalAccounts.accounts,
metamaskState.AccountsController.internalAccounts.accounts,
).length,
[MetaMetricsUserTrait.NumberOfNftCollections]:
this.#getAllUniqueNFTAddressesLength(metamaskState.allNfts),
this.#getAllUniqueNFTAddressesLength(
metamaskState.NftController.allNfts,
),
[MetaMetricsUserTrait.NumberOfNfts]: this.#getAllNFTsFlattened(
metamaskState.allNfts,
metamaskState.NftController.allNfts,
).length,
[MetaMetricsUserTrait.NumberOfTokens]: this.#getNumberOfTokens(
metamaskState.allTokens,
metamaskState.TokensController.allTokens,
),
[MetaMetricsUserTrait.OpenSeaApiEnabled]: metamaskState.openSeaEnabled,
[MetaMetricsUserTrait.OpenSeaApiEnabled]:
metamaskState.PreferencesController.openSeaEnabled,
[MetaMetricsUserTrait.ThreeBoxEnabled]: false, // deprecated, hard-coded as false
[MetaMetricsUserTrait.Theme]: metamaskState.theme || 'default',
[MetaMetricsUserTrait.Theme]:
metamaskState.PreferencesController.theme || 'default',
[MetaMetricsUserTrait.TokenDetectionEnabled]:
metamaskState.useTokenDetection,
metamaskState.PreferencesController.useTokenDetection,
[MetaMetricsUserTrait.ShowNativeTokenAsMainBalance]:
metamaskState.ShowNativeTokenAsMainBalance,
[MetaMetricsUserTrait.CurrentCurrency]: metamaskState.currentCurrency,
metamaskState.PreferencesController.preferences
.showNativeTokenAsMainBalance,
[MetaMetricsUserTrait.CurrentCurrency]:
metamaskState.CurrencyController.currentCurrency,
///: BEGIN:ONLY_INCLUDE_IF(build-mmi)
[MetaMetricsUserTrait.MmiExtensionId]: this.#extension?.runtime?.id,
[MetaMetricsUserTrait.MmiAccountAddress]: mmiAccountAddress ?? null,
[MetaMetricsUserTrait.MmiIsCustodian]: Boolean(mmiAccountAddress),
///: END:ONLY_INCLUDE_IF
[MetaMetricsUserTrait.SecurityProviders]:
metamaskState.securityAlertsEnabled ? ['blockaid'] : [],
[MetaMetricsUserTrait.SecurityProviders]: metamaskState
.PreferencesController.securityAlertsEnabled
? ['blockaid']
: [],
[MetaMetricsUserTrait.PetnameAddressCount]:
this.#getPetnameAddressCount(metamaskState),
[MetaMetricsUserTrait.IsMetricsOptedIn]:
metamaskState.participateInMetaMetrics,
metamaskState.MetaMetricsController.participateInMetaMetrics,
[MetaMetricsUserTrait.HasMarketingConsent]:
metamaskState.dataCollectionForMarketing,
metamaskState.MetaMetricsController.dataCollectionForMarketing,
[MetaMetricsUserTrait.TokenSortPreference]:
metamaskState.tokenSortConfig?.key || '',
metamaskState.PreferencesController.preferences.tokenSortConfig?.key ||
'',
[MetaMetricsUserTrait.PrivacyModeEnabled]:
metamaskState.preferences.privacyMode,
metamaskState.PreferencesController.preferences.privacyMode,
[MetaMetricsUserTrait.NetworkFilterPreference]: Object.keys(
metamaskState.preferences.tokenNetworkFilter || {},
metamaskState.PreferencesController.preferences.tokenNetworkFilter ||
{},
),
};

Expand Down Expand Up @@ -1299,11 +1271,15 @@ export default class MetaMetricsController extends BaseController<
*
* @param allNfts
*/
#getAllNFTsFlattened = memoize((allNfts: MetaMaskState['allNfts'] = {}) => {
return Object.values(allNfts).reduce((result: Nft[], chainNFTs) => {
return result.concat(...Object.values(chainNFTs));
}, []);
});
#getAllNFTsFlattened = memoize(
(
allNfts: MemStoreControllersComposedState['NftController']['allNfts'] = {},
) => {
return Object.values(allNfts).reduce((result: Nft[], chainNFTs) => {
return result.concat(...Object.values(chainNFTs));
}, []);
},
);

/**
* Returns the number of unique NFT addresses the user
Expand All @@ -1312,7 +1288,7 @@ export default class MetaMetricsController extends BaseController<
* @param allNfts
*/
#getAllUniqueNFTAddressesLength(
allNfts: MetaMaskState['allNfts'] = {},
allNfts: MemStoreControllersComposedState['NftController']['allNfts'] = {},
): number {
const allNFTAddresses = this.#getAllNFTsFlattened(allNfts).map(
(nft) => nft.address,
Expand All @@ -1325,7 +1301,9 @@ export default class MetaMetricsController extends BaseController<
* @param allTokens
* @returns number of unique token addresses
*/
#getNumberOfTokens(allTokens: MetaMaskState['allTokens']): number {
#getNumberOfTokens(
allTokens: MemStoreControllersComposedState['TokensController']['allTokens'],
): number {
return Object.values(allTokens).reduce((result, accountsByChain) => {
return result + sum(Object.values(accountsByChain).map(size));
}, 0);
Expand Down Expand Up @@ -1549,8 +1527,11 @@ export default class MetaMetricsController extends BaseController<
*
* @param metamaskState
*/
#getPetnameAddressCount(metamaskState: MetaMaskState): number {
const addressNames = metamaskState.names?.[NameType.ETHEREUM_ADDRESS] ?? {};
#getPetnameAddressCount(
metamaskState: MemStoreControllersComposedState,
): number {
const addressNames =
metamaskState.NameController.names?.[NameType.ETHEREUM_ADDRESS] ?? {};

return Object.keys(addressNames).reduce((totalCount, address) => {
const addressEntry = addressNames[address];
Expand Down
4 changes: 2 additions & 2 deletions shared/constants/metametrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -455,11 +455,11 @@ export type MetaMetricsUserTraits = {
/**
* Does the user opt in for metrics
*/
is_metrics_opted_in?: boolean;
is_metrics_opted_in?: boolean | null;
/**
* Does the user accepted marketing consent
*/
has_marketing_consent?: boolean;
has_marketing_consent?: boolean | null;
/**
* The date the extension was installed.
*/
Expand Down
27 changes: 25 additions & 2 deletions ui/ducks/metamask/constants.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { Preferences } from '../../../app/scripts/controllers/preferences-controller';
import { NameControllerState } from '@metamask/name-controller';
import {
getDefaultPreferencesControllerState,
Preferences,
} from '../../../app/scripts/controllers/preferences-controller';
import { MemStoreControllersComposedState } from '../../../app/scripts/metamask-controller-stores';
import { DEFAULT_AUTO_LOCK_TIME_LIMIT } from '../../../shared/constants/preferences';
import {
DEFAULT_AUTO_LOCK_TIME_LIMIT,
ThemeType,
} from '../../../shared/constants/preferences';

export const initialMetamaskState: Partial<{
[ControllerName in keyof MemStoreControllersComposedState]: Partial<
Expand All @@ -26,6 +33,7 @@ export const initialMetamaskState: Partial<{
approvalFlows: [],
},
CurrencyController: {
currentCurrency: 'usd',
currencyRates: {
ETH: {
conversionRate: null,
Expand All @@ -50,18 +58,29 @@ export const initialMetamaskState: Partial<{
participateInMetaMetrics: null,
dataCollectionForMarketing: null,
},
NameController: {
names: {} as NameControllerState['names'],
},
NetworkController: {
selectedNetworkClientId: '',
networkConfigurationsByChainId: {},
networksMetadata: {},
},
NftController: {
allNfts: {},
},
OnboardingController: {
firstTimeFlowType: null,
completedOnboarding: false,
},
PreferencesController: {
theme: ThemeType.os,
useBlockie: false,
use4ByteResolution: true,
useNftDetection: false,
useTokenDetection: true,
openSeaEnabled: false,
securityAlertsEnabled: false,
featureFlags: {},
currentLocale: '',
knownMethodData: {},
Expand All @@ -70,13 +89,17 @@ export const initialMetamaskState: Partial<{
autoLockTimeLimit: DEFAULT_AUTO_LOCK_TIME_LIMIT,
showExtensionInFullSizeView: false,
showFiatInTestnets: false,
showNativeTokenAsMainBalance: true,
showTestNetworks: false,
smartTransactionsOptInStatus: true,
petnamesEnabled: true,
featureNotificationsEnabled: false,
privacyMode: false,
showMultiRpcModal: false,
tokenSortConfig: {},
tokenNetworkFilter: {},
} as Preferences,
...getDefaultPreferencesControllerState(),
},
SignatureController: {
unapprovedPersonalMsgs: {},
Expand Down

0 comments on commit 25a6496

Please sign in to comment.