From 9deca33c8ffb5a5734ee362440dcc1072fbc8e9a Mon Sep 17 00:00:00 2001 From: Ariella Vu <20778143+digiwand@users.noreply.github.com> Date: Sat, 30 Sep 2023 00:45:37 +0200 Subject: [PATCH 1/3] test:e2e: create Security Alert Blockaid tests for signature requests (#21029) --- test/e2e/run-all.js | 1 + test/e2e/snaps/ppom-blockaid-alert.spec.js | 265 +++++++++++++++++++++ 2 files changed, 266 insertions(+) create mode 100644 test/e2e/snaps/ppom-blockaid-alert.spec.js diff --git a/test/e2e/run-all.js b/test/e2e/run-all.js index 97cd8123a10f..c5383103d6b2 100644 --- a/test/e2e/run-all.js +++ b/test/e2e/run-all.js @@ -138,6 +138,7 @@ async function main() { 'test-remove-accounts-snap.spec.js', 'test-snap-lifecycle.spec.js', 'test-snap-get-locale.spec.js', + 'ppom-blockaid-alert.spec.js', 'ppom-toggle-settings.spec.js', 'petnames.spec.js', ]; diff --git a/test/e2e/snaps/ppom-blockaid-alert.spec.js b/test/e2e/snaps/ppom-blockaid-alert.spec.js new file mode 100644 index 000000000000..a9fb855acb24 --- /dev/null +++ b/test/e2e/snaps/ppom-blockaid-alert.spec.js @@ -0,0 +1,265 @@ +const { strict: assert } = require('assert'); +const FixtureBuilder = require('../fixture-builder'); +const { + defaultGanacheOptions, + getWindowHandles, + openDapp, + unlockWallet, + withFixtures, +} = require('../helpers'); + +const { + CHAIN_IDS, + NETWORK_TYPES, +} = require('../../../shared/constants/network'); + +const bannerAlertSelector = '[data-testid="security-provider-banner-alert"]'; +const selectedAddress = '0x5cfe73b6021e818b776b421b1c4db2474086a7e1'; + +const mainnetProviderConfig = { + providerConfig: { + chainId: CHAIN_IDS.MAINNET, + nickname: '', + rpcUrl: '', + type: NETWORK_TYPES.MAINNET, + }, +}; + +async function mockInfura(mockServer) { + await mockServer + .forPost() + .withJsonBodyIncluding({ method: 'eth_estimateGas' }) + .thenCallback((req) => { + return { + statusCode: 200, + json: { + jsonrpc: '2.0', + id: req.body.json.id, + result: '0x5cec', + }, + }; + }); + await mockServer + .forPost() + .withJsonBodyIncluding({ method: 'eth_getBalance' }) + .thenCallback((req) => { + return { + statusCode: 200, + json: { + jsonrpc: '2.0', + id: req.body.json.id, + result: '0x55DE6A779BBAC0000', + }, + }; + }); + await mockServer + .forPost() + .withJsonBodyIncluding({ method: 'eth_getTransactionCount' }) + .thenCallback((req) => { + return { + statusCode: 200, + json: { + jsonrpc: '2.0', + id: req.body.json.id, + result: '0x115e89f', + }, + }; + }); + await mockServer + .forPost() + .withJsonBodyIncluding({ method: 'eth_blockNumber' }) + .thenCallback((req) => { + return { + statusCode: 200, + json: { + jsonrpc: '2.0', + id: req.body.json.id, + result: '0x1', + // result: '0x115e89f', + }, + }; + }); + await mockServer + .forPost() + .withJsonBodyIncluding({ method: 'eth_gasPrice' }) + .thenCallback((req) => { + return { + statusCode: 200, + json: { + jsonrpc: '2.0', + id: req.body.json.id, + result: '0x09184e72a000', + }, + }; + }); +} + +/** + * Tests various Blockaid PPOM security alerts. Data for the E2E test requests and responses are provided here: + * + * @see {@link https://wobbly-nutmeg-8a5.notion.site/MM-E2E-Testing-1e51b617f79240a49cd3271565c6e12d} + */ +describe('Confirmation Security Alert - Blockaid', function () { + it('should not show security alerts for benign requests', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkController(mainnetProviderConfig) + .withPermissionControllerConnectedToTestDapp() + .withPreferencesController({ + securityAlertsEnabled: true, + }) + .build(), + defaultGanacheOptions, + testSpecificMock: mockInfura, + title: this.test.title, + }, + + async ({ driver }) => { + await driver.navigate(); + await unlockWallet(driver); + await openDapp(driver); + + const testBenignConfigs = [ + { + logExpectedDetail: 'Benign 1', + method: 'eth_sendTransaction', + params: [ + { + from: selectedAddress, + data: '0x095ea7b3000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', + to: '0x6b175474e89094c44da98b954eedeac495271d0f', + value: '0x0', + }, + ], + }, + { + logExpectedDetail: 'blur', + method: 'eth_signTypedData_v4', + params: [ + selectedAddress, + '{"types":{"Order":[{"name":"trader","type":"address"},{"name":"side","type":"uint8"},{"name":"matchingPolicy","type":"address"},{"name":"collection","type":"address"},{"name":"tokenId","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"paymentToken","type":"address"},{"name":"price","type":"uint256"},{"name":"listingTime","type":"uint256"},{"name":"expirationTime","type":"uint256"},{"name":"fees","type":"Fee[]"},{"name":"salt","type":"uint256"},{"name":"extraParams","type":"bytes"},{"name":"nonce","type":"uint256"}],"Fee":[{"name":"rate","type":"uint16"},{"name":"recipient","type":"address"}],"EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}]},"domain":{"name":"Blur Exchange","version":"1.0","chainId":"1","verifyingContract":"0x000000000000ad05ccc4f10045630fb830b95127"},"primaryType":"Order","message":{"trader":"0xd854343f41b2138b686f2d3ba38402a9f7fb4337","side":"1","matchingPolicy":"0x0000000000dab4a563819e8fd93dba3b25bc3495","collection":"0xc4a5025c4563ad0acc09d92c2506e6744dad58eb","tokenId":"30420","amount":"1","paymentToken":"0x0000000000000000000000000000000000000000","price":"1000000000000000000","listingTime":"1679418212","expirationTime":"1680023012","salt":"154790208154270131670189427454206980105","extraParams":"0x01","nonce":"0"}}', + ], + }, + { + logExpectedDetail: 'seaport', + method: 'eth_signTypedData_v4', + params: [ + selectedAddress, + '{"types":{"EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}],"OrderComponents":[{"name":"offerer","type":"address"},{"name":"zone","type":"address"},{"name":"offer","type":"OfferItem[]"},{"name":"consideration","type":"ConsiderationItem[]"},{"name":"orderType","type":"uint8"},{"name":"startTime","type":"uint256"},{"name":"endTime","type":"uint256"},{"name":"zoneHash","type":"bytes32"},{"name":"salt","type":"uint256"},{"name":"conduitKey","type":"bytes32"},{"name":"counter","type":"uint256"}],"OfferItem":[{"name":"itemType","type":"uint8"},{"name":"token","type":"address"},{"name":"identifierOrCriteria","type":"uint256"},{"name":"startAmount","type":"uint256"},{"name":"endAmount","type":"uint256"}],"ConsiderationItem":[{"name":"itemType","type":"uint8"},{"name":"token","type":"address"},{"name":"identifierOrCriteria","type":"uint256"},{"name":"startAmount","type":"uint256"},{"name":"endAmount","type":"uint256"},{"name":"recipient","type":"address"}]},"primaryType":"OrderComponents","domain":{"name":"Seaport","version":"1.4","chainId":"1","verifyingContract":"0x00000000000001ad428e4906aE43D8F9852d0dD6"},"message":{"offerer":"0xCaFca5eDFb361E8A39a735233f23DAf86CBeD5FC","offer":[{"itemType":"1","token":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2","identifierOrCriteria":"0","startAmount":"2500000000000000","endAmount":"2500000000000000"}],"consideration":[{"itemType":"2","token":"0xaA7200ee500dE2dcde75E996De83CBD73BCa9705","identifierOrCriteria":"11909","startAmount":"1","endAmount":"1","recipient":"0xCaFca5eDFb361E8A39a735233f23DAf86CBeD5FC"},{"itemType":"1","token":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2","identifierOrCriteria":"0","startAmount":"62500000000000","endAmount":"62500000000000","recipient":"0x0000a26b00c1F0DF003000390027140000fAa719"},{"itemType":"1","token":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2","identifierOrCriteria":"0","startAmount":"12500000000000","endAmount":"12500000000000","recipient":"0x8324BdEF2F30E08E368f2Fa2F14143cDCA77423D"}],"startTime":"1681835413","endTime":"1682094598","orderType":"0","zone":"0x004C00500000aD104D7DBd00e3ae0A5C00560C00","zoneHash":"0x0000000000000000000000000000000000000000000000000000000000000000","salt":"24446860302761739304752683030156737591518664810215442929812618382526293324216","conduitKey":"0x0000007b02230091a7ed01230072f7006a004d60a8d4e71d599b8104250f0000","totalOriginalConsiderationItems":"3","counter":"0"}}', + ], + }, + ]; + + for (const config of testBenignConfigs) { + const { logExpectedDetail, method, params } = config; + + // Send JSON-RPC request + const request = JSON.stringify({ + jsonrpc: '2.0', + method, + params, + }); + await driver.executeScript( + `window.transactionHash = window.ethereum.request(${request})`, + ); + + // Wait for confirmation pop-up + await driver.waitUntilXWindowHandles(3); + const windowHandles = await getWindowHandles(driver, 3); + await driver.switchToWindowWithTitle('MetaMask Notification'); + + const isPresent = await driver.isElementPresent(bannerAlertSelector); + assert.equal( + isPresent, + false, + `Banner alert unexpectedly found. \nExpected detail: ${logExpectedDetail}`, + ); + + // Wait for confirmation pop-up to close + await driver.clickElement({ text: 'Reject', tag: 'button' }); + await driver.switchToWindow(windowHandles.dapp); + } + }, + ); + }); + + /** + * Disclaimer: this test may be missing checks for some reason types. e.g. blur, domain, and failed + */ + it('should show security alerts for malicious requests', async function () { + await withFixtures( + { + dapp: true, + fixtures: new FixtureBuilder() + .withNetworkController(mainnetProviderConfig) + .withPermissionControllerConnectedToTestDapp() + .withPreferencesController({ + securityAlertsEnabled: true, + }) + .build(), + defaultGanacheOptions, + testSpecificMock: mockInfura, + title: this.test.title, + }, + + async ({ driver }) => { + await driver.navigate(); + await unlockWallet(driver); + await openDapp(driver); + + const expectedTitle = 'This is a deceptive request'; + + const testMaliciousConfigs = [ + { + btnSelector: '#maliciousPermit', + expectedDescription: + 'If you approve this request, a third party known for scams might take all your assets.', + expectedReason: 'permit_farming', + }, + { + btnSelector: '#maliciousSeaport', + expectedDescription: + 'If you approve this request, someone can steal your assets listed on OpenSea.', + expectedReason: 'seaport_farming', + }, + { + btnSelector: '#maliciousTradeOrder', + expectedDescription: + 'If you approve this request, you might lose your assets.', + expectedReason: 'trade_order_farming', + }, + ]; + + for (const config of testMaliciousConfigs) { + const { expectedDescription, expectedReason, btnSelector } = config; + + // Click TestDapp button to send JSON-RPC request + await driver.clickElement(btnSelector); + + // Wait for confirmation pop-up + await driver.waitUntilXWindowHandles(3); + const windowHandles = await getWindowHandles(driver, 3); + await driver.switchToWindowWithTitle('MetaMask Notification'); + + const bannerAlert = await driver.findElement(bannerAlertSelector); + const bannerAlertText = await bannerAlert.getText(); + + assert( + bannerAlertText.includes(expectedTitle), + `Expected banner alert title: ${expectedTitle} \nExpected reason: ${expectedReason}\n`, + ); + assert( + bannerAlertText.includes(expectedDescription), + `Expected banner alert description: ${expectedDescription} \nExpected reason: ${expectedReason}\n`, + ); + + // Wait for confirmation pop-up to close + await driver.clickElement({ text: 'Reject', tag: 'button' }); + await driver.switchToWindow(windowHandles.dapp); + } + }, + ); + }); +}); From 0a215ca2d89958b5bb3902490530b06565114e61 Mon Sep 17 00:00:00 2001 From: Michele Esposito <34438276+mikesposito@users.noreply.github.com> Date: Sat, 30 Sep 2023 10:02:04 +0200 Subject: [PATCH 2/3] Remove `eth-keyring-controller` use from `MetamaskController` (#20504) --- .storybook/test-data.js | 6 - ...ring-controller-npm-8.0.0-806630ae4e.patch | 40 ----- ...ture-controller-npm-5.3.0-225628460b.patch | 26 --- ...ture-controller-npm-6.0.0-90e8e479a9.patch | 17 ++ app/scripts/background.js | 1 - app/scripts/lib/setupSentry.js | 1 - app/scripts/lib/snap-keyring/snap-keyring.ts | 8 +- .../metamask-controller.actions.test.js | 4 +- app/scripts/metamask-controller.js | 69 ++++---- app/scripts/metamask-controller.test.js | 54 +++--- lavamoat/browserify/beta/policy.json | 76 ++------- lavamoat/browserify/desktop/policy.json | 76 ++------- lavamoat/browserify/flask/policy.json | 76 ++------- lavamoat/browserify/main/policy.json | 76 ++------- lavamoat/browserify/mmi/policy.json | 76 ++------- package.json | 9 +- ...rs-after-init-opt-in-background-state.json | 4 +- .../errors-after-init-opt-in-ui-state.json | 1 - test/jest/mock-store.js | 1 - types/eth-keyring-controller.d.ts | 17 -- .../token-allowance/token-allowance.test.js | 1 - yarn.lock | 159 ++++++------------ 22 files changed, 228 insertions(+), 570 deletions(-) delete mode 100644 .yarn/patches/@metamask-keyring-controller-npm-8.0.0-806630ae4e.patch delete mode 100644 .yarn/patches/@metamask-signature-controller-npm-5.3.0-225628460b.patch create mode 100644 .yarn/patches/@metamask-signature-controller-npm-6.0.0-90e8e479a9.patch delete mode 100644 types/eth-keyring-controller.d.ts diff --git a/.storybook/test-data.js b/.storybook/test-data.js index 353064992c42..b78ae04c0620 100644 --- a/.storybook/test-data.js +++ b/.storybook/test-data.js @@ -1062,12 +1062,6 @@ const state = { unapprovedEncryptionPublicKeyMsgCount: 0, unapprovedTypedMessages: {}, unapprovedTypedMessagesCount: 0, - keyringTypes: [ - KeyringType.imported, - KeyringType.hdKeyTree, - KeyringType.trezor, - KeyringType.ledger, - ], keyrings: [ { type: KeyringType.hdKeyTree, diff --git a/.yarn/patches/@metamask-keyring-controller-npm-8.0.0-806630ae4e.patch b/.yarn/patches/@metamask-keyring-controller-npm-8.0.0-806630ae4e.patch deleted file mode 100644 index 331eea84d518..000000000000 --- a/.yarn/patches/@metamask-keyring-controller-npm-8.0.0-806630ae4e.patch +++ /dev/null @@ -1,40 +0,0 @@ -diff --git a/dist/KeyringController.d.ts b/dist/KeyringController.d.ts -index 44c6427ec774475b87f60995738f736611875194..d359269ad413a0a626d06e44a84eb0cbbdb8c7b0 100644 ---- a/dist/KeyringController.d.ts -+++ b/dist/KeyringController.d.ts -@@ -5,6 +5,7 @@ import { BaseControllerV2 } from '@metamask/base-controller'; - import type { PersonalMessageParams, TypedMessageParams } from '@metamask/message-manager'; - import type { PreferencesController } from '@metamask/preferences-controller'; - import type { Eip1024EncryptedData, Hex, Keyring, Json } from '@metamask/utils'; -+import type { KeyringController as EthKeyringController } from '@metamask/eth-keyring-controller'; - import type { Patch } from 'immer'; - declare const name = "KeyringController"; - /** -@@ -171,6 +172,10 @@ export declare class KeyringController extends BaseControllerV2 { -+ // Expecting reject error but throwing manually rather than waiting -+ }); - __classPrivateFieldGet(this, _SignatureController_instances, "m", _SignatureController_cancelAbstractMessage).call(this, messageManager, messageId); -- throw eth_rpc_errors_1.ethErrors.provider.userRejectedRequest('User rejected the request.'); -+ throw eth_rpc_errors_1.ethErrors.provider.userRejectedRequest(`MetaMask ${messageName} Signature: User denied message signature.`); - } - yield signMessage(messageParamsWithId, signingOpts); - const signatureResult = yield signaturePromise; -@@ -305,7 +308,7 @@ _SignatureController_keyringController = new WeakMap(), _SignatureController_isE - return __awaiter(this, void 0, void 0, function* () { - return yield __classPrivateFieldGet(this, _SignatureController_instances, "m", _SignatureController_signAbstractMessage).call(this, __classPrivateFieldGet(this, _SignatureController_personalMessageManager, "f"), controller_utils_1.ApprovalType.PersonalSign, msgParams, (cleanMsgParams) => __awaiter(this, void 0, void 0, function* () { return yield __classPrivateFieldGet(this, _SignatureController_keyringController, "f").signPersonalMessage(cleanMsgParams); })); - }); --}, _SignatureController_signTypedMessage = function _SignatureController_signTypedMessage(msgParams, -+}, _SignatureController_signTypedMessage = function _SignatureController_signTypedMessage(msgParams, - /* istanbul ignore next */ - opts = { parseJsonData: true }) { - return __awaiter(this, void 0, void 0, function* () { diff --git a/.yarn/patches/@metamask-signature-controller-npm-6.0.0-90e8e479a9.patch b/.yarn/patches/@metamask-signature-controller-npm-6.0.0-90e8e479a9.patch new file mode 100644 index 000000000000..128ad3f80189 --- /dev/null +++ b/.yarn/patches/@metamask-signature-controller-npm-6.0.0-90e8e479a9.patch @@ -0,0 +1,17 @@ +diff --git a/dist/SignatureController.js b/dist/SignatureController.js +index 46d4b4d0553f86d368d30b7e90a9dc2e03d26ef9..e7063a3753bc3821e661c11132e33304b4fce416 100644 +--- a/dist/SignatureController.js ++++ b/dist/SignatureController.js +@@ -280,8 +280,11 @@ _SignatureController_isEthSignEnabled = new WeakMap(), _SignatureController_getA + resultCallbacks = acceptResult.resultCallbacks; + } + catch (_a) { ++ signaturePromise.catch(() => { ++ // Expecting reject error but throwing manually rather than waiting ++ }); + __classPrivateFieldGet(this, _SignatureController_instances, "m", _SignatureController_cancelAbstractMessage).call(this, messageManager, messageId); +- throw eth_rpc_errors_1.ethErrors.provider.userRejectedRequest('User rejected the request.'); ++ throw eth_rpc_errors_1.ethErrors.provider.userRejectedRequest(`MetaMask ${messageName} Signature: User denied message signature.`); + } + yield signMessage(messageParamsWithId, signingOpts); + const signatureResult = yield signaturePromise; diff --git a/app/scripts/background.js b/app/scripts/background.js index 57f5ab43c4c1..4ae4ecbbce87 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -248,7 +248,6 @@ browser.runtime.onConnectExternal.addListener(async (...args) => { * @property {object} unapprovedTypedMsgs - An object of messages pending approval, mapping a unique ID to the options. * @property {number} unapprovedTypedMsgCount - The number of messages in unapprovedTypedMsgs. * @property {number} pendingApprovalCount - The number of pending request in the approval controller. - * @property {string[]} keyringTypes - An array of unique keyring identifying strings, representing available strategies for creating accounts. * @property {Keyring[]} keyrings - An array of keyring descriptions, summarizing the accounts that are available for use, and what keyrings they belong to. * @property {string} selectedAddress - A lower case hex string of the currently selected address. * @property {string} currentCurrency - A string identifying the user's preferred display currency, for use in showing conversion rates. diff --git a/app/scripts/lib/setupSentry.js b/app/scripts/lib/setupSentry.js index 8a1be42a182c..2b908647deea 100644 --- a/app/scripts/lib/setupSentry.js +++ b/app/scripts/lib/setupSentry.js @@ -113,7 +113,6 @@ export const SENTRY_BACKGROUND_STATE = { KeyringController: { isUnlocked: true, keyrings: false, - keyringTypes: false, }, LoggingController: { logs: false, diff --git a/app/scripts/lib/snap-keyring/snap-keyring.ts b/app/scripts/lib/snap-keyring/snap-keyring.ts index 56b8bba7a9e3..26ab295cffe1 100644 --- a/app/scripts/lib/snap-keyring/snap-keyring.ts +++ b/app/scripts/lib/snap-keyring/snap-keyring.ts @@ -29,7 +29,6 @@ export const getAccountsBySnapId = async ( * * @param getSnapController - A function that retrieves the Snap Controller instance. * @param getApprovalController - A function that retrieves the Approval Controller instance. - * @param getKeyringController - A function that retrieves the Keyring Controller instance. * @param getCoreKeyringController - A function that retrieves the Core Keyring Controller instance. * @param removeAccountHelper - A function to help remove an account based on its address. * @returns The constructed SnapKeyring builder instance with the following methods: @@ -40,7 +39,6 @@ export const getAccountsBySnapId = async ( export const snapKeyringBuilder = ( getSnapController: () => SnapController, getApprovalController: () => ApprovalController, - getKeyringController: () => KeyringController, getCoreKeyringController: () => KeyringController, removeAccountHelper: (address: string) => Promise, ) => { @@ -51,7 +49,7 @@ export const snapKeyringBuilder = ( return addresses.includes(address.toLowerCase()); }, saveState: async () => { - await getKeyringController().persistAllKeyrings(); + await getCoreKeyringController().persistAllKeyrings(); }, addAccount: async ( _address: string, @@ -77,7 +75,7 @@ export const snapKeyringBuilder = ( if (confirmationResult) { try { await handleUserInput(confirmationResult); - await getKeyringController().persistAllKeyrings(); + await getCoreKeyringController().persistAllKeyrings(); await getApprovalController().success({ message: t('snapAccountCreated') ?? 'Your account is ready!', header: [snapAuthorshipHeader], @@ -129,7 +127,7 @@ export const snapKeyringBuilder = ( try { await removeAccountHelper(address); await handleUserInput(confirmationResult); - await getKeyringController().persistAllKeyrings(); + await getCoreKeyringController().persistAllKeyrings(); await getApprovalController().success({ message: t('snapAccountRemoved') ?? 'Account removed', header: [snapAuthorshipHeader], diff --git a/app/scripts/metamask-controller.actions.test.js b/app/scripts/metamask-controller.actions.test.js index a0dba444b2df..51b69a12008f 100644 --- a/app/scripts/metamask-controller.actions.test.js +++ b/app/scripts/metamask-controller.actions.test.js @@ -177,7 +177,7 @@ describe('MetaMaskController', function () { ]), Promise.resolve(1).then(() => { keyringControllerState1 = JSON.stringify( - metamaskController.keyringController.memStore.getState(), + metamaskController.coreKeyringController.state, ); metamaskController.importAccountWithStrategy('privateKey', [ importPrivkey, @@ -185,7 +185,7 @@ describe('MetaMaskController', function () { }), Promise.resolve(2).then(() => { keyringControllerState2 = JSON.stringify( - metamaskController.keyringController.memStore.getState(), + metamaskController.coreKeyringController.state, ); }), ]); diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 05fedae55c46..60bea6679ba0 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -857,14 +857,12 @@ export default class MetamaskController extends EventEmitter { ///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps) const getSnapController = () => this.snapController; const getApprovalController = () => this.approvalController; - const getKeyringController = () => this.keyringController; const getCoreKeyringController = () => this.coreKeyringController; additionalKeyrings.push( snapKeyringBuilder( getSnapController, getApprovalController, - getKeyringController, getCoreKeyringController, (address) => this.removeAccount(address), ), @@ -930,9 +928,6 @@ export default class MetamaskController extends EventEmitter { }, ); - this.keyringController = - this.coreKeyringController.getEthKeyringController(); - const getIdentities = () => this.preferencesController.store.getState().identities; @@ -954,8 +949,8 @@ export default class MetamaskController extends EventEmitter { permissionSpecifications: { ...getPermissionSpecifications({ getIdentities, - getAllAccounts: this.keyringController.getAccounts.bind( - this.keyringController, + getAllAccounts: this.coreKeyringController.getAccounts.bind( + this.coreKeyringController, ), captureKeyringTypesWithMissingIdentities: ( identities = {}, @@ -1252,8 +1247,8 @@ export default class MetamaskController extends EventEmitter { this.networkController.state.providerConfig.chainId, preferencesStore: this.preferencesController.store, txHistoryLimit: 60, - signTransaction: this.keyringController.signTransaction.bind( - this.keyringController, + signTransaction: this.coreKeyringController.signTransaction.bind( + this.coreKeyringController, ), provider: this.provider, blockTracker: this.blockTracker, @@ -1439,9 +1434,13 @@ export default class MetamaskController extends EventEmitter { this.signatureController = new SignatureController({ messenger: this.controllerMessenger.getRestricted({ name: 'SignatureController', - allowedActions: [`${this.approvalController.name}:addRequest`], + allowedActions: [ + `${this.approvalController.name}:addRequest`, + `${this.coreKeyringController.name}:signMessage`, + `${this.coreKeyringController.name}:signPersonalMessage`, + `${this.coreKeyringController.name}:signTypedMessage`, + ], }), - keyringController: this.keyringController, isEthSignEnabled: () => this.preferencesController.store.getState() ?.disabledRpcMethodPreferences?.eth_sign, @@ -1735,7 +1734,7 @@ export default class MetamaskController extends EventEmitter { AppStateController: this.appStateController.store, AppMetadataController: this.appMetadataController.store, TransactionController: this.txController.store, - KeyringController: this.keyringController.store, + KeyringController: this.coreKeyringController, PreferencesController: this.preferencesController.store, MetaMetricsController: this.metaMetricsController.store, AddressBookController: this.addressBookController, @@ -1787,7 +1786,7 @@ export default class MetamaskController extends EventEmitter { AppMetadataController: this.appMetadataController.store, NetworkController: this.networkController, CachedBalancesController: this.cachedBalancesController.store, - KeyringController: this.keyringController.memStore, + KeyringController: this.coreKeyringController, PreferencesController: this.preferencesController.store, MetaMetricsController: this.metaMetricsController.store, AddressBookController: this.addressBookController, @@ -2297,11 +2296,14 @@ export default class MetamaskController extends EventEmitter { * @returns {object} status */ getState() { - const { vault } = this.keyringController.store.getState(); + const { vault } = this.coreKeyringController.state; const isInitialized = Boolean(vault); const flatState = this.memStore.getFlatState(); + // The vault should not be exposed to the UI + delete flatState.vault; + return { isInitialized, ...flatState, @@ -2949,7 +2951,7 @@ export default class MetamaskController extends EventEmitter { async exportAccount(address, password) { await this.verifyPassword(password); - return this.keyringController.exportAccount(address, password); + return this.coreKeyringController.exportAccount(password, address); } async getTokenStandardAndDetails(address, userAddress, tokenId) { @@ -3046,18 +3048,13 @@ export default class MetamaskController extends EventEmitter { async createNewVaultAndKeychain(password) { const releaseLock = await this.createVaultMutex.acquire(); try { - let vault; - const accounts = await this.keyringController.getAccounts(); - if (accounts.length > 0) { - vault = await this.keyringController.fullUpdate(); - } else { - vault = await this.keyringController.createNewVaultAndKeychain( - password, - ); - const addresses = await this.keyringController.getAccounts(); - this.preferencesController.setAddresses(addresses); - this.selectFirstIdentity(); - } + const vault = await this.coreKeyringController.createNewVaultAndKeychain( + password, + ); + + const accounts = await this.coreKeyringController.getAccounts(); + this.preferencesController.setAddresses(accounts); + this.selectFirstIdentity(); return vault; } finally { @@ -3298,7 +3295,7 @@ export default class MetamaskController extends EventEmitter { * @param {string} password - The user's password */ async verifyPassword(password) { - await this.keyringController.verifyPassword(password); + await this.coreKeyringController.verifyPassword(password); } /** @@ -3378,7 +3375,7 @@ export default class MetamaskController extends EventEmitter { keyringName, ); if (!keyring) { - keyring = await this.keyringController.addNewKeyring(keyringName); + keyring = await this.coreKeyringController.addNewKeyring(keyringName); } if (hdPath && keyring.setHdPath) { keyring.setHdPath(hdPath); @@ -3432,7 +3429,7 @@ export default class MetamaskController extends EventEmitter { // Merge with existing accounts // and make sure addresses are not repeated - const oldAccounts = await this.keyringController.getAccounts(); + const oldAccounts = await this.coreKeyringController.getAccounts(); const accountsToTrack = [ ...new Set( oldAccounts.concat(accounts.map((a) => a.address.toLowerCase())), @@ -3548,9 +3545,11 @@ export default class MetamaskController extends EventEmitter { const keyring = await this.getKeyringForDevice(deviceName, hdPath); keyring.setAccountToUnlock(index); - const oldAccounts = await this.keyringController.getAccounts(); - const keyState = await this.keyringController.addNewAccount(keyring); - const newAccounts = await this.keyringController.getAccounts(); + const oldAccounts = await this.coreKeyringController.getAccounts(); + const keyState = await this.coreKeyringController.addNewAccountForKeyring( + keyring, + ); + const newAccounts = await this.coreKeyringController.getAccounts(); this.preferencesController.setAddresses(newAccounts); newAccounts.forEach((address) => { if (!oldAccounts.includes(address)) { @@ -3699,7 +3698,7 @@ export default class MetamaskController extends EventEmitter { address, ); // Remove account from the keyring - await this.keyringController.removeAccount(address); + await this.coreKeyringController.removeAccount(address); const updatedKeyringAccounts = keyring ? await keyring.getAccounts() : {}; if (updatedKeyringAccounts?.length === 0) { keyring.destroy?.(); @@ -4657,7 +4656,7 @@ export default class MetamaskController extends EventEmitter { * @returns {boolean} Whether the extension is unlocked. */ isUnlocked() { - return this.keyringController.memStore.getState().isUnlocked; + return this.coreKeyringController.state.isUnlocked; } //============================================================================= diff --git a/app/scripts/metamask-controller.test.js b/app/scripts/metamask-controller.test.js index c8e6c070e14d..40ad6d240527 100644 --- a/app/scripts/metamask-controller.test.js +++ b/app/scripts/metamask-controller.test.js @@ -318,13 +318,16 @@ describe('MetaMaskController', () => { }); jest.spyOn( - metamaskController.keyringController, + metamaskController.coreKeyringController, 'createNewVaultAndKeychain', ); jest.spyOn( metamaskController.coreKeyringController, 'createNewVaultAndRestore', ); + jest + .spyOn(metamaskController.preferencesController, 'removeAddress') + .mockImplementation((address) => address); }); describe('should reset states on first time profile load', () => { @@ -363,7 +366,7 @@ describe('MetaMaskController', () => { it('adds 1 account', async () => { const keyringAccounts = - await metamaskController.keyringController.getAccounts(); + await metamaskController.coreKeyringController.getAccounts(); expect(keyringAccounts[keyringAccounts.length - 1]).toStrictEqual( '0xe18035bf8712672935fdb4e5e431b1a0183d2dfc', ); @@ -413,15 +416,16 @@ describe('MetaMaskController', () => { describe('#createNewVaultAndKeychain', () => { it('can only create new vault on keyringController once', async () => { jest.spyOn(metamaskController, 'selectFirstIdentity').mockReturnValue(); - const password = 'a-fake-password'; - await metamaskController.createNewVaultAndKeychain(password); - await metamaskController.createNewVaultAndKeychain(password); + const vault1 = await metamaskController.createNewVaultAndKeychain( + password, + ); + const vault2 = await metamaskController.createNewVaultAndKeychain( + password, + ); - expect( - metamaskController.keyringController.createNewVaultAndKeychain, - ).toHaveBeenCalledTimes(1); + expect(vault1).toStrictEqual(vault2); }); }); @@ -622,7 +626,7 @@ describe('MetaMaskController', () => { }); it('should add the Trezor Hardware keyring', async () => { - jest.spyOn(metamaskController.keyringController, 'addNewKeyring'); + jest.spyOn(metamaskController.coreKeyringController, 'addNewKeyring'); await metamaskController .connectHardware(HardwareDeviceNames.trezor, 0) .catch(() => null); @@ -631,13 +635,13 @@ describe('MetaMaskController', () => { KeyringType.trezor, ); expect( - metamaskController.keyringController.addNewKeyring, + metamaskController.coreKeyringController.addNewKeyring, ).toHaveBeenCalledWith(KeyringType.trezor); expect(keyrings).toHaveLength(1); }); it('should add the Ledger Hardware keyring', async () => { - jest.spyOn(metamaskController.keyringController, 'addNewKeyring'); + jest.spyOn(metamaskController.coreKeyringController, 'addNewKeyring'); await metamaskController .connectHardware(HardwareDeviceNames.ledger, 0) .catch(() => null); @@ -646,7 +650,7 @@ describe('MetaMaskController', () => { KeyringType.ledger, ); expect( - metamaskController.keyringController.addNewKeyring, + metamaskController.coreKeyringController.addNewKeyring, ).toHaveBeenCalledWith(KeyringType.ledger); expect(keyrings).toHaveLength(1); }); @@ -729,13 +733,20 @@ describe('MetaMaskController', () => { describe('unlockHardwareWalletAccount', () => { const accountToUnlock = 10; beforeEach(async () => { + await metamaskController.coreKeyringController.createNewVaultAndRestore( + 'password', + TEST_SEED, + ); jest.spyOn(window, 'open').mockReturnValue(); jest - .spyOn(metamaskController.keyringController, 'addNewAccount') + .spyOn( + metamaskController.coreKeyringController, + 'addNewAccountForKeyring', + ) .mockReturnValue('0x123'); jest - .spyOn(metamaskController.keyringController, 'getAccounts') + .spyOn(metamaskController.coreKeyringController, 'getAccounts') .mockResolvedValueOnce(['0x1']) .mockResolvedValueOnce(['0x2']) .mockResolvedValueOnce(['0x3']); @@ -749,9 +760,6 @@ describe('MetaMaskController', () => { .spyOn(metamaskController.preferencesController, 'setAccountLabel') .mockReturnValue(); - await metamaskController - .connectHardware(HardwareDeviceNames.trezor, 0, `m/44'/1'/0'/0`) - .catch(() => null); await metamaskController.unlockHardwareWalletAccount( accountToUnlock, HardwareDeviceNames.trezor, @@ -769,14 +777,14 @@ describe('MetaMaskController', () => { it('should call keyringController.addNewAccount', async () => { expect( - metamaskController.keyringController.addNewAccount, + metamaskController.coreKeyringController.addNewAccountForKeyring, ).toHaveBeenCalledTimes(1); }); it('should call keyringController.getAccounts', async () => { expect( - metamaskController.keyringController.getAccounts, - ).toHaveBeenCalledTimes(3); + metamaskController.coreKeyringController.getAccounts, + ).toHaveBeenCalledTimes(2); }); it('should call preferencesController.setAddresses', async () => { @@ -817,7 +825,7 @@ describe('MetaMaskController', () => { await metamaskController.createNewVaultAndKeychain('password'); await metamaskController.addNewAccount(1); const getAccounts = - await metamaskController.keyringController.getAccounts(); + await metamaskController.coreKeyringController.getAccounts(); expect(getAccounts).toHaveLength(2); }); }); @@ -876,7 +884,7 @@ describe('MetaMaskController', () => { destroy: jest.fn(), }; jest - .spyOn(metamaskController.keyringController, 'removeAccount') + .spyOn(metamaskController.coreKeyringController, 'removeAccount') .mockReturnValue(); jest .spyOn(metamaskController, 'removeAllAccountPermissions') @@ -894,7 +902,7 @@ describe('MetaMaskController', () => { it('should call keyringController.removeAccount', async () => { expect( - metamaskController.keyringController.removeAccount, + metamaskController.coreKeyringController.removeAccount, ).toHaveBeenCalledWith(addressToRemove); }); it('should call metamaskController.removeAllAccountPermissions', async () => { diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index 5f198c10ec85..9d5cb9d86f59 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -933,12 +933,16 @@ } }, "@metamask/eth-keyring-controller": { + "globals": { + "console.error": true + }, "packages": { "@metamask/browser-passworder": true, "@metamask/eth-keyring-controller>@metamask/eth-hd-keyring": true, "@metamask/eth-keyring-controller>@metamask/eth-sig-util": true, "@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": true, - "@metamask/eth-keyring-controller>obs-store": true, + "@metamask/eth-keyring-controller>@metamask/utils": true, + "@metamask/obs-store": true, "webpack>events": true } }, @@ -994,7 +998,7 @@ "@metamask/eth-keyring-controller>@metamask/eth-sig-util": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography": true, + "@ethereumjs/tx>ethereum-cryptography": true, "bn.js": true, "browserify>buffer": true, "eth-sig-util>ethereumjs-util>ethjs-util": true, @@ -1002,21 +1006,6 @@ "eth-sig-util>tweetnacl-util": true } }, - "@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography": { - "globals": { - "TextDecoder": true, - "crypto": true - }, - "packages": { - "@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true - } - }, - "@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": { - "globals": { - "TextEncoder": true, - "crypto": true - } - }, "@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, @@ -1042,10 +1031,17 @@ "crypto": true } }, - "@metamask/eth-keyring-controller>obs-store": { + "@metamask/eth-keyring-controller>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/eth-token-tracker>safe-event-emitter": true, - "watchify>xtend": true + "@metamask/key-tree>@noble/hashes": true, + "browserify>buffer": true, + "nock>debug": true, + "semver": true, + "superstruct": true } }, "@metamask/eth-ledger-bridge-keyring": { @@ -1559,51 +1555,13 @@ "@metamask/keyring-controller": { "packages": { "@metamask/base-controller": true, - "@metamask/keyring-controller>@metamask/eth-keyring-controller": true, + "@metamask/eth-keyring-controller": true, "@metamask/keyring-controller>@metamask/utils": true, "@metamask/keyring-controller>ethereumjs-wallet": true, "eth-json-rpc-filters>async-mutex": true, "ethereumjs-util": true } }, - "@metamask/keyring-controller>@metamask/eth-keyring-controller": { - "globals": { - "console.error": true - }, - "packages": { - "@metamask/browser-passworder": true, - "@metamask/eth-keyring-controller>@metamask/eth-hd-keyring": true, - "@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": true, - "@metamask/keyring-controller>@metamask/eth-keyring-controller>@metamask/eth-sig-util": true, - "@metamask/keyring-controller>@metamask/eth-keyring-controller>@metamask/utils": true, - "@metamask/obs-store": true, - "webpack>events": true - } - }, - "@metamask/keyring-controller>@metamask/eth-keyring-controller>@metamask/eth-sig-util": { - "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "bn.js": true, - "browserify>buffer": true, - "eth-sig-util>ethereumjs-util>ethjs-util": true, - "eth-sig-util>tweetnacl": true, - "eth-sig-util>tweetnacl-util": true - } - }, - "@metamask/keyring-controller>@metamask/eth-keyring-controller>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/key-tree>@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true, - "superstruct": true - } - }, "@metamask/keyring-controller>@metamask/utils": { "globals": { "TextDecoder": true, diff --git a/lavamoat/browserify/desktop/policy.json b/lavamoat/browserify/desktop/policy.json index 35711e8e5ab9..fae323bcb153 100644 --- a/lavamoat/browserify/desktop/policy.json +++ b/lavamoat/browserify/desktop/policy.json @@ -1004,12 +1004,16 @@ } }, "@metamask/eth-keyring-controller": { + "globals": { + "console.error": true + }, "packages": { "@metamask/browser-passworder": true, "@metamask/eth-keyring-controller>@metamask/eth-hd-keyring": true, "@metamask/eth-keyring-controller>@metamask/eth-sig-util": true, "@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": true, - "@metamask/eth-keyring-controller>obs-store": true, + "@metamask/eth-keyring-controller>@metamask/utils": true, + "@metamask/obs-store": true, "webpack>events": true } }, @@ -1065,7 +1069,7 @@ "@metamask/eth-keyring-controller>@metamask/eth-sig-util": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography": true, + "@ethereumjs/tx>ethereum-cryptography": true, "bn.js": true, "browserify>buffer": true, "eth-sig-util>ethereumjs-util>ethjs-util": true, @@ -1073,21 +1077,6 @@ "eth-sig-util>tweetnacl-util": true } }, - "@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography": { - "globals": { - "TextDecoder": true, - "crypto": true - }, - "packages": { - "@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true - } - }, - "@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": { - "globals": { - "TextEncoder": true, - "crypto": true - } - }, "@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, @@ -1113,10 +1102,17 @@ "crypto": true } }, - "@metamask/eth-keyring-controller>obs-store": { + "@metamask/eth-keyring-controller>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/eth-token-tracker>safe-event-emitter": true, - "watchify>xtend": true + "@metamask/key-tree>@noble/hashes": true, + "browserify>buffer": true, + "nock>debug": true, + "semver": true, + "superstruct": true } }, "@metamask/eth-ledger-bridge-keyring": { @@ -1700,51 +1696,13 @@ "@metamask/keyring-controller": { "packages": { "@metamask/base-controller": true, - "@metamask/keyring-controller>@metamask/eth-keyring-controller": true, + "@metamask/eth-keyring-controller": true, "@metamask/keyring-controller>@metamask/utils": true, "@metamask/keyring-controller>ethereumjs-wallet": true, "eth-json-rpc-filters>async-mutex": true, "ethereumjs-util": true } }, - "@metamask/keyring-controller>@metamask/eth-keyring-controller": { - "globals": { - "console.error": true - }, - "packages": { - "@metamask/browser-passworder": true, - "@metamask/eth-keyring-controller>@metamask/eth-hd-keyring": true, - "@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": true, - "@metamask/keyring-controller>@metamask/eth-keyring-controller>@metamask/eth-sig-util": true, - "@metamask/keyring-controller>@metamask/eth-keyring-controller>@metamask/utils": true, - "@metamask/obs-store": true, - "webpack>events": true - } - }, - "@metamask/keyring-controller>@metamask/eth-keyring-controller>@metamask/eth-sig-util": { - "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "bn.js": true, - "browserify>buffer": true, - "eth-sig-util>ethereumjs-util>ethjs-util": true, - "eth-sig-util>tweetnacl": true, - "eth-sig-util>tweetnacl-util": true - } - }, - "@metamask/keyring-controller>@metamask/eth-keyring-controller>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/key-tree>@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true, - "superstruct": true - } - }, "@metamask/keyring-controller>@metamask/utils": { "globals": { "TextDecoder": true, diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index 9db7cc3bdce0..9a99fcf70258 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -1004,12 +1004,16 @@ } }, "@metamask/eth-keyring-controller": { + "globals": { + "console.error": true + }, "packages": { "@metamask/browser-passworder": true, "@metamask/eth-keyring-controller>@metamask/eth-hd-keyring": true, "@metamask/eth-keyring-controller>@metamask/eth-sig-util": true, "@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": true, - "@metamask/eth-keyring-controller>obs-store": true, + "@metamask/eth-keyring-controller>@metamask/utils": true, + "@metamask/obs-store": true, "webpack>events": true } }, @@ -1065,7 +1069,7 @@ "@metamask/eth-keyring-controller>@metamask/eth-sig-util": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography": true, + "@ethereumjs/tx>ethereum-cryptography": true, "bn.js": true, "browserify>buffer": true, "eth-sig-util>ethereumjs-util>ethjs-util": true, @@ -1073,21 +1077,6 @@ "eth-sig-util>tweetnacl-util": true } }, - "@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography": { - "globals": { - "TextDecoder": true, - "crypto": true - }, - "packages": { - "@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true - } - }, - "@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": { - "globals": { - "TextEncoder": true, - "crypto": true - } - }, "@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, @@ -1113,10 +1102,17 @@ "crypto": true } }, - "@metamask/eth-keyring-controller>obs-store": { + "@metamask/eth-keyring-controller>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/eth-token-tracker>safe-event-emitter": true, - "watchify>xtend": true + "@metamask/key-tree>@noble/hashes": true, + "browserify>buffer": true, + "nock>debug": true, + "semver": true, + "superstruct": true } }, "@metamask/eth-ledger-bridge-keyring": { @@ -1700,51 +1696,13 @@ "@metamask/keyring-controller": { "packages": { "@metamask/base-controller": true, - "@metamask/keyring-controller>@metamask/eth-keyring-controller": true, + "@metamask/eth-keyring-controller": true, "@metamask/keyring-controller>@metamask/utils": true, "@metamask/keyring-controller>ethereumjs-wallet": true, "eth-json-rpc-filters>async-mutex": true, "ethereumjs-util": true } }, - "@metamask/keyring-controller>@metamask/eth-keyring-controller": { - "globals": { - "console.error": true - }, - "packages": { - "@metamask/browser-passworder": true, - "@metamask/eth-keyring-controller>@metamask/eth-hd-keyring": true, - "@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": true, - "@metamask/keyring-controller>@metamask/eth-keyring-controller>@metamask/eth-sig-util": true, - "@metamask/keyring-controller>@metamask/eth-keyring-controller>@metamask/utils": true, - "@metamask/obs-store": true, - "webpack>events": true - } - }, - "@metamask/keyring-controller>@metamask/eth-keyring-controller>@metamask/eth-sig-util": { - "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "bn.js": true, - "browserify>buffer": true, - "eth-sig-util>ethereumjs-util>ethjs-util": true, - "eth-sig-util>tweetnacl": true, - "eth-sig-util>tweetnacl-util": true - } - }, - "@metamask/keyring-controller>@metamask/eth-keyring-controller>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/key-tree>@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true, - "superstruct": true - } - }, "@metamask/keyring-controller>@metamask/utils": { "globals": { "TextDecoder": true, diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index c413d7fa8933..fba77e073592 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -933,12 +933,16 @@ } }, "@metamask/eth-keyring-controller": { + "globals": { + "console.error": true + }, "packages": { "@metamask/browser-passworder": true, "@metamask/eth-keyring-controller>@metamask/eth-hd-keyring": true, "@metamask/eth-keyring-controller>@metamask/eth-sig-util": true, "@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": true, - "@metamask/eth-keyring-controller>obs-store": true, + "@metamask/eth-keyring-controller>@metamask/utils": true, + "@metamask/obs-store": true, "webpack>events": true } }, @@ -994,7 +998,7 @@ "@metamask/eth-keyring-controller>@metamask/eth-sig-util": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography": true, + "@ethereumjs/tx>ethereum-cryptography": true, "bn.js": true, "browserify>buffer": true, "eth-sig-util>ethereumjs-util>ethjs-util": true, @@ -1002,21 +1006,6 @@ "eth-sig-util>tweetnacl-util": true } }, - "@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography": { - "globals": { - "TextDecoder": true, - "crypto": true - }, - "packages": { - "@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true - } - }, - "@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": { - "globals": { - "TextEncoder": true, - "crypto": true - } - }, "@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, @@ -1042,10 +1031,17 @@ "crypto": true } }, - "@metamask/eth-keyring-controller>obs-store": { + "@metamask/eth-keyring-controller>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/eth-token-tracker>safe-event-emitter": true, - "watchify>xtend": true + "@metamask/key-tree>@noble/hashes": true, + "browserify>buffer": true, + "nock>debug": true, + "semver": true, + "superstruct": true } }, "@metamask/eth-ledger-bridge-keyring": { @@ -1559,51 +1555,13 @@ "@metamask/keyring-controller": { "packages": { "@metamask/base-controller": true, - "@metamask/keyring-controller>@metamask/eth-keyring-controller": true, + "@metamask/eth-keyring-controller": true, "@metamask/keyring-controller>@metamask/utils": true, "@metamask/keyring-controller>ethereumjs-wallet": true, "eth-json-rpc-filters>async-mutex": true, "ethereumjs-util": true } }, - "@metamask/keyring-controller>@metamask/eth-keyring-controller": { - "globals": { - "console.error": true - }, - "packages": { - "@metamask/browser-passworder": true, - "@metamask/eth-keyring-controller>@metamask/eth-hd-keyring": true, - "@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": true, - "@metamask/keyring-controller>@metamask/eth-keyring-controller>@metamask/eth-sig-util": true, - "@metamask/keyring-controller>@metamask/eth-keyring-controller>@metamask/utils": true, - "@metamask/obs-store": true, - "webpack>events": true - } - }, - "@metamask/keyring-controller>@metamask/eth-keyring-controller>@metamask/eth-sig-util": { - "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "bn.js": true, - "browserify>buffer": true, - "eth-sig-util>ethereumjs-util>ethjs-util": true, - "eth-sig-util>tweetnacl": true, - "eth-sig-util>tweetnacl-util": true - } - }, - "@metamask/keyring-controller>@metamask/eth-keyring-controller>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/key-tree>@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true, - "superstruct": true - } - }, "@metamask/keyring-controller>@metamask/utils": { "globals": { "TextDecoder": true, diff --git a/lavamoat/browserify/mmi/policy.json b/lavamoat/browserify/mmi/policy.json index b04f94e1e8d5..f093833e6007 100644 --- a/lavamoat/browserify/mmi/policy.json +++ b/lavamoat/browserify/mmi/policy.json @@ -1073,12 +1073,16 @@ } }, "@metamask/eth-keyring-controller": { + "globals": { + "console.error": true + }, "packages": { "@metamask/browser-passworder": true, "@metamask/eth-keyring-controller>@metamask/eth-hd-keyring": true, "@metamask/eth-keyring-controller>@metamask/eth-sig-util": true, "@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": true, - "@metamask/eth-keyring-controller>obs-store": true, + "@metamask/eth-keyring-controller>@metamask/utils": true, + "@metamask/obs-store": true, "webpack>events": true } }, @@ -1134,7 +1138,7 @@ "@metamask/eth-keyring-controller>@metamask/eth-sig-util": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, - "@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography": true, + "@ethereumjs/tx>ethereum-cryptography": true, "bn.js": true, "browserify>buffer": true, "eth-sig-util>ethereumjs-util>ethjs-util": true, @@ -1142,21 +1146,6 @@ "eth-sig-util>tweetnacl-util": true } }, - "@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography": { - "globals": { - "TextDecoder": true, - "crypto": true - }, - "packages": { - "@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true - } - }, - "@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": { - "globals": { - "TextEncoder": true, - "crypto": true - } - }, "@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": { "packages": { "@ethereumjs/tx>@ethereumjs/util": true, @@ -1182,10 +1171,17 @@ "crypto": true } }, - "@metamask/eth-keyring-controller>obs-store": { + "@metamask/eth-keyring-controller>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, "packages": { - "@metamask/eth-token-tracker>safe-event-emitter": true, - "watchify>xtend": true + "@metamask/key-tree>@noble/hashes": true, + "browserify>buffer": true, + "nock>debug": true, + "semver": true, + "superstruct": true } }, "@metamask/eth-ledger-bridge-keyring": { @@ -1699,51 +1695,13 @@ "@metamask/keyring-controller": { "packages": { "@metamask/base-controller": true, - "@metamask/keyring-controller>@metamask/eth-keyring-controller": true, + "@metamask/eth-keyring-controller": true, "@metamask/keyring-controller>@metamask/utils": true, "@metamask/keyring-controller>ethereumjs-wallet": true, "eth-json-rpc-filters>async-mutex": true, "ethereumjs-util": true } }, - "@metamask/keyring-controller>@metamask/eth-keyring-controller": { - "globals": { - "console.error": true - }, - "packages": { - "@metamask/browser-passworder": true, - "@metamask/eth-keyring-controller>@metamask/eth-hd-keyring": true, - "@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": true, - "@metamask/keyring-controller>@metamask/eth-keyring-controller>@metamask/eth-sig-util": true, - "@metamask/keyring-controller>@metamask/eth-keyring-controller>@metamask/utils": true, - "@metamask/obs-store": true, - "webpack>events": true - } - }, - "@metamask/keyring-controller>@metamask/eth-keyring-controller>@metamask/eth-sig-util": { - "packages": { - "@ethereumjs/tx>@ethereumjs/util": true, - "@ethereumjs/tx>ethereum-cryptography": true, - "bn.js": true, - "browserify>buffer": true, - "eth-sig-util>ethereumjs-util>ethjs-util": true, - "eth-sig-util>tweetnacl": true, - "eth-sig-util>tweetnacl-util": true - } - }, - "@metamask/keyring-controller>@metamask/eth-keyring-controller>@metamask/utils": { - "globals": { - "TextDecoder": true, - "TextEncoder": true - }, - "packages": { - "@metamask/key-tree>@noble/hashes": true, - "browserify>buffer": true, - "nock>debug": true, - "semver": true, - "superstruct": true - } - }, "@metamask/keyring-controller>@metamask/utils": { "globals": { "TextDecoder": true, diff --git a/package.json b/package.json index 00dff8148f3f..c437ea5ab066 100644 --- a/package.json +++ b/package.json @@ -205,8 +205,7 @@ "request@^2.88.2": "patch:request@npm%3A2.88.2#./.yarn/patches/request-npm-2.88.2-f4a57c72c4.patch", "request@^2.85.0": "patch:request@npm%3A2.88.2#./.yarn/patches/request-npm-2.88.2-f4a57c72c4.patch", "lavamoat-core@npm:^14.4.1": "patch:lavamoat-core@npm%3A14.4.1#~/.yarn/patches/lavamoat-core-npm-14.4.1-c4e8bbb016.patch", - "@metamask/keyring-controller@^8.0.0": "patch:@metamask/keyring-controller@npm%3A8.0.0#~/.yarn/patches/@metamask-keyring-controller-npm-8.0.0-806630ae4e.patch", - "@metamask/signature-controller@^5.3.0": "patch:@metamask/signature-controller@npm%3A5.3.0#./.yarn/patches/@metamask-signature-controller-npm-5.3.0-225628460b.patch", + "@metamask/signature-controller@^6.0.0": "patch:@metamask/signature-controller@npm%3A6.0.0#~/.yarn/patches/@metamask-signature-controller-npm-6.0.0-90e8e479a9.patch", "semver@7.3.7": "^7.5.4", "semver@7.3.8": "^7.5.4" }, @@ -246,7 +245,7 @@ "@metamask/design-tokens": "^1.12.0", "@metamask/desktop": "^0.3.0", "@metamask/eth-json-rpc-middleware": "^11.0.0", - "@metamask/eth-keyring-controller": "^10.0.1", + "@metamask/eth-keyring-controller": "^13.0.1", "@metamask/eth-ledger-bridge-keyring": "^0.15.0", "@metamask/eth-snap-keyring": "0.3.1", "@metamask/eth-token-tracker": "^4.0.0", @@ -256,7 +255,7 @@ "@metamask/gas-fee-controller": "^6.0.1", "@metamask/jazzicon": "^2.0.0", "@metamask/key-tree": "^9.0.0", - "@metamask/keyring-controller": "^8.0.0", + "@metamask/keyring-controller": "^8.0.1", "@metamask/logging-controller": "^1.0.1", "@metamask/logo": "^3.1.1", "@metamask/message-manager": "^7.3.0", @@ -275,7 +274,7 @@ "@metamask/safe-event-emitter": "^2.0.0", "@metamask/scure-bip39": "^2.0.3", "@metamask/selected-network-controller": "^1.0.0", - "@metamask/signature-controller": "^5.3.0", + "@metamask/signature-controller": "^6.0.0", "@metamask/slip44": "^3.0.0", "@metamask/smart-transactions-controller": "^4.0.0", "@metamask/snaps-controllers": "^2.0.1", diff --git a/test/e2e/tests/state-snapshots/errors-after-init-opt-in-background-state.json b/test/e2e/tests/state-snapshots/errors-after-init-opt-in-background-state.json index d41af246394d..5aa7a4426840 100644 --- a/test/e2e/tests/state-snapshots/errors-after-init-opt-in-background-state.json +++ b/test/e2e/tests/state-snapshots/errors-after-init-opt-in-background-state.json @@ -68,8 +68,8 @@ }, "KeyringController": { "isUnlocked": false, - "keyringTypes": "object", - "keyrings": "object" + "keyrings": "object", + "vault": "string" }, "LoggingController": { "logs": "object" }, "MetaMetricsController": { diff --git a/test/e2e/tests/state-snapshots/errors-after-init-opt-in-ui-state.json b/test/e2e/tests/state-snapshots/errors-after-init-opt-in-ui-state.json index 98a7ecf58f11..b3fa6f2ba7e7 100644 --- a/test/e2e/tests/state-snapshots/errors-after-init-opt-in-ui-state.json +++ b/test/e2e/tests/state-snapshots/errors-after-init-opt-in-ui-state.json @@ -80,7 +80,6 @@ } }, "cachedBalances": "object", - "keyringTypes": "object", "keyrings": "object", "useNonceField": false, "usePhishDetect": true, diff --git a/test/jest/mock-store.js b/test/jest/mock-store.js index 4ceaded9cee0..96697f354f23 100644 --- a/test/jest/mock-store.js +++ b/test/jest/mock-store.js @@ -260,7 +260,6 @@ export const createSwapsMockStore = () => { }, selectedAddress: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', currentLocale: 'en', - keyringTypes: [KeyringType.imported, KeyringType.hdKeyTree], keyrings: [ { type: KeyringType.hdKeyTree, diff --git a/types/eth-keyring-controller.d.ts b/types/eth-keyring-controller.d.ts deleted file mode 100644 index ee7525bf394d..000000000000 --- a/types/eth-keyring-controller.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -declare module '@metamask/eth-keyring-controller' { - export class KeyringController { - signMessage: (...any) => any; - - signPersonalMessage: (...any) => any; - - signTypedMessage: (...any) => any; - - getKeyringForAccount: (address: string) => Promise<{ - type: string; - }>; - - getEncryptionPublicKey: (address: string) => Promise; - - decryptMessage: (...any) => any; - } -} diff --git a/ui/pages/token-allowance/token-allowance.test.js b/ui/pages/token-allowance/token-allowance.test.js index 7000fc0e23a0..d9f9021e6b5e 100644 --- a/ui/pages/token-allowance/token-allowance.test.js +++ b/ui/pages/token-allowance/token-allowance.test.js @@ -74,7 +74,6 @@ const state = { }, ], transactions: [], - keyringTypes: [], keyrings: [ { type: KeyringType.hdKeyTree, diff --git a/yarn.lock b/yarn.lock index c0e8ace5b487..482e9efc68fc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3865,17 +3865,17 @@ __metadata: languageName: node linkType: hard -"@metamask/base-controller@npm:^3.0.0, @metamask/base-controller@npm:^3.1.0, @metamask/base-controller@npm:^3.2.0, @metamask/base-controller@npm:^3.2.1": - version: 3.2.1 - resolution: "@metamask/base-controller@npm:3.2.1" +"@metamask/base-controller@npm:^3.0.0, @metamask/base-controller@npm:^3.1.0, @metamask/base-controller@npm:^3.2.0, @metamask/base-controller@npm:^3.2.1, @metamask/base-controller@npm:^3.2.2": + version: 3.2.2 + resolution: "@metamask/base-controller@npm:3.2.2" dependencies: "@metamask/utils": "npm:^6.2.0" immer: "npm:^9.0.6" - checksum: ff4db984a72c942694b0ab849ec61f1c36423e6c6b7144a560f52fb6449e91dd4ce3b937a3b7e092468d0c679f305cc0c805085593f9b83acd98fbfe6f971b69 + checksum: 4d6537ef8cefbf091e652393d2a1d9c61d728032d0286bf22a228f8c8dc1b82e7551346fd17a92841d4fb61dd3bf37409e2305b504db393190363072ae528ca0 languageName: node linkType: hard -"@metamask/browser-passworder@npm:^4.0.2, @metamask/browser-passworder@npm:^4.1.0": +"@metamask/browser-passworder@npm:^4.1.0": version: 4.1.0 resolution: "@metamask/browser-passworder@npm:4.1.0" checksum: c09db69dd80ed020e017e70bc0589348343e659c8f402810a5c950ca42a16340a43998a0651ec0747cf4b2e2c0ce16dadd8511d2760ecb958e0a0a09fa95016e @@ -3920,9 +3920,9 @@ __metadata: languageName: node linkType: hard -"@metamask/controller-utils@npm:^5.0.0": - version: 5.0.0 - resolution: "@metamask/controller-utils@npm:5.0.0" +"@metamask/controller-utils@npm:^5.0.1": + version: 5.0.1 + resolution: "@metamask/controller-utils@npm:5.0.1" dependencies: "@metamask/eth-query": "npm:^3.0.1" "@metamask/utils": "npm:^6.2.0" @@ -3932,7 +3932,7 @@ __metadata: ethereumjs-util: "npm:^7.0.10" ethjs-unit: "npm:^0.1.6" fast-deep-equal: "npm:^3.1.3" - checksum: 4fbefc1affa9aee110fcb1b7fc95a96f29fc6d41d6fa6b92bd691d541833cf8531a282d7866daeb7585741533b50a5d9e8d0564071fc1abf09769c9fe039845b + checksum: e830a4e86085463ca2a81adb5cf71b81e4ab66468a8cadb6b2f4ef083f4746d2303b1d8587adf20f80eb618181a427288c115b63b695020511b4be8c152b52f3 languageName: node linkType: hard @@ -4073,19 +4073,6 @@ __metadata: languageName: node linkType: hard -"@metamask/eth-keyring-controller@npm:^10.0.1": - version: 10.0.1 - resolution: "@metamask/eth-keyring-controller@npm:10.0.1" - dependencies: - "@metamask/browser-passworder": "npm:^4.0.2" - "@metamask/eth-hd-keyring": "npm:^6.0.0" - "@metamask/eth-sig-util": "npm:5.0.2" - "@metamask/eth-simple-keyring": "npm:^5.0.0" - obs-store: "npm:^4.0.3" - checksum: b739eca06665ab384a33fb1c82b1c9e52de69223ff950a99676d1a542b1b1acaa21d3a1ed07cd7fda23fd3b70510706f2ab65bc7631bfd8902bab8bcf41ace0f - languageName: node - linkType: hard - "@metamask/eth-keyring-controller@npm:^13.0.1": version: 13.0.1 resolution: "@metamask/eth-keyring-controller@npm:13.0.1" @@ -4123,20 +4110,6 @@ __metadata: languageName: node linkType: hard -"@metamask/eth-sig-util@npm:5.0.2": - version: 5.0.2 - resolution: "@metamask/eth-sig-util@npm:5.0.2" - dependencies: - "@ethereumjs/util": "npm:^8.0.0" - bn.js: "npm:^4.11.8" - ethereum-cryptography: "npm:^1.1.2" - ethjs-util: "npm:^0.1.6" - tweetnacl: "npm:^1.0.3" - tweetnacl-util: "npm:^0.15.1" - checksum: 37489528d8e987bae00d9c5b2025b86e9ca6914cc9f3b98bae2eb39c3a890959d15cb09fad9c761f88ce0ae49e2a91f0237425f5771b1e3f0be62f2965e46a38 - languageName: node - linkType: hard - "@metamask/eth-sig-util@npm:^5.0.1, @metamask/eth-sig-util@npm:^5.0.2": version: 5.1.0 resolution: "@metamask/eth-sig-util@npm:5.1.0" @@ -4336,43 +4309,23 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-controller@npm:8.0.0": - version: 8.0.0 - resolution: "@metamask/keyring-controller@npm:8.0.0" - dependencies: - "@keystonehq/metamask-airgapped-keyring": "npm:^0.13.1" - "@metamask/base-controller": "npm:^3.2.1" - "@metamask/eth-keyring-controller": "npm:^13.0.1" - "@metamask/message-manager": "npm:^7.3.3" - "@metamask/preferences-controller": "npm:^4.4.1" - "@metamask/utils": "npm:^6.2.0" - async-mutex: "npm:^0.2.6" - ethereumjs-util: "npm:^7.0.10" - ethereumjs-wallet: "npm:^1.0.1" - immer: "npm:^9.0.6" - peerDependencies: - "@metamask/preferences-controller": ^4.4.1 - checksum: 2cd0173d210c634357aa8be0c3fc2472939e6919f69b4d375ebc6c464d116928603b3b917a4fa6120e75870bc2288553a23f5659a6719c84902d982e0aa376a4 - languageName: node - linkType: hard - -"@metamask/keyring-controller@patch:@metamask/keyring-controller@npm%3A8.0.0#~/.yarn/patches/@metamask-keyring-controller-npm-8.0.0-806630ae4e.patch": - version: 8.0.0 - resolution: "@metamask/keyring-controller@patch:@metamask/keyring-controller@npm%3A8.0.0#~/.yarn/patches/@metamask-keyring-controller-npm-8.0.0-806630ae4e.patch::version=8.0.0&hash=65339a" +"@metamask/keyring-controller@npm:^8.0.1": + version: 8.0.1 + resolution: "@metamask/keyring-controller@npm:8.0.1" dependencies: "@keystonehq/metamask-airgapped-keyring": "npm:^0.13.1" - "@metamask/base-controller": "npm:^3.2.1" + "@metamask/base-controller": "npm:^3.2.2" "@metamask/eth-keyring-controller": "npm:^13.0.1" - "@metamask/message-manager": "npm:^7.3.3" - "@metamask/preferences-controller": "npm:^4.4.1" + "@metamask/message-manager": "npm:^7.3.4" + "@metamask/preferences-controller": "npm:^4.4.2" "@metamask/utils": "npm:^6.2.0" async-mutex: "npm:^0.2.6" ethereumjs-util: "npm:^7.0.10" ethereumjs-wallet: "npm:^1.0.1" immer: "npm:^9.0.6" peerDependencies: - "@metamask/preferences-controller": ^4.4.1 - checksum: f9a4f8eaec927b5c2fdc91f12066254a90b4358e79dcf01ff4c380414cdb53f37914cb9e5dd71a9758fd67ffe7346fcb181f2124e6d6f1fca8c21af5bb5b1920 + "@metamask/preferences-controller": ^4.4.2 + checksum: e950270c6f22b0745d4a1f35c94601bbe4642da573850f071e25c94befa3b8e95c5891a1fb317827e884438a34a7cc4cf7da9a838080ad13cd15c54cf4e56327 languageName: node linkType: hard @@ -4397,19 +4350,19 @@ __metadata: languageName: node linkType: hard -"@metamask/message-manager@npm:^7.2.0, @metamask/message-manager@npm:^7.3.0, @metamask/message-manager@npm:^7.3.3": - version: 7.3.3 - resolution: "@metamask/message-manager@npm:7.3.3" +"@metamask/message-manager@npm:^7.3.0, @metamask/message-manager@npm:^7.3.2, @metamask/message-manager@npm:^7.3.4": + version: 7.3.4 + resolution: "@metamask/message-manager@npm:7.3.4" dependencies: - "@metamask/base-controller": "npm:^3.2.1" - "@metamask/controller-utils": "npm:^5.0.0" + "@metamask/base-controller": "npm:^3.2.2" + "@metamask/controller-utils": "npm:^5.0.1" "@metamask/eth-sig-util": "npm:^7.0.0" "@metamask/utils": "npm:^6.2.0" "@types/uuid": "npm:^8.3.0" ethereumjs-util: "npm:^7.0.10" jsonschema: "npm:^1.2.4" uuid: "npm:^8.3.2" - checksum: 1f9175c3ce44bf8d8ee80e391f1d36f559cef31e883a6ba7e3032d06c0263cc8e1d5fe15a591583bd415bbb01d113750ff6de99220d99ef71b4057985e34406e + checksum: 59ac697ac75f86d820b756dfaf1496a86061132abea651a563f526c74c8cf4b39f7dcfc28ce6357c0d2bf1495fa5a8abce23a882a831ba6ad8361bc871fb95c5 languageName: node linkType: hard @@ -4632,13 +4585,13 @@ __metadata: languageName: node linkType: hard -"@metamask/preferences-controller@npm:^4.1.0, @metamask/preferences-controller@npm:^4.4.1": - version: 4.4.1 - resolution: "@metamask/preferences-controller@npm:4.4.1" +"@metamask/preferences-controller@npm:^4.1.0, @metamask/preferences-controller@npm:^4.4.2": + version: 4.4.2 + resolution: "@metamask/preferences-controller@npm:4.4.2" dependencies: - "@metamask/base-controller": "npm:^3.2.1" - "@metamask/controller-utils": "npm:^5.0.0" - checksum: 2404cf4c6f207316af7fd8cf9a7ae2ff3f38766bedde67103143d964ad4e253c8cf228da692a80644e65f072306bfaa807895771e45e93797ab879b9645744a7 + "@metamask/base-controller": "npm:^3.2.2" + "@metamask/controller-utils": "npm:^5.0.1" + checksum: 873530da1f20ec1d830d41114ef0b134de77abd283e2e06b02b79454c2c96fb13b674074aa1facf37b62e6fe3dc785caf20958a69501fef6450c3f77e0ce5ad7 languageName: node linkType: hard @@ -4765,41 +4718,41 @@ __metadata: languageName: node linkType: hard -"@metamask/signature-controller@npm:5.3.0": - version: 5.3.0 - resolution: "@metamask/signature-controller@npm:5.3.0" +"@metamask/signature-controller@npm:6.0.0": + version: 6.0.0 + resolution: "@metamask/signature-controller@npm:6.0.0" dependencies: - "@metamask/approval-controller": "npm:^3.5.0" - "@metamask/base-controller": "npm:^3.2.0" - "@metamask/controller-utils": "npm:^4.3.0" - "@metamask/message-manager": "npm:^7.2.0" + "@metamask/approval-controller": "npm:^3.5.1" + "@metamask/base-controller": "npm:^3.2.1" + "@metamask/controller-utils": "npm:^4.3.2" + "@metamask/message-manager": "npm:^7.3.2" "@metamask/utils": "npm:^6.2.0" eth-rpc-errors: "npm:^4.0.2" ethereumjs-util: "npm:^7.0.10" immer: "npm:^9.0.6" lodash: "npm:^4.17.21" peerDependencies: - "@metamask/approval-controller": ^3.5.0 - checksum: d5b5aad5ed4c97032f3fd3d1dc7f260d700ae8b630f50b30019519b79b760bdaa4ad368721db5b24719062bd650193f23b9410a51e34c3d363f33f9ad83528d6 + "@metamask/approval-controller": ^3.5.1 + checksum: 4d2b6e47d721905e8e0fde981a492f3bcb498893b7892a0a649389ef957cbdcbe00238144c37dad189c5da4121606ffe0f1c061f8bc473c073ce84e4fbe24965 languageName: node linkType: hard -"@metamask/signature-controller@patch:@metamask/signature-controller@npm%3A5.3.0#./.yarn/patches/@metamask-signature-controller-npm-5.3.0-225628460b.patch::locator=metamask-crx%40workspace%3A.": - version: 5.3.0 - resolution: "@metamask/signature-controller@patch:@metamask/signature-controller@npm%3A5.3.0#./.yarn/patches/@metamask-signature-controller-npm-5.3.0-225628460b.patch::version=5.3.0&hash=b8da18&locator=metamask-crx%40workspace%3A." +"@metamask/signature-controller@patch:@metamask/signature-controller@npm%3A6.0.0#~/.yarn/patches/@metamask-signature-controller-npm-6.0.0-90e8e479a9.patch": + version: 6.0.0 + resolution: "@metamask/signature-controller@patch:@metamask/signature-controller@npm%3A6.0.0#~/.yarn/patches/@metamask-signature-controller-npm-6.0.0-90e8e479a9.patch::version=6.0.0&hash=ae5433" dependencies: - "@metamask/approval-controller": "npm:^3.5.0" - "@metamask/base-controller": "npm:^3.2.0" - "@metamask/controller-utils": "npm:^4.3.0" - "@metamask/message-manager": "npm:^7.2.0" + "@metamask/approval-controller": "npm:^3.5.1" + "@metamask/base-controller": "npm:^3.2.1" + "@metamask/controller-utils": "npm:^4.3.2" + "@metamask/message-manager": "npm:^7.3.2" "@metamask/utils": "npm:^6.2.0" eth-rpc-errors: "npm:^4.0.2" ethereumjs-util: "npm:^7.0.10" immer: "npm:^9.0.6" lodash: "npm:^4.17.21" peerDependencies: - "@metamask/approval-controller": ^3.5.0 - checksum: 973259698560a21b8f7d5436f4e4c198202781d7b796012b2d6336bd1738eeedfe1bd405e352c468b46958889f12a709f1b3247ec6e9e8f388984fa25ae0eff3 + "@metamask/approval-controller": ^3.5.1 + checksum: f178e2aacfe031930eb68018571e7531bb91b742a2d4beacb51d5ff8d35e609d0dd601c7cd8ae734c9f8a1f7c41d3ca4d59b3fd48261fb691223f0e6b85ba7d9 languageName: node linkType: hard @@ -23908,7 +23861,7 @@ __metadata: "@metamask/eslint-config-nodejs": "npm:^9.0.0" "@metamask/eslint-config-typescript": "npm:^9.0.1" "@metamask/eth-json-rpc-middleware": "npm:^11.0.0" - "@metamask/eth-keyring-controller": "npm:^10.0.1" + "@metamask/eth-keyring-controller": "npm:^13.0.1" "@metamask/eth-ledger-bridge-keyring": "npm:^0.15.0" "@metamask/eth-snap-keyring": "npm:0.3.1" "@metamask/eth-token-tracker": "npm:^4.0.0" @@ -23919,7 +23872,7 @@ __metadata: "@metamask/gas-fee-controller": "npm:^6.0.1" "@metamask/jazzicon": "npm:^2.0.0" "@metamask/key-tree": "npm:^9.0.0" - "@metamask/keyring-controller": "npm:^8.0.0" + "@metamask/keyring-controller": "npm:^8.0.1" "@metamask/logging-controller": "npm:^1.0.1" "@metamask/logo": "npm:^3.1.1" "@metamask/message-manager": "npm:^7.3.0" @@ -23939,7 +23892,7 @@ __metadata: "@metamask/safe-event-emitter": "npm:^2.0.0" "@metamask/scure-bip39": "npm:^2.0.3" "@metamask/selected-network-controller": "npm:^1.0.0" - "@metamask/signature-controller": "npm:^5.3.0" + "@metamask/signature-controller": "npm:^6.0.0" "@metamask/slip44": "npm:^3.0.0" "@metamask/smart-transactions-controller": "npm:^4.0.0" "@metamask/snaps-controllers": "npm:^2.0.1" @@ -26196,18 +26149,6 @@ __metadata: languageName: node linkType: hard -"obs-store@npm:^4.0.3": - version: 4.0.3 - resolution: "obs-store@npm:4.0.3" - dependencies: - readable-stream: "npm:^2.2.2" - safe-event-emitter: "npm:^1.0.1" - through2: "npm:^2.0.3" - xtend: "npm:^4.0.1" - checksum: d56da17699a00fc16d9485aa668cf8d27a6cbf9ae38905cd0bfd75eb37f32bbfed9e976a257371d969b18d627c0c8a6f7b13c5e3f277aa36c740f2bc90ae2a11 - languageName: node - linkType: hard - "on-exit-leak-free@npm:^2.1.0": version: 2.1.0 resolution: "on-exit-leak-free@npm:2.1.0" From b7ad9f64588ad39d869da410fd7bacd5b378e5ee Mon Sep 17 00:00:00 2001 From: Matthew Walsh Date: Mon, 2 Oct 2023 10:21:46 +0100 Subject: [PATCH 3/3] Add petnames metrics (#20994) Remove proposed name from Name component. Update proposed names every 2 seconds in the NameDetails component. Display checksum addresses. Truncate the Name component text using ellipsis. Truncate the proposed names options in the NameDetails component using ellipsis. Sort proposed name options by source label. Optimise petnames E2E tests. --- app/scripts/controllers/metametrics.js | 30 ++ app/scripts/controllers/metametrics.test.js | 36 ++ app/scripts/lib/SnapsNameProvider.test.ts | 6 +- app/scripts/lib/SnapsNameProvider.ts | 2 +- app/scripts/metamask-controller.js | 1 - lavamoat/browserify/beta/policy.json | 17 +- lavamoat/browserify/desktop/policy.json | 17 +- lavamoat/browserify/flask/policy.json | 17 +- lavamoat/browserify/main/policy.json | 17 +- lavamoat/browserify/mmi/policy.json | 17 +- package.json | 2 +- shared/constants/metametrics.ts | 11 +- shared/constants/names.ts | 13 - test/e2e/flask/petnames.spec.js | 213 ++++-------- test/e2e/mock-e2e.js | 10 +- .../contract-details-modal.js | 7 +- .../app/name/__snapshots__/name.test.tsx.snap | 58 +--- ui/components/app/name/index.scss | 13 +- .../__snapshots__/name-details.test.tsx.snap | 226 +++++++++++- .../app/name/name-details/metrics.ts | 102 ++++++ .../name/name-details/name-details.test.tsx | 321 ++++++++++++++---- .../app/name/name-details/name-details.tsx | 232 ++++++++++--- ui/components/app/name/name.stories.tsx | 118 +++---- ui/components/app/name/name.test.tsx | 168 ++------- ui/components/app/name/name.tsx | 92 ++--- .../signature-request-data.js | 7 +- ui/components/ui/form-combo-field/index.scss | 7 + ui/contexts/metametrics.js | 2 +- ui/hooks/useName.test.ts | 34 +- ui/hooks/useName.ts | 30 +- yarn.lock | 14 +- 31 files changed, 1188 insertions(+), 652 deletions(-) delete mode 100644 shared/constants/names.ts create mode 100644 ui/components/app/name/name-details/metrics.ts diff --git a/app/scripts/controllers/metametrics.js b/app/scripts/controllers/metametrics.js index 564ec1dff2c3..a72e64219df4 100644 --- a/app/scripts/controllers/metametrics.js +++ b/app/scripts/controllers/metametrics.js @@ -11,6 +11,7 @@ import { import { ObservableStore } from '@metamask/obs-store'; import { bufferToHex, keccak } from 'ethereumjs-util'; import { v4 as uuidv4 } from 'uuid'; +import { NameType } from '@metamask/name-controller'; import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../shared/constants/app'; import { METAMETRICS_ANONYMOUS_ID, @@ -800,6 +801,10 @@ export default class MetaMetricsController { ///: END:ONLY_INCLUDE_IN [MetaMetricsUserTrait.SecurityProviders]: metamaskState.transactionSecurityCheckEnabled ? ['opensea'] : [], + ///: BEGIN:ONLY_INCLUDE_IN(petnames) + [MetaMetricsUserTrait.PetnameAddressCount]: + this._getPetnameAddressCount(metamaskState), + ///: END:ONLY_INCLUDE_IN }; if (!previousUserTraits) { @@ -1076,4 +1081,29 @@ export default class MetaMetricsController { }; this.segment[eventType](modifiedPayload, modifiedCallback); } + + /** + * Returns the total number of Ethereum addresses with saved petnames, + * including all chain ID variations. + * + * @param {object} metamaskState + * @returns {number} + */ + _getPetnameAddressCount(metamaskState) { + const addressNames = metamaskState.names?.[NameType.ETHEREUM_ADDRESS] ?? {}; + + return Object.keys(addressNames).reduce((totalCount, address) => { + const addressEntry = addressNames[address]; + + const addressNameCount = Object.keys(addressEntry).reduce( + (count, chainId) => { + const hasName = Boolean(addressEntry[chainId].name?.length); + return count + (hasName ? 1 : 0); + }, + 0, + ); + + return totalCount + addressNameCount; + }, 0); + } } diff --git a/app/scripts/controllers/metametrics.test.js b/app/scripts/controllers/metametrics.test.js index 0e060bed1e72..3532e3b15de3 100644 --- a/app/scripts/controllers/metametrics.test.js +++ b/app/scripts/controllers/metametrics.test.js @@ -1,6 +1,7 @@ import { strict as assert } from 'assert'; import sinon from 'sinon'; import { toHex } from '@metamask/controller-utils'; +import { NameType } from '@metamask/name-controller'; import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../shared/constants/app'; import { createSegmentMock } from '../lib/segment'; import { @@ -1028,6 +1029,38 @@ describe('MetaMetricsController', function () { useTokenDetection: true, desktopEnabled: false, security_providers: [], + names: { + [NameType.ETHEREUM_ADDRESS]: { + '0x123': { + '0x1': { + name: 'Test 1', + }, + '0x2': { + name: 'Test 2', + }, + '0x3': { + name: null, + }, + }, + '0x456': { + '0x1': { + name: 'Test 3', + }, + }, + '0x789': { + '0x1': { + name: null, + }, + }, + }, + otherType: { + otherValue: { + otherVariation: { + name: 'Test 4', + }, + }, + }, + }, }); assert.deepEqual(traits, { @@ -1056,6 +1089,9 @@ describe('MetaMetricsController', function () { [MetaMetricsUserTrait.MmiAccountAddress]: null, [MetaMetricsUserTrait.MmiIsCustodian]: false, ///: END:ONLY_INCLUDE_IN + ///: BEGIN:ONLY_INCLUDE_IN(petnames) + [MetaMetricsUserTrait.PetnameAddressCount]: 3, + ///: END:ONLY_INCLUDE_IN }); }); diff --git a/app/scripts/lib/SnapsNameProvider.test.ts b/app/scripts/lib/SnapsNameProvider.test.ts index 5ac250c9f494..cef4356e379c 100644 --- a/app/scripts/lib/SnapsNameProvider.test.ts +++ b/app/scripts/lib/SnapsNameProvider.test.ts @@ -139,7 +139,7 @@ describe('SnapsNameProvider', () => { const response = await provider.getProposedNames({ value: VALUE_MOCK, type: NameType.ETHEREUM_ADDRESS, - chainId: CHAIN_ID_MOCK, + variation: CHAIN_ID_MOCK, }); expect(response).toStrictEqual({ @@ -193,7 +193,7 @@ describe('SnapsNameProvider', () => { const response = await provider.getProposedNames({ value: VALUE_MOCK, type: NameType.ETHEREUM_ADDRESS, - chainId: CHAIN_ID_MOCK, + variation: CHAIN_ID_MOCK, }); expect(response).toStrictEqual({ @@ -224,7 +224,7 @@ describe('SnapsNameProvider', () => { const response = await provider.getProposedNames({ value: VALUE_MOCK, type: NameType.ETHEREUM_ADDRESS, - chainId: CHAIN_ID_MOCK, + variation: CHAIN_ID_MOCK, }); expect(response).toStrictEqual({ diff --git a/app/scripts/lib/SnapsNameProvider.ts b/app/scripts/lib/SnapsNameProvider.ts index 59438d725b3e..abf6cc8761b1 100644 --- a/app/scripts/lib/SnapsNameProvider.ts +++ b/app/scripts/lib/SnapsNameProvider.ts @@ -107,7 +107,7 @@ export class SnapsNameProvider implements NameProvider { snap: TruncatedSnap, request: NameProviderRequest, ): Promise<{ sourceId: string; result: NameProviderSourceResult }> { - const { chainId: chainIdHex, value } = request; + const { variation: chainIdHex, value } = request; const sourceId = snap.id; const chainIdDecimal = parseInt(chainIdHex, 16); diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 60bea6679ba0..27ebd056f8f3 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1538,7 +1538,6 @@ export default class MetamaskController extends EventEmitter { ///: BEGIN:ONLY_INCLUDE_IN(petnames) this.nameController = new NameController({ - getChainId: () => this.networkController.state.providerConfig.chainId, messenger: this.controllerMessenger.getRestricted({ name: 'NameController', allowedActions: [], diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index 9d5cb9d86f59..137d438d31e5 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -1729,7 +1729,22 @@ "fetch": true }, "packages": { - "@metamask/base-controller": true + "@metamask/base-controller": true, + "@metamask/name-controller>@metamask/utils": true, + "eth-json-rpc-filters>async-mutex": true + } + }, + "@metamask/name-controller>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/key-tree>@noble/hashes": true, + "browserify>buffer": true, + "nock>debug": true, + "semver": true, + "superstruct": true } }, "@metamask/network-controller": { diff --git a/lavamoat/browserify/desktop/policy.json b/lavamoat/browserify/desktop/policy.json index fae323bcb153..5f3e7b1e6a65 100644 --- a/lavamoat/browserify/desktop/policy.json +++ b/lavamoat/browserify/desktop/policy.json @@ -1870,7 +1870,22 @@ "fetch": true }, "packages": { - "@metamask/base-controller": true + "@metamask/base-controller": true, + "@metamask/name-controller>@metamask/utils": true, + "eth-json-rpc-filters>async-mutex": true + } + }, + "@metamask/name-controller>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/key-tree>@noble/hashes": true, + "browserify>buffer": true, + "nock>debug": true, + "semver": true, + "superstruct": true } }, "@metamask/network-controller": { diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index 9a99fcf70258..62ee4d7636f5 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -1870,7 +1870,22 @@ "fetch": true }, "packages": { - "@metamask/base-controller": true + "@metamask/base-controller": true, + "@metamask/name-controller>@metamask/utils": true, + "eth-json-rpc-filters>async-mutex": true + } + }, + "@metamask/name-controller>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/key-tree>@noble/hashes": true, + "browserify>buffer": true, + "nock>debug": true, + "semver": true, + "superstruct": true } }, "@metamask/network-controller": { diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index fba77e073592..3620f072010a 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -1729,7 +1729,22 @@ "fetch": true }, "packages": { - "@metamask/base-controller": true + "@metamask/base-controller": true, + "@metamask/name-controller>@metamask/utils": true, + "eth-json-rpc-filters>async-mutex": true + } + }, + "@metamask/name-controller>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/key-tree>@noble/hashes": true, + "browserify>buffer": true, + "nock>debug": true, + "semver": true, + "superstruct": true } }, "@metamask/network-controller": { diff --git a/lavamoat/browserify/mmi/policy.json b/lavamoat/browserify/mmi/policy.json index f093833e6007..da52999e2f72 100644 --- a/lavamoat/browserify/mmi/policy.json +++ b/lavamoat/browserify/mmi/policy.json @@ -1869,7 +1869,22 @@ "fetch": true }, "packages": { - "@metamask/base-controller": true + "@metamask/base-controller": true, + "@metamask/name-controller>@metamask/utils": true, + "eth-json-rpc-filters>async-mutex": true + } + }, + "@metamask/name-controller>@metamask/utils": { + "globals": { + "TextDecoder": true, + "TextEncoder": true + }, + "packages": { + "@metamask/key-tree>@noble/hashes": true, + "browserify>buffer": true, + "nock>debug": true, + "semver": true, + "superstruct": true } }, "@metamask/network-controller": { diff --git a/package.json b/package.json index c437ea5ab066..4ff01e9f53aa 100644 --- a/package.json +++ b/package.json @@ -260,7 +260,7 @@ "@metamask/logo": "^3.1.1", "@metamask/message-manager": "^7.3.0", "@metamask/metamask-eth-abis": "^3.0.0", - "@metamask/name-controller": "^1.0.0", + "@metamask/name-controller": "^3.0.0", "@metamask/network-controller": "^12.2.0", "@metamask/notification-controller": "^3.0.0", "@metamask/obs-store": "^8.1.0", diff --git a/shared/constants/metametrics.ts b/shared/constants/metametrics.ts index b17c67e63038..e9b26f6c6712 100644 --- a/shared/constants/metametrics.ts +++ b/shared/constants/metametrics.ts @@ -455,6 +455,9 @@ export enum MetaMetricsUserTrait { */ MmiIsCustodian = 'mmi_is_custodian', ///: END:ONLY_INCLUDE_IN + ///: BEGIN:ONLY_INCLUDE_IN(petnames) + PetnameAddressCount = 'petname_addresses_count', + ///: END:ONLY_INCLUDE_IN } /** @@ -545,6 +548,11 @@ export enum MetaMetricsEventName { PermissionsApproved = 'Permissions Approved', PermissionsRejected = 'Permissions Rejected', PermissionsRequested = 'Permissions Requested', + PetnameCreated = 'Petname Created', + PetnameDeleted = 'Petname Deleted', + PetnameDisplayed = 'Petname Displayed', + PetnameModalOpened = 'Petname Modal Opened', + PetnameUpdated = 'Petname Updated', PhishingPageDisplayed = 'Phishing Page Displayed', PortfolioLinkClicked = 'Portfolio Link Clicked', ProviderMethodCalled = 'Provider Method Called', @@ -665,18 +673,19 @@ export enum MetaMetricsEventCategory { Navigation = 'Navigation', Network = 'Network', Onboarding = 'Onboarding', + Petnames = 'Petnames', Phishing = 'Phishing', Retention = 'Retention', ServiceWorkers = 'service_workers', Settings = 'Settings', Snaps = 'Snaps', Swaps = 'Swaps', + Tokens = 'Tokens', Transactions = 'Transactions', Wallet = 'Wallet', ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) MMI = 'Institutional', ///: END:ONLY_INCLUDE_IN - Tokens = 'Tokens', } export enum MetaMetricsEventLinkType { diff --git a/shared/constants/names.ts b/shared/constants/names.ts deleted file mode 100644 index 33538a59192c..000000000000 --- a/shared/constants/names.ts +++ /dev/null @@ -1,13 +0,0 @@ -export enum NameSourceId { - ENS = 'ens', - ETHERSCAN = 'etherscan', - LENS_PROTOCOL = 'lens', - TOKEN = 'token', -} - -export const DEFAULT_NAME_SOURCE_PRIORITY = [ - NameSourceId.ENS, - NameSourceId.LENS_PROTOCOL, - NameSourceId.TOKEN, - NameSourceId.ETHERSCAN, -]; diff --git a/test/e2e/flask/petnames.spec.js b/test/e2e/flask/petnames.spec.js index 5c090eb9e6b7..7f1a3ebc4979 100644 --- a/test/e2e/flask/petnames.spec.js +++ b/test/e2e/flask/petnames.spec.js @@ -1,4 +1,3 @@ -const { strict: assert } = require('assert'); const { withFixtures, openDapp, convertToHexValue } = require('../helpers'); const FixtureBuilder = require('../fixture-builder'); const { TEST_SNAPS_WEBSITE_URL } = require('../snaps/enums'); @@ -88,84 +87,41 @@ async function focusTestDapp(driver) { } async function showThirdPartyDetails(driver) { - const verifyContractDetailsButton = await driver.findElement( + await driver.clickElement( '.signature-request-content__verify-contract-details', ); - - verifyContractDetailsButton.click(); - - await driver.delay(3000); - - return await driver.findElement('.contract-details-modal'); } async function closeThirdPartyDetails(driver) { await driver.clickElement({ text: 'Got it', tag: 'button' }); } -async function getAddressesInMessage(driver) { - return await driver.findElements( - '.signature-request-data__node__value__address', - ); -} - -async function expectName( - parent, - expectedValue, - expectedProposedName, - isSaved, -) { - const value = await ( - await parent.nestedFindElement(isSaved ? '.name__name' : '.name__value') - ).getText(); +async function expectName(driver, expectedValue, isSaved) { + const containerClass = isSaved ? 'name__saved' : 'name__missing'; + const valueClass = isSaved ? 'name__name' : 'name__value'; - assert.equal(value, expectedValue, 'Name value is incorrect'); - - if (expectedProposedName) { - const proposedName = ( - await (await parent.nestedFindElement(`.name__proposed`))?.getText() - ) - ?.replace('“', '') - .replace('”', ''); - - assert.equal( - proposedName, - expectedProposedName, - 'Proposed name is incorrect', - ); - } + await driver.findElement({ + css: `.${containerClass} .${valueClass}`, + text: expectedValue, + }); +} - if (isSaved) { - await parent.nestedFindElement(`.name__saved`); - } else { - await parent.nestedFindElement(`.name__missing`); - } +async function clickName(driver, value) { + await driver.clickElement({ + css: `.name`, + text: value, + }); } -async function saveName(driver, parent, name, proposedName) { - (await parent.nestedFindElement('.name')).click(); - (await driver.findElement('.form-combo-field')).click(); +async function saveName(driver, value, name, proposedName) { + await clickName(driver, value); + await driver.clickElement('.form-combo-field'); if (proposedName) { - const options = await driver.findElements( - '.form-combo-field__option-primary', - ); - - let found = false; - - for (const option of options) { - const text = await option.getText(); - - if (text === proposedName) { - option.click(); - found = true; - break; - } - } - - if (!found) { - assert.fail('Could not find proposed name'); - } + await driver.clickElement({ + css: '.form-combo-field__option-primary', + text: proposedName, + }); } if (name) { @@ -177,28 +133,21 @@ async function saveName(driver, parent, name, proposedName) { await driver.clickElement({ text: 'Save', tag: 'button' }); } -async function getProposedNames(driver, parent) { - (await parent.nestedFindElement('.name')).click(); - (await driver.findElement('.form-combo-field')).click(); - - const primaryTextElements = await driver.findElements( - '.form-combo-field__option-primary', - ); - - const secondaryTextElements = await driver.findElements( - '.form-combo-field__option-secondary', - ); +async function expectProposedNames(driver, value, options) { + await clickName(driver, value); + await driver.clickElement('.form-combo-field'); - const proposedNames = []; + for (const option of options) { + await driver.findElement({ + css: '.form-combo-field__option-primary', + text: option[0], + }); - for (let i = 0; i < primaryTextElements.length; i++) { - const primaryText = await primaryTextElements[i].getText(); - const secondaryText = await secondaryTextElements[i].getText(); - - proposedNames.push([primaryText, secondaryText]); + await driver.findElement({ + css: '.form-combo-field__option-secondary', + text: option[1], + }); } - - return proposedNames; } describe('Petnames', function () { @@ -218,39 +167,22 @@ describe('Petnames', function () { await openDapp(driver); await createSignatureRequest(driver, SIGNATURE_TYPE.TYPED_V3); await focusNotification(driver); - - let addresses = await getAddressesInMessage(driver); - - await expectName(addresses[0], '0xCD2a3...DD826', 'test.lens', false); - await expectName(addresses[1], '0xbBbBB...bBBbB', 'test2.lens', false); - - await saveName(driver, addresses[0], undefined, 'test.lens'); - await saveName(driver, addresses[1], undefined, 'test2.lens'); - - let contractDetailsModal = await showThirdPartyDetails(driver); - - await expectName( - contractDetailsModal, - '0xCcCCc...ccccC', - 'test3.lens', - false, - ); - - await saveName(driver, contractDetailsModal, 'Custom Name'); + await expectName(driver, '0xCD2a3...DD826', false); + await expectName(driver, '0xbBbBB...bBBbB', false); + await saveName(driver, '0xCD2a3...DD826', undefined, 'test.lens'); + await saveName(driver, '0xbBbBB...bBBbB', undefined, 'test2.lens'); + await showThirdPartyDetails(driver); + await expectName(driver, '0xCcCCc...ccccC', false); + await saveName(driver, '0xCcCCc...ccccC', 'Custom Name'); await closeThirdPartyDetails(driver); await rejectSignatureRequest(driver); await focusTestDapp(driver); await createSignatureRequest(driver, SIGNATURE_TYPE.TYPED_V3); await focusNotification(driver); - - addresses = await getAddressesInMessage(driver); - - await expectName(addresses[0], 'test.lens', undefined, true); - await expectName(addresses[1], 'test2.lens', undefined, true); - - contractDetailsModal = await showThirdPartyDetails(driver); - - await expectName(contractDetailsModal, 'Custom Name', undefined, true); + await expectName(driver, 'test.lens', true); + await expectName(driver, 'test2.lens', true); + await showThirdPartyDetails(driver); + await expectName(driver, 'Custom Name', true); }, ); }); @@ -271,47 +203,25 @@ describe('Petnames', function () { await openDapp(driver); await createSignatureRequest(driver, SIGNATURE_TYPE.TYPED_V4); await focusNotification(driver); - - let addresses = await getAddressesInMessage(driver); - - await expectName(addresses[0], '0xCD2a3...DD826', 'test.lens', false); - await expectName(addresses[1], '0xDeaDb...DbeeF', 'Test Token', false); - await expectName(addresses[2], '0xbBbBB...bBBbB', 'test2.lens', false); - await expectName( - addresses[3], - '0xB0Bda...bEa57', - 'Test Token 2', - false, - ); - await expectName(addresses[4], '0xB0B0b...00000', undefined, false); - - await saveName(driver, addresses[0], undefined, 'test.lens'); - await saveName(driver, addresses[3], undefined, 'Test Token 2'); - - let contractDetailsModal = await showThirdPartyDetails(driver); - - await expectName( - contractDetailsModal, - '0xCcCCc...ccccC', - 'test3.lens', - false, - ); - - await saveName(driver, contractDetailsModal, 'Custom Name'); + await expectName(driver, '0xCD2a3...DD826', false); + await expectName(driver, '0xDeaDb...DbeeF', false); + await expectName(driver, '0xbBbBB...bBBbB', false); + await expectName(driver, '0xB0Bda...bEa57', false); + await expectName(driver, '0xB0B0b...00000', false); + await saveName(driver, '0xCD2a3...DD826', undefined, 'test.lens'); + await saveName(driver, '0xB0Bda...bEa57', undefined, 'Test Token 2'); + await showThirdPartyDetails(driver); + await expectName(driver, '0xCcCCc...ccccC', false); + await saveName(driver, '0xCcCCc...ccccC', 'Custom Name'); await closeThirdPartyDetails(driver); await rejectSignatureRequest(driver); await focusTestDapp(driver); await createSignatureRequest(driver, SIGNATURE_TYPE.TYPED_V4); await focusNotification(driver); - - addresses = await getAddressesInMessage(driver); - - await expectName(addresses[0], 'test.lens', undefined, true); - await expectName(addresses[3], 'Test Token 2', undefined, true); - - contractDetailsModal = await showThirdPartyDetails(driver); - - await expectName(contractDetailsModal, 'Custom Name', undefined, true); + await expectName(driver, 'test.lens', true); + await expectName(driver, 'Test Token 2', true); + await showThirdPartyDetails(driver); + await expectName(driver, 'Custom Name', true); }, ); }); @@ -335,12 +245,9 @@ describe('Petnames', function () { await focusTestDapp(driver); await createSignatureRequest(driver, SIGNATURE_TYPE.TYPED_V4); await focusNotification(driver); - - const addresses = await getAddressesInMessage(driver); - - assert.deepEqual(await getProposedNames(driver, addresses[0]), [ - ['example.domain - 0xCD2 / 0x539', 'Name Lookup Example Snap'], + await expectProposedNames(driver, '0xCD2a3...DD826', [ ['test.lens', 'Lens Protocol'], + ['example.domain - 0xcd2 / 0x539', 'Name Lookup Example Snap'], ]); }, ); diff --git a/test/e2e/mock-e2e.js b/test/e2e/mock-e2e.js index f78f7e8a0b91..91a32c5c5fdb 100644 --- a/test/e2e/mock-e2e.js +++ b/test/e2e/mock-e2e.js @@ -396,9 +396,9 @@ async function setupMocking(server, testSpecificMock, { chainId }) { async function mockLensNameProvider(server) { const handlesByAddress = { - '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826': 'test.lens', - '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB': 'test2.lens', - '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC': 'test3.lens', + '0xcd2a3d9f938e13cd947ec05abc7fe734df8dd826': 'test.lens', + '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb': 'test2.lens', + '0xcccccccccccccccccccccccccccccccccccccccc': 'test3.lens', }; await server.forPost('https://api.lens.dev').thenCallback((request) => { @@ -424,8 +424,8 @@ async function mockLensNameProvider(server) { async function mockTokenNameProvider(server) { const namesByAddress = { - '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF': 'Test Token', - '0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57': 'Test Token 2', + '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef': 'Test Token', + '0xb0bdabea57b0bdabea57b0bdabea57b0bdabea57': 'Test Token 2', }; for (const address of Object.keys(namesByAddress)) { diff --git a/ui/components/app/modals/contract-details-modal/contract-details-modal.js b/ui/components/app/modals/contract-details-modal/contract-details-modal.js index 9a722c440d0b..fe6ebd423faf 100644 --- a/ui/components/app/modals/contract-details-modal/contract-details-modal.js +++ b/ui/components/app/modals/contract-details-modal/contract-details-modal.js @@ -28,7 +28,6 @@ import NftCollectionImage from '../../../ui/nft-collection-image/nft-collection- import { ButtonIcon, IconName, Text } from '../../../component-library'; import Name from '../../name/name'; import { usePetnamesEnabled } from '../../../../hooks/usePetnamesEnabled'; -import { DEFAULT_NAME_SOURCE_PRIORITY } from '../../../../../shared/constants/names'; export default function ContractDetailsModal({ onClose, @@ -219,11 +218,7 @@ export default function ContractDetailsModal({ {petnamesEnabled ? ( - + ) : (
- 0xc0ffe...54978 - - - “ - TestProposedName - ” - -
-
- -`; - -exports[`Name renders address with proposed name according to source priority 1`] = ` -
-
-
- - - 0xc0ffe...54978 - - - “ - TestProposedName - ” + 0xC0ffe...54977
@@ -73,23 +39,3 @@ exports[`Name renders address with saved name 1`] = `
`; - -exports[`Name renders address without proposed name 1`] = ` -
-
-
- - - 0xc0ffe...54979 - -
-
-
-`; diff --git a/ui/components/app/name/index.scss b/ui/components/app/name/index.scss index becff5641d2a..e180c5a68168 100644 --- a/ui/components/app/name/index.scss +++ b/ui/components/app/name/index.scss @@ -5,6 +5,7 @@ align-items: center; gap: 5px; font-size: 12px; + max-width: 100%; &__missing { background-color: var(--color-warning-muted); @@ -23,15 +24,17 @@ } &__value, - &__proposed { + &__name { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + &__value { color: var(--color-warning-default); } &__name { color: var(--color-info-default); } - - &__proposed { - font-style: italic; - } } diff --git a/ui/components/app/name/name-details/__snapshots__/name-details.test.tsx.snap b/ui/components/app/name/name-details/__snapshots__/name-details.test.tsx.snap index 6e13e96a592d..f26559cf09eb 100644 --- a/ui/components/app/name/name-details/__snapshots__/name-details.test.tsx.snap +++ b/ui/components/app/name/name-details/__snapshots__/name-details.test.tsx.snap @@ -1,5 +1,229 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`NameDetails renders proposed names 1`] = ` + +
+
+
+
+
+