mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Move "Enable Opensea API" and "NFT Autodetect" into Security & Privacy settings (#20278)
* move opensea api and nft settings to security tab * DS techdebt; experimental tab * rerouting the NFT tab enable autodetect to setting * reverting vscode settings and preferences.js * Rerouting NFT tab autodetect setting banner link * resolving settingsRef collision
This commit is contained in:
parent
6947133899
commit
97073e1907
@ -2,7 +2,7 @@ import React from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { BannerAlert } from '../../component-library';
|
||||
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||
import { EXPERIMENTAL_ROUTE } from '../../../helpers/constants/routes';
|
||||
import { SECURITY_ROUTE } from '../../../helpers/constants/routes';
|
||||
|
||||
export default function NftsDetectionNotice() {
|
||||
const t = useI18nContext();
|
||||
@ -15,7 +15,7 @@ export default function NftsDetectionNotice() {
|
||||
actionButtonLabel={t('selectNFTPrivacyPreference')}
|
||||
actionButtonOnClick={(e) => {
|
||||
e.preventDefault();
|
||||
history.push(`${EXPERIMENTAL_ROUTE}#autodetect-nfts`);
|
||||
history.push(`${SECURITY_ROUTE}#autodetect-nfts`);
|
||||
}}
|
||||
>
|
||||
{t('newNFTDetectedMessage')}
|
||||
|
@ -14,7 +14,7 @@ import {
|
||||
} from '../../../helpers/constants/design-system';
|
||||
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||
import { getIsMainnet, getUseNftDetection } from '../../../selectors';
|
||||
import { EXPERIMENTAL_ROUTE } from '../../../helpers/constants/routes';
|
||||
import { SECURITY_ROUTE } from '../../../helpers/constants/routes';
|
||||
import {
|
||||
checkAndUpdateAllNftsOwnershipStatus,
|
||||
detectNfts,
|
||||
@ -36,7 +36,7 @@ export default function NftsTab() {
|
||||
useNftsCollections();
|
||||
|
||||
const onEnableAutoDetect = () => {
|
||||
history.push(EXPERIMENTAL_ROUTE);
|
||||
history.push(SECURITY_ROUTE);
|
||||
};
|
||||
|
||||
const onRefresh = () => {
|
||||
|
@ -3,7 +3,7 @@ import { fireEvent, screen } from '@testing-library/react';
|
||||
import reactRouterDom from 'react-router-dom';
|
||||
import configureStore from '../../../store/store';
|
||||
import { renderWithProvider } from '../../../../test/jest/rendering';
|
||||
import { EXPERIMENTAL_ROUTE } from '../../../helpers/constants/routes';
|
||||
import { SECURITY_ROUTE } from '../../../helpers/constants/routes';
|
||||
import { setBackgroundConnection } from '../../../../test/jest';
|
||||
import NftsTab from '.';
|
||||
|
||||
@ -218,7 +218,7 @@ describe('NFT Items', () => {
|
||||
fireEvent.click(screen.queryByText('Turn on NFT detection in Settings'));
|
||||
expect(historyPushMock).toHaveBeenCalledTimes(1);
|
||||
expect(historyPushMock).toHaveBeenCalledWith(
|
||||
`${EXPERIMENTAL_ROUTE}#autodetect-nfts`,
|
||||
`${SECURITY_ROUTE}#autodetect-nfts`,
|
||||
);
|
||||
});
|
||||
it('should not render the NFTs Detection Notice when currently selected network is Mainnet and currently selected account has no NFTs but use NFT autodetection preference is set to true', () => {
|
||||
@ -292,7 +292,7 @@ describe('NFT Items', () => {
|
||||
expect(historyPushMock).toHaveBeenCalledTimes(0);
|
||||
fireEvent.click(screen.queryByText('Enable autodetect'));
|
||||
expect(historyPushMock).toHaveBeenCalledTimes(1);
|
||||
expect(historyPushMock).toHaveBeenCalledWith(EXPERIMENTAL_ROUTE);
|
||||
expect(historyPushMock).toHaveBeenCalledWith(SECURITY_ROUTE);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -213,6 +213,20 @@ export const SETTINGS_CONSTANTS = [
|
||||
route: `${SECURITY_ROUTE}#ens-domains`,
|
||||
icon: 'fa fa-lock',
|
||||
},
|
||||
{
|
||||
tabMessage: (t) => t('securityAndPrivacy'),
|
||||
sectionMessage: (t) => t('enableOpenSeaAPI'),
|
||||
descriptionMessage: (t) => t('enableOpenSeaAPIDescription'),
|
||||
route: `${SECURITY_ROUTE}#opensea-api`,
|
||||
icon: 'fa fa-lock',
|
||||
},
|
||||
{
|
||||
tabMessage: (t) => t('securityAndPrivacy'),
|
||||
sectionMessage: (t) => t('useNftDetection'),
|
||||
descriptionMessage: (t) => t('useNftDetectionDescription'),
|
||||
route: `${SECURITY_ROUTE}#autodetect-nfts`,
|
||||
icon: 'fa fa-lock',
|
||||
},
|
||||
{
|
||||
tabMessage: (t) => t('alerts'),
|
||||
sectionMessage: (t) => t('alertSettingsUnconnectedAccount'),
|
||||
@ -336,20 +350,6 @@ export const SETTINGS_CONSTANTS = [
|
||||
route: `${ABOUT_US_ROUTE}#beta-terms`,
|
||||
iconName: IconName.Info,
|
||||
},
|
||||
{
|
||||
tabMessage: (t) => t('experimental'),
|
||||
sectionMessage: (t) => t('enableOpenSeaAPI'),
|
||||
descriptionMessage: (t) => t('enableOpenSeaAPIDescription'),
|
||||
route: `${EXPERIMENTAL_ROUTE}#opensea-api`,
|
||||
icon: 'fa fa-flask',
|
||||
},
|
||||
{
|
||||
tabMessage: (t) => t('experimental'),
|
||||
sectionMessage: (t) => t('useNftDetection'),
|
||||
descriptionMessage: (t) => t('useNftDetectionDescription'),
|
||||
route: `${EXPERIMENTAL_ROUTE}#autodetect-nfts`,
|
||||
icon: 'fa fa-flask',
|
||||
},
|
||||
{
|
||||
tabMessage: (t) => t('advanced'),
|
||||
sectionMessage: (t) => t('backupUserData'),
|
||||
|
@ -165,7 +165,7 @@ describe('Settings Search Utils', () => {
|
||||
it('should get good security & privacy section number', () => {
|
||||
expect(
|
||||
getNumberOfSettingsInSection(t, t('securityAndPrivacy')),
|
||||
).toStrictEqual(10);
|
||||
).toStrictEqual(12);
|
||||
});
|
||||
|
||||
it('should get good alerts section number', () => {
|
||||
@ -178,7 +178,7 @@ describe('Settings Search Utils', () => {
|
||||
|
||||
it('should get good experimental section number', () => {
|
||||
expect(getNumberOfSettingsInSection(t, t('experimental'))).toStrictEqual(
|
||||
3,
|
||||
1,
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -96,7 +96,7 @@ exports[`ExperimentalTab with desktop enabled renders ExperimentalTab component
|
||||
</div>
|
||||
</div>
|
||||
<h4
|
||||
class="box box--margin-top-1 box--margin-bottom-2 box--flex-direction-row typography typography--h4 typography--weight-bold typography--style-normal typography--color-text-alternative"
|
||||
class="mm-box mm-text mm-text--heading-sm mm-text--font-weight-bold mm-box--margin-bottom-2 mm-box--color-text-alternative"
|
||||
>
|
||||
Privacy
|
||||
</h4>
|
||||
@ -112,24 +112,24 @@ exports[`ExperimentalTab with desktop enabled renders ExperimentalTab component
|
||||
<div
|
||||
class="settings-page__content-description"
|
||||
>
|
||||
<h6
|
||||
class="box box--margin-top-1 box--margin-bottom-1 box--flex-direction-row typography typography--h6 typography--weight-normal typography--style-normal typography--color-text-alternative"
|
||||
<p
|
||||
class="mm-box mm-text mm-text--body-sm mm-box--color-text-alternative"
|
||||
>
|
||||
We use third-party APIs to detect and display risks involved in unsigned transaction and signature requests before you sign them. These services will have access to your unsigned transaction and signature requests, your account address, and your preferred language.
|
||||
</h6>
|
||||
<h6
|
||||
class="box box--margin-top-3 box--margin-bottom-1 box--flex-direction-row typography typography--h6 typography--weight-normal typography--style-normal typography--color-text-alternative"
|
||||
</p>
|
||||
<p
|
||||
class="mm-box mm-text mm-text--body-sm mm-box--margin-top-3 mm-box--margin-bottom-1 mm-box--color-text-alternative"
|
||||
>
|
||||
Select providers:
|
||||
</h6>
|
||||
</p>
|
||||
<div
|
||||
class="settings-page__content-item-col settings-page__content-item-col-open-sea"
|
||||
>
|
||||
<h5
|
||||
class="box box--margin-top-1 box--flex-direction-row typography typography--h5 typography--weight-medium typography--style-normal typography--color-text-default"
|
||||
<p
|
||||
class="mm-box mm-text mm-text--body-md mm-text--font-weight-medium mm-box--margin-bottom-0 mm-box--color-text-default"
|
||||
>
|
||||
OpenSea + Blockaid (Beta)
|
||||
</h5>
|
||||
</p>
|
||||
<label
|
||||
class="toggle-button toggle-button--off"
|
||||
tabindex="0"
|
||||
@ -172,8 +172,8 @@ exports[`ExperimentalTab with desktop enabled renders ExperimentalTab component
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<h6
|
||||
class="box box--margin-bottom-1 box--flex-direction-row typography typography--h6 typography--weight-normal typography--style-normal typography--color-text-alternative"
|
||||
<p
|
||||
class="mm-box mm-text mm-text--body-sm mm-box--margin-top-0 mm-box--color-text-alternative"
|
||||
>
|
||||
<span>
|
||||
|
||||
@ -188,172 +188,12 @@ exports[`ExperimentalTab with desktop enabled renders ExperimentalTab component
|
||||
.
|
||||
|
||||
</span>
|
||||
</h6>
|
||||
<h5
|
||||
class="box box--margin-top-2 box--margin-bottom-1 box--flex-direction-row typography typography--h5 typography--weight-medium typography--style-normal typography--color-text-muted"
|
||||
</p>
|
||||
<p
|
||||
class="mm-box mm-text mm-text--body-md mm-text--font-weight-medium mm-box--margin-top-2 mm-box--color-text-muted"
|
||||
>
|
||||
More providers coming soon
|
||||
</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="settings-page__content-row"
|
||||
>
|
||||
<div
|
||||
class="settings-page__content-item"
|
||||
>
|
||||
<span>
|
||||
Enable OpenSea API
|
||||
</span>
|
||||
<div
|
||||
class="settings-page__content-description"
|
||||
>
|
||||
Use OpenSea's API to fetch NFT data. NFT auto-detection relies on OpenSea's API, and will not be available when this is turned off.
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="settings-page__content-item"
|
||||
>
|
||||
<div
|
||||
class="settings-page__content-item-col"
|
||||
>
|
||||
<label
|
||||
class="toggle-button toggle-button--off"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
style="display: flex; width: 52px; align-items: center; justify-content: flex-start; position: relative; cursor: pointer; background-color: transparent; border: 0px; padding: 0px; user-select: none;"
|
||||
>
|
||||
<div
|
||||
style="width: 40px; height: 24px; padding: 0px; border-radius: 26px; display: flex; align-items: center; justify-content: center; background-color: rgb(242, 244, 246);"
|
||||
>
|
||||
<div
|
||||
style="font-size: 11px; display: flex; align-items: center; justify-content: center; font-family: 'Helvetica Neue', Helvetica, sans-serif; position: relative; color: rgb(250, 250, 250); margin-top: auto; margin-bottom: auto; line-height: 0; opacity: 0; width: 26px; height: 20px; left: 4px;"
|
||||
/>
|
||||
<div
|
||||
style="font-size: 11px; display: flex; align-items: center; justify-content: center; font-family: 'Helvetica Neue', Helvetica, sans-serif; position: relative; color: rgba(255, 255, 255, 0.6); bottom: 0px; margin-top: auto; margin-bottom: auto; padding-right: 5px; line-height: 0; width: 26px; height: 20px; opacity: 1;"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
style="position: absolute; height: 100%; top: 0px; left: 0px; display: flex; flex: 1; align-self: stretch; align-items: center; justify-content: flex-start;"
|
||||
>
|
||||
<div
|
||||
style="width: 18px; height: 18px; display: flex; align-self: center; box-shadow: none; border-radius: 50%; box-sizing: border-box; position: relative; background-color: rgb(106, 115, 125); left: 3px;"
|
||||
/>
|
||||
</div>
|
||||
<input
|
||||
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: absolute; width: 1px;"
|
||||
type="checkbox"
|
||||
value="false"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="toggle-button__status"
|
||||
>
|
||||
<span
|
||||
class="toggle-button__label-off"
|
||||
>
|
||||
Off
|
||||
</span>
|
||||
<span
|
||||
class="toggle-button__label-on"
|
||||
>
|
||||
On
|
||||
</span>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="settings-page__content-row"
|
||||
>
|
||||
<div
|
||||
class="settings-page__content-item"
|
||||
>
|
||||
<span>
|
||||
Autodetect NFTs
|
||||
</span>
|
||||
<div
|
||||
class="settings-page__content-description"
|
||||
>
|
||||
<p
|
||||
class="mm-box mm-text mm-text--body-md mm-box--color-text-alternative"
|
||||
>
|
||||
We use third-party APIs to detect NFTs in your wallet, which means your IP address may be exposed to centralized servers. There are a few things to be cautious about when enabling this feature.
|
||||
</p>
|
||||
<ul
|
||||
class="settings-page__content-unordered-list"
|
||||
>
|
||||
<li>
|
||||
Your account address will be viewable to third-party APIs.
|
||||
</li>
|
||||
<li>
|
||||
NFT metadata may contain links to scams or phishing sites.
|
||||
</li>
|
||||
<li>
|
||||
Anyone can airdrop NFTs to your account. This can include offensive content that might be automatically displayed in your wallet.
|
||||
</li>
|
||||
</ul>
|
||||
<p
|
||||
class="mm-box mm-text mm-text--body-md mm-box--padding-top-4 mm-box--color-text-alternative"
|
||||
>
|
||||
Leave this feature off if you don't want the app to pull data from those services.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="settings-page__content-item"
|
||||
>
|
||||
<div
|
||||
class="settings-page__content-item-col"
|
||||
>
|
||||
<label
|
||||
class="toggle-button toggle-button--off"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
style="display: flex; width: 52px; align-items: center; justify-content: flex-start; position: relative; cursor: pointer; background-color: transparent; border: 0px; padding: 0px; user-select: none;"
|
||||
>
|
||||
<div
|
||||
style="width: 40px; height: 24px; padding: 0px; border-radius: 26px; display: flex; align-items: center; justify-content: center; background-color: rgb(242, 244, 246);"
|
||||
>
|
||||
<div
|
||||
style="font-size: 11px; display: flex; align-items: center; justify-content: center; font-family: 'Helvetica Neue', Helvetica, sans-serif; position: relative; color: rgb(250, 250, 250); margin-top: auto; margin-bottom: auto; line-height: 0; opacity: 0; width: 26px; height: 20px; left: 4px;"
|
||||
/>
|
||||
<div
|
||||
style="font-size: 11px; display: flex; align-items: center; justify-content: center; font-family: 'Helvetica Neue', Helvetica, sans-serif; position: relative; color: rgba(255, 255, 255, 0.6); bottom: 0px; margin-top: auto; margin-bottom: auto; padding-right: 5px; line-height: 0; width: 26px; height: 20px; opacity: 1;"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
style="position: absolute; height: 100%; top: 0px; left: 0px; display: flex; flex: 1; align-self: stretch; align-items: center; justify-content: flex-start;"
|
||||
>
|
||||
<div
|
||||
style="width: 18px; height: 18px; display: flex; align-self: center; box-shadow: none; border-radius: 50%; box-sizing: border-box; position: relative; background-color: rgb(106, 115, 125); left: 3px;"
|
||||
/>
|
||||
</div>
|
||||
<input
|
||||
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: absolute; width: 1px;"
|
||||
type="checkbox"
|
||||
value="false"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="toggle-button__status"
|
||||
>
|
||||
<span
|
||||
class="toggle-button__label-off"
|
||||
>
|
||||
Off
|
||||
</span>
|
||||
<span
|
||||
class="toggle-button__label-on"
|
||||
>
|
||||
On
|
||||
</span>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -6,15 +6,11 @@ import {
|
||||
handleSettingsRefs,
|
||||
} from '../../../helpers/utils/settings-search';
|
||||
import { MetaMetricsEventCategory } from '../../../../shared/constants/metametrics';
|
||||
import Typography from '../../../components/ui/typography/typography';
|
||||
import { Text } from '../../../components/component-library';
|
||||
import {
|
||||
FONT_WEIGHT,
|
||||
FontWeight,
|
||||
TextColor,
|
||||
///: BEGIN:ONLY_INCLUDE_IN(blockaid)
|
||||
TextVariant,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
TypographyVariant,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
///: BEGIN:ONLY_INCLUDE_IN(desktop)
|
||||
import DesktopEnableButton from '../../../components/app/desktop-enable-button';
|
||||
@ -27,10 +23,6 @@ export default class ExperimentalTab extends PureComponent {
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
useNftDetection: PropTypes.bool,
|
||||
setUseNftDetection: PropTypes.func,
|
||||
setOpenSeaEnabled: PropTypes.func,
|
||||
openSeaEnabled: PropTypes.bool,
|
||||
transactionSecurityCheckEnabled: PropTypes.bool,
|
||||
setTransactionSecurityCheckEnabled: PropTypes.func,
|
||||
///: BEGIN:ONLY_INCLUDE_IN(blockaid)
|
||||
@ -65,7 +57,6 @@ export default class ExperimentalTab extends PureComponent {
|
||||
const { t } = this.context;
|
||||
|
||||
const { securityAlertsEnabled, setSecurityAlertsEnabled } = this.props;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Text
|
||||
@ -141,94 +132,6 @@ export default class ExperimentalTab extends PureComponent {
|
||||
}
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
renderOpenSeaEnabledToggle() {
|
||||
const { t } = this.context;
|
||||
const {
|
||||
openSeaEnabled,
|
||||
setOpenSeaEnabled,
|
||||
useNftDetection,
|
||||
setUseNftDetection,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div ref={this.settingsRefs[0]} className="settings-page__content-row">
|
||||
<div className="settings-page__content-item">
|
||||
<span>{t('enableOpenSeaAPI')}</span>
|
||||
<div className="settings-page__content-description">
|
||||
{t('enableOpenSeaAPIDescription')}
|
||||
</div>
|
||||
</div>
|
||||
<div className="settings-page__content-item">
|
||||
<div className="settings-page__content-item-col">
|
||||
<ToggleButton
|
||||
value={openSeaEnabled}
|
||||
onToggle={(value) => {
|
||||
this.context.trackEvent({
|
||||
category: MetaMetricsEventCategory.Settings,
|
||||
event: 'Enabled/Disable OpenSea',
|
||||
properties: {
|
||||
action: 'Enabled/Disable OpenSea',
|
||||
legacy_event: true,
|
||||
},
|
||||
});
|
||||
// value is positive when being toggled off
|
||||
if (value && useNftDetection) {
|
||||
setUseNftDetection(false);
|
||||
}
|
||||
setOpenSeaEnabled(!value);
|
||||
}}
|
||||
offLabel={t('off')}
|
||||
onLabel={t('on')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ref={this.settingsRefs[1]} className="settings-page__content-row">
|
||||
<div className="settings-page__content-item">
|
||||
<span>{t('useNftDetection')}</span>
|
||||
<div className="settings-page__content-description">
|
||||
<Text color={TextColor.textAlternative}>
|
||||
{t('useNftDetectionDescription')}
|
||||
</Text>
|
||||
<ul className="settings-page__content-unordered-list">
|
||||
<li>{t('useNftDetectionDescriptionLine2')}</li>
|
||||
<li>{t('useNftDetectionDescriptionLine3')}</li>
|
||||
<li>{t('useNftDetectionDescriptionLine4')}</li>
|
||||
</ul>
|
||||
<Text color={TextColor.textAlternative} paddingTop={4}>
|
||||
{t('useNftDetectionDescriptionLine5')}
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
<div className="settings-page__content-item">
|
||||
<div className="settings-page__content-item-col">
|
||||
<ToggleButton
|
||||
value={useNftDetection}
|
||||
onToggle={(value) => {
|
||||
this.context.trackEvent({
|
||||
category: MetaMetricsEventCategory.Settings,
|
||||
event: 'NFT Detected',
|
||||
properties: {
|
||||
action: 'NFT Detected',
|
||||
legacy_event: true,
|
||||
},
|
||||
});
|
||||
if (!value && !openSeaEnabled) {
|
||||
setOpenSeaEnabled(!value);
|
||||
}
|
||||
setUseNftDetection(!value);
|
||||
}}
|
||||
offLabel={t('off')}
|
||||
onLabel={t('on')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
renderTransactionSecurityCheckToggle() {
|
||||
const { t } = this.context;
|
||||
|
||||
@ -239,14 +142,14 @@ export default class ExperimentalTab extends PureComponent {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Typography
|
||||
variant={TypographyVariant.H4}
|
||||
<Text
|
||||
variant={TextVariant.headingSm}
|
||||
color={TextColor.textAlternative}
|
||||
marginBottom={2}
|
||||
fontWeight={FONT_WEIGHT.BOLD}
|
||||
fontWeight={FontWeight.Bold}
|
||||
>
|
||||
{t('privacy')}
|
||||
</Typography>
|
||||
</Text>
|
||||
<div
|
||||
ref={this.settingsRefs[1]}
|
||||
className="settings-page__content-row settings-page__content-row-experimental"
|
||||
@ -254,29 +157,29 @@ export default class ExperimentalTab extends PureComponent {
|
||||
<div className="settings-page__content-item">
|
||||
<span>{t('transactionSecurityCheck')}</span>
|
||||
<div className="settings-page__content-description">
|
||||
<Typography
|
||||
variant={TypographyVariant.H6}
|
||||
<Text
|
||||
variant={TextVariant.bodySm}
|
||||
color={TextColor.textAlternative}
|
||||
>
|
||||
{t('transactionSecurityCheckDescription')}
|
||||
</Typography>
|
||||
<Typography
|
||||
</Text>
|
||||
<Text
|
||||
marginTop={3}
|
||||
marginBottom={1}
|
||||
variant={TypographyVariant.H6}
|
||||
variant={TextVariant.bodySm}
|
||||
color={TextColor.textAlternative}
|
||||
>
|
||||
{t('selectProvider')}
|
||||
</Typography>
|
||||
</Text>
|
||||
<div className="settings-page__content-item-col settings-page__content-item-col-open-sea">
|
||||
<Typography
|
||||
variant={TypographyVariant.H5}
|
||||
<Text
|
||||
variant={TextVariant.bodyMd}
|
||||
color={TextColor.textDefault}
|
||||
fontWeight={FONT_WEIGHT.MEDIUM}
|
||||
fontWeight={FontWeight.Medium}
|
||||
marginBottom={0}
|
||||
>
|
||||
{t('openSea')}
|
||||
</Typography>
|
||||
</Text>
|
||||
<ToggleButton
|
||||
value={transactionSecurityCheckEnabled}
|
||||
onToggle={(value) => {
|
||||
@ -292,8 +195,8 @@ export default class ExperimentalTab extends PureComponent {
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<Typography
|
||||
variant={TypographyVariant.H6}
|
||||
<Text
|
||||
variant={TextVariant.bodySm}
|
||||
color={TextColor.textAlternative}
|
||||
marginTop={0}
|
||||
>
|
||||
@ -307,15 +210,15 @@ export default class ExperimentalTab extends PureComponent {
|
||||
{t('termsOfUse')}
|
||||
</a>,
|
||||
])}
|
||||
</Typography>
|
||||
<Typography
|
||||
variant={TypographyVariant.H5}
|
||||
</Text>
|
||||
<Text
|
||||
variant={TextVariant.bodyMd}
|
||||
color={TextColor.textMuted}
|
||||
fontWeight={FONT_WEIGHT.MEDIUM}
|
||||
fontWeight={FontWeight.Medium}
|
||||
marginTop={2}
|
||||
>
|
||||
{t('moreComingSoon')}
|
||||
</Typography>
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -355,7 +258,6 @@ export default class ExperimentalTab extends PureComponent {
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
}
|
||||
{this.renderTransactionSecurityCheckToggle()}
|
||||
{this.renderOpenSeaEnabledToggle()}
|
||||
{
|
||||
///: BEGIN:ONLY_INCLUDE_IN(desktop)
|
||||
this.renderDesktopEnableButton()
|
||||
|
@ -2,16 +2,12 @@ import { compose } from 'redux';
|
||||
import { connect } from 'react-redux';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import {
|
||||
setUseNftDetection,
|
||||
setOpenSeaEnabled,
|
||||
setTransactionSecurityCheckEnabled,
|
||||
///: BEGIN:ONLY_INCLUDE_IN(blockaid)
|
||||
setSecurityAlertsEnabled,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
} from '../../../store/actions';
|
||||
import {
|
||||
getUseNftDetection,
|
||||
getOpenSeaEnabled,
|
||||
getIsTransactionSecurityCheckEnabled,
|
||||
///: BEGIN:ONLY_INCLUDE_IN(blockaid)
|
||||
getIsSecurityAlertsEnabled,
|
||||
@ -21,8 +17,6 @@ import ExperimentalTab from './experimental-tab.component';
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
return {
|
||||
useNftDetection: getUseNftDetection(state),
|
||||
openSeaEnabled: getOpenSeaEnabled(state),
|
||||
transactionSecurityCheckEnabled:
|
||||
getIsTransactionSecurityCheckEnabled(state),
|
||||
///: BEGIN:ONLY_INCLUDE_IN(blockaid)
|
||||
@ -33,8 +27,6 @@ const mapStateToProps = (state) => {
|
||||
|
||||
const mapDispatchToProps = (dispatch) => {
|
||||
return {
|
||||
setUseNftDetection: (val) => dispatch(setUseNftDetection(val)),
|
||||
setOpenSeaEnabled: (val) => dispatch(setOpenSeaEnabled(val)),
|
||||
setTransactionSecurityCheckEnabled: (val) =>
|
||||
dispatch(setTransactionSecurityCheckEnabled(val)),
|
||||
///: BEGIN:ONLY_INCLUDE_IN(blockaid)
|
||||
|
@ -714,6 +714,168 @@ exports[`Security Tab should match snapshot 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="settings-page__content-row"
|
||||
>
|
||||
<div
|
||||
class="settings-page__content-item"
|
||||
>
|
||||
<span>
|
||||
Enable OpenSea API
|
||||
</span>
|
||||
<div
|
||||
class="settings-page__content-description"
|
||||
>
|
||||
Use OpenSea's API to fetch NFT data. NFT auto-detection relies on OpenSea's API, and will not be available when this is turned off.
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="settings-page__content-item"
|
||||
>
|
||||
<div
|
||||
class="settings-page__content-item-col"
|
||||
data-testid="enableOpenSeaAPI"
|
||||
>
|
||||
<label
|
||||
class="toggle-button toggle-button--off"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
style="display: flex; width: 52px; align-items: center; justify-content: flex-start; position: relative; cursor: pointer; background-color: transparent; border: 0px; padding: 0px; user-select: none;"
|
||||
>
|
||||
<div
|
||||
style="width: 40px; height: 24px; padding: 0px; border-radius: 26px; display: flex; align-items: center; justify-content: center; background-color: rgb(242, 244, 246);"
|
||||
>
|
||||
<div
|
||||
style="font-size: 11px; display: flex; align-items: center; justify-content: center; font-family: 'Helvetica Neue', Helvetica, sans-serif; position: relative; color: rgb(250, 250, 250); margin-top: auto; margin-bottom: auto; line-height: 0; opacity: 0; width: 26px; height: 20px; left: 4px;"
|
||||
/>
|
||||
<div
|
||||
style="font-size: 11px; display: flex; align-items: center; justify-content: center; font-family: 'Helvetica Neue', Helvetica, sans-serif; position: relative; color: rgba(255, 255, 255, 0.6); bottom: 0px; margin-top: auto; margin-bottom: auto; padding-right: 5px; line-height: 0; width: 26px; height: 20px; opacity: 1;"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
style="position: absolute; height: 100%; top: 0px; left: 0px; display: flex; flex: 1; align-self: stretch; align-items: center; justify-content: flex-start;"
|
||||
>
|
||||
<div
|
||||
style="width: 18px; height: 18px; display: flex; align-self: center; box-shadow: none; border-radius: 50%; box-sizing: border-box; position: relative; background-color: rgb(106, 115, 125); left: 3px;"
|
||||
/>
|
||||
</div>
|
||||
<input
|
||||
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: absolute; width: 1px;"
|
||||
type="checkbox"
|
||||
value="false"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="toggle-button__status"
|
||||
>
|
||||
<span
|
||||
class="toggle-button__label-off"
|
||||
>
|
||||
Off
|
||||
</span>
|
||||
<span
|
||||
class="toggle-button__label-on"
|
||||
>
|
||||
On
|
||||
</span>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="settings-page__content-row"
|
||||
>
|
||||
<div
|
||||
class="settings-page__content-item"
|
||||
>
|
||||
<span>
|
||||
Autodetect NFTs
|
||||
</span>
|
||||
<div
|
||||
class="settings-page__content-description"
|
||||
>
|
||||
<p
|
||||
class="mm-box mm-text mm-text--body-md mm-box--color-text-alternative"
|
||||
>
|
||||
We use third-party APIs to detect NFTs in your wallet, which means your IP address may be exposed to centralized servers. There are a few things to be cautious about when enabling this feature.
|
||||
</p>
|
||||
<ul
|
||||
class="settings-page__content-unordered-list"
|
||||
>
|
||||
<li>
|
||||
Your account address will be viewable to third-party APIs.
|
||||
</li>
|
||||
<li>
|
||||
NFT metadata may contain links to scams or phishing sites.
|
||||
</li>
|
||||
<li>
|
||||
Anyone can airdrop NFTs to your account. This can include offensive content that might be automatically displayed in your wallet.
|
||||
</li>
|
||||
</ul>
|
||||
<p
|
||||
class="mm-box mm-text mm-text--body-md mm-box--padding-top-4 mm-box--color-text-alternative"
|
||||
>
|
||||
Leave this feature off if you don't want the app to pull data from those services.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="settings-page__content-item"
|
||||
>
|
||||
<div
|
||||
class="settings-page__content-item-col"
|
||||
data-testid="useNftDetection"
|
||||
>
|
||||
<label
|
||||
class="toggle-button toggle-button--off"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
style="display: flex; width: 52px; align-items: center; justify-content: flex-start; position: relative; cursor: pointer; background-color: transparent; border: 0px; padding: 0px; user-select: none;"
|
||||
>
|
||||
<div
|
||||
style="width: 40px; height: 24px; padding: 0px; border-radius: 26px; display: flex; align-items: center; justify-content: center; background-color: rgb(242, 244, 246);"
|
||||
>
|
||||
<div
|
||||
style="font-size: 11px; display: flex; align-items: center; justify-content: center; font-family: 'Helvetica Neue', Helvetica, sans-serif; position: relative; color: rgb(250, 250, 250); margin-top: auto; margin-bottom: auto; line-height: 0; opacity: 0; width: 26px; height: 20px; left: 4px;"
|
||||
/>
|
||||
<div
|
||||
style="font-size: 11px; display: flex; align-items: center; justify-content: center; font-family: 'Helvetica Neue', Helvetica, sans-serif; position: relative; color: rgba(255, 255, 255, 0.6); bottom: 0px; margin-top: auto; margin-bottom: auto; padding-right: 5px; line-height: 0; width: 26px; height: 20px; opacity: 1;"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
style="position: absolute; height: 100%; top: 0px; left: 0px; display: flex; flex: 1; align-self: stretch; align-items: center; justify-content: flex-start;"
|
||||
>
|
||||
<div
|
||||
style="width: 18px; height: 18px; display: flex; align-self: center; box-shadow: none; border-radius: 50%; box-sizing: border-box; position: relative; background-color: rgb(106, 115, 125); left: 3px;"
|
||||
/>
|
||||
</div>
|
||||
<input
|
||||
style="border: 0px; height: 1px; margin: -1px; overflow: hidden; padding: 0px; position: absolute; width: 1px;"
|
||||
type="checkbox"
|
||||
value="false"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="toggle-button__status"
|
||||
>
|
||||
<span
|
||||
class="toggle-button__label-off"
|
||||
>
|
||||
Off
|
||||
</span>
|
||||
<span
|
||||
class="toggle-button__label-on"
|
||||
>
|
||||
On
|
||||
</span>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
class="settings-page__security-tab-sub-header"
|
||||
|
@ -47,6 +47,10 @@ export default class SecurityTab extends PureComponent {
|
||||
static propTypes = {
|
||||
warning: PropTypes.string,
|
||||
history: PropTypes.object,
|
||||
openSeaEnabled: PropTypes.bool,
|
||||
setOpenSeaEnabled: PropTypes.func,
|
||||
useNftDetection: PropTypes.bool,
|
||||
setUseNftDetection: PropTypes.func,
|
||||
participateInMetaMetrics: PropTypes.bool.isRequired,
|
||||
setParticipateInMetaMetrics: PropTypes.func.isRequired,
|
||||
showIncomingTransactions: PropTypes.bool.isRequired,
|
||||
@ -603,6 +607,110 @@ export default class SecurityTab extends PureComponent {
|
||||
);
|
||||
}
|
||||
|
||||
renderOpenSeaEnabledToggle() {
|
||||
const { t } = this.context;
|
||||
const {
|
||||
openSeaEnabled,
|
||||
setOpenSeaEnabled,
|
||||
useNftDetection,
|
||||
setUseNftDetection,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<div ref={this.settingsRefs[10]} className="settings-page__content-row">
|
||||
<div className="settings-page__content-item">
|
||||
<span>{t('enableOpenSeaAPI')}</span>
|
||||
<div className="settings-page__content-description">
|
||||
{t('enableOpenSeaAPIDescription')}
|
||||
</div>
|
||||
</div>
|
||||
<div className="settings-page__content-item">
|
||||
<div
|
||||
className="settings-page__content-item-col"
|
||||
data-testid="enableOpenSeaAPI"
|
||||
>
|
||||
<ToggleButton
|
||||
value={openSeaEnabled}
|
||||
onToggle={(value) => {
|
||||
this.context.trackEvent({
|
||||
category: MetaMetricsEventCategory.Settings,
|
||||
event: 'Enabled/Disable OpenSea',
|
||||
properties: {
|
||||
action: 'Enabled/Disable OpenSea',
|
||||
legacy_event: true,
|
||||
},
|
||||
});
|
||||
// value is positive when being toggled off
|
||||
if (value && useNftDetection) {
|
||||
setUseNftDetection(false);
|
||||
}
|
||||
setOpenSeaEnabled(!value);
|
||||
}}
|
||||
offLabel={t('off')}
|
||||
onLabel={t('on')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderNftDetectionToggle() {
|
||||
const { t } = this.context;
|
||||
const {
|
||||
openSeaEnabled,
|
||||
setOpenSeaEnabled,
|
||||
useNftDetection,
|
||||
setUseNftDetection,
|
||||
} = this.props;
|
||||
return (
|
||||
<div ref={this.settingsRefs[11]} className="settings-page__content-row">
|
||||
<div className="settings-page__content-item">
|
||||
<span>{t('useNftDetection')}</span>
|
||||
<div className="settings-page__content-description">
|
||||
<Text color={TextColor.textAlternative}>
|
||||
{t('useNftDetectionDescription')}
|
||||
</Text>
|
||||
<ul className="settings-page__content-unordered-list">
|
||||
<li>{t('useNftDetectionDescriptionLine2')}</li>
|
||||
<li>{t('useNftDetectionDescriptionLine3')}</li>
|
||||
<li>{t('useNftDetectionDescriptionLine4')}</li>
|
||||
</ul>
|
||||
<Text color={TextColor.textAlternative} paddingTop={4}>
|
||||
{t('useNftDetectionDescriptionLine5')}
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
<div className="settings-page__content-item">
|
||||
<div
|
||||
className="settings-page__content-item-col"
|
||||
data-testid="useNftDetection"
|
||||
>
|
||||
<ToggleButton
|
||||
value={useNftDetection}
|
||||
onToggle={(value) => {
|
||||
this.context.trackEvent({
|
||||
category: MetaMetricsEventCategory.Settings,
|
||||
event: 'NFT Detected',
|
||||
properties: {
|
||||
action: 'NFT Detected',
|
||||
legacy_event: true,
|
||||
},
|
||||
});
|
||||
if (!value && !openSeaEnabled) {
|
||||
setOpenSeaEnabled(!value);
|
||||
}
|
||||
setUseNftDetection(!value);
|
||||
}}
|
||||
offLabel={t('off')}
|
||||
onLabel={t('on')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { warning } = this.props;
|
||||
|
||||
@ -643,6 +751,8 @@ export default class SecurityTab extends PureComponent {
|
||||
<div className="settings-page__content-padded">
|
||||
{this.renderAutoDetectTokensToggle()}
|
||||
{this.renderBatchAccountBalanceRequestsToggle()}
|
||||
{this.renderOpenSeaEnabledToggle()}
|
||||
{this.renderNftDetectionToggle()}
|
||||
</div>
|
||||
<span className="settings-page__security-tab-sub-header">
|
||||
{this.context.t('metrics')}
|
||||
|
@ -10,6 +10,8 @@ import {
|
||||
setUsePhishDetect,
|
||||
setUseTokenDetection,
|
||||
setUseAddressBarEnsResolution,
|
||||
setOpenSeaEnabled,
|
||||
setUseNftDetection,
|
||||
} from '../../../store/actions';
|
||||
import SecurityTab from './security-tab.component';
|
||||
|
||||
@ -27,6 +29,8 @@ const mapStateToProps = (state) => {
|
||||
useMultiAccountBalanceChecker,
|
||||
useCurrencyRateCheck,
|
||||
useAddressBarEnsResolution,
|
||||
openSeaEnabled,
|
||||
useNftDetection,
|
||||
} = metamask;
|
||||
|
||||
return {
|
||||
@ -39,6 +43,8 @@ const mapStateToProps = (state) => {
|
||||
useMultiAccountBalanceChecker,
|
||||
useCurrencyRateCheck,
|
||||
useAddressBarEnsResolution,
|
||||
openSeaEnabled,
|
||||
useNftDetection,
|
||||
};
|
||||
};
|
||||
|
||||
@ -61,6 +67,8 @@ const mapDispatchToProps = (dispatch) => {
|
||||
},
|
||||
setUseAddressBarEnsResolution: (value) =>
|
||||
dispatch(setUseAddressBarEnsResolution(value)),
|
||||
setOpenSeaEnabled: (val) => dispatch(setOpenSeaEnabled(val)),
|
||||
setUseNftDetection: (val) => dispatch(setUseNftDetection(val)),
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -46,6 +46,14 @@ describe('Security Tab', () => {
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('toggles opensea api enabled', async () => {
|
||||
expect(await toggleCheckbox('enableOpenSeaAPI', false)).toBe(true);
|
||||
});
|
||||
|
||||
it('toggles nft detection', async () => {
|
||||
expect(await toggleCheckbox('useNftDetection', false)).toBe(true);
|
||||
});
|
||||
|
||||
it('toggles phishing detection', async () => {
|
||||
expect(await toggleCheckbox('usePhishingDetection', true)).toBe(true);
|
||||
});
|
||||
|
@ -2988,18 +2988,31 @@ export function setUseTokenDetection(
|
||||
};
|
||||
}
|
||||
|
||||
export function setOpenSeaEnabled(
|
||||
val: boolean,
|
||||
): ThunkAction<void, MetaMaskReduxState, unknown, AnyAction> {
|
||||
return async (dispatch: MetaMaskReduxDispatch) => {
|
||||
dispatch(showLoadingIndication());
|
||||
log.debug(`background.setOpenSeaEnabled`);
|
||||
try {
|
||||
await submitRequestToBackground('setOpenSeaEnabled', [val]);
|
||||
} finally {
|
||||
dispatch(hideLoadingIndication());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function setUseNftDetection(
|
||||
val: boolean,
|
||||
): ThunkAction<void, MetaMaskReduxState, unknown, AnyAction> {
|
||||
return (dispatch: MetaMaskReduxDispatch) => {
|
||||
return async (dispatch: MetaMaskReduxDispatch) => {
|
||||
dispatch(showLoadingIndication());
|
||||
log.debug(`background.setUseNftDetection`);
|
||||
callBackgroundMethod('setUseNftDetection', [val], (err) => {
|
||||
try {
|
||||
await submitRequestToBackground('setUseNftDetection', [val]);
|
||||
} finally {
|
||||
dispatch(hideLoadingIndication());
|
||||
if (err) {
|
||||
dispatch(displayWarning(err));
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -3018,21 +3031,6 @@ export function setUseCurrencyRateCheck(
|
||||
};
|
||||
}
|
||||
|
||||
export function setOpenSeaEnabled(
|
||||
val: boolean,
|
||||
): ThunkAction<void, MetaMaskReduxState, unknown, AnyAction> {
|
||||
return (dispatch: MetaMaskReduxDispatch) => {
|
||||
dispatch(showLoadingIndication());
|
||||
log.debug(`background.setOpenSeaEnabled`);
|
||||
callBackgroundMethod('setOpenSeaEnabled', [val], (err) => {
|
||||
dispatch(hideLoadingIndication());
|
||||
if (err) {
|
||||
dispatch(displayWarning(err));
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// DetectTokenController
|
||||
export function detectNewTokens(): ThunkAction<
|
||||
void,
|
||||
|
Loading…
Reference in New Issue
Block a user