From 7bdb91c0894217f0ff6bae377310c3fb0f5d5a45 Mon Sep 17 00:00:00 2001 From: legobeat <109787230+legobeat@users.noreply.github.com> Date: Tue, 20 Dec 2022 00:27:47 +0900 Subject: [PATCH 1/4] test/e2e: increase timeout 60s -> 80s (#16592) --- test/e2e/run-e2e-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/run-e2e-test.js b/test/e2e/run-e2e-test.js index 88b40a4fecdb..6ede0be7187e 100644 --- a/test/e2e/run-e2e-test.js +++ b/test/e2e/run-e2e-test.js @@ -79,7 +79,7 @@ async function main() { process.env.E2E_DEBUG = 'true'; } - let testTimeoutInMilliseconds = 60 * 1000; + let testTimeoutInMilliseconds = 80 * 1000; let exit = '--exit'; if (leaveRunning) { From 0992dd54371f0ad3d94e4d0eb659e0265d89bff5 Mon Sep 17 00:00:00 2001 From: mirjanaKukic <94608179+mirjanaKukic@users.noreply.github.com> Date: Mon, 19 Dec 2022 17:46:07 +0100 Subject: [PATCH 2/4] added new test for adding custom network (#15484) add custom network and switch to network lint fix add custom network and not switch the network add wait for selector lint fix fix add waitforselector fix yarn lock added delay added comments lint fix added rpc networks in mock-e2e.js lint fix fix yarn lock alphabetic order of the array in mock-e2e fix lint fix fix removed unnecessary networks changed blacklistedHosts added fixture builder changed to Arbitrum One network --- test/e2e/mock-e2e.js | 1 + test/e2e/tests/add-custom-network.spec.js | 150 ++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 test/e2e/tests/add-custom-network.spec.js diff --git a/test/e2e/mock-e2e.js b/test/e2e/mock-e2e.js index b7249812681c..c043bf5704ed 100644 --- a/test/e2e/mock-e2e.js +++ b/test/e2e/mock-e2e.js @@ -1,4 +1,5 @@ const blacklistedHosts = [ + 'arbitrum-mainnet.infura.io', 'goerli.infura.io', 'mainnet.infura.io', 'sepolia.infura.io', diff --git a/test/e2e/tests/add-custom-network.spec.js b/test/e2e/tests/add-custom-network.spec.js new file mode 100644 index 000000000000..9a20337cd62b --- /dev/null +++ b/test/e2e/tests/add-custom-network.spec.js @@ -0,0 +1,150 @@ +const { strict: assert } = require('assert'); +const FixtureBuilder = require('../fixture-builder'); +const { convertToHexValue, withFixtures } = require('../helpers'); + +describe('Custom network', function () { + const chainID = 42161; + const networkURL = 'https://arbitrum-mainnet.infura.io'; + const networkNAME = 'Arbitrum One'; + const currencySYMBOL = 'ETH'; + const blockExplorerURL = 'https://explorer.arbitrum.io'; + const ganacheOptions = { + accounts: [ + { + secretKey: + '0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC', + balance: convertToHexValue(25000000000000000000), + }, + ], + }; + it('add custom network and switch the network', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + ganacheOptions, + title: this.test.title, + }, + async ({ driver }) => { + await driver.navigate(); + await driver.fill('#password', 'correct horse battery staple'); + await driver.press('#password', driver.Key.ENTER); + + await driver.clickElement('.account-menu__icon'); + await driver.clickElement({ tag: 'div', text: 'Settings' }); + + await driver.clickElement('.network-display'); + await driver.clickElement({ tag: 'button', text: 'Add network' }); + + await driver.clickElement({ + tag: 'button', + text: 'Add', + }); + // verify network details + const title = await driver.findElement({ + tag: 'h6', + text: 'Arbitrum One', + }); + assert.equal( + await title.getText(), + 'Arbitrum One', + 'Title of popup should be selected network', + ); + + const [networkName, networkUrl, chainIdElement, currencySymbol] = + await driver.findElements('.definition-list dd'); + + assert.equal( + await networkName.getText(), + networkNAME, + 'Network name is not correct displayed', + ); + assert.equal( + await networkUrl.getText(), + networkURL, + 'Network Url is not correct displayed', + ); + assert.equal( + await chainIdElement.getText(), + chainID.toString(), + 'Chain Id is not correct displayed', + ); + assert.equal( + await currencySymbol.getText(), + currencySYMBOL, + 'Currency symbol is not correct displayed', + ); + + await driver.clickElement({ tag: 'a', text: 'View all details' }); + + const networkDetailsLabels = await driver.findElements('dd'); + assert.equal( + await networkDetailsLabels[8].getText(), + blockExplorerURL, + 'Block Explorer URL is not correct', + ); + + await driver.clickElement({ tag: 'button', text: 'Close' }); + await driver.clickElement({ tag: 'button', text: 'Approve' }); + + await driver.clickElement({ + tag: 'h6', + text: 'Switch to Arbitrum One', + }); + // verify network switched + const networkDisplayed = await driver.findElement({ + tag: 'span', + text: 'Arbitrum One', + }); + assert.equal( + await networkDisplayed.getText(), + 'Arbitrum One', + 'You have not switched to Arbitrum Network', + ); + }, + ); + }); + + it('add custom network and not switch the network', async function () { + await withFixtures( + { + fixtures: new FixtureBuilder().build(), + ganacheOptions, + title: this.test.title, + }, + async ({ driver }) => { + await driver.navigate(); + await driver.fill('#password', 'correct horse battery staple'); + await driver.press('#password', driver.Key.ENTER); + + await driver.clickElement('.account-menu__icon'); + await driver.clickElement({ tag: 'div', text: 'Settings' }); + + await driver.clickElement('.network-display'); + await driver.clickElement({ tag: 'button', text: 'Add network' }); + + // had to put all Add elements in list since list is changing and networks are not always in same order + await driver.clickElement({ + tag: 'button', + text: 'Add', + }); + + await driver.clickElement({ tag: 'button', text: 'Approve' }); + + await driver.clickElement({ + tag: 'h6', + text: 'Dismiss', + }); + + // verify if added network is in list of networks + const networkDisplay = await driver.findElement('.network-display'); + await networkDisplay.click(); + + const arbitrumNetwork = await driver.findElements({ + text: `Arbitrum One`, + tag: 'span', + }); + assert.ok(arbitrumNetwork.length, 1); + }, + ); + }); +}); From 22fc60a3419ff248aac57480360ee7dfb6124b20 Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Mon, 19 Dec 2022 13:38:28 -0330 Subject: [PATCH 3/4] Show user the general contract interaction screen for token approvals, when the asset standard is undefined (#16765) Co-authored-by: Jyoti Puri --- ui/pages/confirm-approve/confirm-approve.js | 4 ++++ .../confirm-transaction-base.component.js | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/ui/pages/confirm-approve/confirm-approve.js b/ui/pages/confirm-approve/confirm-approve.js index 1dd08cd7525e..4fa2fe8fe27f 100644 --- a/ui/pages/confirm-approve/confirm-approve.js +++ b/ui/pages/confirm-approve/confirm-approve.js @@ -16,6 +16,7 @@ import { getNativeCurrency, isAddressLedger, } from '../../ducks/metamask/metamask'; +import ConfirmContractInteraction from '../confirm-contract-interaction'; import { getCurrentCurrency, getSubjectMetadata, @@ -164,6 +165,9 @@ export default function ConfirmApprove({ if (tokenSymbol === undefined && assetName === undefined) { return ; } + if (assetStandard === undefined) { + return ; + } if (improvedTokenAllowanceEnabled && assetStandard === ERC20) { return ( 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 c5dddfdaa640..ab9bef7651f7 100644 --- a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js +++ b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -1162,8 +1162,21 @@ export default class ConfirmTransactionBase extends Component { requestsWaitingText, } = this.getNavigateTxData(); + // This `isTokenApproval` case is added to handle possible rendering of this component from + // confirm-approve.js when `assetStandard` is `undefined`. That will happen if the request to + // get the asset standard fails. In that scenario, confirm-approve.js returns the `` + // component, which in turn returns this `` component. We meed to prevent + // the user from editing the transaction in those cases. + + const isTokenApproval = + txData.type === TRANSACTION_TYPES.TOKEN_METHOD_SET_APPROVAL_FOR_ALL || + txData.type === TRANSACTION_TYPES.TOKEN_METHOD_APPROVE; + + const isContractInteraction = + txData.type === TRANSACTION_TYPES.CONTRACT_INTERACTION; + const isContractInteractionFromDapp = - txData.type === TRANSACTION_TYPES.CONTRACT_INTERACTION && + (isTokenApproval || isContractInteraction) && txData.origin !== 'metamask'; let functionType; if (isContractInteractionFromDapp) { From 13de51e748876707b06b144b0996b1e71738720b Mon Sep 17 00:00:00 2001 From: Olusegun Akintayo Date: Mon, 19 Dec 2022 18:46:36 +0100 Subject: [PATCH 4/4] Security and Privacy Settings Re-org (#16756) --- app/_locales/de/messages.json | 9 +- app/_locales/el/messages.json | 9 +- app/_locales/en/messages.json | 58 +- app/_locales/es/messages.json | 9 +- app/_locales/es_419/messages.json | 9 +- app/_locales/fr/messages.json | 9 +- app/_locales/hi/messages.json | 9 +- app/_locales/id/messages.json | 9 +- app/_locales/it/messages.json | 9 +- app/_locales/ja/messages.json | 9 +- app/_locales/ko/messages.json | 9 +- app/_locales/ph/messages.json | 9 +- app/_locales/pt/messages.json | 9 +- app/_locales/pt_BR/messages.json | 9 +- app/_locales/ru/messages.json | 9 +- app/_locales/tl/messages.json | 9 +- app/_locales/tr/messages.json | 9 +- app/_locales/vi/messages.json | 9 +- app/_locales/zh_CN/messages.json | 9 +- app/_locales/zh_TW/messages.json | 6 +- app/scripts/controllers/preferences.js | 3 +- app/scripts/lib/util.js | 7 + shared/constants/metametrics.js | 8 + shared/lib/ui-utils.js | 5 + test/e2e/fixture-builder.js | 2 + test/e2e/restore/MetaMaskUserData.json | 3 +- .../app/whats-new-popup/whats-new-popup.js | 2 +- ui/helpers/constants/settings.js | 53 +- ui/helpers/utils/settings-search.test.js | 4 +- .../import-token/import-token.component.js | 6 +- .../advanced-tab/advanced-tab.component.js | 422 +++++--------- .../advanced-tab.component.test.js | 14 +- .../advanced-tab/advanced-tab.container.js | 12 - .../experimental-tab.component.js | 52 -- ui/pages/settings/index.scss | 28 +- .../__snapshots__/security-tab.test.js.snap | 537 +++++++++++++----- .../security-tab/security-tab.component.js | 334 ++++++++++- .../security-tab/security-tab.container.js | 24 +- .../security-tab/security-tab.test.js | 46 +- ui/store/actions.js | 2 - 40 files changed, 1101 insertions(+), 689 deletions(-) diff --git a/app/_locales/de/messages.json b/app/_locales/de/messages.json index f9adc745d2c4..069bef770a6a 100644 --- a/app/_locales/de/messages.json +++ b/app/_locales/de/messages.json @@ -1676,12 +1676,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "Ungültige Eingabe! Die geheime Wiederherstellungsphrase berücksichtigt Groß- und Kleinschreibung." }, - "ipfsGateway": { - "message": "IPFS-Gateway" - }, - "ipfsGatewayDescription": { - "message": "Geben Sie die URL des IPFS CID Gateways ein, das für die Auflösung der ENS Inhalte verwendet werden soll." - }, "jazzAndBlockies": { "message": "Jazzicons und Blockies sind zwei verschiedene Arten von einzigartigen Symbolen, mit denen Sie ein Konto auf einen Blick erkennen können." }, @@ -3021,7 +3015,8 @@ "message": "Eingehende Transaktionen anzeigen" }, "showIncomingTransactionsDescription": { - "message": "Aktivieren Sie dies, um Etherscan zu aktivieren und eingehende Transaktionen in der Transaktionsliste anzuzeigen" + "message": "Aktivieren Sie dies, um Etherscan zu aktivieren und eingehende Transaktionen in der Transaktionsliste anzuzeigen", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Berechtigungen anzeigen" diff --git a/app/_locales/el/messages.json b/app/_locales/el/messages.json index 740d490f474e..3e8142f2f97f 100644 --- a/app/_locales/el/messages.json +++ b/app/_locales/el/messages.json @@ -1676,12 +1676,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "Μη έγκυρη εισαγωγή! Η Μυστική σας Φράση Ανάκτησης κάνει διάκριση πεζών-κεφαλαίων." }, - "ipfsGateway": { - "message": "Πύλη IPFS" - }, - "ipfsGatewayDescription": { - "message": "Εισάγετε τη διεύθυνση URL της πύλης IPFS CID που θα χρησιμοποιηθεί για την ανάλυση περιεχομένου ENS." - }, "jazzAndBlockies": { "message": "Τα Jazzicons και τα Blockies είναι δύο διαφορετικά στυλ μοναδικών εικονιδίων που σας βοηθούν να αναγνωρίζετε έναν λογαριασμό με μια ματιά." }, @@ -3021,7 +3015,8 @@ "message": "Εμφάνιση Εισερχομένων Συναλλαγών" }, "showIncomingTransactionsDescription": { - "message": "Επιλέξτε αυτό για να χρησιμοποιήσετε Etherscan για να εμφανίσετε τις εισερχόμενες συναλλαγές στη λίστα συναλλαγών" + "message": "Επιλέξτε αυτό για να χρησιμοποιήσετε Etherscan για να εμφανίσετε τις εισερχόμενες συναλλαγές στη λίστα συναλλαγών", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Εμφάνιση δικαιωμάτων" diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index d0abc28d36c4..a40219cf1d89 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -183,6 +183,15 @@ "addContact": { "message": "Add contact" }, + "addCustomIPFSGateway": { + "message": "Add custom IPFS gateway" + }, + "addCustomIPFSGatewayDescription": { + "message": "The IPFS gateway makes it possible to access and view data hosted by third parties. You can add a custom IPFS gateway or continue using the default." + }, + "addCustomNetwork": { + "message": "Add custom network" + }, "addCustomToken": { "message": "Add custom token" }, @@ -415,6 +424,13 @@ "authorizedPermissions": { "message": "You have authorized the following permissions" }, + "autoDetectTokens": { + "message": "Autodetect tokens" + }, + "autoDetectTokensDescription": { + "message": "We use third-party APIs to detect and display new tokens sent to your wallet. Turn off if you don’t want the app to pull data from those services. $1", + "description": "$1 is a link to a support article" + }, "autoLockTimeLimit": { "message": "Auto-lock timer (minutes)" }, @@ -639,6 +655,13 @@ "message": "The network with chain ID $1 may use a different currency symbol ($2) than the one you have entered. Please verify before continuing.", "description": "$1 is the chain id currently entered in the network form and $2 is the return value of nativeCurrency.symbol from chainlist.network" }, + "chooseYourNetwork": { + "message": "Choose your network" + }, + "chooseYourNetworkDescription": { + "message": "We use Infura as our remote procedure call (RPC) provider to offer the most reliable and private access to Ethereum data we can. You can choose your own RPC, but remember that any RPC will receive your IP address and Ethereum wallet to make transactions. Read our $1 to learn more about how Infura handles data.", + "description": "$1 is a link to the privacy policy" + }, "chromeRequiredForHardwareWallets": { "message": "You need to use MetaMask on Google Chrome in order to connect to your Hardware Wallet." }, @@ -1797,12 +1820,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "Invalid input! Secret Recovery Phrase is case sensitive." }, - "ipfsGateway": { - "message": "IPFS Gateway" - }, - "ipfsGatewayDescription": { - "message": "Enter the URL of the IPFS CID gateway to use for ENS content resolution." - }, "jazzAndBlockies": { "message": "Jazzicons and Blockies are two different styles of unique icons that help you identify an account at a glance." }, @@ -2159,6 +2176,9 @@ "networkNameTestnet": { "message": "Testnet" }, + "networkProvider": { + "message": "Network provider" + }, "networkSettingsChainIdDescription": { "message": "The chain ID is used for signing transactions. It must match the chain ID returned by the network. You can enter a decimal or '0x'-prefixed hexadecimal number, but we will display the number in decimal." }, @@ -2857,6 +2877,9 @@ "priorityFeeProperCase": { "message": "Priority Fee" }, + "privacy": { + "message": "Privacy" + }, "privacyMsg": { "message": "Privacy policy" }, @@ -3123,6 +3146,9 @@ "secureWallet": { "message": "Secure wallet" }, + "security": { + "message": "Security" + }, "securityAndPrivacy": { "message": "Security & privacy" }, @@ -3295,7 +3321,8 @@ "message": "Show incoming transactions" }, "showIncomingTransactionsDescription": { - "message": "Select this to use Etherscan to show incoming transactions in the transactions list" + "message": "This relies on $1 which will have access to your Ethereum address and your IP address. $2", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Show permissions" @@ -4104,6 +4131,9 @@ "tokenList": { "message": "Token lists:" }, + "tokenNftAutoDetection": { + "message": "Token and NFT autodetection" + }, "tokenScamSecurityRisk": { "message": "token scams and security risks" }, @@ -4231,6 +4261,9 @@ "transactionUpdated": { "message": "Transaction updated at $2." }, + "transactions": { + "message": "Transactions" + }, "transfer": { "message": "Transfer" }, @@ -4346,7 +4379,16 @@ "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." + "message": "We use third-party APIs to detect NFTs in your wallet, which means your IP address may be exposed to their servers. Leave this feature off if you don't want the app to pull data from those services." + }, + "useCollectibleDetectionDescriptionLine2": { + "message": "Additionally, be aware that:" + }, + "useCollectibleDetectionDescriptionLine3": { + "message": "NFT metadata may contain links to scams or phishing sites." + }, + "useCollectibleDetectionDescriptionLine4": { + "message": "Anyone can airdrop NFTs to your account. This can include offensive content that might be automatically displayed in your wallet." }, "useDefault": { "message": "Use default" diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json index 788a19c1b869..c141284fa8be 100644 --- a/app/_locales/es/messages.json +++ b/app/_locales/es/messages.json @@ -1676,12 +1676,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "¡Entrada inválida! La frase secreta de recuperación distingue entre mayúsculas y minúsculas." }, - "ipfsGateway": { - "message": "Puerta de enlace de IPFS" - }, - "ipfsGatewayDescription": { - "message": "Escriba la dirección URL de la puerta de enlace de IPFS CID para usar la resolución de contenido de ENS." - }, "jazzAndBlockies": { "message": "Jazzicons y Blockies son dos estilos distintos de íconos únicos que pueden ayudarlo a identificar rápidamente una cuenta." }, @@ -3021,7 +3015,8 @@ "message": "Mostrar transacciones entrantes" }, "showIncomingTransactionsDescription": { - "message": "Seleccione esta opción para usar Etherscan para mostrar las transacciones entrantes en la lista de transacciones" + "message": "Seleccione esta opción para usar Etherscan para mostrar las transacciones entrantes en la lista de transacciones", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Mostrar permisos" diff --git a/app/_locales/es_419/messages.json b/app/_locales/es_419/messages.json index e8b075049a42..ac098591f6f4 100644 --- a/app/_locales/es_419/messages.json +++ b/app/_locales/es_419/messages.json @@ -1312,12 +1312,6 @@ "invalidSeedPhrase": { "message": "Frase secreta de recuperación no válida" }, - "ipfsGateway": { - "message": "Puerta de enlace de IPFS" - }, - "ipfsGatewayDescription": { - "message": "Escriba la dirección URL de la puerta de enlace de IPFS CID para usar la resolución de contenido de ENS." - }, "jsDeliver": { "message": "jsDeliver" }, @@ -2310,7 +2304,8 @@ "message": "Mostrar transacciones entrantes" }, "showIncomingTransactionsDescription": { - "message": "Seleccione esta opción para usar Etherscan para mostrar las transacciones entrantes en la lista de transacciones" + "message": "Seleccione esta opción para usar Etherscan para mostrar las transacciones entrantes en la lista de transacciones", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Mostrar permisos" diff --git a/app/_locales/fr/messages.json b/app/_locales/fr/messages.json index 284a0fd48287..6492041ca156 100644 --- a/app/_locales/fr/messages.json +++ b/app/_locales/fr/messages.json @@ -1676,12 +1676,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "Entrée invalide ! La phrase secrète de récupération est sensible à la casse." }, - "ipfsGateway": { - "message": "Passerelle IPFS" - }, - "ipfsGatewayDescription": { - "message": "Entrez l’URL de la passerelle CID IPFS à utiliser pour résoudre les contenus ENS." - }, "jazzAndBlockies": { "message": "Les Jazzicons et les Blockies sont deux styles différents d’icônes uniques qui vous aident à identifier un compte en un coup d’œil." }, @@ -3021,7 +3015,8 @@ "message": "Afficher les transactions entrantes" }, "showIncomingTransactionsDescription": { - "message": "Sélectionnez ceci pour utiliser Etherscan afin d’afficher les transactions entrantes dans la liste des transactions" + "message": "Sélectionnez ceci pour utiliser Etherscan afin d’afficher les transactions entrantes dans la liste des transactions", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Afficher les autorisations" diff --git a/app/_locales/hi/messages.json b/app/_locales/hi/messages.json index f893f4496364..af6f24e23691 100644 --- a/app/_locales/hi/messages.json +++ b/app/_locales/hi/messages.json @@ -1676,12 +1676,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "अमान्य निवेश! गुप्त पुनर्प्राप्ति वाक्यांश केस संवेदी है।" }, - "ipfsGateway": { - "message": "IPFS गेटवे" - }, - "ipfsGatewayDescription": { - "message": "ENS सामग्री रिजॉल्यूशन का उपयोग करने के लिए IPFS CID गेटवे का URL दर्ज करें।" - }, "jazzAndBlockies": { "message": "जाज़िकॉन्स और ब्लॉकीज़ विशिष्ट आइकनों की दो अलग-अलग शैलियां हैं जो आपको एक नज़र में किसी अकाउंट की पहचान करने में मदद करती हैं।" }, @@ -3021,7 +3015,8 @@ "message": "आने वाले लेन-देन दिखाएं" }, "showIncomingTransactionsDescription": { - "message": "लेनदेन सूची में आने वाले लेनदेन को दिखाने के लिए Etherscan का उपयोग करने के लिए इसका चयन करें" + "message": "लेनदेन सूची में आने वाले लेनदेन को दिखाने के लिए Etherscan का उपयोग करने के लिए इसका चयन करें", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "अनुमतियां दिखाएं" diff --git a/app/_locales/id/messages.json b/app/_locales/id/messages.json index 9e0fb2768361..cdf811f751b2 100644 --- a/app/_locales/id/messages.json +++ b/app/_locales/id/messages.json @@ -1676,12 +1676,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "Masukan tidak valid! Frasa Pemulihan Rahasia peka terhadap huruf besar/kecil." }, - "ipfsGateway": { - "message": "Gateway IPFS" - }, - "ipfsGatewayDescription": { - "message": "Masukkan URL gateway CID IPFS dan gunakan untuk resolusi konten ENS." - }, "jazzAndBlockies": { "message": "Jazzicons dan Blockies merupakan dua gaya ikon unik yang berbeda untuk membantu Anda mengidentifikasi akun dengan cepat." }, @@ -3021,7 +3015,8 @@ "message": "Tampilkan transaksi masuk" }, "showIncomingTransactionsDescription": { - "message": "Pilih ini untuk menggunakan Etherscan untuk menampilkan transaksi yang masuk di daftar transaksi" + "message": "Pilih ini untuk menggunakan Etherscan untuk menampilkan transaksi yang masuk di daftar transaksi", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Tampilkan Izin" diff --git a/app/_locales/it/messages.json b/app/_locales/it/messages.json index 0d300b38537e..774565740821 100644 --- a/app/_locales/it/messages.json +++ b/app/_locales/it/messages.json @@ -1269,12 +1269,6 @@ "invalidSeedPhrase": { "message": "Frase seed non valida" }, - "ipfsGateway": { - "message": "Portale IPFS" - }, - "ipfsGatewayDescription": { - "message": "Inserisci l'URL del portale IPFS CID da usare per la risoluzione del contenuto ENS." - }, "jsonFile": { "message": "File JSON", "description": "format for importing an account" @@ -1733,7 +1727,8 @@ "message": "Mostra Transazioni in Ingresso" }, "showIncomingTransactionsDescription": { - "message": "Usa Etherscan per visualizzare le transazioni in ingresso nella lista delle transazioni" + "message": "Usa Etherscan per visualizzare le transazioni in ingresso nella lista delle transazioni", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Mostra permessi" diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json index acdf40c49e49..e97f916078aa 100644 --- a/app/_locales/ja/messages.json +++ b/app/_locales/ja/messages.json @@ -1676,12 +1676,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "入力値が無効です!秘密のリカバリーフレーズは大文字・小文字が区別されます。" }, - "ipfsGateway": { - "message": "IPFSゲートウェイ" - }, - "ipfsGatewayDescription": { - "message": "ENSコンテンツの解決に使用するIPFS CIDゲートウェイのURLを入力します。" - }, "jazzAndBlockies": { "message": "Jazzicon と Blockie は、アカウントを一目で見分けるためのユニークなアイコンであり、2 つの異なるスタイルが特徴です。" }, @@ -3021,7 +3015,8 @@ "message": "受信トランザクションを表示" }, "showIncomingTransactionsDescription": { - "message": "これを選択すると、Etherscanを使用して受信トランザクションがトランザクションリストに表示されます" + "message": "これを選択すると、Etherscanを使用して受信トランザクションがトランザクションリストに表示されます", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "表示許可" diff --git a/app/_locales/ko/messages.json b/app/_locales/ko/messages.json index 0c37c3dd801b..2980a251b905 100644 --- a/app/_locales/ko/messages.json +++ b/app/_locales/ko/messages.json @@ -1676,12 +1676,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "입력 오류: 비밀 복구 구문은 대소문자를 구분해야 합니다." }, - "ipfsGateway": { - "message": "IPFS 게이트웨이" - }, - "ipfsGatewayDescription": { - "message": "ENS 콘텐츠 해결에 사용할 IPFS CID 게이트웨이의 URL을 입력하세요." - }, "jazzAndBlockies": { "message": "Jazzicons와 Blockies는 계정을 한눈에 식별할 수 있게 도와주는 두 가지 고유한 아이콘 스타일입니다." }, @@ -3021,7 +3015,8 @@ "message": "수신 거래 표시" }, "showIncomingTransactionsDescription": { - "message": "이 항목을 선택하면 Etherscan을 사용해 거래 목록에 수신 거래를 표시할 수 있습니다." + "message": "이 항목을 선택하면 Etherscan을 사용해 거래 목록에 수신 거래를 표시할 수 있습니다.", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "권한 표시" diff --git a/app/_locales/ph/messages.json b/app/_locales/ph/messages.json index ed06090f89e8..ecc3ddb44c16 100644 --- a/app/_locales/ph/messages.json +++ b/app/_locales/ph/messages.json @@ -878,12 +878,6 @@ "invalidSeedPhrase": { "message": "Invalid na Secret Recovery Phrase" }, - "ipfsGateway": { - "message": "IPFS Gateway" - }, - "ipfsGatewayDescription": { - "message": "Ilagay ang URL ng IPFS CID gateway para magamit para sa resolusyon ng content ng ENS." - }, "jsonFile": { "message": "JSON File", "description": "format for importing an account" @@ -1532,7 +1526,8 @@ "message": "Ipakita ang Mga Papasok na Transaksyon" }, "showIncomingTransactionsDescription": { - "message": "Piliin ito para gamitin ang Etherscan sa pagpapakita ng mga papasok na transaksyon sa listahan ng mga transaksyon" + "message": "Piliin ito para gamitin ang Etherscan sa pagpapakita ng mga papasok na transaksyon sa listahan ng mga transaksyon", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Ipakita ang mga pahintulot" diff --git a/app/_locales/pt/messages.json b/app/_locales/pt/messages.json index d83a6b56e372..83cddcccbec7 100644 --- a/app/_locales/pt/messages.json +++ b/app/_locales/pt/messages.json @@ -1676,12 +1676,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "Entrada inválida! A frase secreta de recuperação diferencia maiúsculas e minúsculas." }, - "ipfsGateway": { - "message": "Gateway IPFS" - }, - "ipfsGatewayDescription": { - "message": "Informe o URL do gateway de CID do IPFS para usar com resolução de conteúdo de ENS." - }, "jazzAndBlockies": { "message": "Jazzicons e Blockies são dois estilos diferentes de ícones únicos que ajudam você a identificar uma conta num relance." }, @@ -3021,7 +3015,8 @@ "message": "Mostrar transações recebidas" }, "showIncomingTransactionsDescription": { - "message": "Selecione essa opção para usar o Etherscan e mostrar as transações recebidas na lista de transações" + "message": "Selecione essa opção para usar o Etherscan e mostrar as transações recebidas na lista de transações", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Mostrar permissões" diff --git a/app/_locales/pt_BR/messages.json b/app/_locales/pt_BR/messages.json index 4b7a39e8030f..0aad26bcedd4 100644 --- a/app/_locales/pt_BR/messages.json +++ b/app/_locales/pt_BR/messages.json @@ -1312,12 +1312,6 @@ "invalidSeedPhrase": { "message": "Frase de Recuperação Secreta inválida" }, - "ipfsGateway": { - "message": "Gateway IPFS" - }, - "ipfsGatewayDescription": { - "message": "Informe o URL do gateway de CID do IPFS para usar com resolução de conteúdo de ENS." - }, "jsDeliver": { "message": "jsDeliver" }, @@ -2310,7 +2304,8 @@ "message": "Mostrar transações recebidas" }, "showIncomingTransactionsDescription": { - "message": "Selecione essa opção para usar o Etherscan e mostrar as transações recebidas na lista de transações" + "message": "Selecione essa opção para usar o Etherscan e mostrar as transações recebidas na lista de transações", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Mostrar permissões" diff --git a/app/_locales/ru/messages.json b/app/_locales/ru/messages.json index 046e4f8c0877..41ed1193a4df 100644 --- a/app/_locales/ru/messages.json +++ b/app/_locales/ru/messages.json @@ -1676,12 +1676,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "Неправильный ввод! Секретная фраза для восстановления чувствительна к регистру." }, - "ipfsGateway": { - "message": "Шлюз IPFS" - }, - "ipfsGatewayDescription": { - "message": "Введите URL-адрес шлюза IPFS CID, который будет использоваться для разрешения содержимого ENS." - }, "jazzAndBlockies": { "message": "«Джазиконы» и «Блокиз» — это два разных стиля уникальных значков, которые помогут вам с первого взгляда идентифицировать свой счет." }, @@ -3021,7 +3015,8 @@ "message": "Показать входящие транзакции" }, "showIncomingTransactionsDescription": { - "message": "Выберите это, чтобы использовать Etherscan для отображения входящих транзакций в списке транзакций" + "message": "Выберите это, чтобы использовать Etherscan для отображения входящих транзакций в списке транзакций", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Показать разрешения" diff --git a/app/_locales/tl/messages.json b/app/_locales/tl/messages.json index b20c3974bde1..9b5fe6036874 100644 --- a/app/_locales/tl/messages.json +++ b/app/_locales/tl/messages.json @@ -1676,12 +1676,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "Di-wastong input! Ang Secret Recovery Phrase ay case sensitive." }, - "ipfsGateway": { - "message": "Gateway na IPFS" - }, - "ipfsGatewayDescription": { - "message": "Ilagay ang URL ng IPFS CID gateway para magamit para sa resolusyon ng content ng ENS." - }, "jazzAndBlockies": { "message": "Ang Jazzicons at Blockies ay dalawang magkaibang istilo ng mga natatanging icon na makakatulong sa iyong matukoy ang account sa isang sulyap." }, @@ -3021,7 +3015,8 @@ "message": "Ipakita ang Mga Papasok na Transaksyon" }, "showIncomingTransactionsDescription": { - "message": "Piliin ito para gamitin ang Etherscan sa pagpapakita ng mga papasok na transaksyon sa listahan ng mga transaksyon" + "message": "Piliin ito para gamitin ang Etherscan sa pagpapakita ng mga papasok na transaksyon sa listahan ng mga transaksyon", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Ipakita ang mga pahintulot" diff --git a/app/_locales/tr/messages.json b/app/_locales/tr/messages.json index 8f3a26cdaf24..5712de5a1f98 100644 --- a/app/_locales/tr/messages.json +++ b/app/_locales/tr/messages.json @@ -1676,12 +1676,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "Giriş geçersiz! Gizli Kurtarma İfadesi büyük/küçük harf duyarlıdır." }, - "ipfsGateway": { - "message": "IPFS Ağ Geçidi" - }, - "ipfsGatewayDescription": { - "message": "ENS içerik çözünürlüğünde kullanmak için IPFS CID ağ geçidi URL adresini girin." - }, "jazzAndBlockies": { "message": "Jazzicons ve Blockies, bir bakışta bir hesabı tanımlamana yardımcı olan iki farklı benzersiz simge stilidir." }, @@ -3021,7 +3015,8 @@ "message": "Gelen İşlemleri Göster" }, "showIncomingTransactionsDescription": { - "message": "Etherscan'in işlemler listesinde gelecek işlemleri göstermesi için bunu seçin" + "message": "Etherscan'in işlemler listesinde gelecek işlemleri göstermesi için bunu seçin", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "İzinleri göster" diff --git a/app/_locales/vi/messages.json b/app/_locales/vi/messages.json index 226670d8eb93..2b3ec4bb0b3a 100644 --- a/app/_locales/vi/messages.json +++ b/app/_locales/vi/messages.json @@ -1676,12 +1676,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "Nội dung nhập không hợp lệ! Cụm từ khôi phục bí mật phân biệt chữ hoa và chữ thường." }, - "ipfsGateway": { - "message": "Cổng kết nối IPFS" - }, - "ipfsGatewayDescription": { - "message": "Nhập URL của cổng kết nối IPFS CID để dùng cho quá trình phân giải nội dung ENS." - }, "jazzAndBlockies": { "message": "Jazzicons và Blockies là hai kiểu biểu tượng độc nhất khác nhau giúp bạn nhận ra tài khoản trong nháy mắt." }, @@ -3021,7 +3015,8 @@ "message": "Hiển thị các giao dịch đến" }, "showIncomingTransactionsDescription": { - "message": "Chọn tùy chọn này nếu bạn muốn dùng Etherscan để hiển thị các giao dịch đến trong danh sách giao dịch" + "message": "Chọn tùy chọn này nếu bạn muốn dùng Etherscan để hiển thị các giao dịch đến trong danh sách giao dịch", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "Hiển thị quyền" diff --git a/app/_locales/zh_CN/messages.json b/app/_locales/zh_CN/messages.json index b6a4dfd4dbc1..16aed98957ed 100644 --- a/app/_locales/zh_CN/messages.json +++ b/app/_locales/zh_CN/messages.json @@ -1676,12 +1676,6 @@ "invalidSeedPhraseCaseSensitive": { "message": "输入无效!助记词须区分大小写。" }, - "ipfsGateway": { - "message": "IPFS 网关" - }, - "ipfsGatewayDescription": { - "message": "输入用于 ENS 内容解析的 IPFS CID 网关的 URL。" - }, "jazzAndBlockies": { "message": "哈希头像是帮助您一眼识别账户的独特图标,有 Jazzicons 和 Blockies 两种不同风格。" }, @@ -3021,7 +3015,8 @@ "message": "显示传入的交易" }, "showIncomingTransactionsDescription": { - "message": "选择此项以使用 Etherscan 在交易列表中显示传入的交易" + "message": "选择此项以使用 Etherscan 在交易列表中显示传入的交易", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "显示权限" diff --git a/app/_locales/zh_TW/messages.json b/app/_locales/zh_TW/messages.json index 4a3146dc0068..9fbf335b1ea5 100644 --- a/app/_locales/zh_TW/messages.json +++ b/app/_locales/zh_TW/messages.json @@ -883,9 +883,6 @@ "invalidSeedPhrase": { "message": "無效的助憶詞" }, - "ipfsGatewayDescription": { - "message": "輸入用於解析 ENS 內容的 IPFS CID gateway URL。" - }, "jsonFile": { "message": "JSON 格式檔案", "description": "format for importing an account" @@ -1421,7 +1418,8 @@ "message": "顯示傳入的交易" }, "showIncomingTransactionsDescription": { - "message": "選擇此項來利用 Etherscan 在交易列表裡顯示傳入的交易" + "message": "選擇此項來利用 Etherscan 在交易列表裡顯示傳入的交易", + "description": "$1 is the link to etherscan url and $2 is the link to the privacy policy of consensys APIs" }, "showPermissions": { "message": "顯示權限" diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index acd5c0c7241b..1024f0e27b93 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -130,8 +130,7 @@ export default class PreferencesController { /** * Setter for the `useMultiAccountBalanceChecker` property * - * @param {boolean} val - Whether or not the user wants to fetch balances for - * all accounts that he has added to the MetaMask wallet state. + * @param {boolean} val - Whether or not the user prefers to turn off/on all security settings */ setUseMultiAccountBalanceChecker(val) { this.store.updateState({ useMultiAccountBalanceChecker: val }); diff --git a/app/scripts/lib/util.js b/app/scripts/lib/util.js index 1f19901f10ca..bfd7469d4886 100644 --- a/app/scripts/lib/util.js +++ b/app/scripts/lib/util.js @@ -246,3 +246,10 @@ export function previousValueComparator(comparator, initialValue) { } }; } + +export function addUrlProtocolPrefix(urlString) { + if (!urlString.match(/(^http:\/\/)|(^https:\/\/)/u)) { + return `https://${urlString}`; + } + return urlString; +} diff --git a/shared/constants/metametrics.js b/shared/constants/metametrics.js index f30dc56c2af9..b96e8fdda5bf 100644 --- a/shared/constants/metametrics.js +++ b/shared/constants/metametrics.js @@ -300,6 +300,14 @@ export const EVENT_NAMES = { KEY_EXPORT_CANCELED: 'Key Export Canceled', KEY_EXPORT_REVEALED: 'Key Material Revealed', KEY_EXPORT_COPIED: 'Key Material Copied', + KEY_TOKEN_DETECTION_SELECTED: 'Key Token Detection Selected', + KEY_GLOBAL_SECURITY_TOGGLE_SELECTED: 'Key Global Security/Privacy Settings', + KEY_BALANCE_TOKEN_PRICE_CHECKER: + 'Key Show Balance and Token Price Checker Settings', + KEY_GAS_FEE_ESTIMATION_BUY_SWAP_TOKENS: + 'Key Show Gas Fee Estimation, Buy Crypto and Swap Tokens', + KEY_AUTO_DETECT_TOKENS: 'Key Autodetect tokens', + KEY_BATCH_ACCOUNT_BALANCE_REQUESTS: 'Key Batch account balance requests', METRICS_OPT_IN: 'Metrics Opt In', METRICS_OPT_OUT: 'Metrics Opt Out', NAV_ACCOUNT_MENU_OPENED: 'Account Menu Opened', diff --git a/shared/lib/ui-utils.js b/shared/lib/ui-utils.js index e03ce61e7880..eb3a2143da82 100644 --- a/shared/lib/ui-utils.js +++ b/shared/lib/ui-utils.js @@ -5,3 +5,8 @@ _supportLink = 'https://metamask-flask.zendesk.com/hc'; ///: END:ONLY_INCLUDE_IN export const SUPPORT_LINK = _supportLink; +// 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/'; +export const AUTO_DETECT_TOKEN_LEARN_MORE_LINK = + 'https://consensys.net/privacy-policy/'; diff --git a/test/e2e/fixture-builder.js b/test/e2e/fixture-builder.js index 5f245e8a83e9..6e83bedb59db 100644 --- a/test/e2e/fixture-builder.js +++ b/test/e2e/fixture-builder.js @@ -238,6 +238,7 @@ function defaultFixture() { useNonceField: false, usePhishDetect: true, useTokenDetection: false, + useMultiAccountBalanceChecker: true, }, SmartTransactionsController: { smartTransactionsState: { @@ -350,6 +351,7 @@ function onboardingFixture() { useNonceField: false, usePhishDetect: true, useTokenDetection: false, + useMultiAccountBalanceChecker: true, }, SmartTransactionsController: { smartTransactionsState: { diff --git a/test/e2e/restore/MetaMaskUserData.json b/test/e2e/restore/MetaMaskUserData.json index cb9dffefb50b..48bf95119b92 100644 --- a/test/e2e/restore/MetaMaskUserData.json +++ b/test/e2e/restore/MetaMaskUserData.json @@ -45,6 +45,7 @@ "useNftDetection": false, "useNonceField": false, "usePhishDetect": true, - "useTokenDetection": false + "useTokenDetection": false, + "useMultiAccountBalanceChecker": true } } diff --git a/ui/components/app/whats-new-popup/whats-new-popup.js b/ui/components/app/whats-new-popup/whats-new-popup.js index 5a6b6c52495a..3c28741cb7f8 100644 --- a/ui/components/app/whats-new-popup/whats-new-popup.js +++ b/ui/components/app/whats-new-popup/whats-new-popup.js @@ -49,7 +49,7 @@ function getActionFunctionById(id, history) { }, 10: () => { updateViewedNotifications({ 10: true }); - history.push(`${ADVANCED_ROUTE}#token-description`); + history.push(`${SECURITY_ROUTE}#token-description`); }, 12: () => { updateViewedNotifications({ 12: true }); diff --git a/ui/helpers/constants/settings.js b/ui/helpers/constants/settings.js index 0747e4b01254..a41d902fe918 100644 --- a/ui/helpers/constants/settings.js +++ b/ui/helpers/constants/settings.js @@ -118,13 +118,6 @@ export const SETTINGS_CONSTANTS = [ route: `${ADVANCED_ROUTE}#autolock-timer`, icon: 'fas fa-sliders-h', }, - { - tabMessage: (t) => t('advanced'), - sectionMessage: (t) => t('ipfsGateway'), - descriptionMessage: (t) => t('ipfsGatewayDescription'), - route: `${ADVANCED_ROUTE}#ipfs-gateway`, - icon: 'fas fa-sliders-h', - }, { tabMessage: (t) => t('advanced'), sectionMessage: (t) => t('preferredLedgerConnectionType'), @@ -183,13 +176,49 @@ export const SETTINGS_CONSTANTS = [ route: `${SECURITY_ROUTE}#metrametrics`, icon: 'fa fa-lock', }, + { + tabMessage: (t) => t('securityAndPrivacy'), + sectionMessage: (t) => t('enhancedTokenDetection'), + descriptionMessage: (t) => t('enhancedTokenDetectionDescription'), + route: `${SECURITY_ROUTE}#token-description`, + icon: 'fas fa-sliders-h', + }, + { + tabMessage: (t) => t('securityAndPrivacy'), + sectionMessage: (t) => t('chooseYourNetwork'), + descriptionMessage: (t) => t('chooseYourNetworkDescription'), + route: `${SECURITY_ROUTE}#-chose-your-network`, + icon: 'fa fa-lock', + }, + { + tabMessage: (t) => t('securityAndPrivacy'), + sectionMessage: (t) => t('addCustomIPFSGateway'), + descriptionMessage: (t) => t('addCustomIPFSGatewayDescription'), + route: `${SECURITY_ROUTE}#-add-custom-ipfs-gateway`, + icon: 'fa fa-lock', + }, + { + tabMessage: (t) => t('securityAndPrivacy'), + sectionMessage: (t) => t('autoDetectTokens'), + descriptionMessage: (t) => t('autoDetectTokensDescription'), + route: `${SECURITY_ROUTE}#-auto-detect-tokens`, + icon: 'fa fa-lock', + }, { tabMessage: (t) => t('securityAndPrivacy'), sectionMessage: (t) => t('useMultiAccountBalanceChecker'), descriptionMessage: (t) => t('useMultiAccountBalanceCheckerDescription'), - route: `${SECURITY_ROUTE}#multi-account-balance-checker`, + route: `${SECURITY_ROUTE}#-use-milti-account-balance-checker`, icon: 'fa fa-lock', }, + { + tabMessage: (t) => t('securityAndPrivacy'), + sectionMessage: (t) => t('useCollectibleDetection'), + descriptionMessage: (t) => t('useCollectibleDetectionDescription'), + route: `${SECURITY_ROUTE}#autodetect-nfts`, + icon: 'fa fa-flask', + featureFlag: 'COLLECTIBLES_V1', + }, { tabMessage: (t) => t('alerts'), sectionMessage: (t) => t('alertSettingsUnconnectedAccount'), @@ -314,14 +343,6 @@ export const SETTINGS_CONSTANTS = [ icon: 'fa fa-flask', featureFlag: 'NFTS_V1', }, - { - tabMessage: (t) => t('experimental'), - sectionMessage: (t) => t('useCollectibleDetection'), - descriptionMessage: (t) => t('useCollectibleDetectionDescription'), - route: `${EXPERIMENTAL_ROUTE}#autodetect-nfts`, - icon: 'fa fa-flask', - featureFlag: 'NFTS_V1', - }, { tabMessage: (t) => t('advanced'), sectionMessage: (t) => t('backupUserData'), diff --git a/ui/helpers/utils/settings-search.test.js b/ui/helpers/utils/settings-search.test.js index 00e0bbac34a8..683bd014e337 100644 --- a/ui/helpers/utils/settings-search.test.js +++ b/ui/helpers/utils/settings-search.test.js @@ -155,7 +155,7 @@ describe('Settings Search Utils', () => { }); it('should get good advanced section number', () => { - expect(getNumberOfSettingsInSection(t, t('advanced'))).toStrictEqual(15); + expect(getNumberOfSettingsInSection(t, t('advanced'))).toStrictEqual(14); }); it('should get good contact section number', () => { @@ -165,7 +165,7 @@ describe('Settings Search Utils', () => { it('should get good security & privacy section number', () => { expect( getNumberOfSettingsInSection(t, t('securityAndPrivacy')), - ).toStrictEqual(5); + ).toStrictEqual(9); }); it('should get good alerts section number', () => { diff --git a/ui/pages/import-token/import-token.component.js b/ui/pages/import-token/import-token.component.js index e429aecfa6b0..fdfa6eb62ed6 100644 --- a/ui/pages/import-token/import-token.component.js +++ b/ui/pages/import-token/import-token.component.js @@ -10,7 +10,7 @@ import { tokenInfoGetter } from '../../helpers/utils/token-util'; import { ADD_COLLECTIBLE_ROUTE, CONFIRM_IMPORT_TOKEN_ROUTE, - ADVANCED_ROUTE, + SECURITY_ROUTE, } from '../../helpers/constants/routes'; import TextField from '../../components/ui/text-field'; import PageContainer from '../../components/ui/page-container'; @@ -445,7 +445,7 @@ class ImportToken extends Component { key="import-token-token-detection-announcement" className="import-token__link" onClick={() => - history.push(`${ADVANCED_ROUTE}#token-description`) + history.push(`${SECURITY_ROUTE}#token-description`) } > {t('inYourSettings')} @@ -588,7 +588,7 @@ class ImportToken extends Component { key="token-detection-announcement" className="import-token__link" onClick={() => - history.push(`${ADVANCED_ROUTE}#token-description`) + history.push(`${SECURITY_ROUTE}#token-description`) } > {t('enableFromSettings')} diff --git a/ui/pages/settings/advanced-tab/advanced-tab.component.js b/ui/pages/settings/advanced-tab/advanced-tab.component.js index 0b3e2a6151bd..0cd79f47695a 100644 --- a/ui/pages/settings/advanced-tab/advanced-tab.component.js +++ b/ui/pages/settings/advanced-tab/advanced-tab.component.js @@ -14,7 +14,6 @@ import { getNumberOfSettingsInSection, handleSettingsRefs, } from '../../../helpers/utils/settings-search'; -import { addUrlProtocolPrefix } from '../../../helpers/utils/ipfs'; import { LEDGER_TRANSPORT_TYPES, @@ -50,15 +49,11 @@ export default class AdvancedTab extends PureComponent { setAutoLockTimeLimit: PropTypes.func.isRequired, setShowFiatConversionOnTestnetsPreference: PropTypes.func.isRequired, setShowTestNetworks: PropTypes.func.isRequired, - setIpfsGateway: PropTypes.func.isRequired, - ipfsGateway: PropTypes.string.isRequired, ledgerTransportType: PropTypes.oneOf(Object.values(LEDGER_TRANSPORT_TYPES)), setLedgerTransportPreference: PropTypes.func.isRequired, setDismissSeedBackUpReminder: PropTypes.func.isRequired, dismissSeedBackUpReminder: PropTypes.bool.isRequired, userHasALedgerAccount: PropTypes.bool.isRequired, - useTokenDetection: PropTypes.bool.isRequired, - setUseTokenDetection: PropTypes.func.isRequired, backupUserData: PropTypes.func.isRequired, restoreUserData: PropTypes.func.isRequired, }; @@ -66,8 +61,6 @@ export default class AdvancedTab extends PureComponent { state = { autoLockTimeLimit: this.props.autoLockTimeLimit, lockTimeError: '', - ipfsGateway: this.props.ipfsGateway, - ipfsGatewayError: '', showLedgerTransportWarning: false, showResultMessage: false, restoreSuccessful: true, @@ -92,37 +85,6 @@ export default class AdvancedTab extends PureComponent { handleSettingsRefs(t, t('advanced'), this.settingsRefs); } - renderMobileSync() { - const { t } = this.context; - const { history } = this.props; - - return ( -
-
- {t('syncWithMobile')} -
-
-
- -
-
-
- ); - } - async getTextFromFile(file) { return new Promise((resolve, reject) => { const reader = new window.FileReader(); @@ -172,68 +134,6 @@ export default class AdvancedTab extends PureComponent { } } - renderRestoreUserData() { - const { t } = this.context; - const { showResultMessage, restoreSuccessful, restoreMessage } = this.state; - - const defaultRestoreMessage = restoreSuccessful - ? t('restoreSuccessful') - : t('restoreFailed'); - const restoreMessageToRender = - restoreMessage === CORRUPT_JSON_FILE - ? t('dataBackupSeemsCorrupt') - : defaultRestoreMessage; - - return ( -
-
- {t('restoreUserData')} - - {t('restoreUserDataDescription')} - -
-
-
- - this.handleFileUpload(e)} - /> -
- {showResultMessage && ( - { - this.setState({ - showResultMessage: false, - restoreSuccessful: true, - restoreMessage: null, - }); - }, - }} - /> - )} -
-
- ); - } - backupUserData = async () => { const { fileName, data } = await this.props.backupUserData(); exportAsFile(fileName, data); @@ -245,29 +145,38 @@ export default class AdvancedTab extends PureComponent { }); }; - renderUserDataBackup() { + renderStateLogs() { const { t } = this.context; + const { displayWarning } = this.props; + return (
- {t('backupUserData')} + {t('stateLogs')} - {t('backupUserDataDescription')} + {t('stateLogsDescription')}
@@ -275,38 +184,30 @@ export default class AdvancedTab extends PureComponent { ); } - renderStateLogs() { + renderMobileSync() { const { t } = this.context; - const { displayWarning } = this.props; + const { history } = this.props; return (
- {t('stateLogs')} - - {t('stateLogsDescription')} - + {t('syncWithMobile')}
@@ -354,27 +255,27 @@ export default class AdvancedTab extends PureComponent { ); } - renderHexDataOptIn() { + renderAdvancedGasInputInline() { const { t } = this.context; - const { sendHexData, setHexDataFeatureFlag } = this.props; + const { advancedInlineGas, setAdvancedInlineGasFeatureFlag } = this.props; return (
- {t('showHexData')} + {t('showAdvancedGasInline')}
- {t('showHexDataDescription')} + {t('showAdvancedGasInlineDescription')}
setHexDataFeatureFlag(!value)} + value={advancedInlineGas} + onToggle={(value) => setAdvancedInlineGasFeatureFlag(!value)} offLabel={t('off')} onLabel={t('on')} /> @@ -384,27 +285,27 @@ export default class AdvancedTab extends PureComponent { ); } - renderAdvancedGasInputInline() { + renderHexDataOptIn() { const { t } = this.context; - const { advancedInlineGas, setAdvancedInlineGasFeatureFlag } = this.props; + const { sendHexData, setHexDataFeatureFlag } = this.props; return (
- {t('showAdvancedGasInline')} + {t('showHexData')}
- {t('showAdvancedGasInlineDescription')} + {t('showHexDataDescription')}
setAdvancedInlineGasFeatureFlag(!value)} + value={sendHexData} + onToggle={(value) => setHexDataFeatureFlag(!value)} offLabel={t('off')} onLabel={t('on')} /> @@ -414,27 +315,30 @@ export default class AdvancedTab extends PureComponent { ); } - renderToggleTestNetworks() { + renderShowConversionInTestnets() { const { t } = this.context; - const { showTestNetworks, setShowTestNetworks } = this.props; + const { showFiatInTestnets, setShowFiatConversionOnTestnetsPreference } = + this.props; return (
- {t('showTestnetNetworks')} + {t('showFiatConversionInTestnets')}
- {t('showTestnetNetworksDescription')} + {t('showFiatConversionInTestnetsDescription')}
setShowTestNetworks(!value)} + value={showFiatInTestnets} + onToggle={(value) => + setShowFiatConversionOnTestnetsPreference(!value) + } offLabel={t('off')} onLabel={t('on')} /> @@ -444,30 +348,27 @@ export default class AdvancedTab extends PureComponent { ); } - renderShowConversionInTestnets() { + renderToggleTestNetworks() { const { t } = this.context; - const { showFiatInTestnets, setShowFiatConversionOnTestnetsPreference } = - this.props; + const { showTestNetworks, setShowTestNetworks } = this.props; return (
- {t('showFiatConversionInTestnets')} + {t('showTestnetNetworks')}
- {t('showFiatConversionInTestnetsDescription')} + {t('showTestnetNetworksDescription')}
- setShowFiatConversionOnTestnetsPreference(!value) - } + value={showTestNetworks} + onToggle={(value) => setShowTestNetworks(!value)} offLabel={t('off')} onLabel={t('on')} /> @@ -507,24 +408,6 @@ export default class AdvancedTab extends PureComponent { ); } - handleLockChange(time) { - const { t } = this.context; - const autoLockTimeLimit = Math.max(Number(time), 0); - - this.setState(() => { - let lockTimeError = ''; - - if (autoLockTimeLimit > 10080) { - lockTimeError = t('lockTimeTooGreat'); - } - - return { - autoLockTimeLimit, - lockTimeError, - }; - }); - } - renderAutoLockTimeLimit() { const { t } = this.context; const { lockTimeError } = this.state; @@ -610,7 +493,7 @@ export default class AdvancedTab extends PureComponent { : LEDGER_TRANSPORT_NAMES.U2F; return ( -
+
{t('preferredLedgerConnectionType')}
@@ -666,151 +549,142 @@ export default class AdvancedTab extends PureComponent { ); } - handleIpfsGatewayChange(url) { - const { t } = this.context; - - this.setState(() => { - let ipfsGatewayError = ''; - - try { - const urlObj = new URL(addUrlProtocolPrefix(url)); - if (!urlObj.host) { - throw new Error(); - } - - // don't allow the use of this gateway - if (urlObj.host === 'gateway.ipfs.io') { - throw new Error('Forbidden gateway'); - } - } catch (error) { - ipfsGatewayError = - error.message === 'Forbidden gateway' - ? t('forbiddenIpfsGateway') - : t('invalidIpfsGateway'); - } - - return { - ipfsGateway: url, - ipfsGatewayError, - }; - }); - } - - handleIpfsGatewaySave() { - const url = new URL(addUrlProtocolPrefix(this.state.ipfsGateway)); - const { host } = url; - - this.props.setIpfsGateway(host); - } - - renderIpfsGatewayControl() { + renderDismissSeedBackupReminderControl() { const { t } = this.context; - const { ipfsGatewayError } = this.state; + const { dismissSeedBackUpReminder, setDismissSeedBackUpReminder } = + this.props; return (
- {t('ipfsGateway')} + {t('dismissReminderField')}
- {t('ipfsGatewayDescription')} + {t('dismissReminderDescriptionField')}
- this.handleIpfsGatewayChange(e.target.value)} - error={ipfsGatewayError} - fullWidth - margin="dense" + setDismissSeedBackUpReminder(!value)} + offLabel={t('off')} + onLabel={t('on')} /> -
); } - renderDismissSeedBackupReminderControl() { + handleLockChange(time) { const { t } = this.context; - const { dismissSeedBackUpReminder, setDismissSeedBackUpReminder } = - this.props; + const autoLockTimeLimit = Math.max(Number(time), 0); + this.setState(() => { + let lockTimeError = ''; + + if (autoLockTimeLimit > 10080) { + lockTimeError = t('lockTimeTooGreat'); + } + + return { + autoLockTimeLimit, + lockTimeError, + }; + }); + } + + renderUserDataBackup() { + const { t } = this.context; return (
- {t('dismissReminderField')} -
- {t('dismissReminderDescriptionField')} -
+ {t('backupUserData')} + + {t('backupUserDataDescription')} +
- setDismissSeedBackUpReminder(!value)} - offLabel={t('off')} - onLabel={t('on')} - /> +
); } - renderTokenDetectionToggle() { + renderRestoreUserData() { const { t } = this.context; - const { useTokenDetection, setUseTokenDetection } = this.props; + const { showResultMessage, restoreSuccessful, restoreMessage } = this.state; + + const defaultRestoreMessage = restoreSuccessful + ? t('restoreSuccessful') + : t('restoreFailed'); + const restoreMessageToRender = + restoreMessage === CORRUPT_JSON_FILE + ? t('dataBackupSeemsCorrupt') + : defaultRestoreMessage; return (
- {t('enhancedTokenDetection')} -
- {t('enhancedTokenDetectionDescription')} -
+ {t('restoreUserData')} + + {t('restoreUserDataDescription')} +
- { - this.context.trackEvent({ - category: EVENT.CATEGORIES.SETTINGS, - event: 'Token Detection', - properties: { - action: 'Token Detection', - legacy_event: true, - }, - }); - setUseTokenDetection(!value); - }} - offLabel={t('off')} - onLabel={t('on')} + + this.handleFileUpload(e)} />
+ {showResultMessage && ( + { + this.setState({ + showResultMessage: false, + restoreSuccessful: true, + restoreMessage: null, + }); + }, + }} + /> + )}
); @@ -828,7 +702,6 @@ export default class AdvancedTab extends PureComponent { {this.renderMobileSync()} {this.renderResetAccount()} {this.renderAdvancedGasInputInline()} - {this.renderTokenDetectionToggle()} {this.renderHexDataOptIn()} {this.renderShowConversionInTestnets()} {this.renderToggleTestNetworks()} @@ -836,7 +709,6 @@ export default class AdvancedTab extends PureComponent { {this.renderAutoLockTimeLimit()} {this.renderUserDataBackup()} {this.renderRestoreUserData()} - {this.renderIpfsGatewayControl()} {notUsingFirefox ? this.renderLedgerLiveControl() : null} {this.renderDismissSeedBackupReminderControl()}
diff --git a/ui/pages/settings/advanced-tab/advanced-tab.component.test.js b/ui/pages/settings/advanced-tab/advanced-tab.component.test.js index fa8d5742dae0..822a0cf67ac3 100644 --- a/ui/pages/settings/advanced-tab/advanced-tab.component.test.js +++ b/ui/pages/settings/advanced-tab/advanced-tab.component.test.js @@ -8,13 +8,11 @@ import AdvancedTab from '.'; const mockSetAutoLockTimeLimit = jest.fn(); const mockSetShowTestNetworks = jest.fn(); -const mockSetUseTokenDetection = jest.fn(); jest.mock('../../../store/actions.js', () => { return { setAutoLockTimeLimit: () => mockSetAutoLockTimeLimit, setShowTestNetworks: () => mockSetShowTestNetworks, - setUseTokenDetection: () => mockSetUseTokenDetection, }; }); @@ -50,20 +48,10 @@ describe('AdvancedTab Component', () => { it('should toggle show test networks', () => { const { queryAllByRole } = renderWithProvider(, mockStore); - const testNetworkToggle = queryAllByRole('checkbox')[4]; + const testNetworkToggle = queryAllByRole('checkbox')[3]; fireEvent.click(testNetworkToggle); expect(mockSetShowTestNetworks).toHaveBeenCalled(); }); - - it('should toggle token detection', () => { - const { queryAllByRole } = renderWithProvider(, mockStore); - - const tokenDetectionToggle = queryAllByRole('checkbox')[1]; - - fireEvent.click(tokenDetectionToggle); - - expect(mockSetUseTokenDetection).toHaveBeenCalled(); - }); }); diff --git a/ui/pages/settings/advanced-tab/advanced-tab.container.js b/ui/pages/settings/advanced-tab/advanced-tab.container.js index 347d9e438542..9826811f6389 100644 --- a/ui/pages/settings/advanced-tab/advanced-tab.container.js +++ b/ui/pages/settings/advanced-tab/advanced-tab.container.js @@ -9,10 +9,8 @@ import { setShowTestNetworks, setAutoLockTimeLimit, setUseNonceField, - setIpfsGateway, setLedgerTransportPreference, setDismissSeedBackUpReminder, - setUseTokenDetection, backupUserData, restoreUserData, } from '../../../store/actions'; @@ -28,10 +26,8 @@ export const mapStateToProps = (state) => { const { featureFlags: { sendHexData, advancedInlineGas } = {}, useNonceField, - ipfsGateway, ledgerTransportType, dismissSeedBackUpReminder, - useTokenDetection, } = metamask; const { showFiatInTestnets, @@ -49,11 +45,9 @@ export const mapStateToProps = (state) => { showTestNetworks, autoLockTimeLimit, useNonceField, - ipfsGateway, ledgerTransportType, dismissSeedBackUpReminder, userHasALedgerAccount, - useTokenDetection, }; }; @@ -78,18 +72,12 @@ export const mapDispatchToProps = (dispatch) => { setAutoLockTimeLimit: (value) => { return dispatch(setAutoLockTimeLimit(value)); }, - setIpfsGateway: (value) => { - return dispatch(setIpfsGateway(value)); - }, setLedgerTransportPreference: (value) => { return dispatch(setLedgerTransportPreference(value)); }, setDismissSeedBackUpReminder: (value) => { return dispatch(setDismissSeedBackUpReminder(value)); }, - setUseTokenDetection: (value) => { - return dispatch(setUseTokenDetection(value)); - }, }; }; diff --git a/ui/pages/settings/experimental-tab/experimental-tab.component.js b/ui/pages/settings/experimental-tab/experimental-tab.component.js index a048ed2a7c64..c2fb225c3703 100644 --- a/ui/pages/settings/experimental-tab/experimental-tab.component.js +++ b/ui/pages/settings/experimental-tab/experimental-tab.component.js @@ -45,57 +45,6 @@ export default class ExperimentalTab extends PureComponent { handleSettingsRefs(t, t('experimental'), this.settingsRefs); } - renderCollectibleDetectionToggle() { - if (!process.env.NFTS_V1) { - return null; - } - - const { t } = this.context; - const { - useNftDetection, - setUseNftDetection, - openSeaEnabled, - setOpenSeaEnabled, - } = this.props; - - return ( -
-
- {t('useCollectibleDetection')} -
- {t('useCollectibleDetectionDescription')} -
-
-
-
- { - this.context.trackEvent({ - category: EVENT.CATEGORIES.SETTINGS, - event: 'Collectible Detection', - properties: { - action: 'Collectible Detection', - legacy_event: true, - }, - }); - if (!value && !openSeaEnabled) { - setOpenSeaEnabled(!value); - } - setUseNftDetection(!value); - }} - offLabel={t('off')} - onLabel={t('on')} - /> -
-
-
- ); - } - renderOpenSeaEnabledToggle() { if (!process.env.NFTS_V1) { return null; @@ -231,7 +180,6 @@ export default class ExperimentalTab extends PureComponent { this.renderTransactionSecurityCheckToggle()} {this.renderImprovedTokenAllowanceToggle()} {this.renderOpenSeaEnabledToggle()} - {this.renderCollectibleDetectionToggle()}
); } diff --git a/ui/pages/settings/index.scss b/ui/pages/settings/index.scss index 13ce61c26fbf..4312200800c2 100644 --- a/ui/pages/settings/index.scss +++ b/ui/pages/settings/index.scss @@ -12,6 +12,10 @@ display: flex; flex-flow: column nowrap; + &__content-padded { + padding: 16px; + } + &__error-text { @include H7; @@ -194,6 +198,18 @@ } } + &__security-tab-sub-header { + font-weight: 500; + font-size: 16px; + color: var(--color-icon-alternative); + + &__bold { + font-weight: 700; + font-size: 18px; + color: var(--color-text-default); + } + } + &__back-button { display: none; @@ -275,6 +291,8 @@ display: flex; flex-direction: column; margin-bottom: 20px; + font-size: 16px; + font-weight: 500; @include screen-sm-max { height: initial; @@ -327,6 +345,8 @@ margin-top: 8px; margin-bottom: 12px; color: var(--color-text-default); + font-size: 14px; + font-weight: 400; } } @@ -334,10 +354,16 @@ text-transform: capitalize; } + &__content-unordered-list { + padding-left: 2.5rem; + margin-top: 2.5rem; + list-style: disc; + } + &__content-description { @include H6; - color: var(--color-text-default); + color: var(--color-text-alternative); padding-top: 5px; a { diff --git a/ui/pages/settings/security-tab/__snapshots__/security-tab.test.js.snap b/ui/pages/settings/security-tab/__snapshots__/security-tab.test.js.snap index f42c8afbe7ad..8e8ad57636bf 100644 --- a/ui/pages/settings/security-tab/__snapshots__/security-tab.test.js.snap +++ b/ui/pages/settings/security-tab/__snapshots__/security-tab.test.js.snap @@ -5,239 +5,476 @@ exports[`Security Tab should match snapshot 1`] = `
+ + Security +
- - Reveal Secret Recovery Phrase - -
-
- + +
+
+
+ +
+ + Privacy + +
+ + Alerts + +
- - Show incoming transactions -
- Select this to use Etherscan to show incoming transactions in the transactions list + + Use phishing detection + +
+ Display a warning for phishing domains targeting Ethereum users +
-
-
-