mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 01:47:00 +01:00
Event tracking for Token Detection V2 (#14441)
This commit is contained in:
parent
4b2cd0ef7a
commit
6c757ab5e0
@ -6,6 +6,9 @@ import { MINUTE } from '../../../shared/constants/time';
|
||||
import { MAINNET_CHAIN_ID } from '../../../shared/constants/network';
|
||||
import { isTokenDetectionEnabledForNetwork } from '../../../shared/modules/network.utils';
|
||||
import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
|
||||
import { TOKEN_STANDARDS } from '../../../ui/helpers/constants/common';
|
||||
import { ASSET_TYPES } from '../../../shared/constants/transaction';
|
||||
import { EVENT, EVENT_NAMES } from '../../../shared/constants/metametrics';
|
||||
|
||||
// By default, poll every 3 minutes
|
||||
const DEFAULT_INTERVAL = MINUTE * 3;
|
||||
@ -26,6 +29,7 @@ export default class DetectTokensController {
|
||||
* @param config.tokenList
|
||||
* @param config.tokensController
|
||||
* @param config.assetsContractController
|
||||
* @param config.trackMetaMetricsEvent
|
||||
*/
|
||||
constructor({
|
||||
interval = DEFAULT_INTERVAL,
|
||||
@ -35,6 +39,7 @@ export default class DetectTokensController {
|
||||
tokenList,
|
||||
tokensController,
|
||||
assetsContractController = null,
|
||||
trackMetaMetricsEvent,
|
||||
} = {}) {
|
||||
this.assetsContractController = assetsContractController;
|
||||
this.tokensController = tokensController;
|
||||
@ -51,6 +56,7 @@ export default class DetectTokensController {
|
||||
this.detectedTokens = process.env.TOKEN_DETECTION_V2
|
||||
? this.tokensController?.state.detectedTokens
|
||||
: [];
|
||||
this._trackMetaMetricsEvent = trackMetaMetricsEvent;
|
||||
|
||||
preferences?.store.subscribe(({ selectedAddress, useTokenDetection }) => {
|
||||
if (
|
||||
@ -162,6 +168,7 @@ export default class DetectTokensController {
|
||||
|
||||
let tokensWithBalance = [];
|
||||
if (process.env.TOKEN_DETECTION_V2) {
|
||||
const eventTokensDetails = [];
|
||||
if (result) {
|
||||
const nonZeroTokenAddresses = Object.keys(result);
|
||||
for (const nonZeroTokenAddress of nonZeroTokenAddresses) {
|
||||
@ -172,6 +179,9 @@ export default class DetectTokensController {
|
||||
iconUrl,
|
||||
aggregators,
|
||||
} = tokenList[nonZeroTokenAddress];
|
||||
|
||||
eventTokensDetails.push(`${symbol} - ${address}`);
|
||||
|
||||
tokensWithBalance.push({
|
||||
address,
|
||||
symbol,
|
||||
@ -180,7 +190,17 @@ export default class DetectTokensController {
|
||||
aggregators,
|
||||
});
|
||||
}
|
||||
|
||||
if (tokensWithBalance.length > 0) {
|
||||
this._trackMetaMetricsEvent({
|
||||
event: EVENT_NAMES.TOKEN_DETECTED,
|
||||
category: EVENT.CATEGORIES.WALLET,
|
||||
properties: {
|
||||
tokens: eventTokensDetails,
|
||||
token_standard: TOKEN_STANDARDS.ERC20,
|
||||
asset_type: ASSET_TYPES.TOKEN,
|
||||
},
|
||||
});
|
||||
await this.tokensController.addDetectedTokens(tokensWithBalance);
|
||||
}
|
||||
}
|
||||
|
@ -571,6 +571,7 @@ export default class MetaMetricsController {
|
||||
[TRAITS.OPENSEA_API_ENABLED]: metamaskState.openSeaEnabled,
|
||||
[TRAITS.THREE_BOX_ENABLED]: metamaskState.threeBoxSyncingAllowed,
|
||||
[TRAITS.THEME]: metamaskState.theme || 'default',
|
||||
[TRAITS.TOKEN_DETECTION_ENABLED]: metamaskState.useTokenDetection,
|
||||
};
|
||||
|
||||
if (!this.previousTraits) {
|
||||
|
@ -682,6 +682,7 @@ describe('MetaMetricsController', function () {
|
||||
threeBoxSyncingAllowed: false,
|
||||
useCollectibleDetection: false,
|
||||
theme: 'default',
|
||||
useTokenDetection: true,
|
||||
});
|
||||
|
||||
assert.deepEqual(traits, {
|
||||
@ -696,6 +697,7 @@ describe('MetaMetricsController', function () {
|
||||
[TRAITS.OPENSEA_API_ENABLED]: true,
|
||||
[TRAITS.THREE_BOX_ENABLED]: false,
|
||||
[TRAITS.THEME]: 'default',
|
||||
[TRAITS.TOKEN_DETECTION_ENABLED]: true,
|
||||
});
|
||||
});
|
||||
|
||||
@ -717,6 +719,7 @@ describe('MetaMetricsController', function () {
|
||||
threeBoxSyncingAllowed: false,
|
||||
useCollectibleDetection: false,
|
||||
theme: 'default',
|
||||
useTokenDetection: true,
|
||||
});
|
||||
|
||||
const updatedTraits = metaMetricsController._buildUserTraitsObject({
|
||||
@ -737,6 +740,7 @@ describe('MetaMetricsController', function () {
|
||||
threeBoxSyncingAllowed: false,
|
||||
useCollectibleDetection: false,
|
||||
theme: 'default',
|
||||
useTokenDetection: true,
|
||||
});
|
||||
|
||||
assert.deepEqual(updatedTraits, {
|
||||
@ -765,6 +769,7 @@ describe('MetaMetricsController', function () {
|
||||
threeBoxSyncingAllowed: false,
|
||||
useCollectibleDetection: true,
|
||||
theme: 'default',
|
||||
useTokenDetection: true,
|
||||
});
|
||||
|
||||
const updatedTraits = metaMetricsController._buildUserTraitsObject({
|
||||
@ -783,6 +788,7 @@ describe('MetaMetricsController', function () {
|
||||
threeBoxSyncingAllowed: false,
|
||||
useCollectibleDetection: true,
|
||||
theme: 'default',
|
||||
useTokenDetection: true,
|
||||
});
|
||||
|
||||
assert.equal(updatedTraits, null);
|
||||
|
@ -1470,7 +1470,7 @@ describe('Transaction Controller', function () {
|
||||
gas_edit_type: 'none',
|
||||
network: '42',
|
||||
referrer: ORIGIN_METAMASK,
|
||||
source: 'user',
|
||||
source: EVENT.SOURCE.TRANSACTION.USER,
|
||||
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
||||
account_type: 'MetaMask',
|
||||
asset_type: ASSET_TYPES.NATIVE,
|
||||
@ -1549,7 +1549,7 @@ describe('Transaction Controller', function () {
|
||||
gas_edit_type: 'none',
|
||||
network: '42',
|
||||
referrer: ORIGIN_METAMASK,
|
||||
source: 'user',
|
||||
source: EVENT.SOURCE.TRANSACTION.USER,
|
||||
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
||||
account_type: 'MetaMask',
|
||||
asset_type: ASSET_TYPES.NATIVE,
|
||||
@ -1638,7 +1638,7 @@ describe('Transaction Controller', function () {
|
||||
gas_edit_type: 'none',
|
||||
network: '42',
|
||||
referrer: 'other',
|
||||
source: 'dapp',
|
||||
source: EVENT.SOURCE.TRANSACTION.DAPP,
|
||||
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
||||
account_type: 'MetaMask',
|
||||
asset_type: ASSET_TYPES.NATIVE,
|
||||
@ -1719,7 +1719,7 @@ describe('Transaction Controller', function () {
|
||||
gas_edit_type: 'none',
|
||||
network: '42',
|
||||
referrer: 'other',
|
||||
source: 'dapp',
|
||||
source: EVENT.SOURCE.TRANSACTION.DAPP,
|
||||
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
||||
account_type: 'MetaMask',
|
||||
asset_type: ASSET_TYPES.NATIVE,
|
||||
@ -1800,7 +1800,7 @@ describe('Transaction Controller', function () {
|
||||
gas_edit_type: 'none',
|
||||
network: '42',
|
||||
referrer: 'other',
|
||||
source: 'dapp',
|
||||
source: EVENT.SOURCE.TRANSACTION.DAPP,
|
||||
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
||||
account_type: 'MetaMask',
|
||||
asset_type: ASSET_TYPES.NATIVE,
|
||||
@ -1859,7 +1859,7 @@ describe('Transaction Controller', function () {
|
||||
properties: {
|
||||
network: '42',
|
||||
referrer: 'other',
|
||||
source: 'dapp',
|
||||
source: EVENT.SOURCE.TRANSACTION.DAPP,
|
||||
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
||||
chain_id: '0x2a',
|
||||
eip_1559_version: '0',
|
||||
@ -1936,7 +1936,7 @@ describe('Transaction Controller', function () {
|
||||
gas_edit_type: 'none',
|
||||
network: '42',
|
||||
referrer: 'other',
|
||||
source: 'dapp',
|
||||
source: EVENT.SOURCE.TRANSACTION.DAPP,
|
||||
type: TRANSACTION_TYPES.SIMPLE_SEND,
|
||||
account_type: 'MetaMask',
|
||||
asset_type: ASSET_TYPES.NATIVE,
|
||||
|
@ -265,7 +265,7 @@ async function addEthereumChainHandler(
|
||||
network: firstValidRPCUrl,
|
||||
symbol: ticker,
|
||||
block_explorer_url: firstValidBlockExplorerUrl,
|
||||
source: 'dapp',
|
||||
source: EVENT.SOURCE.TRANSACTION.DAPP,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -713,6 +713,9 @@ export default class MetamaskController extends EventEmitter {
|
||||
network: this.networkController,
|
||||
keyringMemStore: this.keyringController.memStore,
|
||||
tokenList: this.tokenListController,
|
||||
trackMetaMetricsEvent: this.metaMetricsController.trackEvent.bind(
|
||||
this.metaMetricsController,
|
||||
),
|
||||
}))
|
||||
: (this.detectTokensController = new DetectTokensController({
|
||||
preferences: this.preferencesController,
|
||||
|
@ -178,6 +178,8 @@
|
||||
* @property {'three_box_enabled'} THREE_BOX_ENABLED - when 3box feature is
|
||||
* toggled we identify the 3box_enabled trait
|
||||
* @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
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -197,6 +199,7 @@ export const TRAITS = {
|
||||
OPENSEA_API_ENABLED: 'opensea_api_enabled',
|
||||
THREE_BOX_ENABLED: 'three_box_enabled',
|
||||
THEME: 'theme',
|
||||
TOKEN_DETECTION_ENABLED: 'token_detection_enabled',
|
||||
};
|
||||
|
||||
/**
|
||||
@ -222,6 +225,7 @@ export const TRAITS = {
|
||||
* @property {boolean} [three_box_enabled] - does the user have 3box sync
|
||||
* enabled?
|
||||
* @property {string} [theme] - which theme the user has selected
|
||||
* @property {boolean} [token_detection_enabled] - does the user have token detection is enabled?
|
||||
*/
|
||||
|
||||
// Mixpanel converts the zero address value to a truly anonymous event, which
|
||||
@ -265,10 +269,15 @@ export const REJECT_NOTFICIATION_CLOSE_SIG =
|
||||
*/
|
||||
|
||||
export const EVENT_NAMES = {
|
||||
SIGNATURE_REQUESTED: 'Signature Requested',
|
||||
ENCRYPTION_PUBLIC_KEY_REQUESTED: 'Encryption Public Key Requested',
|
||||
DECRYPTION_REQUESTED: 'Decryption Requested',
|
||||
PERMISSIONS_REQUESTED: 'Permissions Requested',
|
||||
SIGNATURE_REQUESTED: 'Signature Requested',
|
||||
TOKEN_ADDED: 'Token Added',
|
||||
TOKEN_DETECTED: 'Token Detected',
|
||||
TOKEN_HIDDEN: 'Token Hidden',
|
||||
TOKEN_IMPORT_CANCELED: 'Token Import Canceled',
|
||||
TOKEN_IMPORT_CLICKED: 'Token Import Clicked',
|
||||
};
|
||||
|
||||
export const EVENT = {
|
||||
@ -288,4 +297,25 @@ export const EVENT = {
|
||||
TRANSACTIONS: 'Transactions',
|
||||
WALLET: 'Wallet',
|
||||
},
|
||||
SOURCE: {
|
||||
SWAPS: {
|
||||
MAIN_VIEW: 'Main View',
|
||||
TOKEN_VIEW: 'Token View',
|
||||
},
|
||||
TRANSACTION: {
|
||||
USER: 'user',
|
||||
DAPP: 'dapp',
|
||||
},
|
||||
TOKEN: {
|
||||
CUSTOM: 'custom',
|
||||
DETECTED: 'detected',
|
||||
DAPP: 'dapp',
|
||||
LIST: 'list',
|
||||
},
|
||||
},
|
||||
LOCATION: {
|
||||
TOKEN_DETECTION: 'token_detection',
|
||||
TOKEN_MENU: 'token_menu',
|
||||
TOKEN_DETAILS: 'token_details',
|
||||
},
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { useContext } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
@ -7,11 +7,32 @@ import Box from '../../../ui/box/box';
|
||||
import Button from '../../../ui/button';
|
||||
import { useI18nContext } from '../../../../hooks/useI18nContext';
|
||||
import { getDetectedTokensInCurrentNetwork } from '../../../../selectors';
|
||||
import { MetaMetricsContext } from '../../../../contexts/metametrics';
|
||||
import {
|
||||
EVENT,
|
||||
EVENT_NAMES,
|
||||
} from '../../../../../shared/constants/metametrics';
|
||||
|
||||
const DetectedTokensLink = ({ className = '', setShowDetectedTokens }) => {
|
||||
const t = useI18nContext();
|
||||
const detectedTokens = useSelector(getDetectedTokensInCurrentNetwork);
|
||||
const trackEvent = useContext(MetaMetricsContext);
|
||||
|
||||
const detectedTokens = useSelector(getDetectedTokensInCurrentNetwork);
|
||||
const detectedTokensDetails = detectedTokens.map(
|
||||
({ address, symbol }) => `${symbol} - ${address}`,
|
||||
);
|
||||
|
||||
const onClick = () => {
|
||||
setShowDetectedTokens(true);
|
||||
trackEvent({
|
||||
event: EVENT_NAMES.TOKEN_IMPORT_CLICKED,
|
||||
category: EVENT.CATEGORIES.WALLET,
|
||||
properties: {
|
||||
source: EVENT.SOURCE.TOKEN.DETECTED,
|
||||
tokens: detectedTokensDetails,
|
||||
},
|
||||
});
|
||||
};
|
||||
return (
|
||||
<Box
|
||||
className={classNames('detected-tokens-link', className)}
|
||||
@ -20,7 +41,7 @@ const DetectedTokensLink = ({ className = '', setShowDetectedTokens }) => {
|
||||
<Button
|
||||
type="link"
|
||||
className="detected-tokens-link__link"
|
||||
onClick={() => setShowDetectedTokens(true)}
|
||||
onClick={onClick}
|
||||
>
|
||||
{t('numberOfNewTokensDetected', [detectedTokens.length])}
|
||||
</Button>
|
||||
|
@ -0,0 +1,28 @@
|
||||
import React from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
import testData from '../../../../../.storybook/test-data';
|
||||
import configureStore from '../../../../store/store';
|
||||
import DetectedTokensLink from './detected-tokens-link';
|
||||
|
||||
const store = configureStore(testData);
|
||||
|
||||
export default {
|
||||
title: 'Components/App/AssetList/DetectedTokensLink',
|
||||
decorators: [(story) => <Provider store={store}>{story()}</Provider>],
|
||||
id: __filename,
|
||||
argTypes: {
|
||||
setShowDetectedTokens: { control: 'func' },
|
||||
},
|
||||
args: {
|
||||
setShowDetectedTokens: 'setShowDetectedTokensSpy',
|
||||
},
|
||||
};
|
||||
|
||||
const Template = (args) => {
|
||||
return <DetectedTokensLink {...args} />;
|
||||
};
|
||||
|
||||
export const DefaultStory = Template.bind({});
|
||||
|
||||
DefaultStory.storyName = 'Default';
|
@ -0,0 +1,32 @@
|
||||
import * as React from 'react';
|
||||
import {
|
||||
renderWithProvider,
|
||||
screen,
|
||||
fireEvent,
|
||||
} from '../../../../../test/jest';
|
||||
import configureStore from '../../../../store/store';
|
||||
import testData from '../../../../../.storybook/test-data';
|
||||
|
||||
import DetectedTokensLink from './detected-tokens-link';
|
||||
|
||||
describe('DetectedTokensLink', () => {
|
||||
let setShowDetectedTokensSpy;
|
||||
const args = {};
|
||||
|
||||
beforeEach(() => {
|
||||
setShowDetectedTokensSpy = jest.fn();
|
||||
args.setShowDetectedTokens = setShowDetectedTokensSpy;
|
||||
});
|
||||
|
||||
it('should render number of tokens detected link', () => {
|
||||
const store = configureStore(testData);
|
||||
renderWithProvider(<DetectedTokensLink {...args} />, store);
|
||||
|
||||
expect(
|
||||
screen.getByText('3 new tokens found in this account'),
|
||||
).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(screen.getByText('3 new tokens found in this account'));
|
||||
expect(setShowDetectedTokensSpy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
@ -1,8 +1,13 @@
|
||||
import React from 'react';
|
||||
import React, { useContext } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { useI18nContext } from '../../../../hooks/useI18nContext';
|
||||
import { MetaMetricsContext } from '../../../../contexts/metametrics';
|
||||
import {
|
||||
EVENT,
|
||||
EVENT_NAMES,
|
||||
} from '../../../../../shared/constants/metametrics';
|
||||
import { getDetectedTokensInCurrentNetwork } from '../../../../selectors';
|
||||
|
||||
import Popover from '../../../ui/popover';
|
||||
@ -19,6 +24,7 @@ const DetectedTokenSelectionPopover = ({
|
||||
sortingBasedOnTokenSelection,
|
||||
}) => {
|
||||
const t = useI18nContext();
|
||||
const trackEvent = useContext(MetaMetricsContext);
|
||||
|
||||
const detectedTokens = useSelector(getDetectedTokensInCurrentNetwork);
|
||||
const { selected: selectedTokens = [] } = sortingBasedOnTokenSelection(
|
||||
@ -31,6 +37,17 @@ const DetectedTokenSelectionPopover = ({
|
||||
|
||||
const onClose = () => {
|
||||
setShowDetectedTokens(false);
|
||||
const eventTokensDetails = detectedTokens.map(
|
||||
({ address, symbol }) => `${symbol} - ${address}`,
|
||||
);
|
||||
trackEvent({
|
||||
event: EVENT_NAMES.TOKEN_IMPORT_CANCELED,
|
||||
category: EVENT.CATEGORIES.WALLET,
|
||||
properties: {
|
||||
source: EVENT.SOURCE.TOKEN.DETECTED,
|
||||
tokens: eventTokensDetails,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const footer = (
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useContext } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import { chain } from 'lodash';
|
||||
@ -9,7 +9,11 @@ import {
|
||||
setNewTokensImported,
|
||||
} from '../../../store/actions';
|
||||
import { getDetectedTokensInCurrentNetwork } from '../../../selectors';
|
||||
import { MetaMetricsContext } from '../../../contexts/metametrics';
|
||||
|
||||
import { TOKEN_STANDARDS } from '../../../helpers/constants/common';
|
||||
import { ASSET_TYPES } from '../../../../shared/constants/transaction';
|
||||
import { EVENT, EVENT_NAMES } 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';
|
||||
|
||||
@ -26,8 +30,10 @@ const sortingBasedOnTokenSelection = (tokensDetected) => {
|
||||
.value()
|
||||
);
|
||||
};
|
||||
|
||||
const DetectedToken = ({ setShowDetectedTokens }) => {
|
||||
const dispatch = useDispatch();
|
||||
const trackEvent = useContext(MetaMetricsContext);
|
||||
|
||||
const detectedTokens = useSelector(getDetectedTokensInCurrentNetwork);
|
||||
|
||||
@ -42,21 +48,49 @@ const DetectedToken = ({ setShowDetectedTokens }) => {
|
||||
setShowDetectedTokenIgnoredPopover,
|
||||
] = useState(false);
|
||||
|
||||
const importSelectedTokens = async (selectedTokens) => {
|
||||
selectedTokens.forEach((importedToken) => {
|
||||
trackEvent({
|
||||
event: EVENT_NAMES.TOKEN_ADDED,
|
||||
category: EVENT.CATEGORIES.WALLET,
|
||||
sensitiveProperties: {
|
||||
token_symbol: importedToken.symbol,
|
||||
token_contract_address: importedToken.address,
|
||||
token_decimal_precision: importedToken.decimals,
|
||||
source: EVENT.SOURCE.TOKEN.DETECTED,
|
||||
token_standard: TOKEN_STANDARDS.ERC20,
|
||||
asset_type: ASSET_TYPES.TOKEN,
|
||||
},
|
||||
});
|
||||
});
|
||||
await dispatch(importTokens(selectedTokens));
|
||||
const tokenSymbols = selectedTokens.map(({ symbol }) => symbol);
|
||||
dispatch(setNewTokensImported(tokenSymbols.join(', ')));
|
||||
};
|
||||
|
||||
const handleClearTokensSelection = async () => {
|
||||
// create a lodash chain on this object
|
||||
const {
|
||||
selected: selectedTokens,
|
||||
deselected: deSelectedTokens,
|
||||
selected: selectedTokens = [],
|
||||
deselected: deSelectedTokens = [],
|
||||
} = sortingBasedOnTokenSelection(tokensListDetected);
|
||||
|
||||
if (deSelectedTokens.length < detectedTokens.length) {
|
||||
await dispatch(ignoreTokens(deSelectedTokens));
|
||||
await dispatch(importTokens(selectedTokens));
|
||||
const tokenSymbols = selectedTokens.map(({ symbol }) => symbol);
|
||||
dispatch(setNewTokensImported(tokenSymbols.join(', ')));
|
||||
} else {
|
||||
await dispatch(ignoreTokens(deSelectedTokens));
|
||||
await importSelectedTokens(selectedTokens);
|
||||
}
|
||||
const tokensDetailsList = deSelectedTokens.map(
|
||||
({ symbol, address }) => `${symbol} - ${address}`,
|
||||
);
|
||||
trackEvent({
|
||||
event: EVENT_NAMES.TOKEN_HIDDEN,
|
||||
category: EVENT.CATEGORIES.WALLET,
|
||||
sensitiveProperties: {
|
||||
tokens: tokensDetailsList,
|
||||
location: EVENT.LOCATION.TOKEN_DETECTION,
|
||||
token_standard: TOKEN_STANDARDS.ERC20,
|
||||
asset_type: ASSET_TYPES.TOKEN,
|
||||
},
|
||||
});
|
||||
await dispatch(ignoreTokens(deSelectedTokens));
|
||||
setShowDetectedTokens(false);
|
||||
};
|
||||
|
||||
@ -71,17 +105,14 @@ const DetectedToken = ({ setShowDetectedTokens }) => {
|
||||
};
|
||||
|
||||
const onImport = async () => {
|
||||
// create a lodash chain on this object
|
||||
const { selected: selectedTokens } = sortingBasedOnTokenSelection(
|
||||
const { selected: selectedTokens = [] } = sortingBasedOnTokenSelection(
|
||||
tokensListDetected,
|
||||
);
|
||||
|
||||
if (selectedTokens.length < detectedTokens.length) {
|
||||
setShowDetectedTokenIgnoredPopover(true);
|
||||
} else {
|
||||
const tokenSymbols = selectedTokens.map(({ symbol }) => symbol);
|
||||
await dispatch(importTokens(selectedTokens));
|
||||
dispatch(setNewTokensImported(tokenSymbols.join(', ')));
|
||||
await importSelectedTokens(selectedTokens);
|
||||
setShowDetectedTokens(false);
|
||||
}
|
||||
};
|
||||
|
@ -136,7 +136,7 @@ const EthOverview = ({ className }) => {
|
||||
event: 'Swaps Opened',
|
||||
category: EVENT.CATEGORIES.SWAPS,
|
||||
properties: {
|
||||
source: 'Main View',
|
||||
source: EVENT.SOURCE.SWAPS.MAIN_VIEW,
|
||||
active_currency: 'ETH',
|
||||
},
|
||||
});
|
||||
|
@ -120,7 +120,7 @@ const TokenOverview = ({ className, token }) => {
|
||||
event: 'Swaps Opened',
|
||||
category: EVENT.CATEGORIES.SWAPS,
|
||||
properties: {
|
||||
source: 'Token View',
|
||||
source: EVENT.SOURCE.SWAPS.TOKEN_VIEW,
|
||||
active_currency: token.symbol,
|
||||
},
|
||||
});
|
||||
|
@ -27,6 +27,7 @@ import { getCollectiblesDetectionNoticeDismissed } from '../../ducks/metamask/me
|
||||
import CollectiblesDetectionNotice from '../../components/app/collectibles-detection-notice';
|
||||
import { MetaMetricsContext } from '../../contexts/metametrics';
|
||||
import { ASSET_TYPES } from '../../../shared/constants/transaction';
|
||||
import { EVENT, EVENT_NAMES } from '../../../shared/constants/metametrics';
|
||||
|
||||
export default function AddCollectible() {
|
||||
const t = useI18nContext();
|
||||
@ -77,7 +78,7 @@ export default function AddCollectible() {
|
||||
);
|
||||
|
||||
trackEvent({
|
||||
event: 'Token Added',
|
||||
event: EVENT_NAMES.TOKEN_ADDED,
|
||||
category: 'Wallet',
|
||||
sensitiveProperties: {
|
||||
token_contract_address: address,
|
||||
@ -85,7 +86,7 @@ export default function AddCollectible() {
|
||||
tokenId: tokenId.toString(),
|
||||
asset_type: ASSET_TYPES.COLLECTIBLE,
|
||||
token_standard: tokenDetails?.standard,
|
||||
source: 'custom',
|
||||
source: EVENT.SOURCE.TOKEN.CUSTOM,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -14,7 +14,7 @@ import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils';
|
||||
import { getSuggestedAssets } from '../../selectors';
|
||||
import { rejectWatchAsset, acceptWatchAsset } from '../../store/actions';
|
||||
import { TOKEN_STANDARDS } from '../../helpers/constants/common';
|
||||
import { EVENT } from '../../../shared/constants/metametrics';
|
||||
import { EVENT, EVENT_NAMES } from '../../../shared/constants/metametrics';
|
||||
import { ASSET_TYPES } from '../../../shared/constants/transaction';
|
||||
|
||||
function getTokenName(name, symbol) {
|
||||
@ -115,14 +115,14 @@ const ConfirmAddSuggestedToken = () => {
|
||||
await dispatch(acceptWatchAsset(id));
|
||||
|
||||
trackEvent({
|
||||
event: 'Token Added',
|
||||
event: EVENT_NAMES.TOKEN_ADDED,
|
||||
category: EVENT.CATEGORIES.WALLET,
|
||||
sensitiveProperties: {
|
||||
token_symbol: asset.symbol,
|
||||
token_contract_address: asset.address,
|
||||
token_decimal_precision: asset.decimals,
|
||||
unlisted: asset.unlisted,
|
||||
source: 'dapp',
|
||||
source: EVENT.SOURCE.TOKEN.DAPP,
|
||||
token_standard: TOKEN_STANDARDS.ERC20,
|
||||
asset_type: ASSET_TYPES.TOKEN,
|
||||
},
|
||||
|
@ -13,7 +13,8 @@ import { MetaMetricsContext } from '../../contexts/metametrics';
|
||||
import { getMostRecentOverviewPage } from '../../ducks/history/history';
|
||||
import { getPendingTokens } from '../../ducks/metamask/metamask';
|
||||
import { addTokens, clearPendingTokens } from '../../store/actions';
|
||||
import { EVENT } from '../../../shared/constants/metametrics';
|
||||
import { TOKEN_STANDARDS } from '../../helpers/constants/common';
|
||||
import { EVENT, EVENT_NAMES } from '../../../shared/constants/metametrics';
|
||||
import { ASSET_TYPES } from '../../../shared/constants/transaction';
|
||||
|
||||
const getTokenName = (name, symbol) => {
|
||||
@ -37,15 +38,17 @@ const ConfirmImportToken = () => {
|
||||
|
||||
addedTokenValues.forEach((pendingToken) => {
|
||||
trackEvent({
|
||||
event: 'Token Added',
|
||||
event: EVENT_NAMES.TOKEN_ADDED,
|
||||
category: EVENT.CATEGORIES.WALLET,
|
||||
sensitiveProperties: {
|
||||
token_symbol: pendingToken.symbol,
|
||||
token_contract_address: pendingToken.address,
|
||||
token_decimal_precision: pendingToken.decimals,
|
||||
unlisted: pendingToken.unlisted,
|
||||
source: pendingToken.isCustom ? 'custom' : 'list',
|
||||
token_standard: pendingToken.standard,
|
||||
source: pendingToken.isCustom
|
||||
? EVENT.SOURCE.TOKEN.CUSTOM
|
||||
: EVENT.SOURCE.TOKEN.LIST,
|
||||
token_standard: TOKEN_STANDARDS.ERC20,
|
||||
asset_type: ASSET_TYPES.TOKEN,
|
||||
},
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user