diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 85ac17bf0..4838bc54f 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -3148,6 +3148,12 @@ "urlExistsErrorMsg": { "message": "This URL is currently used by the $1 network." }, + "useCollectibleDetection": { + "message": "Autodetect NFTs" + }, + "useCollectibleDetectionDescription": { + "message": "Displaying NFTs media & data may expose your IP address to centralized servers. Third-party APIs (like OpenSea) are used to detect NFTs in your wallet. This exposes your account address with those services. Leave this disabled if you don’t want the app to pull data from those those services." + }, "usePhishingDetection": { "message": "Use Phishing Detection" }, diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index a53cf8993..4c4b92872 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -37,6 +37,7 @@ export default class PreferencesController { // set to true means the dynamic list from the API is being used // set to false will be using the static list from contract-metadata useTokenDetection: false, + useCollectibleDetection: false, advancedGasFee: null, // WARNING: Do not use feature flags for security-sensitive things. @@ -130,6 +131,16 @@ export default class PreferencesController { this.store.updateState({ useTokenDetection: val }); } + /** + * Setter for the `useCollectibleDetection` property + * + * @param {boolean} val - Whether or not the user prefers to autodetect collectibles. + * + */ + setUseCollectibleDetection(val) { + this.store.updateState({ useCollectibleDetection: val }); + } + /** * Setter for the `advancedGasFee` property * diff --git a/app/scripts/controllers/preferences.test.js b/app/scripts/controllers/preferences.test.js index bce64e1a9..1bc023e7a 100644 --- a/app/scripts/controllers/preferences.test.js +++ b/app/scripts/controllers/preferences.test.js @@ -267,6 +267,25 @@ describe('preferences controller', function () { }); }); + describe('setUseCollectibleDetection', function () { + it('should default to false', function () { + const state = preferencesController.store.getState(); + assert.equal(state.useCollectibleDetection, false); + }); + + it('should set the useCollectibleDetection property in state', function () { + assert.equal( + preferencesController.store.getState().useCollectibleDetection, + false, + ); + preferencesController.setUseCollectibleDetection(true); + assert.equal( + preferencesController.store.getState().useCollectibleDetection, + true, + ); + }); + }); + describe('setAdvancedGasFee', function () { it('should default to null', function () { const state = preferencesController.store.getState(); diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 5eec84f24..9dcb7df46 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -909,6 +909,10 @@ export default class MetamaskController extends EventEmitter { this.preferencesController.setUseTokenDetection, this.preferencesController, ), + setUseCollectibleDetection: nodeify( + this.preferencesController.setUseCollectibleDetection, + this.preferencesController, + ), setIpfsGateway: this.setIpfsGateway.bind(this), setParticipateInMetaMetrics: this.setParticipateInMetaMetrics.bind(this), setCurrentLocale: this.setCurrentLocale.bind(this), diff --git a/ui/pages/settings/experimental-tab/experimental-tab.component.js b/ui/pages/settings/experimental-tab/experimental-tab.component.js index db41d008a..e6fc61cdf 100644 --- a/ui/pages/settings/experimental-tab/experimental-tab.component.js +++ b/ui/pages/settings/experimental-tab/experimental-tab.component.js @@ -11,6 +11,8 @@ export default class ExperimentalTab extends PureComponent { static propTypes = { useTokenDetection: PropTypes.bool, setUseTokenDetection: PropTypes.func, + useCollectibleDetection: PropTypes.bool, + setUseCollectibleDetection: PropTypes.func, }; renderTokenDetectionToggle() { @@ -48,10 +50,46 @@ export default class ExperimentalTab extends PureComponent { ); } + renderCollectibleDetectionToggle() { + const { t } = this.context; + const { useCollectibleDetection, setUseCollectibleDetection } = this.props; + + return ( +