mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 09:57:02 +01:00
UX: Multichain: Analytics (#18674)
This commit is contained in:
parent
bbb35dbe8d
commit
e339afce7a
@ -458,6 +458,7 @@ export enum MetaMetricsEventName {
|
|||||||
AppInstalled = 'App Installed',
|
AppInstalled = 'App Installed',
|
||||||
AppUnlocked = 'App Unlocked',
|
AppUnlocked = 'App Unlocked',
|
||||||
AppUnlockedFailed = 'App Unlocked Failed',
|
AppUnlockedFailed = 'App Unlocked Failed',
|
||||||
|
AppLocked = 'App Locked',
|
||||||
AppWindowExpanded = 'App Window Expanded',
|
AppWindowExpanded = 'App Window Expanded',
|
||||||
BridgeLinkClicked = 'Bridge Link Clicked',
|
BridgeLinkClicked = 'Bridge Link Clicked',
|
||||||
DecryptionApproved = 'Decryption Approved',
|
DecryptionApproved = 'Decryption Approved',
|
||||||
@ -541,6 +542,17 @@ export enum MetaMetricsEventName {
|
|||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
UserClickedDeepLink = 'User clicked deeplink',
|
UserClickedDeepLink = 'User clicked deeplink',
|
||||||
///: END:ONLY_INCLUDE_IN
|
///: END:ONLY_INCLUDE_IN
|
||||||
|
AccountDetailMenuOpened = 'Account Details Menu Opened',
|
||||||
|
BlockExplorerLinkClicked = 'Block Explorer Clicked',
|
||||||
|
AccountRemoved = 'Account Removed',
|
||||||
|
TestNetworksDisplayed = 'Test Networks Displayed',
|
||||||
|
AddNetworkButtonClick = 'Add Network Button Clicked',
|
||||||
|
CustomNetworkAdded = 'Custom Network Added',
|
||||||
|
TokenDetailsOpened = 'Token Details Opened',
|
||||||
|
NftScreenOpened = 'NFT Screen Opened',
|
||||||
|
ActivityScreenOpened = 'Activity Screen Opened',
|
||||||
|
WhatsNewViewed = `What's New Viewed`,
|
||||||
|
WhatsNewClicked = `What's New Link Clicked`,
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum MetaMetricsEventAccountType {
|
export enum MetaMetricsEventAccountType {
|
||||||
@ -583,6 +595,7 @@ export enum MetaMetricsEventCategory {
|
|||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
MMI = 'Institutional',
|
MMI = 'Institutional',
|
||||||
///: END:ONLY_INCLUDE_IN
|
///: END:ONLY_INCLUDE_IN
|
||||||
|
Tokens = 'Tokens',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum MetaMetricsEventLinkType {
|
export enum MetaMetricsEventLinkType {
|
||||||
|
@ -34,7 +34,7 @@ describe('Portfolio site', function () {
|
|||||||
// Verify site
|
// Verify site
|
||||||
assert.equal(
|
assert.equal(
|
||||||
await driver.getCurrentUrl(),
|
await driver.getCurrentUrl(),
|
||||||
'http://127.0.0.1:8080/?metamaskEntry=ext',
|
'http://127.0.0.1:8080/?metamaskEntry=ext&metametricsId=null',
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -6,7 +6,10 @@ import classNames from 'classnames';
|
|||||||
import Box from '../../../ui/box/box';
|
import Box from '../../../ui/box/box';
|
||||||
import Button from '../../../ui/button';
|
import Button from '../../../ui/button';
|
||||||
import { useI18nContext } from '../../../../hooks/useI18nContext';
|
import { useI18nContext } from '../../../../hooks/useI18nContext';
|
||||||
import { getDetectedTokensInCurrentNetwork } from '../../../../selectors';
|
import {
|
||||||
|
getCurrentChainId,
|
||||||
|
getDetectedTokensInCurrentNetwork,
|
||||||
|
} from '../../../../selectors';
|
||||||
import { MetaMetricsContext } from '../../../../contexts/metametrics';
|
import { MetaMetricsContext } from '../../../../contexts/metametrics';
|
||||||
import {
|
import {
|
||||||
MetaMetricsEventCategory,
|
MetaMetricsEventCategory,
|
||||||
@ -23,13 +26,16 @@ const DetectedTokensLink = ({ className = '', setShowDetectedTokens }) => {
|
|||||||
({ address, symbol }) => `${symbol} - ${address}`,
|
({ address, symbol }) => `${symbol} - ${address}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const chainId = useSelector(getCurrentChainId);
|
||||||
|
|
||||||
const onClick = () => {
|
const onClick = () => {
|
||||||
setShowDetectedTokens(true);
|
setShowDetectedTokens(true);
|
||||||
trackEvent({
|
trackEvent({
|
||||||
event: MetaMetricsEventName.TokenImportClicked,
|
event: MetaMetricsEventName.TokenImportClicked,
|
||||||
category: MetaMetricsEventCategory.Wallet,
|
category: MetaMetricsEventCategory.Wallet,
|
||||||
properties: {
|
properties: {
|
||||||
source: MetaMetricsTokenEventSource.Detected,
|
source_connection_method: MetaMetricsTokenEventSource.Detected,
|
||||||
|
chain_id: chainId,
|
||||||
tokens: detectedTokensDetails,
|
tokens: detectedTokensDetails,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -12,6 +12,7 @@ import { TypographyVariant } from '../../../../helpers/constants/design-system';
|
|||||||
|
|
||||||
import SecurityProviderBannerMessage from '../../security-provider-banner-message/security-provider-banner-message';
|
import SecurityProviderBannerMessage from '../../security-provider-banner-message/security-provider-banner-message';
|
||||||
import { SECURITY_PROVIDER_MESSAGE_SEVERITIES } from '../../security-provider-banner-message/security-provider-banner-message.constants';
|
import { SECURITY_PROVIDER_MESSAGE_SEVERITIES } from '../../security-provider-banner-message/security-provider-banner-message.constants';
|
||||||
|
import { getPortfolioUrl } from '../../../../helpers/utils/portfolio';
|
||||||
import { ConfirmPageContainerSummary, ConfirmPageContainerWarning } from '.';
|
import { ConfirmPageContainerSummary, ConfirmPageContainerWarning } from '.';
|
||||||
|
|
||||||
export default class ConfirmPageContainerContent extends Component {
|
export default class ConfirmPageContainerContent extends Component {
|
||||||
@ -54,6 +55,7 @@ export default class ConfirmPageContainerContent extends Component {
|
|||||||
transactionType: PropTypes.string,
|
transactionType: PropTypes.string,
|
||||||
isBuyableChain: PropTypes.bool,
|
isBuyableChain: PropTypes.bool,
|
||||||
txData: PropTypes.object,
|
txData: PropTypes.object,
|
||||||
|
metaMetricsId: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
renderContent() {
|
renderContent() {
|
||||||
@ -159,6 +161,7 @@ export default class ConfirmPageContainerContent extends Component {
|
|||||||
transactionType,
|
transactionType,
|
||||||
isBuyableChain,
|
isBuyableChain,
|
||||||
txData,
|
txData,
|
||||||
|
metaMetricsId,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const { t } = this.context;
|
const { t } = this.context;
|
||||||
@ -222,9 +225,12 @@ export default class ConfirmPageContainerContent extends Component {
|
|||||||
type="inline"
|
type="inline"
|
||||||
className="confirm-page-container-content__link"
|
className="confirm-page-container-content__link"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const portfolioUrl = process.env.PORTFOLIO_URL;
|
|
||||||
global.platform.openTab({
|
global.platform.openTab({
|
||||||
url: `${portfolioUrl}/buy?metamaskEntry=ext_buy_button`,
|
url: getPortfolioUrl(
|
||||||
|
'buy',
|
||||||
|
'ext_buy_button',
|
||||||
|
metaMetricsId,
|
||||||
|
),
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
key={`${nativeCurrency}-buy-button`}
|
key={`${nativeCurrency}-buy-button`}
|
||||||
|
@ -39,6 +39,7 @@ import {
|
|||||||
getIsBuyableChain,
|
getIsBuyableChain,
|
||||||
getMetadataContractName,
|
getMetadataContractName,
|
||||||
getMetaMaskIdentities,
|
getMetaMaskIdentities,
|
||||||
|
getMetaMetricsId,
|
||||||
getNetworkIdentifier,
|
getNetworkIdentifier,
|
||||||
getSwapsDefaultToken,
|
getSwapsDefaultToken,
|
||||||
} from '../../../selectors';
|
} from '../../../selectors';
|
||||||
@ -116,6 +117,8 @@ const ConfirmPageContainer = (props) => {
|
|||||||
getMetadataContractName(state, toAddress),
|
getMetadataContractName(state, toAddress),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const metaMetricsId = useSelector(getMetaMetricsId);
|
||||||
|
|
||||||
// TODO: Move useRamps hook to the confirm-transaction-base parent component.
|
// TODO: Move useRamps hook to the confirm-transaction-base parent component.
|
||||||
// TODO: openBuyCryptoInPdapp should be passed to this component as a custom prop.
|
// TODO: openBuyCryptoInPdapp should be passed to this component as a custom prop.
|
||||||
// We try to keep this component for layout purpose only, we need to move this hook to the confirm-transaction-base parent
|
// We try to keep this component for layout purpose only, we need to move this hook to the confirm-transaction-base parent
|
||||||
@ -198,6 +201,7 @@ const ConfirmPageContainer = (props) => {
|
|||||||
)}
|
)}
|
||||||
{contentComponent || (
|
{contentComponent || (
|
||||||
<ConfirmPageContainerContent
|
<ConfirmPageContainerContent
|
||||||
|
metaMetricsId={metaMetricsId}
|
||||||
action={action}
|
action={action}
|
||||||
title={title}
|
title={title}
|
||||||
image={image}
|
image={image}
|
||||||
|
@ -9,7 +9,10 @@ import {
|
|||||||
MetaMetricsEventName,
|
MetaMetricsEventName,
|
||||||
MetaMetricsTokenEventSource,
|
MetaMetricsTokenEventSource,
|
||||||
} from '../../../../../shared/constants/metametrics';
|
} from '../../../../../shared/constants/metametrics';
|
||||||
import { getDetectedTokensInCurrentNetwork } from '../../../../selectors';
|
import {
|
||||||
|
getCurrentChainId,
|
||||||
|
getDetectedTokensInCurrentNetwork,
|
||||||
|
} from '../../../../selectors';
|
||||||
|
|
||||||
import Popover from '../../../ui/popover';
|
import Popover from '../../../ui/popover';
|
||||||
import Box from '../../../ui/box';
|
import Box from '../../../ui/box';
|
||||||
@ -27,6 +30,8 @@ const DetectedTokenSelectionPopover = ({
|
|||||||
const t = useI18nContext();
|
const t = useI18nContext();
|
||||||
const trackEvent = useContext(MetaMetricsContext);
|
const trackEvent = useContext(MetaMetricsContext);
|
||||||
|
|
||||||
|
const chainId = useSelector(getCurrentChainId);
|
||||||
|
|
||||||
const detectedTokens = useSelector(getDetectedTokensInCurrentNetwork);
|
const detectedTokens = useSelector(getDetectedTokensInCurrentNetwork);
|
||||||
const { selected: selectedTokens = [] } =
|
const { selected: selectedTokens = [] } =
|
||||||
sortingBasedOnTokenSelection(tokensListDetected);
|
sortingBasedOnTokenSelection(tokensListDetected);
|
||||||
@ -44,7 +49,8 @@ const DetectedTokenSelectionPopover = ({
|
|||||||
event: MetaMetricsEventName.TokenImportCanceled,
|
event: MetaMetricsEventName.TokenImportCanceled,
|
||||||
category: MetaMetricsEventCategory.Wallet,
|
category: MetaMetricsEventCategory.Wallet,
|
||||||
properties: {
|
properties: {
|
||||||
source: MetaMetricsTokenEventSource.Detected,
|
source_connection_method: MetaMetricsTokenEventSource.Detected,
|
||||||
|
chain_id: chainId,
|
||||||
tokens: eventTokensDetails,
|
tokens: eventTokensDetails,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -8,7 +8,10 @@ import {
|
|||||||
ignoreTokens,
|
ignoreTokens,
|
||||||
setNewTokensImported,
|
setNewTokensImported,
|
||||||
} from '../../../store/actions';
|
} from '../../../store/actions';
|
||||||
import { getDetectedTokensInCurrentNetwork } from '../../../selectors';
|
import {
|
||||||
|
getCurrentChainId,
|
||||||
|
getDetectedTokensInCurrentNetwork,
|
||||||
|
} from '../../../selectors';
|
||||||
import { MetaMetricsContext } from '../../../contexts/metametrics';
|
import { MetaMetricsContext } from '../../../contexts/metametrics';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -47,6 +50,7 @@ const DetectedToken = ({ setShowDetectedTokens }) => {
|
|||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const trackEvent = useContext(MetaMetricsContext);
|
const trackEvent = useContext(MetaMetricsContext);
|
||||||
|
|
||||||
|
const chainId = useSelector(getCurrentChainId);
|
||||||
const detectedTokens = useSelector(getDetectedTokensInCurrentNetwork);
|
const detectedTokens = useSelector(getDetectedTokensInCurrentNetwork);
|
||||||
|
|
||||||
const [tokensListDetected, setTokensListDetected] = useState(() =>
|
const [tokensListDetected, setTokensListDetected] = useState(() =>
|
||||||
@ -69,9 +73,11 @@ const DetectedToken = ({ setShowDetectedTokens }) => {
|
|||||||
token_symbol: importedToken.symbol,
|
token_symbol: importedToken.symbol,
|
||||||
token_contract_address: importedToken.address,
|
token_contract_address: importedToken.address,
|
||||||
token_decimal_precision: importedToken.decimals,
|
token_decimal_precision: importedToken.decimals,
|
||||||
source: MetaMetricsTokenEventSource.Detected,
|
source_connection_method: MetaMetricsTokenEventSource.Detected,
|
||||||
token_standard: TokenStandard.ERC20,
|
token_standard: TokenStandard.ERC20,
|
||||||
asset_type: AssetType.token,
|
asset_type: AssetType.token,
|
||||||
|
token_added_type: 'detected',
|
||||||
|
chain_id: chainId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -30,6 +30,8 @@ import {
|
|||||||
getIsBuyableChain,
|
getIsBuyableChain,
|
||||||
getNativeCurrencyImage,
|
getNativeCurrencyImage,
|
||||||
getSelectedAccountCachedBalance,
|
getSelectedAccountCachedBalance,
|
||||||
|
getCurrentChainId,
|
||||||
|
getMetaMetricsId,
|
||||||
} from '../../../selectors';
|
} from '../../../selectors';
|
||||||
import { setSwapsFromToken } from '../../../ducks/swaps/swaps';
|
import { setSwapsFromToken } from '../../../ducks/swaps/swaps';
|
||||||
import IconButton from '../../ui/icon-button';
|
import IconButton from '../../ui/icon-button';
|
||||||
@ -52,6 +54,7 @@ import {
|
|||||||
} from '../../component-library';
|
} from '../../component-library';
|
||||||
import { IconColor } from '../../../helpers/constants/design-system';
|
import { IconColor } from '../../../helpers/constants/design-system';
|
||||||
import useRamps from '../../../hooks/experiences/useRamps';
|
import useRamps from '../../../hooks/experiences/useRamps';
|
||||||
|
import { getPortfolioUrl } from '../../../helpers/utils/portfolio';
|
||||||
import WalletOverview from './wallet-overview';
|
import WalletOverview from './wallet-overview';
|
||||||
|
|
||||||
const EthOverview = ({ className }) => {
|
const EthOverview = ({ className }) => {
|
||||||
@ -70,6 +73,8 @@ const EthOverview = ({ className }) => {
|
|||||||
const isBuyableChain = useSelector(getIsBuyableChain);
|
const isBuyableChain = useSelector(getIsBuyableChain);
|
||||||
const primaryTokenImage = useSelector(getNativeCurrencyImage);
|
const primaryTokenImage = useSelector(getNativeCurrencyImage);
|
||||||
const defaultSwapsToken = useSelector(getSwapsDefaultToken);
|
const defaultSwapsToken = useSelector(getSwapsDefaultToken);
|
||||||
|
const chainId = useSelector(getCurrentChainId);
|
||||||
|
const metaMetricsId = useSelector(getMetaMetricsId);
|
||||||
|
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
const mmiPortfolioEnabled = useSelector(getMmiPortfolioEnabled);
|
const mmiPortfolioEnabled = useSelector(getMmiPortfolioEnabled);
|
||||||
@ -166,9 +171,13 @@ const EthOverview = ({ className }) => {
|
|||||||
ariaLabel={t('portfolio')}
|
ariaLabel={t('portfolio')}
|
||||||
size={ButtonIconSize.Lg}
|
size={ButtonIconSize.Lg}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const portfolioUrl = process.env.PORTFOLIO_URL;
|
const portfolioUrl = getPortfolioUrl(
|
||||||
|
'',
|
||||||
|
'ext',
|
||||||
|
metaMetricsId,
|
||||||
|
);
|
||||||
global.platform.openTab({
|
global.platform.openTab({
|
||||||
url: `${portfolioUrl}?metamaskEntry=ext`,
|
url: portfolioUrl,
|
||||||
});
|
});
|
||||||
trackEvent(
|
trackEvent(
|
||||||
{
|
{
|
||||||
@ -226,6 +235,8 @@ const EthOverview = ({ className }) => {
|
|||||||
properties: {
|
properties: {
|
||||||
location: 'Home',
|
location: 'Home',
|
||||||
text: 'Buy',
|
text: 'Buy',
|
||||||
|
chain_id: chainId,
|
||||||
|
token_symbol: defaultSwapsToken,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
@ -257,6 +268,7 @@ const EthOverview = ({ className }) => {
|
|||||||
token_symbol: 'ETH',
|
token_symbol: 'ETH',
|
||||||
location: 'Home',
|
location: 'Home',
|
||||||
text: 'Send',
|
text: 'Send',
|
||||||
|
chain_id: chainId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
dispatch(
|
dispatch(
|
||||||
@ -284,6 +296,7 @@ const EthOverview = ({ className }) => {
|
|||||||
token_symbol: 'ETH',
|
token_symbol: 'ETH',
|
||||||
location: MetaMetricsSwapsEventSource.MainView,
|
location: MetaMetricsSwapsEventSource.MainView,
|
||||||
text: 'Swap',
|
text: 'Swap',
|
||||||
|
chain_id: chainId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
dispatch(setSwapsFromToken(defaultSwapsToken));
|
dispatch(setSwapsFromToken(defaultSwapsToken));
|
||||||
@ -320,10 +333,13 @@ const EthOverview = ({ className }) => {
|
|||||||
label={t('bridge')}
|
label={t('bridge')}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (isBridgeChain) {
|
if (isBridgeChain) {
|
||||||
const portfolioUrl = process.env.PORTFOLIO_URL;
|
const portfolioUrl = getPortfolioUrl(
|
||||||
const bridgeUrl = `${portfolioUrl}/bridge`;
|
'bridge',
|
||||||
|
'ext_bridge_button',
|
||||||
|
metaMetricsId,
|
||||||
|
);
|
||||||
global.platform.openTab({
|
global.platform.openTab({
|
||||||
url: `${bridgeUrl}?metamaskEntry=ext_bridge_button${
|
url: `${portfolioUrl}${
|
||||||
location.pathname.includes('asset') ? '&token=native' : ''
|
location.pathname.includes('asset') ? '&token=native' : ''
|
||||||
}`,
|
}`,
|
||||||
});
|
});
|
||||||
@ -333,6 +349,8 @@ const EthOverview = ({ className }) => {
|
|||||||
properties: {
|
properties: {
|
||||||
location: 'Home',
|
location: 'Home',
|
||||||
text: 'Bridge',
|
text: 'Bridge',
|
||||||
|
chain_id: chainId,
|
||||||
|
token_symbol: 'ETH',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,8 @@ import {
|
|||||||
getIsSwapsChain,
|
getIsSwapsChain,
|
||||||
getIsBuyableChain,
|
getIsBuyableChain,
|
||||||
getIsBridgeToken,
|
getIsBridgeToken,
|
||||||
|
getCurrentChainId,
|
||||||
|
getMetaMetricsId,
|
||||||
} from '../../../selectors';
|
} from '../../../selectors';
|
||||||
|
|
||||||
import IconButton from '../../ui/icon-button';
|
import IconButton from '../../ui/icon-button';
|
||||||
@ -39,6 +41,7 @@ import { ButtonIcon, Icon, IconName } from '../../component-library';
|
|||||||
import { IconColor } from '../../../helpers/constants/design-system';
|
import { IconColor } from '../../../helpers/constants/design-system';
|
||||||
|
|
||||||
import { BUTTON_ICON_SIZES } from '../../component-library/button-icon/deprecated';
|
import { BUTTON_ICON_SIZES } from '../../component-library/button-icon/deprecated';
|
||||||
|
import { getPortfolioUrl } from '../../../helpers/utils/portfolio';
|
||||||
import WalletOverview from './wallet-overview';
|
import WalletOverview from './wallet-overview';
|
||||||
|
|
||||||
const TokenOverview = ({ className, token }) => {
|
const TokenOverview = ({ className, token }) => {
|
||||||
@ -56,9 +59,11 @@ const TokenOverview = ({ className, token }) => {
|
|||||||
balanceToRender,
|
balanceToRender,
|
||||||
token.symbol,
|
token.symbol,
|
||||||
);
|
);
|
||||||
|
const chainId = useSelector(getCurrentChainId);
|
||||||
const isSwapsChain = useSelector(getIsSwapsChain);
|
const isSwapsChain = useSelector(getIsSwapsChain);
|
||||||
const isBridgeToken = useSelector(getIsBridgeToken(token.address));
|
const isBridgeToken = useSelector(getIsBridgeToken(token.address));
|
||||||
const isBuyableChain = useSelector(getIsBuyableChain);
|
const isBuyableChain = useSelector(getIsBuyableChain);
|
||||||
|
const metaMetricsId = useSelector(getMetaMetricsId);
|
||||||
|
|
||||||
const { openBuyCryptoInPdapp } = useRamps();
|
const { openBuyCryptoInPdapp } = useRamps();
|
||||||
|
|
||||||
@ -92,9 +97,9 @@ const TokenOverview = ({ className, token }) => {
|
|||||||
ariaLabel={t('portfolio')}
|
ariaLabel={t('portfolio')}
|
||||||
size={BUTTON_ICON_SIZES.LG}
|
size={BUTTON_ICON_SIZES.LG}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const portfolioUrl = process.env.PORTFOLIO_URL;
|
const portfolioUrl = getPortfolioUrl('', 'ext', metaMetricsId);
|
||||||
global.platform.openTab({
|
global.platform.openTab({
|
||||||
url: `${portfolioUrl}?metamaskEntry=ext`,
|
url: portfolioUrl,
|
||||||
});
|
});
|
||||||
trackEvent(
|
trackEvent(
|
||||||
{
|
{
|
||||||
@ -137,6 +142,8 @@ const TokenOverview = ({ className, token }) => {
|
|||||||
properties: {
|
properties: {
|
||||||
location: 'Token Overview',
|
location: 'Token Overview',
|
||||||
text: 'Buy',
|
text: 'Buy',
|
||||||
|
chain_id: chainId,
|
||||||
|
token_symbol: token.symbol,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
@ -152,6 +159,7 @@ const TokenOverview = ({ className, token }) => {
|
|||||||
token_symbol: token.symbol,
|
token_symbol: token.symbol,
|
||||||
location: MetaMetricsSwapsEventSource.TokenView,
|
location: MetaMetricsSwapsEventSource.TokenView,
|
||||||
text: 'Send',
|
text: 'Send',
|
||||||
|
chain_id: chainId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
@ -195,6 +203,7 @@ const TokenOverview = ({ className, token }) => {
|
|||||||
token_symbol: token.symbol,
|
token_symbol: token.symbol,
|
||||||
location: MetaMetricsSwapsEventSource.TokenView,
|
location: MetaMetricsSwapsEventSource.TokenView,
|
||||||
text: 'Swap',
|
text: 'Swap',
|
||||||
|
chain_id: chainId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
dispatch(
|
dispatch(
|
||||||
@ -225,11 +234,13 @@ const TokenOverview = ({ className, token }) => {
|
|||||||
}
|
}
|
||||||
label={t('bridge')}
|
label={t('bridge')}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const portfolioUrl = process.env.PORTFOLIO_URL;
|
const portfolioUrl = getPortfolioUrl(
|
||||||
|
'bridge',
|
||||||
const bridgeUrl = `${portfolioUrl}/bridge`;
|
'ext_bridge_button',
|
||||||
|
metaMetricsId,
|
||||||
|
);
|
||||||
global.platform.openTab({
|
global.platform.openTab({
|
||||||
url: `${bridgeUrl}?metamaskEntry=ext_bridge_button&token=${token.address}`,
|
url: `${portfolioUrl}&token=${token.address}`,
|
||||||
});
|
});
|
||||||
trackEvent({
|
trackEvent({
|
||||||
category: MetaMetricsEventCategory.Navigation,
|
category: MetaMetricsEventCategory.Navigation,
|
||||||
@ -237,6 +248,9 @@ const TokenOverview = ({ className, token }) => {
|
|||||||
properties: {
|
properties: {
|
||||||
location: 'Token Overview',
|
location: 'Token Overview',
|
||||||
text: 'Bridge',
|
text: 'Bridge',
|
||||||
|
url: portfolioUrl,
|
||||||
|
chain_id: chainId,
|
||||||
|
token_symbol: token.symbol,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
|
@ -307,7 +307,7 @@ describe('TokenOverview', () => {
|
|||||||
await waitFor(() =>
|
await waitFor(() =>
|
||||||
expect(openTabSpy).toHaveBeenCalledWith({
|
expect(openTabSpy).toHaveBeenCalledWith({
|
||||||
url: expect.stringContaining(
|
url: expect.stringContaining(
|
||||||
'/bridge?metamaskEntry=ext_bridge_button&token=0x7ceb23fd6bc0add59e62ac25578270cff1B9f619',
|
'/bridge?metamaskEntry=ext_bridge_button&metametricsId=&token=0x7ceb23fd6bc0add59e62ac25578270cff1B9f619',
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
@ -20,6 +20,11 @@ import {
|
|||||||
} from '../../../helpers/constants/routes';
|
} from '../../../helpers/constants/routes';
|
||||||
import { TextVariant } from '../../../helpers/constants/design-system';
|
import { TextVariant } from '../../../helpers/constants/design-system';
|
||||||
import ZENDESK_URLS from '../../../helpers/constants/zendesk-url';
|
import ZENDESK_URLS from '../../../helpers/constants/zendesk-url';
|
||||||
|
import { MetaMetricsContext } from '../../../contexts/metametrics';
|
||||||
|
import {
|
||||||
|
MetaMetricsEventCategory,
|
||||||
|
MetaMetricsEventName,
|
||||||
|
} from '../../../../shared/constants/metametrics';
|
||||||
|
|
||||||
function getActionFunctionById(id, history) {
|
function getActionFunctionById(id, history) {
|
||||||
const actionFunctions = {
|
const actionFunctions = {
|
||||||
@ -107,9 +112,16 @@ const renderDescription = (description) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderFirstNotification = (notification, idRefMap, history, isLast) => {
|
const renderFirstNotification = (
|
||||||
|
notification,
|
||||||
|
idRefMap,
|
||||||
|
history,
|
||||||
|
isLast,
|
||||||
|
trackEvent,
|
||||||
|
) => {
|
||||||
const { id, date, title, description, image, actionText } = notification;
|
const { id, date, title, description, image, actionText } = notification;
|
||||||
const actionFunction = getActionFunctionById(id, history);
|
const actionFunction = getActionFunctionById(id, history);
|
||||||
|
|
||||||
const imageComponent = image && (
|
const imageComponent = image && (
|
||||||
<img
|
<img
|
||||||
className="whats-new-popup__notification-image"
|
className="whats-new-popup__notification-image"
|
||||||
@ -144,7 +156,13 @@ const renderFirstNotification = (notification, idRefMap, history, isLast) => {
|
|||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
className="whats-new-popup__button"
|
className="whats-new-popup__button"
|
||||||
onClick={actionFunction}
|
onClick={() => {
|
||||||
|
actionFunction();
|
||||||
|
trackEvent({
|
||||||
|
category: MetaMetricsEventCategory.Home,
|
||||||
|
event: MetaMetricsEventName.WhatsNewClicked,
|
||||||
|
});
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{actionText}
|
{actionText}
|
||||||
</Button>
|
</Button>
|
||||||
@ -218,6 +236,8 @@ export default function WhatsNewPopup({ onClose }) {
|
|||||||
[memoizedNotifications],
|
[memoizedNotifications],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const trackEvent = useContext(MetaMetricsContext);
|
||||||
|
|
||||||
const handleScrollDownClick = (e) => {
|
const handleScrollDownClick = (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
idRefMap[notifications[notifications.length - 1].id].current.scrollIntoView(
|
idRefMap[notifications[notifications.length - 1].id].current.scrollIntoView(
|
||||||
@ -267,6 +287,14 @@ export default function WhatsNewPopup({ onClose }) {
|
|||||||
className="whats-new-popup__popover"
|
className="whats-new-popup__popover"
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
updateViewedNotifications(seenNotifications);
|
updateViewedNotifications(seenNotifications);
|
||||||
|
trackEvent({
|
||||||
|
category: MetaMetricsEventCategory.Home,
|
||||||
|
event: MetaMetricsEventName.WhatsNewViewed,
|
||||||
|
properties: {
|
||||||
|
number_viewed: Object.keys(seenNotifications).pop(),
|
||||||
|
completed_all: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
onClose();
|
onClose();
|
||||||
}}
|
}}
|
||||||
popoverRef={popoverRef}
|
popoverRef={popoverRef}
|
||||||
@ -280,7 +308,13 @@ export default function WhatsNewPopup({ onClose }) {
|
|||||||
// Display the swaps notification with full image
|
// Display the swaps notification with full image
|
||||||
// Displays the NFTs & OpenSea notifications 18,19 with full image
|
// Displays the NFTs & OpenSea notifications 18,19 with full image
|
||||||
return index === 0 || id === 1 || id === 18 || id === 19
|
return index === 0 || id === 1 || id === 18 || id === 19
|
||||||
? renderFirstNotification(notification, idRefMap, history, isLast)
|
? renderFirstNotification(
|
||||||
|
notification,
|
||||||
|
idRefMap,
|
||||||
|
history,
|
||||||
|
isLast,
|
||||||
|
trackEvent,
|
||||||
|
)
|
||||||
: renderSubsequentNotification(
|
: renderSubsequentNotification(
|
||||||
notification,
|
notification,
|
||||||
idRefMap,
|
idRefMap,
|
||||||
|
@ -9,7 +9,10 @@ import {
|
|||||||
getRpcPrefsForCurrentProvider,
|
getRpcPrefsForCurrentProvider,
|
||||||
getBlockExplorerLinkText,
|
getBlockExplorerLinkText,
|
||||||
getCurrentChainId,
|
getCurrentChainId,
|
||||||
|
getHardwareWalletType,
|
||||||
|
getAccountTypeForKeyring,
|
||||||
} from '../../../selectors';
|
} from '../../../selectors';
|
||||||
|
import { findKeyringForAddress } from '../../../ducks/metamask/metamask';
|
||||||
import { NETWORKS_ROUTE } from '../../../helpers/constants/routes';
|
import { NETWORKS_ROUTE } from '../../../helpers/constants/routes';
|
||||||
import { Menu, MenuItem } from '../../ui/menu';
|
import { Menu, MenuItem } from '../../ui/menu';
|
||||||
import { Text, IconName } from '../../component-library';
|
import { Text, IconName } from '../../component-library';
|
||||||
@ -21,6 +24,7 @@ import {
|
|||||||
import { getURLHostName } from '../../../helpers/utils/util';
|
import { getURLHostName } from '../../../helpers/utils/util';
|
||||||
import { showModal } from '../../../store/actions';
|
import { showModal } from '../../../store/actions';
|
||||||
import { TextVariant } from '../../../helpers/constants/design-system';
|
import { TextVariant } from '../../../helpers/constants/design-system';
|
||||||
|
import { formatAccountType } from '../../../helpers/utils/metrics';
|
||||||
|
|
||||||
export const AccountListItemMenu = ({
|
export const AccountListItemMenu = ({
|
||||||
anchorElement,
|
anchorElement,
|
||||||
@ -39,6 +43,13 @@ export const AccountListItemMenu = ({
|
|||||||
const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider);
|
const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider);
|
||||||
const addressLink = getAccountLink(identity.address, chainId, rpcPrefs);
|
const addressLink = getAccountLink(identity.address, chainId, rpcPrefs);
|
||||||
|
|
||||||
|
const deviceName = useSelector(getHardwareWalletType);
|
||||||
|
|
||||||
|
const keyring = useSelector((state) =>
|
||||||
|
findKeyringForAddress(state, identity.address),
|
||||||
|
);
|
||||||
|
const accountType = formatAccountType(getAccountTypeForKeyring(keyring));
|
||||||
|
|
||||||
const blockExplorerLinkText = useSelector(getBlockExplorerLinkText);
|
const blockExplorerLinkText = useSelector(getBlockExplorerLinkText);
|
||||||
const openBlockExplorer = () => {
|
const openBlockExplorer = () => {
|
||||||
trackEvent({
|
trackEvent({
|
||||||
@ -50,6 +61,7 @@ export const AccountListItemMenu = ({
|
|||||||
url_domain: getURLHostName(addressLink),
|
url_domain: getURLHostName(addressLink),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
global.platform.openTab({
|
global.platform.openTab({
|
||||||
url: addressLink,
|
url: addressLink,
|
||||||
});
|
});
|
||||||
@ -67,11 +79,20 @@ export const AccountListItemMenu = ({
|
|||||||
onHide={onClose}
|
onHide={onClose}
|
||||||
>
|
>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
onClick={
|
onClick={() => {
|
||||||
blockExplorerLinkText.firstPart === 'addBlockExplorer'
|
blockExplorerLinkText.firstPart === 'addBlockExplorer'
|
||||||
? routeToAddBlockExplorerUrl
|
? routeToAddBlockExplorerUrl()
|
||||||
: openBlockExplorer
|
: openBlockExplorer();
|
||||||
}
|
|
||||||
|
trackEvent({
|
||||||
|
event: MetaMetricsEventName.BlockExplorerLinkClicked,
|
||||||
|
category: MetaMetricsEventCategory.Accounts,
|
||||||
|
properties: {
|
||||||
|
location: 'Account Options',
|
||||||
|
chain_id: chainId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}}
|
||||||
subtitle={blockExplorerUrlSubTitle || null}
|
subtitle={blockExplorerUrlSubTitle || null}
|
||||||
iconName={IconName.Export}
|
iconName={IconName.Export}
|
||||||
data-testid="account-list-menu-open-explorer"
|
data-testid="account-list-menu-open-explorer"
|
||||||
@ -105,6 +126,15 @@ export const AccountListItemMenu = ({
|
|||||||
identity,
|
identity,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
trackEvent({
|
||||||
|
event: MetaMetricsEventName.AccountRemoved,
|
||||||
|
category: MetaMetricsEventCategory.Accounts,
|
||||||
|
properties: {
|
||||||
|
account_hardware_type: deviceName,
|
||||||
|
chain_id: chainId,
|
||||||
|
account_type: accountType,
|
||||||
|
},
|
||||||
|
});
|
||||||
onClose();
|
onClose();
|
||||||
}}
|
}}
|
||||||
iconName={IconName.Trash}
|
iconName={IconName.Trash}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useRef } from 'react';
|
import React, { useState, useRef, useContext } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
|
|
||||||
@ -38,6 +38,11 @@ import UserPreferencedCurrencyDisplay from '../../app/user-preferenced-currency-
|
|||||||
import { SECONDARY, PRIMARY } from '../../../helpers/constants/common';
|
import { SECONDARY, PRIMARY } from '../../../helpers/constants/common';
|
||||||
import { findKeyringForAddress } from '../../../ducks/metamask/metamask';
|
import { findKeyringForAddress } from '../../../ducks/metamask/metamask';
|
||||||
import Tooltip from '../../ui/tooltip/tooltip';
|
import Tooltip from '../../ui/tooltip/tooltip';
|
||||||
|
import {
|
||||||
|
MetaMetricsEventCategory,
|
||||||
|
MetaMetricsEventName,
|
||||||
|
} from '../../../../shared/constants/metametrics';
|
||||||
|
import { MetaMetricsContext } from '../../../contexts/metametrics';
|
||||||
|
|
||||||
const MAXIMUM_CURRENCY_DECIMALS = 3;
|
const MAXIMUM_CURRENCY_DECIMALS = 3;
|
||||||
const MAXIMUM_CHARACTERS_WITHOUT_TOOLTIP = 17;
|
const MAXIMUM_CHARACTERS_WITHOUT_TOOLTIP = 17;
|
||||||
@ -82,6 +87,8 @@ export const AccountListItem = ({
|
|||||||
const { blockExplorerUrl } = rpcPrefs;
|
const { blockExplorerUrl } = rpcPrefs;
|
||||||
const blockExplorerUrlSubTitle = getURLHostName(blockExplorerUrl);
|
const blockExplorerUrlSubTitle = getURLHostName(blockExplorerUrl);
|
||||||
|
|
||||||
|
const trackEvent = useContext(MetaMetricsContext);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
display={DISPLAY.FLEX}
|
display={DISPLAY.FLEX}
|
||||||
@ -207,6 +214,13 @@ export const AccountListItem = ({
|
|||||||
size={IconSize.Sm}
|
size={IconSize.Sm}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
trackEvent({
|
||||||
|
event: MetaMetricsEventName.AccountDetailMenuOpened,
|
||||||
|
category: MetaMetricsEventCategory.Navigation,
|
||||||
|
properties: {
|
||||||
|
location: 'Account Options',
|
||||||
|
},
|
||||||
|
});
|
||||||
setAccountOptionsMenuOpen(true);
|
setAccountOptionsMenuOpen(true);
|
||||||
}}
|
}}
|
||||||
data-testid="account-list-item-menu-button"
|
data-testid="account-list-item-menu-button"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useContext, useState, useRef } from 'react';
|
import React, { useContext, useState, useRef, useCallback } from 'react';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import browser from 'webextension-polyfill';
|
import browser from 'webextension-polyfill';
|
||||||
@ -30,6 +30,7 @@ import {
|
|||||||
} from '../../component-library';
|
} from '../../component-library';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
getCurrentChainId,
|
||||||
getCurrentNetwork,
|
getCurrentNetwork,
|
||||||
getOnboardedInThisUISession,
|
getOnboardedInThisUISession,
|
||||||
getOriginOfCurrentTab,
|
getOriginOfCurrentTab,
|
||||||
@ -60,6 +61,7 @@ export const AppHeader = ({ onClick }) => {
|
|||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const isUnlocked = useSelector((state) => state.metamask.isUnlocked);
|
const isUnlocked = useSelector((state) => state.metamask.isUnlocked);
|
||||||
const t = useI18nContext();
|
const t = useI18nContext();
|
||||||
|
const chainId = useSelector(getCurrentChainId);
|
||||||
|
|
||||||
// Used for account picker
|
// Used for account picker
|
||||||
const identity = useSelector(getSelectedIdentity);
|
const identity = useSelector(getSelectedIdentity);
|
||||||
@ -71,7 +73,7 @@ export const AppHeader = ({ onClick }) => {
|
|||||||
// Used for network icon / dropdown
|
// Used for network icon / dropdown
|
||||||
const currentNetwork = useSelector(getCurrentNetwork);
|
const currentNetwork = useSelector(getCurrentNetwork);
|
||||||
|
|
||||||
// used to get the environment and connection status
|
// Used to get the environment and connection status
|
||||||
const popupStatus = getEnvironmentType() === ENVIRONMENT_TYPE_POPUP;
|
const popupStatus = getEnvironmentType() === ENVIRONMENT_TYPE_POPUP;
|
||||||
const showStatus =
|
const showStatus =
|
||||||
getEnvironmentType() === ENVIRONMENT_TYPE_POPUP &&
|
getEnvironmentType() === ENVIRONMENT_TYPE_POPUP &&
|
||||||
@ -83,6 +85,19 @@ export const AppHeader = ({ onClick }) => {
|
|||||||
.querySelector('[dir]')
|
.querySelector('[dir]')
|
||||||
?.getAttribute('dir');
|
?.getAttribute('dir');
|
||||||
|
|
||||||
|
// Callback for network dropdown
|
||||||
|
const networkOpenCallback = useCallback(() => {
|
||||||
|
dispatch(toggleNetworkMenu());
|
||||||
|
trackEvent({
|
||||||
|
event: MetaMetricsEventName.NavNetworkMenuOpened,
|
||||||
|
category: MetaMetricsEventCategory.Navigation,
|
||||||
|
properties: {
|
||||||
|
location: 'App header',
|
||||||
|
chain_id: chainId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}, [chainId, dispatch, trackEvent]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{isUnlocked && !popupStatus ? (
|
{isUnlocked && !popupStatus ? (
|
||||||
@ -140,14 +155,14 @@ export const AppHeader = ({ onClick }) => {
|
|||||||
name={currentNetwork?.nickname}
|
name={currentNetwork?.nickname}
|
||||||
src={currentNetwork?.rpcPrefs?.imageUrl}
|
src={currentNetwork?.rpcPrefs?.imageUrl}
|
||||||
size={Size.SM}
|
size={Size.SM}
|
||||||
onClick={() => dispatch(toggleNetworkMenu())}
|
onClick={networkOpenCallback}
|
||||||
display={[DISPLAY.FLEX, DISPLAY.NONE]} // show on popover hide on desktop
|
display={[DISPLAY.FLEX, DISPLAY.NONE]} // show on popover hide on desktop
|
||||||
/>
|
/>
|
||||||
<PickerNetwork
|
<PickerNetwork
|
||||||
margin={2}
|
margin={2}
|
||||||
label={currentNetwork?.nickname}
|
label={currentNetwork?.nickname}
|
||||||
src={currentNetwork?.rpcPrefs?.imageUrl}
|
src={currentNetwork?.rpcPrefs?.imageUrl}
|
||||||
onClick={() => dispatch(toggleNetworkMenu())}
|
onClick={networkOpenCallback}
|
||||||
display={[DISPLAY.NONE, DISPLAY.FLEX]} // show on desktop hide on popover
|
display={[DISPLAY.NONE, DISPLAY.FLEX]} // show on desktop hide on popover
|
||||||
/>
|
/>
|
||||||
{showProductTour &&
|
{showProductTour &&
|
||||||
@ -171,7 +186,17 @@ export const AppHeader = ({ onClick }) => {
|
|||||||
<AccountPicker
|
<AccountPicker
|
||||||
address={identity.address}
|
address={identity.address}
|
||||||
name={identity.name}
|
name={identity.name}
|
||||||
onClick={() => dispatch(toggleAccountMenu())}
|
onClick={() => {
|
||||||
|
dispatch(toggleAccountMenu());
|
||||||
|
|
||||||
|
trackEvent({
|
||||||
|
event: MetaMetricsEventName.NavAccountMenuOpened,
|
||||||
|
category: MetaMetricsEventCategory.Navigation,
|
||||||
|
properties: {
|
||||||
|
location: 'Home',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<Box
|
<Box
|
||||||
display={DISPLAY.FLEX}
|
display={DISPLAY.FLEX}
|
||||||
@ -181,7 +206,13 @@ export const AppHeader = ({ onClick }) => {
|
|||||||
{showStatus ? (
|
{showStatus ? (
|
||||||
<Box ref={menuRef}>
|
<Box ref={menuRef}>
|
||||||
<ConnectedStatusIndicator
|
<ConnectedStatusIndicator
|
||||||
onClick={() => history.push(CONNECTED_ACCOUNTS_ROUTE)}
|
onClick={() => {
|
||||||
|
history.push(CONNECTED_ACCOUNTS_ROUTE);
|
||||||
|
trackEvent({
|
||||||
|
event: MetaMetricsEventName.NavConnectedSitesOpened,
|
||||||
|
category: MetaMetricsEventCategory.Navigation,
|
||||||
|
});
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
) : null}{' '}
|
) : null}{' '}
|
||||||
|
@ -4,7 +4,10 @@ import PropTypes from 'prop-types';
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import { useI18nContext } from '../../../hooks/useI18nContext';
|
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||||
import { getDetectedTokensInCurrentNetwork } from '../../../selectors';
|
import {
|
||||||
|
getCurrentChainId,
|
||||||
|
getDetectedTokensInCurrentNetwork,
|
||||||
|
} from '../../../selectors';
|
||||||
import { MetaMetricsContext } from '../../../contexts/metametrics';
|
import { MetaMetricsContext } from '../../../contexts/metametrics';
|
||||||
import {
|
import {
|
||||||
MetaMetricsEventCategory,
|
MetaMetricsEventCategory,
|
||||||
@ -26,14 +29,17 @@ export const DetectedTokensBanner = ({
|
|||||||
({ address, symbol }) => `${symbol} - ${address}`,
|
({ address, symbol }) => `${symbol} - ${address}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const chainId = useSelector(getCurrentChainId);
|
||||||
|
|
||||||
const handleOnClick = () => {
|
const handleOnClick = () => {
|
||||||
actionButtonOnClick();
|
actionButtonOnClick();
|
||||||
trackEvent({
|
trackEvent({
|
||||||
event: MetaMetricsEventName.TokenImportClicked,
|
event: MetaMetricsEventName.TokenImportClicked,
|
||||||
category: MetaMetricsEventCategory.Wallet,
|
category: MetaMetricsEventCategory.Wallet,
|
||||||
properties: {
|
properties: {
|
||||||
source: MetaMetricsTokenEventSource.Detected,
|
source_connection_method: MetaMetricsTokenEventSource.Detected,
|
||||||
tokens: detectedTokensDetails,
|
tokens: detectedTokensDetails,
|
||||||
|
chain_id: chainId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import {
|
import {
|
||||||
CONNECTED_ROUTE,
|
CONNECTED_ROUTE,
|
||||||
SETTINGS_ROUTE,
|
SETTINGS_ROUTE,
|
||||||
@ -21,12 +21,15 @@ import {
|
|||||||
MetaMetricsEventCategory,
|
MetaMetricsEventCategory,
|
||||||
MetaMetricsContextProp,
|
MetaMetricsContextProp,
|
||||||
} from '../../../../shared/constants/metametrics';
|
} from '../../../../shared/constants/metametrics';
|
||||||
|
import { getPortfolioUrl } from '../../../helpers/utils/portfolio';
|
||||||
|
import { getMetaMetricsId } from '../../../selectors';
|
||||||
|
|
||||||
export const GlobalMenu = ({ closeMenu, anchorElement }) => {
|
export const GlobalMenu = ({ closeMenu, anchorElement }) => {
|
||||||
const t = useI18nContext();
|
const t = useI18nContext();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const trackEvent = useContext(MetaMetricsContext);
|
const trackEvent = useContext(MetaMetricsContext);
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
const metaMetricsId = useSelector(getMetaMetricsId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu anchorElement={anchorElement} onHide={closeMenu}>
|
<Menu anchorElement={anchorElement} onHide={closeMenu}>
|
||||||
@ -38,7 +41,7 @@ export const GlobalMenu = ({ closeMenu, anchorElement }) => {
|
|||||||
event: MetaMetricsEventName.NavConnectedSitesOpened,
|
event: MetaMetricsEventName.NavConnectedSitesOpened,
|
||||||
category: MetaMetricsEventCategory.Navigation,
|
category: MetaMetricsEventCategory.Navigation,
|
||||||
properties: {
|
properties: {
|
||||||
location: 'Account Options',
|
location: 'Global Menu',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
closeMenu();
|
closeMenu();
|
||||||
@ -49,9 +52,9 @@ export const GlobalMenu = ({ closeMenu, anchorElement }) => {
|
|||||||
<MenuItem
|
<MenuItem
|
||||||
iconName={IconName.Diagram}
|
iconName={IconName.Diagram}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const portfolioUrl = process.env.PORTFOLIO_URL;
|
const portfolioUrl = getPortfolioUrl('', 'ext', metaMetricsId);
|
||||||
global.platform.openTab({
|
global.platform.openTab({
|
||||||
url: `${portfolioUrl}?metamaskEntry=ext`,
|
url: portfolioUrl,
|
||||||
});
|
});
|
||||||
trackEvent(
|
trackEvent(
|
||||||
{
|
{
|
||||||
@ -59,6 +62,7 @@ export const GlobalMenu = ({ closeMenu, anchorElement }) => {
|
|||||||
event: MetaMetricsEventName.PortfolioLinkClicked,
|
event: MetaMetricsEventName.PortfolioLinkClicked,
|
||||||
properties: {
|
properties: {
|
||||||
url: portfolioUrl,
|
url: portfolioUrl,
|
||||||
|
location: 'Global Menu',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -82,7 +86,7 @@ export const GlobalMenu = ({ closeMenu, anchorElement }) => {
|
|||||||
event: MetaMetricsEventName.AppWindowExpanded,
|
event: MetaMetricsEventName.AppWindowExpanded,
|
||||||
category: MetaMetricsEventCategory.Navigation,
|
category: MetaMetricsEventCategory.Navigation,
|
||||||
properties: {
|
properties: {
|
||||||
location: 'Account Options',
|
location: 'Global Menu',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
closeMenu();
|
closeMenu();
|
||||||
@ -102,6 +106,7 @@ export const GlobalMenu = ({ closeMenu, anchorElement }) => {
|
|||||||
event: MetaMetricsEventName.SupportLinkClicked,
|
event: MetaMetricsEventName.SupportLinkClicked,
|
||||||
properties: {
|
properties: {
|
||||||
url: SUPPORT_LINK,
|
url: SUPPORT_LINK,
|
||||||
|
location: 'Global Menu',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -124,7 +129,7 @@ export const GlobalMenu = ({ closeMenu, anchorElement }) => {
|
|||||||
category: MetaMetricsEventCategory.Navigation,
|
category: MetaMetricsEventCategory.Navigation,
|
||||||
event: MetaMetricsEventName.NavSettingsOpened,
|
event: MetaMetricsEventName.NavSettingsOpened,
|
||||||
properties: {
|
properties: {
|
||||||
location: 'Main Menu',
|
location: 'Global Menu',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
closeMenu();
|
closeMenu();
|
||||||
@ -137,6 +142,13 @@ export const GlobalMenu = ({ closeMenu, anchorElement }) => {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
dispatch(lockMetamask());
|
dispatch(lockMetamask());
|
||||||
history.push(DEFAULT_ROUTE);
|
history.push(DEFAULT_ROUTE);
|
||||||
|
trackEvent({
|
||||||
|
category: MetaMetricsEventCategory.Navigation,
|
||||||
|
event: MetaMetricsEventName.AppLocked,
|
||||||
|
properties: {
|
||||||
|
location: 'Global Menu',
|
||||||
|
},
|
||||||
|
});
|
||||||
closeMenu();
|
closeMenu();
|
||||||
}}
|
}}
|
||||||
data-testid="global-menu-lock"
|
data-testid="global-menu-lock"
|
||||||
|
@ -38,7 +38,7 @@ describe('AccountListItem', () => {
|
|||||||
fireEvent.click(getByTestId('global-menu-portfolio'));
|
fireEvent.click(getByTestId('global-menu-portfolio'));
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
expect(global.platform.openTab).toHaveBeenCalledWith({
|
expect(global.platform.openTab).toHaveBeenCalledWith({
|
||||||
url: `${process.env.PORTFOLIO_URL}?metamaskEntry=ext`,
|
url: `/?metamaskEntry=ext&metametricsId=`,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import React, { useContext } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
@ -21,9 +21,14 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
} from '../../component-library';
|
} from '../../component-library';
|
||||||
import Box from '../../ui/box/box';
|
import Box from '../../ui/box/box';
|
||||||
import { getNativeCurrencyImage } from '../../../selectors';
|
import { getCurrentChainId, getNativeCurrencyImage } from '../../../selectors';
|
||||||
import Tooltip from '../../ui/tooltip';
|
import Tooltip from '../../ui/tooltip';
|
||||||
import { useI18nContext } from '../../../hooks/useI18nContext';
|
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||||
|
import { MetaMetricsContext } from '../../../contexts/metametrics';
|
||||||
|
import {
|
||||||
|
MetaMetricsEventCategory,
|
||||||
|
MetaMetricsEventName,
|
||||||
|
} from '../../../../shared/constants/metametrics';
|
||||||
|
|
||||||
export const MultichainTokenListItem = ({
|
export const MultichainTokenListItem = ({
|
||||||
className,
|
className,
|
||||||
@ -37,6 +42,9 @@ export const MultichainTokenListItem = ({
|
|||||||
const t = useI18nContext();
|
const t = useI18nContext();
|
||||||
const primaryTokenImage = useSelector(getNativeCurrencyImage);
|
const primaryTokenImage = useSelector(getNativeCurrencyImage);
|
||||||
const dataTheme = document.documentElement.getAttribute('data-theme');
|
const dataTheme = document.documentElement.getAttribute('data-theme');
|
||||||
|
const trackEvent = useContext(MetaMetricsContext);
|
||||||
|
const chainId = useSelector(getCurrentChainId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
className={classnames('multichain-token-list-item', className)}
|
className={classnames('multichain-token-list-item', className)}
|
||||||
@ -56,6 +64,15 @@ export const MultichainTokenListItem = ({
|
|||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
onClick();
|
onClick();
|
||||||
|
trackEvent({
|
||||||
|
category: MetaMetricsEventCategory.Tokens,
|
||||||
|
event: MetaMetricsEventName.TokenDetailsOpened,
|
||||||
|
properties: {
|
||||||
|
location: 'Home',
|
||||||
|
chain_id: chainId,
|
||||||
|
token_symbol: tokenSymbol,
|
||||||
|
},
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<BadgeWrapper
|
<BadgeWrapper
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import React, { useContext } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
@ -28,6 +28,11 @@ import { Button, BUTTON_VARIANT, Text } from '../../component-library';
|
|||||||
import { ADD_POPULAR_CUSTOM_NETWORK } from '../../../helpers/constants/routes';
|
import { ADD_POPULAR_CUSTOM_NETWORK } from '../../../helpers/constants/routes';
|
||||||
import { getEnvironmentType } from '../../../../app/scripts/lib/util';
|
import { getEnvironmentType } from '../../../../app/scripts/lib/util';
|
||||||
import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../shared/constants/app';
|
import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../shared/constants/app';
|
||||||
|
import { MetaMetricsContext } from '../../../contexts/metametrics';
|
||||||
|
import {
|
||||||
|
MetaMetricsEventCategory,
|
||||||
|
MetaMetricsEventName,
|
||||||
|
} from '../../../../shared/constants/metametrics';
|
||||||
|
|
||||||
const UNREMOVABLE_CHAIN_IDS = [CHAIN_IDS.MAINNET, ...TEST_CHAINS];
|
const UNREMOVABLE_CHAIN_IDS = [CHAIN_IDS.MAINNET, ...TEST_CHAINS];
|
||||||
|
|
||||||
@ -38,6 +43,7 @@ export const NetworkListMenu = ({ onClose }) => {
|
|||||||
const currentChainId = useSelector(getCurrentChainId);
|
const currentChainId = useSelector(getCurrentChainId);
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
const trackEvent = useContext(MetaMetricsContext);
|
||||||
|
|
||||||
const environmentType = getEnvironmentType();
|
const environmentType = getEnvironmentType();
|
||||||
const isFullScreen = environmentType === ENVIRONMENT_TYPE_FULLSCREEN;
|
const isFullScreen = environmentType === ENVIRONMENT_TYPE_FULLSCREEN;
|
||||||
@ -65,6 +71,16 @@ export const NetworkListMenu = ({ onClose }) => {
|
|||||||
} else {
|
} else {
|
||||||
dispatch(setActiveNetwork(network.id));
|
dispatch(setActiveNetwork(network.id));
|
||||||
}
|
}
|
||||||
|
trackEvent({
|
||||||
|
event: MetaMetricsEventName.NavNetworkSwitched,
|
||||||
|
category: MetaMetricsEventCategory.Network,
|
||||||
|
properties: {
|
||||||
|
location: 'Network Menu',
|
||||||
|
chain_id: currentChainId,
|
||||||
|
from_network: currentChainId,
|
||||||
|
to_network: network.id || network.chainId,
|
||||||
|
},
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
onDeleteClick={
|
onDeleteClick={
|
||||||
canDeleteNetwork
|
canDeleteNetwork
|
||||||
@ -92,7 +108,16 @@ export const NetworkListMenu = ({ onClose }) => {
|
|||||||
<Text>{t('showTestnetNetworks')}</Text>
|
<Text>{t('showTestnetNetworks')}</Text>
|
||||||
<ToggleButton
|
<ToggleButton
|
||||||
value={showTestNetworks}
|
value={showTestNetworks}
|
||||||
onToggle={(value) => dispatch(setShowTestNetworks(!value))}
|
onToggle={(value) => {
|
||||||
|
const shouldShowTestNetworks = !value;
|
||||||
|
dispatch(setShowTestNetworks(shouldShowTestNetworks));
|
||||||
|
if (shouldShowTestNetworks) {
|
||||||
|
trackEvent({
|
||||||
|
event: MetaMetricsEventName.TestNetworksDisplayed,
|
||||||
|
category: MetaMetricsEventCategory.Network,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<Box padding={4}>
|
<Box padding={4}>
|
||||||
@ -106,6 +131,10 @@ export const NetworkListMenu = ({ onClose }) => {
|
|||||||
ADD_POPULAR_CUSTOM_NETWORK,
|
ADD_POPULAR_CUSTOM_NETWORK,
|
||||||
);
|
);
|
||||||
dispatch(toggleNetworkMenu());
|
dispatch(toggleNetworkMenu());
|
||||||
|
trackEvent({
|
||||||
|
event: MetaMetricsEventName.AddNetworkButtonClick,
|
||||||
|
category: MetaMetricsEventCategory.Network,
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{t('addNetwork')}
|
{t('addNetwork')}
|
||||||
|
@ -8,3 +8,11 @@ export function getMethodName(camelCase) {
|
|||||||
.replace(/([A-Z])([a-z])/gu, ' $1$2')
|
.replace(/([A-Z])([a-z])/gu, ' $1$2')
|
||||||
.replace(/ +/gu, ' ');
|
.replace(/ +/gu, ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function formatAccountType(accountType) {
|
||||||
|
if (accountType === 'default') {
|
||||||
|
return 'metamask';
|
||||||
|
}
|
||||||
|
|
||||||
|
return accountType;
|
||||||
|
}
|
||||||
|
8
ui/helpers/utils/portfolio.js
Normal file
8
ui/helpers/utils/portfolio.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export function getPortfolioUrl(
|
||||||
|
endpoint = '',
|
||||||
|
metamaskEntry = '',
|
||||||
|
metaMetricsId = '',
|
||||||
|
) {
|
||||||
|
const portfolioUrl = process.env.PORTFOLIO_URL || '';
|
||||||
|
return `${portfolioUrl}/${endpoint}?metamaskEntry=${metamaskEntry}&metametricsId=${metaMetricsId}`;
|
||||||
|
}
|
@ -112,7 +112,7 @@ export default function AddNft() {
|
|||||||
tokenId: tokenId.toString(),
|
tokenId: tokenId.toString(),
|
||||||
asset_type: AssetType.NFT,
|
asset_type: AssetType.NFT,
|
||||||
token_standard: tokenDetails?.standard,
|
token_standard: tokenDetails?.standard,
|
||||||
source: MetaMetricsTokenEventSource.Custom,
|
source_connection_method: MetaMetricsTokenEventSource.Custom,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ const ConfirmAddSuggestedToken = () => {
|
|||||||
token_contract_address: asset.address,
|
token_contract_address: asset.address,
|
||||||
token_decimal_precision: asset.decimals,
|
token_decimal_precision: asset.decimals,
|
||||||
unlisted: asset.unlisted,
|
unlisted: asset.unlisted,
|
||||||
source: MetaMetricsTokenEventSource.Dapp,
|
source_connection_method: MetaMetricsTokenEventSource.Dapp,
|
||||||
token_standard: TokenStandard.ERC20,
|
token_standard: TokenStandard.ERC20,
|
||||||
asset_type: AssetType.token,
|
asset_type: AssetType.token,
|
||||||
},
|
},
|
||||||
|
@ -51,7 +51,7 @@ const ConfirmImportToken = () => {
|
|||||||
token_contract_address: pendingToken.address,
|
token_contract_address: pendingToken.address,
|
||||||
token_decimal_precision: pendingToken.decimals,
|
token_decimal_precision: pendingToken.decimals,
|
||||||
unlisted: pendingToken.unlisted,
|
unlisted: pendingToken.unlisted,
|
||||||
source: pendingToken.isCustom
|
source_connection_method: pendingToken.isCustom
|
||||||
? MetaMetricsTokenEventSource.Custom
|
? MetaMetricsTokenEventSource.Custom
|
||||||
: MetaMetricsTokenEventSource.List,
|
: MetaMetricsTokenEventSource.List,
|
||||||
token_standard: TokenStandard.ERC20,
|
token_standard: TokenStandard.ERC20,
|
||||||
|
@ -48,10 +48,12 @@ export default function NewAccountImportForm() {
|
|||||||
navigateToMostRecentOverviewPage();
|
navigateToMostRecentOverviewPage();
|
||||||
} else {
|
} else {
|
||||||
dispatch(actions.displayWarning(t('importAccountError')));
|
dispatch(actions.displayWarning(t('importAccountError')));
|
||||||
trackImportEvent(strategy, false);
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => translateWarning(error.message));
|
.catch((error) => {
|
||||||
|
trackImportEvent(strategy, error.message);
|
||||||
|
translateWarning(error.message);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function trackImportEvent(strategy, wasSuccessful) {
|
function trackImportEvent(strategy, wasSuccessful) {
|
||||||
|
@ -35,6 +35,7 @@ export default class NewAccountCreateForm extends Component {
|
|||||||
event: MetaMetricsEventName.AccountAdded,
|
event: MetaMetricsEventName.AccountAdded,
|
||||||
properties: {
|
properties: {
|
||||||
account_type: MetaMetricsEventAccountType.Default,
|
account_type: MetaMetricsEventAccountType.Default,
|
||||||
|
location: 'Home',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
history.push(mostRecentOverviewPage);
|
history.push(mostRecentOverviewPage);
|
||||||
|
@ -674,7 +674,24 @@ export default class Home extends PureComponent {
|
|||||||
<Tabs
|
<Tabs
|
||||||
t={this.context.t}
|
t={this.context.t}
|
||||||
defaultActiveTabKey={defaultHomeActiveTabName}
|
defaultActiveTabKey={defaultHomeActiveTabName}
|
||||||
onTabClick={onTabClick}
|
onTabClick={(tabName) => {
|
||||||
|
onTabClick(tabName);
|
||||||
|
let event;
|
||||||
|
switch (tabName) {
|
||||||
|
case 'nfts':
|
||||||
|
event = MetaMetricsEventName.NftScreenOpened;
|
||||||
|
break;
|
||||||
|
case 'activity':
|
||||||
|
event = MetaMetricsEventName.ActivityScreenOpened;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
event = MetaMetricsEventName.TokenScreenOpened;
|
||||||
|
}
|
||||||
|
this.context.trackEvent({
|
||||||
|
category: MetaMetricsEventCategory.Home,
|
||||||
|
event,
|
||||||
|
});
|
||||||
|
}}
|
||||||
tabsClassName="home__tabs"
|
tabsClassName="home__tabs"
|
||||||
>
|
>
|
||||||
<Tab
|
<Tab
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
import React, {
|
||||||
|
useCallback,
|
||||||
|
useContext,
|
||||||
|
useEffect,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
} from 'react';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import validUrl from 'valid-url';
|
import validUrl from 'valid-url';
|
||||||
@ -23,12 +29,17 @@ import {
|
|||||||
} from '../../../../store/actions';
|
} from '../../../../store/actions';
|
||||||
import fetchWithCache from '../../../../../shared/lib/fetch-with-cache';
|
import fetchWithCache from '../../../../../shared/lib/fetch-with-cache';
|
||||||
import { usePrevious } from '../../../../hooks/usePrevious';
|
import { usePrevious } from '../../../../hooks/usePrevious';
|
||||||
import { MetaMetricsNetworkEventSource } from '../../../../../shared/constants/metametrics';
|
import {
|
||||||
|
MetaMetricsEventCategory,
|
||||||
|
MetaMetricsEventName,
|
||||||
|
MetaMetricsNetworkEventSource,
|
||||||
|
} from '../../../../../shared/constants/metametrics';
|
||||||
import {
|
import {
|
||||||
infuraProjectId,
|
infuraProjectId,
|
||||||
FEATURED_RPCS,
|
FEATURED_RPCS,
|
||||||
} from '../../../../../shared/constants/network';
|
} from '../../../../../shared/constants/network';
|
||||||
import { decimalToHex } from '../../../../../shared/modules/conversion.utils';
|
import { decimalToHex } from '../../../../../shared/modules/conversion.utils';
|
||||||
|
import { MetaMetricsContext } from '../../../../contexts/metametrics';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to convert the given chainId to a decimal string, for display
|
* Attempts to convert the given chainId to a decimal string, for display
|
||||||
@ -96,6 +107,8 @@ const NetworksForm = ({
|
|||||||
const [isEditing, setIsEditing] = useState(Boolean(addNewNetwork));
|
const [isEditing, setIsEditing] = useState(Boolean(addNewNetwork));
|
||||||
const [previousNetwork, setPreviousNetwork] = useState(selectedNetwork);
|
const [previousNetwork, setPreviousNetwork] = useState(selectedNetwork);
|
||||||
|
|
||||||
|
const trackEvent = useContext(MetaMetricsContext);
|
||||||
|
|
||||||
const resetForm = useCallback(() => {
|
const resetForm = useCallback(() => {
|
||||||
setNetworkName(selectedNetworkName || '');
|
setNetworkName(selectedNetworkName || '');
|
||||||
setRpcUrl(selectedNetwork.rpcUrl);
|
setRpcUrl(selectedNetwork.rpcUrl);
|
||||||
@ -543,6 +556,19 @@ const NetworksForm = ({
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
trackEvent({
|
||||||
|
event: MetaMetricsEventName.CustomNetworkAdded,
|
||||||
|
category: MetaMetricsEventCategory.Network,
|
||||||
|
properties: {
|
||||||
|
block_explorer_url: blockExplorerUrl,
|
||||||
|
chain_id: prefixedChainId,
|
||||||
|
network_name: networkName,
|
||||||
|
source_connection_method:
|
||||||
|
MetaMetricsNetworkEventSource.CustomNetworkForm,
|
||||||
|
token_symbol: ticker,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
submitCallback?.();
|
submitCallback?.();
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -119,6 +119,11 @@ export function getCurrentChainId(state) {
|
|||||||
return chainId;
|
return chainId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getMetaMetricsId(state) {
|
||||||
|
const { metaMetricsId } = state.metamask;
|
||||||
|
return metaMetricsId;
|
||||||
|
}
|
||||||
|
|
||||||
export function isCurrentProviderCustom(state) {
|
export function isCurrentProviderCustom(state) {
|
||||||
const provider = getProvider(state);
|
const provider = getProvider(state);
|
||||||
return (
|
return (
|
||||||
@ -233,7 +238,15 @@ export function getHardwareWalletType(state) {
|
|||||||
|
|
||||||
export function getAccountType(state) {
|
export function getAccountType(state) {
|
||||||
const currentKeyring = getCurrentKeyring(state);
|
const currentKeyring = getCurrentKeyring(state);
|
||||||
const type = currentKeyring && currentKeyring.type;
|
return getAccountTypeForKeyring(currentKeyring);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAccountTypeForKeyring(keyring) {
|
||||||
|
if (!keyring) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const { type } = keyring;
|
||||||
|
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
if (type.startsWith('Custody')) {
|
if (type.startsWith('Custody')) {
|
||||||
@ -245,6 +258,7 @@ export function getAccountType(state) {
|
|||||||
case KeyringType.trezor:
|
case KeyringType.trezor:
|
||||||
case KeyringType.ledger:
|
case KeyringType.ledger:
|
||||||
case KeyringType.lattice:
|
case KeyringType.lattice:
|
||||||
|
case KeyringType.qr:
|
||||||
return 'hardware';
|
return 'hardware';
|
||||||
case KeyringType.imported:
|
case KeyringType.imported:
|
||||||
return 'imported';
|
return 'imported';
|
||||||
|
Loading…
Reference in New Issue
Block a user