diff --git a/.storybook/test-data.js b/.storybook/test-data.js index 9bef59566eec..f0cf03fae566 100644 --- a/.storybook/test-data.js +++ b/.storybook/test-data.js @@ -1225,6 +1225,7 @@ const state = { useNonceField: false, usePhishDetect: true, useTokenDetection: true, + useCurrencyRateCheck: true, lostIdentities: {}, forgottenPassword: false, ipfsGateway: 'dweb.link', diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 6ba73447a050..c5a082f48c2e 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -682,6 +682,9 @@ "close": { "message": "Close" }, + "coingecko": { + "message": "CoinGecko" + }, "collectibleAddFailedMessage": { "message": "NFT can’t be added as the ownership details do not match. Make sure you have entered correct information." }, @@ -894,9 +897,19 @@ "createPassword": { "message": "Create password" }, + "cryptoCompare": { + "message": "CryptoCompare" + }, "currencyConversion": { "message": "Currency conversion" }, + "currencyRateCheckToggle": { + "message": "Show balance and token price checker" + }, + "currencyRateCheckToggleDescription": { + "message": "We use $1 and $2 APIs to display your balance and token price. $3", + "description": "$1 represents Coingecko, $2 represents CryptoCompare and $3 represents Privacy Policy" + }, "currencySymbol": { "message": "Currency symbol" }, diff --git a/app/scripts/controllers/detect-tokens.js b/app/scripts/controllers/detect-tokens.js index 524f8f5be573..f888888e0821 100644 --- a/app/scripts/controllers/detect-tokens.js +++ b/app/scripts/controllers/detect-tokens.js @@ -116,7 +116,7 @@ export default class DetectTokensController { const tokensToDetect = []; for (const tokenAddress in tokenListUsed) { if ( - !this.tokenAddresses.find(({ address }) => + !this.tokenAddresses.find((address) => isEqualCaseInsensitive(address, tokenAddress), ) && !this.hiddenTokens.find((address) => diff --git a/app/scripts/controllers/detect-tokens.test.js b/app/scripts/controllers/detect-tokens.test.js index 80fe3bdc7833..feef8d19a71c 100644 --- a/app/scripts/controllers/detect-tokens.test.js +++ b/app/scripts/controllers/detect-tokens.test.js @@ -11,8 +11,9 @@ import { } from '@metamask/assets-controllers'; import { NETWORK_TYPES } from '../../../shared/constants/network'; import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils'; +import { hexToDecimal } from '../../../shared/lib/metamask-controller-utils'; import DetectTokensController from './detect-tokens'; -import NetworkController from './network'; +import NetworkController, { NETWORK_EVENTS } from './network'; import PreferencesController from './preferences'; describe('DetectTokensController', function () { @@ -64,14 +65,34 @@ describe('DetectTokensController', function () { onPreferencesStateChange: preferences.store.subscribe.bind( preferences.store, ), - onNetworkStateChange: network.store.subscribe.bind(network.store), + onNetworkStateChange: (cb) => + network.store.subscribe((networkState) => { + const modifiedNetworkState = { + ...networkState, + providerConfig: { + ...networkState.provider, + }, + }; + return cb(modifiedNetworkState); + }), }); assetsContractController = new AssetsContractController({ onPreferencesStateChange: preferences.store.subscribe.bind( preferences.store, ), - onNetworkStateChange: network.store.subscribe.bind(network.store), + onNetworkStateChange: (cb) => + network.on(NETWORK_EVENTS.NETWORK_DID_CHANGE, () => { + const networkState = network.store.getState(); + const modifiedNetworkState = { + ...networkState, + providerConfig: { + ...networkState.provider, + chainId: hexToDecimal(networkState.provider.chainId), + }, + }; + return cb(modifiedNetworkState); + }), }); sandbox diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index 555af2c41a94..cc2b79e41eaa 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -37,6 +37,7 @@ export default class PreferencesController { // set to false will be using the static list from contract-metadata useTokenDetection: false, useNftDetection: false, + useCurrencyRateCheck: true, openSeaEnabled: false, advancedGasFee: null, @@ -156,6 +157,15 @@ export default class PreferencesController { this.store.updateState({ useNftDetection }); } + /** + * Setter for the `useCurrencyRateCheck` property + * + * @param {boolean} val - Whether or not the user prefers to use currency rate check for ETH and tokens. + */ + setUseCurrencyRateCheck(val) { + this.store.updateState({ useCurrencyRateCheck: val }); + } + /** * Setter for the `openSeaEnabled` property * diff --git a/app/scripts/controllers/preferences.test.js b/app/scripts/controllers/preferences.test.js index 079bac240d28..b0b232c6543f 100644 --- a/app/scripts/controllers/preferences.test.js +++ b/app/scripts/controllers/preferences.test.js @@ -367,4 +367,23 @@ describe('preferences controller', function () { assert.equal(preferencesController.store.getState().theme, 'dark'); }); }); + + describe('setUseCurrencyRateCheck', function () { + it('should default to false', function () { + const state = preferencesController.store.getState(); + assert.equal(state.useCurrencyRateCheck, true); + }); + + it('should set the useCurrencyRateCheck property in state', function () { + assert.equal( + preferencesController.store.getState().useCurrencyRateCheck, + true, + ); + preferencesController.setUseCurrencyRateCheck(false); + assert.equal( + preferencesController.store.getState().useCurrencyRateCheck, + false, + ); + }); + }); }); diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 5ab6bad7e94b..71db33f023b0 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -266,7 +266,7 @@ export default class MetamaskController extends EventEmitter { this.networkController.store.subscribe((networkState) => { const modifiedNetworkState = { ...networkState, - provider: { + providerConfig: { ...networkState.provider, chainId: hexToDecimal(networkState.provider.chainId), }, @@ -291,9 +291,16 @@ export default class MetamaskController extends EventEmitter { onPreferencesStateChange: this.preferencesController.store.subscribe.bind( this.preferencesController.store, ), - onNetworkStateChange: this.networkController.store.subscribe.bind( - this.networkController.store, - ), + onNetworkStateChange: (cb) => + this.networkController.store.subscribe((networkState) => { + const modifiedNetworkState = { + ...networkState, + providerConfig: { + ...networkState.provider, + }, + }; + return cb(modifiedNetworkState); + }), config: { provider: this.provider }, state: initState.TokensController, }); @@ -307,7 +314,7 @@ export default class MetamaskController extends EventEmitter { const networkState = this.networkController.store.getState(); const modifiedNetworkState = { ...networkState, - provider: { + providerConfig: { ...networkState.provider, chainId: hexToDecimal(networkState.provider.chainId), }, @@ -327,9 +334,16 @@ export default class MetamaskController extends EventEmitter { this.preferencesController.store.subscribe.bind( this.preferencesController.store, ), - onNetworkStateChange: this.networkController.store.subscribe.bind( - this.networkController.store, - ), + onNetworkStateChange: (cb) => + this.networkController.store.subscribe((networkState) => { + const modifiedNetworkState = { + ...networkState, + providerConfig: { + ...networkState.provider, + }, + }; + return cb(modifiedNetworkState); + }), getERC721AssetName: this.assetsContractController.getERC721AssetName.bind( this.assetsContractController, @@ -504,7 +518,7 @@ export default class MetamaskController extends EventEmitter { this.networkController.store.subscribe((networkState) => { const modifiedNetworkState = { ...networkState, - provider: { + providerConfig: { ...networkState.provider, chainId: hexToDecimal(networkState.provider.chainId), }, @@ -512,9 +526,29 @@ export default class MetamaskController extends EventEmitter { return cb(modifiedNetworkState); }), }, - undefined, + { + disabled: + !this.preferencesController.store.getState().useCurrencyRateCheck, + }, initState.TokenRatesController, ); + this.preferencesController.store.subscribe( + previousValueComparator((prevState, currState) => { + const { useCurrencyRateCheck: prevUseCurrencyRateCheck } = prevState; + const { useCurrencyRateCheck: currUseCurrencyRateCheck } = currState; + if (currUseCurrencyRateCheck && !prevUseCurrencyRateCheck) { + this.currencyRateController.start(); + this.tokenRatesController.configure( + { disabled: false }, + false, + false, + ); + } else if (!currUseCurrencyRateCheck && prevUseCurrencyRateCheck) { + this.currencyRateController.stop(); + this.tokenRatesController.configure({ disabled: true }, false, false); + } + }, this.preferencesController.store.getState()), + ); this.ensController = new EnsController({ provider: this.provider, @@ -1245,7 +1279,9 @@ export default class MetamaskController extends EventEmitter { triggerNetworkrequests() { this.accountTracker.start(); this.incomingTransactionsController.start(); - this.currencyRateController.start(); + if (this.preferencesController.store.getState().useCurrencyRateCheck) { + this.currencyRateController.start(); + } if (this.preferencesController.store.getState().useTokenDetection) { this.tokenListController.start(); } @@ -1254,7 +1290,9 @@ export default class MetamaskController extends EventEmitter { stopNetworkRequests() { this.accountTracker.stop(); this.incomingTransactionsController.stop(); - this.currencyRateController.stop(); + if (this.preferencesController.store.getState().useCurrencyRateCheck) { + this.currencyRateController.stop(); + } if (this.preferencesController.store.getState().useTokenDetection) { this.tokenListController.stop(); } @@ -1634,6 +1672,10 @@ export default class MetamaskController extends EventEmitter { setUseNftDetection: preferencesController.setUseNftDetection.bind( preferencesController, ), + setUseCurrencyRateCheck: + preferencesController.setUseCurrencyRateCheck.bind( + preferencesController, + ), setOpenSeaEnabled: preferencesController.setOpenSeaEnabled.bind( preferencesController, ), diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index 297409e17956..9c5db4b745b4 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -501,6 +501,7 @@ "URL": true, "clearInterval": true, "clearTimeout": true, + "console.info": true, "console.log": true, "setInterval": true, "setTimeout": true @@ -508,10 +509,10 @@ "packages": { "@ethersproject/contracts": true, "@ethersproject/providers": true, - "@metamask/assets-controllers>@metamask/contract-metadata": true, "@metamask/assets-controllers>abort-controller": true, "@metamask/assets-controllers>multiformats": true, "@metamask/base-controller": true, + "@metamask/contract-metadata": true, "@metamask/controller-utils": true, "@metamask/metamask-eth-abis": true, "browserify>events": true, diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index c7ca311630b8..76ed56808462 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -501,6 +501,7 @@ "URL": true, "clearInterval": true, "clearTimeout": true, + "console.info": true, "console.log": true, "setInterval": true, "setTimeout": true @@ -508,10 +509,10 @@ "packages": { "@ethersproject/contracts": true, "@ethersproject/providers": true, - "@metamask/assets-controllers>@metamask/contract-metadata": true, "@metamask/assets-controllers>abort-controller": true, "@metamask/assets-controllers>multiformats": true, "@metamask/base-controller": true, + "@metamask/contract-metadata": true, "@metamask/controller-utils": true, "@metamask/metamask-eth-abis": true, "browserify>events": true, diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index 297409e17956..9c5db4b745b4 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -501,6 +501,7 @@ "URL": true, "clearInterval": true, "clearTimeout": true, + "console.info": true, "console.log": true, "setInterval": true, "setTimeout": true @@ -508,10 +509,10 @@ "packages": { "@ethersproject/contracts": true, "@ethersproject/providers": true, - "@metamask/assets-controllers>@metamask/contract-metadata": true, "@metamask/assets-controllers>abort-controller": true, "@metamask/assets-controllers>multiformats": true, "@metamask/base-controller": true, + "@metamask/contract-metadata": true, "@metamask/controller-utils": true, "@metamask/metamask-eth-abis": true, "browserify>events": true, diff --git a/package.json b/package.json index 0b7bd843a9f6..01c9a15c7669 100644 --- a/package.json +++ b/package.json @@ -209,7 +209,7 @@ "@metamask/address-book-controller": "^1.0.0", "@metamask/announcement-controller": "^1.0.0", "@metamask/approval-controller": "^1.0.0", - "@metamask/assets-controllers": "^1.0.1", + "@metamask/assets-controllers": "^3.0.1", "@metamask/base-controller": "^1.0.0", "@metamask/contract-metadata": "^2.1.0", "@metamask/controller-utils": "^1.0.0", diff --git a/shared/lib/ui-utils.js b/shared/lib/ui-utils.js index eb3a2143da82..c562e7a82784 100644 --- a/shared/lib/ui-utils.js +++ b/shared/lib/ui-utils.js @@ -5,6 +5,11 @@ _supportLink = 'https://metamask-flask.zendesk.com/hc'; ///: END:ONLY_INCLUDE_IN export const SUPPORT_LINK = _supportLink; + +export const COINGECKO_LINK = 'https://www.coingecko.com/'; +export const CRYPTOCOMPARE_LINK = 'https://www.cryptocompare.com/'; +export const PRIVACY_POLICY_LINK = 'https://consensys.net/privacy-policy/'; + // TODO make sure these links are correct export const ETHERSCAN_PRIVACY_LINK = 'https://etherscan.io/privacyPolicy'; export const CONSENSYS_PRIVACY_LINK = 'https://consensys.net/privacy-policy/'; diff --git a/test/data/mock-state.json b/test/data/mock-state.json index 5eb643c68441..c98e05daf4ec 100644 --- a/test/data/mock-state.json +++ b/test/data/mock-state.json @@ -252,6 +252,7 @@ "unapprovedTypedMessages": {}, "unapprovedTypedMessagesCount": 0, "useTokenDetection": true, + "useCurrencyRateCheck": true, "advancedGasFee": { "maxBaseFee": "75", "priorityFee": "2" diff --git a/test/e2e/fixture-builder.js b/test/e2e/fixture-builder.js index cc1936642e78..fff749f5d959 100644 --- a/test/e2e/fixture-builder.js +++ b/test/e2e/fixture-builder.js @@ -239,6 +239,7 @@ function defaultFixture() { useNonceField: false, usePhishDetect: true, useTokenDetection: false, + useCurrencyRateCheck: true, useMultiAccountBalanceChecker: true, }, SmartTransactionsController: { @@ -352,6 +353,7 @@ function onboardingFixture() { useNonceField: false, usePhishDetect: true, useTokenDetection: false, + useCurrencyRateCheck: true, useMultiAccountBalanceChecker: true, }, SmartTransactionsController: { diff --git a/test/e2e/restore/MetaMaskUserData.json b/test/e2e/restore/MetaMaskUserData.json index 48bf95119b92..4719406dad72 100644 --- a/test/e2e/restore/MetaMaskUserData.json +++ b/test/e2e/restore/MetaMaskUserData.json @@ -46,6 +46,7 @@ "useNonceField": false, "usePhishDetect": true, "useTokenDetection": false, + "useCurrencyRateCheck": true, "useMultiAccountBalanceChecker": true } } diff --git a/test/jest/mock-store.js b/test/jest/mock-store.js index a447124a4f35..3fdc80b6ff31 100644 --- a/test/jest/mock-store.js +++ b/test/jest/mock-store.js @@ -218,6 +218,7 @@ export const createSwapsMockStore = () => { postTxBalance: '19a61aaaf06e4bd1', }, ], + useCurrencyRateCheck: true, conversionRate: 1, contractExchangeRates: { '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48': 2, diff --git a/ui/components/app/currency-input/currency-input.test.js b/ui/components/app/currency-input/currency-input.test.js index 3fd1c9cf2db3..a870cfe9907d 100644 --- a/ui/components/app/currency-input/currency-input.test.js +++ b/ui/components/app/currency-input/currency-input.test.js @@ -16,6 +16,7 @@ describe('CurrencyInput Component', () => { preferences: { showFiatInTestnets: true, }, + useCurrencyRateCheck: true, }, }; describe('rendering', () => { diff --git a/ui/components/app/detected-token/detected-token-values/detected-token-values.js b/ui/components/app/detected-token/detected-token-values/detected-token-values.js index b6c4f4648ec5..9f9d4f56cb61 100644 --- a/ui/components/app/detected-token/detected-token-values/detected-token-values.js +++ b/ui/components/app/detected-token/detected-token-values/detected-token-values.js @@ -1,5 +1,6 @@ import React, { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; +import { useSelector } from 'react-redux'; import Box from '../../../ui/box'; import Typography from '../../../ui/typography'; @@ -12,6 +13,7 @@ import { } from '../../../../helpers/constants/design-system'; import { useTokenTracker } from '../../../../hooks/useTokenTracker'; import { useTokenFiatAmount } from '../../../../hooks/useTokenFiatAmount'; +import { getUseCurrencyRateCheck } from '../../../../selectors'; const DetectedTokenValues = ({ token, @@ -30,6 +32,8 @@ const DetectedTokenValues = ({ token.symbol, ); + const useCurrencyRateCheck = useSelector(getUseCurrencyRateCheck); + useEffect(() => { setTokenSelection(tokensListDetected[token.address]?.selected); }, [tokensListDetected, token.address, tokenSelection, setTokenSelection]); @@ -46,7 +50,9 @@ const DetectedTokenValues = ({ {`${balanceString || '0'} ${token.symbol}`} - {formattedFiatBalance || '$0'} + {useCurrencyRateCheck + ? formattedFiatBalance || '$0' // since formattedFiatBalance will be when teh conversion rate is not obtained, should be replace the `$0` with `N/A` + : formattedFiatBalance} diff --git a/ui/components/app/gas-details-item/gas-details-item.js b/ui/components/app/gas-details-item/gas-details-item.js index 560031f5c0c6..3b914b5fd224 100644 --- a/ui/components/app/gas-details-item/gas-details-item.js +++ b/ui/components/app/gas-details-item/gas-details-item.js @@ -5,7 +5,7 @@ import { useSelector } from 'react-redux'; import { COLORS } from '../../../helpers/constants/design-system'; import { PRIMARY, SECONDARY } from '../../../helpers/constants/common'; -import { getPreferences } from '../../../selectors'; +import { getPreferences, getUseCurrencyRateCheck } from '../../../selectors'; import { useGasFeeContext } from '../../../contexts/gasFee'; import { useI18nContext } from '../../../hooks/useI18nContext'; @@ -29,6 +29,8 @@ const GasDetailsItem = ({ userAcknowledgedGasMissing = false }) => { const { useNativeCurrencyAsPrimaryCurrency } = useSelector(getPreferences); + const useCurrencyRateCheck = useSelector(getUseCurrencyRateCheck); + if (hasSimulationError && !userAcknowledgedGasMissing) { return null; } @@ -39,14 +41,16 @@ const GasDetailsItem = ({ userAcknowledgedGasMissing = false }) => { detailTitle={} detailTitleColor={COLORS.TEXT_DEFAULT} detailText={ -
- - -
+ useCurrencyRateCheck && ( +
+ + +
+ ) } detailTotal={
diff --git a/ui/components/app/token-cell/__snapshots__/token-cell.test.js.snap b/ui/components/app/token-cell/__snapshots__/token-cell.test.js.snap index c179d1da0aac..efea9cda4e5c 100644 --- a/ui/components/app/token-cell/__snapshots__/token-cell.test.js.snap +++ b/ui/components/app/token-cell/__snapshots__/token-cell.test.js.snap @@ -3,7 +3,7 @@ exports[`Token Cell should match snapshot 1`] = `
@@ -77,15 +77,6 @@ exports[`Token Cell should match snapshot 1`] = `
-
-

- $0.52 USD -

-
diff --git a/ui/helpers/constants/settings.js b/ui/helpers/constants/settings.js index 568f4a5290ea..d80f1c25d28d 100644 --- a/ui/helpers/constants/settings.js +++ b/ui/helpers/constants/settings.js @@ -219,6 +219,13 @@ export const SETTINGS_CONSTANTS = [ icon: 'fa fa-flask', featureFlag: 'NFTS_V1', }, + { + tabMessage: (t) => t('securityAndPrivacy'), + sectionMessage: (t) => t('currencyRateCheckToggle'), + descriptionMessage: (t) => t('currencyRateCheckToggleDescription'), + route: `${SECURITY_ROUTE}#price-checker`, + icon: 'fa fa-lock', + }, { tabMessage: (t) => t('alerts'), sectionMessage: (t) => t('alertSettingsUnconnectedAccount'), diff --git a/ui/helpers/utils/settings-search.test.js b/ui/helpers/utils/settings-search.test.js index 683bd014e337..7152d4451c97 100644 --- a/ui/helpers/utils/settings-search.test.js +++ b/ui/helpers/utils/settings-search.test.js @@ -137,6 +137,10 @@ const t = (key) => { return 'Contact us'; case 'snaps': return 'Snaps'; + case 'currencyRateCheckToggle': + return 'Show balance and token price checker'; + case 'currencyRateCheckToggleDescription': + return 'We use Coingecko and CryptoCompare APIs to display your balance and token price. Privacy Policy'; default: return ''; } @@ -165,7 +169,7 @@ describe('Settings Search Utils', () => { it('should get good security & privacy section number', () => { expect( getNumberOfSettingsInSection(t, t('securityAndPrivacy')), - ).toStrictEqual(9); + ).toStrictEqual(10); }); it('should get good alerts section number', () => { diff --git a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js index 2d1e66c60574..974a287e2283 100644 --- a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js +++ b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -160,6 +160,7 @@ export default class ConfirmTransactionBase extends Component { insightSnaps: PropTypes.arrayOf(PropTypes.object), ///: END:ONLY_INCLUDE_IN assetStandard: PropTypes.string, + useCurrencyRateCheck: PropTypes.bool, }; state = { @@ -349,6 +350,7 @@ export default class ConfirmTransactionBase extends Component { isMultiLayerFeeNetwork, nativeCurrency, isBuyableChain, + useCurrencyRateCheck, } = this.props; const { t } = this.context; const { userAcknowledgedGasMissing } = this.state; @@ -511,14 +513,16 @@ export default class ConfirmTransactionBase extends Component { ) } detailText={ -
- {renderHeartBeatIfNotInTest()} - -
+ useCurrencyRateCheck && ( +
+ {renderHeartBeatIfNotInTest()} + +
+ ) } detailTotal={
@@ -637,7 +641,7 @@ export default class ConfirmTransactionBase extends Component { { ///: BEGIN:ONLY_INCLUDE_IN(flask) insightSnaps, ///: END:ONLY_INCLUDE_IN + useCurrencyRateCheck: getUseCurrencyRateCheck(state), }; }; diff --git a/ui/pages/onboarding-flow/privacy-settings/privacy-settings.js b/ui/pages/onboarding-flow/privacy-settings/privacy-settings.js index 41b9eff91477..aeb166621780 100644 --- a/ui/pages/onboarding-flow/privacy-settings/privacy-settings.js +++ b/ui/pages/onboarding-flow/privacy-settings/privacy-settings.js @@ -22,13 +22,20 @@ import { showModal, setIpfsGateway, showNetworkDropdown, + setUseCurrencyRateCheck, } from '../../../store/actions'; import { ONBOARDING_PIN_EXTENSION_ROUTE } from '../../../helpers/constants/routes'; import { Icon, TextField } from '../../../components/component-library'; import NetworkDropdown from '../../../components/app/dropdowns/network-dropdown'; import NetworkDisplay from '../../../components/app/network-display/network-display'; +import { + COINGECKO_LINK, + CRYPTOCOMPARE_LINK, + PRIVACY_POLICY_LINK, +} from '../../../../shared/lib/ui-utils'; import { MetaMetricsContext } from '../../../contexts/metametrics'; import { EVENT_NAMES, EVENT } from '../../../../shared/constants/metametrics'; + import { Setting } from './setting'; export default function PrivacySettings() { @@ -37,6 +44,7 @@ export default function PrivacySettings() { const history = useHistory(); const [usePhishingDetection, setUsePhishingDetection] = useState(true); const [turnOnTokenDetection, setTurnOnTokenDetection] = useState(true); + const [turnOnCurrencyRateCheck, setTurnOnCurrencyRateCheck] = useState(true); const [showIncomingTransactions, setShowIncomingTransactions] = useState(true); const [ @@ -60,6 +68,7 @@ export default function PrivacySettings() { dispatch( setUseMultiAccountBalanceChecker(isMultiAccountBalanceCheckerEnabled), ); + dispatch(setUseCurrencyRateCheck(turnOnCurrencyRateCheck)); dispatch(setCompletedOnboarding()); if (ipfsURL && !ipfsError) { @@ -254,6 +263,37 @@ export default function PrivacySettings() { } /> + + {t('coingecko')} + , + + {t('cryptoCompare')} + , + + {t('privacyMsg')} + , + ])} + />