diff --git a/.yarn/patches/@metamask-network-controller-npm-18.0.1-c4d0cfaecd.patch b/.yarn/patches/@metamask-network-controller-npm-18.0.1-c4d0cfaecd.patch new file mode 100644 index 000000000000..9469548a639d --- /dev/null +++ b/.yarn/patches/@metamask-network-controller-npm-18.0.1-c4d0cfaecd.patch @@ -0,0 +1,24 @@ +diff --git a/dist/chunk-VNCJZRDU.js b/dist/chunk-VNCJZRDU.js +index 78251fc9517438d90261ed53172d2a4133d3a5fd..3ecc0c2838ac12c0ff5b5521a82b08955287956b 100644 +--- a/dist/chunk-VNCJZRDU.js ++++ b/dist/chunk-VNCJZRDU.js +@@ -323,7 +323,6 @@ var NetworkController = class extends _basecontroller.BaseController { + async initializeProvider() { + _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _ensureAutoManagedNetworkClientRegistryPopulated, ensureAutoManagedNetworkClientRegistryPopulated_fn).call(this); + _chunkZ4BLTVTBjs.__privateMethod.call(void 0, this, _applyNetworkSelection, applyNetworkSelection_fn).call(this); +- await this.lookupNetwork(); + } + /** + * Refreshes the network meta with EIP-1559 support and the network status +diff --git a/dist/chunk-XWP6GXMK.mjs b/dist/chunk-XWP6GXMK.mjs +index fb7e30d27367a38e8a357ff9e744894a4505b5a5..884bb1d124934a613847d7fd398fbc6cb02cade8 100644 +--- a/dist/chunk-XWP6GXMK.mjs ++++ b/dist/chunk-XWP6GXMK.mjs +@@ -323,7 +323,6 @@ var NetworkController = class extends BaseController { + async initializeProvider() { + __privateMethod(this, _ensureAutoManagedNetworkClientRegistryPopulated, ensureAutoManagedNetworkClientRegistryPopulated_fn).call(this); + __privateMethod(this, _applyNetworkSelection, applyNetworkSelection_fn).call(this); +- await this.lookupNetwork(); + } + /** + * Refreshes the network meta with EIP-1559 support and the network status diff --git a/.yarn/patches/PATCH.txt b/.yarn/patches/PATCH.txt new file mode 100644 index 000000000000..cc75703faaa6 --- /dev/null +++ b/.yarn/patches/PATCH.txt @@ -0,0 +1,6 @@ +@metamask-network-controller-npm-18.0.1-c4d0cfaecd.patch + +We remove lookupNetwork from initializeProvider in the network controller to prevent network requests before user onboarding is completed. +The network lookup is done after onboarding is completed, and when the extension reloads if onboarding has been completed. +This patch is part of a temporary fix that will be reverted soon to make way for a more permanent solution. https://github.com/MetaMask/metamask-extension/pull/23005 +You can see the changes before compilation on this branch: https://github.com/MetaMask/core/compare/pnf/ext-23622-review?expand=1 \ No newline at end of file diff --git a/app/scripts/lib/account-tracker.js b/app/scripts/lib/account-tracker.js index ea772a9d90aa..7de8632e2b74 100644 --- a/app/scripts/lib/account-tracker.js +++ b/app/scripts/lib/account-tracker.js @@ -78,14 +78,6 @@ export default class AccountTracker { this.onboardingController = opts.onboardingController; this.controllerMessenger = opts.controllerMessenger; - // blockTracker.currentBlock may be null - this.#currentBlockNumberByChainId = { - [this.getCurrentChainId()]: this.#blockTracker.getCurrentBlock(), - }; - this.#blockTracker.once('latest', (blockNumber) => { - this.#currentBlockNumberByChainId[this.getCurrentChainId()] = blockNumber; - }); - // subscribe to account removal opts.onAccountRemoved((address) => this.removeAccounts([address])); @@ -124,6 +116,14 @@ export default class AccountTracker { * Starts polling with global selected network */ start() { + // blockTracker.currentBlock may be null + this.#currentBlockNumberByChainId = { + [this.getCurrentChainId()]: this.#blockTracker.getCurrentBlock(), + }; + this.#blockTracker.once('latest', (blockNumber) => { + this.#currentBlockNumberByChainId[this.getCurrentChainId()] = blockNumber; + }); + // remove first to avoid double add this.#blockTracker.removeListener('latest', this.#updateForBlock); // add listener diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 008994eebb31..f1154c01c63b 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -489,7 +489,6 @@ export default class MetamaskController extends EventEmitter { // TODO: Delete when ready to remove `networkVersion` from provider object this.deprecatedNetworkId = null; - this.updateDeprecatedNetworkId(); networkControllerMessenger.subscribe( 'NetworkController:networkDidChange', () => this.updateDeprecatedNetworkId(), @@ -1433,6 +1432,7 @@ export default class MetamaskController extends EventEmitter { const { completedOnboarding: prevCompletedOnboarding } = prevState; const { completedOnboarding: currCompletedOnboarding } = currState; if (!prevCompletedOnboarding && currCompletedOnboarding) { + this.postOnboardingInitialization(); this.triggerNetworkrequests(); } }, this.onboardingController.store.getState()), @@ -1638,7 +1638,6 @@ export default class MetamaskController extends EventEmitter { }, ); - this.networkController.lookupNetwork(); this.decryptMessageController = new DecryptMessageController({ getState: this.getState.bind(this), messenger: this.controllerMessenger.getRestricted({ @@ -2196,6 +2195,15 @@ export default class MetamaskController extends EventEmitter { this.extension.runtime.onMessageExternal.addListener(onMessageReceived); // Fire a ping message to check if other extensions are running checkForMultipleVersionsRunning(); + + if (this.onboardingController.store.getState().completedOnboarding) { + this.postOnboardingInitialization(); + } + } + + postOnboardingInitialization() { + this.updateDeprecatedNetworkId(); + this.networkController.lookupNetwork(); } triggerNetworkrequests() { diff --git a/package.json b/package.json index 3c3fce61bc51..3d7f0c9c4ae6 100644 --- a/package.json +++ b/package.json @@ -231,7 +231,12 @@ "@babel/runtime@npm:^7.4.0": "patch:@babel/runtime@npm%3A7.24.0#~/.yarn/patches/@babel-runtime-npm-7.24.0-7eb1dd11a2.patch", "@babel/runtime@npm:^7.18.3": "patch:@babel/runtime@npm%3A7.24.0#~/.yarn/patches/@babel-runtime-npm-7.24.0-7eb1dd11a2.patch", "@babel/runtime@npm:^7.8.3": "patch:@babel/runtime@npm%3A7.24.0#~/.yarn/patches/@babel-runtime-npm-7.24.0-7eb1dd11a2.patch", - "@babel/runtime@npm:^7.8.4": "patch:@babel/runtime@npm%3A7.24.0#~/.yarn/patches/@babel-runtime-npm-7.24.0-7eb1dd11a2.patch" + "@babel/runtime@npm:^7.8.4": "patch:@babel/runtime@npm%3A7.24.0#~/.yarn/patches/@babel-runtime-npm-7.24.0-7eb1dd11a2.patch", + "@metamask/network-controller@npm:^17.2.0": "patch:@metamask/network-controller@npm%3A18.0.1#~/.yarn/patches/@metamask-network-controller-npm-18.0.1-c4d0cfaecd.patch", + "@metamask/network-controller@npm:^17.0.0": "patch:@metamask/network-controller@npm%3A18.0.1#~/.yarn/patches/@metamask-network-controller-npm-18.0.1-c4d0cfaecd.patch", + "@metamask/network-controller@npm:^15.0.0": "patch:@metamask/network-controller@npm%3A18.0.1#~/.yarn/patches/@metamask-network-controller-npm-18.0.1-c4d0cfaecd.patch", + "@metamask/network-controller@npm:^18.0.1": "patch:@metamask/network-controller@npm%3A18.0.1#~/.yarn/patches/@metamask-network-controller-npm-18.0.1-c4d0cfaecd.patch", + "@metamask/network-controller@npm:^17.2.1": "patch:@metamask/network-controller@npm%3A18.0.1#~/.yarn/patches/@metamask-network-controller-npm-18.0.1-c4d0cfaecd.patch" }, "dependencies": { "@babel/runtime": "patch:@babel/runtime@npm%3A7.24.0#~/.yarn/patches/@babel-runtime-npm-7.24.0-7eb1dd11a2.patch", @@ -293,7 +298,7 @@ "@metamask/message-manager": "^7.3.0", "@metamask/metamask-eth-abis": "^3.0.0", "@metamask/name-controller": "^4.2.0", - "@metamask/network-controller": "^18.0.0", + "@metamask/network-controller": "patch:@metamask/network-controller@npm%3A18.0.1#~/.yarn/patches/@metamask-network-controller-npm-18.0.1-c4d0cfaecd.patch", "@metamask/notification-controller": "^3.0.0", "@metamask/obs-store": "^8.1.0", "@metamask/permission-controller": "^8.0.0", diff --git a/test/e2e/tests/onboarding/onboarding.spec.js b/test/e2e/tests/onboarding/onboarding.spec.js index bcad233470a9..3e6bad3eda65 100644 --- a/test/e2e/tests/onboarding/onboarding.spec.js +++ b/test/e2e/tests/onboarding/onboarding.spec.js @@ -12,6 +12,12 @@ const { locateAccountBalanceDOM, defaultGanacheOptions, WALLET_PASSWORD, + onboardingBeginCreateNewWallet, + onboardingChooseMetametricsOption, + onboardingCreatePassword, + onboardingRevealAndConfirmSRP, + onboardingCompleteWalletCreation, + regularDelayMs, } = require('../../helpers'); const FixtureBuilder = require('../../fixture-builder'); @@ -301,4 +307,140 @@ describe('MetaMask onboarding @no-mmi', function () { }, ); }); + + it("doesn't make any network requests to infura before onboarding is completed", async function () { + async function mockInfura(mockServer) { + const infuraUrl = + 'https://mainnet.infura.io/v3/00000000000000000000000000000000'; + const sampleAddress = '1111111111111111111111111111111111111111'; + + return [ + await mockServer + .forPost(infuraUrl) + .withJsonBodyIncluding({ method: 'eth_blockNumber' }) + .thenCallback(() => { + return { + statusCode: 200, + json: { + jsonrpc: '2.0', + id: '1111111111111111', + result: '0x1', + }, + }; + }), + await mockServer + .forPost(infuraUrl) + .withJsonBodyIncluding({ method: 'eth_getBalance' }) + .thenCallback(() => { + return { + statusCode: 200, + json: { + jsonrpc: '2.0', + id: '1111111111111111', + result: '0x1', + }, + }; + }), + await mockServer + .forPost(infuraUrl) + .withJsonBodyIncluding({ method: 'eth_getBlockByNumber' }) + .thenCallback(() => { + return { + statusCode: 200, + json: { + jsonrpc: '2.0', + id: '1111111111111111', + result: {}, + }, + }; + }), + await mockServer + .forPost(infuraUrl) + .withJsonBodyIncluding({ method: 'eth_call' }) + .thenCallback(() => { + return { + statusCode: 200, + json: { + jsonrpc: '2.0', + id: '1111111111111111', + result: `0x000000000000000000000000${sampleAddress}`, + }, + }; + }), + await mockServer + .forPost(infuraUrl) + .withJsonBodyIncluding({ method: 'net_version' }) + .thenCallback(() => { + return { + statusCode: 200, + json: { id: 8262367391254633, jsonrpc: '2.0', result: '1337' }, + }; + }), + ]; + } + + await withFixtures( + { + fixtures: new FixtureBuilder({ onboarding: true }) + .withNetworkControllerOnMainnet() + .build(), + ganacheOptions: defaultGanacheOptions, + title: this.test.fullTitle(), + testSpecificMock: mockInfura, + }, + async ({ driver, mockedEndpoint: mockedEndpoints }) => { + const password = 'password'; + + await driver.navigate(); + + await onboardingBeginCreateNewWallet(driver); + await onboardingChooseMetametricsOption(driver, false); + await onboardingCreatePassword(driver, password); + await onboardingRevealAndConfirmSRP(driver); + await onboardingCompleteWalletCreation(driver); + + // pin extension walkthrough screen + await driver.clickElement('[data-testid="pin-extension-next"]'); + + await driver.delay(regularDelayMs); + + for (let i = 0; i < mockedEndpoints.length; i += 1) { + const mockedEndpoint = await mockedEndpoints[i]; + const isPending = await mockedEndpoint.isPending(); + assert.equal( + isPending, + true, + `${mockedEndpoints[i]} mock should still be pending before onboarding`, + ); + const requests = await mockedEndpoint.getSeenRequests(); + + assert.equal( + requests.length, + 0, + `${mockedEndpoints[i]} should make no requests before onboarding`, + ); + } + + await driver.clickElement('[data-testid="pin-extension-done"]'); + // requests happen here! + + for (let i = 0; i < mockedEndpoints.length; i += 1) { + const mockedEndpoint = await mockedEndpoints[i]; + + await driver.wait(async () => { + const isPending = await mockedEndpoint.isPending(); + return isPending === false; + }, driver.timeout); + + const requests = await mockedEndpoint.getSeenRequests(); + + assert.equal( + requests.length > 0, + true, + `${mockedEndpoints[i]} should make requests after onboarding`, + ); + } + }, + ); + }); }); diff --git a/ui/pages/routes/routes.component.js b/ui/pages/routes/routes.component.js index 83ee52b5b232..1ab110fcf66b 100644 --- a/ui/pages/routes/routes.component.js +++ b/ui/pages/routes/routes.component.js @@ -640,11 +640,12 @@ export default class Routes extends Component { isUnlocked && !shouldShowSeedPhraseReminder; - let isLoadingShown = isLoading; + let isLoadingShown = isLoading && completedOnboarding; ///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps) isLoadingShown = isLoading && + completedOnboarding && !pendingConfirmations.some( (confirmation) => confirmation.type === @@ -707,7 +708,9 @@ export default class Routes extends Component { } {isLoadingShown ? : null} - {!isLoading && isNetworkLoading ? : null} + {!isLoading && isNetworkLoading && completedOnboarding ? ( + + ) : null} {this.renderRoutes()} {isUnlocked ? : null} diff --git a/yarn.lock b/yarn.lock index 3498ef92f90c..cd9b36ba5bc8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4054,7 +4054,7 @@ __metadata: languageName: node linkType: hard -"@metamask/base-controller@npm:^3.0.0, @metamask/base-controller@npm:^3.2.1, @metamask/base-controller@npm:^3.2.3": +"@metamask/base-controller@npm:^3.0.0, @metamask/base-controller@npm:^3.2.1": version: 3.2.3 resolution: "@metamask/base-controller@npm:3.2.3" dependencies: @@ -4125,7 +4125,7 @@ __metadata: languageName: node linkType: hard -"@metamask/controller-utils@npm:^5.0.0, @metamask/controller-utils@npm:^5.0.2": +"@metamask/controller-utils@npm:^5.0.0": version: 5.0.2 resolution: "@metamask/controller-utils@npm:5.0.2" dependencies: @@ -4306,7 +4306,7 @@ __metadata: languageName: node linkType: hard -"@metamask/eth-json-rpc-infura@npm:^9.0.0, @metamask/eth-json-rpc-infura@npm:^9.1.0": +"@metamask/eth-json-rpc-infura@npm:^9.1.0": version: 9.1.0 resolution: "@metamask/eth-json-rpc-infura@npm:9.1.0" dependencies: @@ -4319,7 +4319,7 @@ __metadata: languageName: node linkType: hard -"@metamask/eth-json-rpc-middleware@npm:^12.0.1, @metamask/eth-json-rpc-middleware@npm:^12.1.0": +"@metamask/eth-json-rpc-middleware@npm:^12.1.0": version: 12.1.0 resolution: "@metamask/eth-json-rpc-middleware@npm:12.1.0" dependencies: @@ -4336,7 +4336,7 @@ __metadata: languageName: node linkType: hard -"@metamask/eth-json-rpc-provider@npm:^2.1.0, @metamask/eth-json-rpc-provider@npm:^2.2.0, @metamask/eth-json-rpc-provider@npm:^2.3.2": +"@metamask/eth-json-rpc-provider@npm:^2.1.0": version: 2.3.2 resolution: "@metamask/eth-json-rpc-provider@npm:2.3.2" dependencies: @@ -4663,7 +4663,7 @@ __metadata: languageName: node linkType: hard -"@metamask/json-rpc-engine@npm:^7.1.0, @metamask/json-rpc-engine@npm:^7.1.1, @metamask/json-rpc-engine@npm:^7.2.0, @metamask/json-rpc-engine@npm:^7.3.1, @metamask/json-rpc-engine@npm:^7.3.2, @metamask/json-rpc-engine@npm:^7.3.3": +"@metamask/json-rpc-engine@npm:^7.1.0, @metamask/json-rpc-engine@npm:^7.1.1, @metamask/json-rpc-engine@npm:^7.3.1, @metamask/json-rpc-engine@npm:^7.3.2, @metamask/json-rpc-engine@npm:^7.3.3": version: 7.3.3 resolution: "@metamask/json-rpc-engine@npm:7.3.3" dependencies: @@ -4870,39 +4870,17 @@ __metadata: languageName: node linkType: hard -"@metamask/network-controller@npm:^15.0.0": - version: 15.2.0 - resolution: "@metamask/network-controller@npm:15.2.0" - dependencies: - "@metamask/base-controller": "npm:^3.2.3" - "@metamask/controller-utils": "npm:^5.0.2" - "@metamask/eth-json-rpc-infura": "npm:^9.0.0" - "@metamask/eth-json-rpc-middleware": "npm:^12.0.1" - "@metamask/eth-json-rpc-provider": "npm:^2.2.0" - "@metamask/eth-query": "npm:^3.0.1" - "@metamask/json-rpc-engine": "npm:^7.2.0" - "@metamask/rpc-errors": "npm:^6.1.0" - "@metamask/swappable-obj-proxy": "npm:^2.1.0" - "@metamask/utils": "npm:^8.2.0" - async-mutex: "npm:^0.2.6" - eth-block-tracker: "npm:^8.0.0" - immer: "npm:^9.0.6" - uuid: "npm:^8.3.2" - checksum: d23cb3a60bd2dbb3662c0717054becc11bfc7367768326b7f9ed8bd7f8f1dd9716ca7b2fd5e00daa008cab0bcc916eea9dd1c06b2392846b304fad35f39196aa - languageName: node - linkType: hard - -"@metamask/network-controller@npm:^17.0.0, @metamask/network-controller@npm:^17.2.0, @metamask/network-controller@npm:^17.2.1": - version: 17.2.1 - resolution: "@metamask/network-controller@npm:17.2.1" +"@metamask/network-controller@npm:18.0.1": + version: 18.0.1 + resolution: "@metamask/network-controller@npm:18.0.1" dependencies: - "@metamask/base-controller": "npm:^4.1.1" - "@metamask/controller-utils": "npm:^8.0.4" - "@metamask/eth-json-rpc-infura": "npm:^9.0.0" + "@metamask/base-controller": "npm:^5.0.1" + "@metamask/controller-utils": "npm:^9.0.1" + "@metamask/eth-json-rpc-infura": "npm:^9.1.0" "@metamask/eth-json-rpc-middleware": "npm:^12.1.0" - "@metamask/eth-json-rpc-provider": "npm:^2.3.2" + "@metamask/eth-json-rpc-provider": "npm:^3.0.1" "@metamask/eth-query": "npm:^4.0.0" - "@metamask/json-rpc-engine": "npm:^7.3.3" + "@metamask/json-rpc-engine": "npm:^8.0.1" "@metamask/rpc-errors": "npm:^6.2.1" "@metamask/swappable-obj-proxy": "npm:^2.2.0" "@metamask/utils": "npm:^8.3.0" @@ -4910,13 +4888,13 @@ __metadata: eth-block-tracker: "npm:^8.0.0" immer: "npm:^9.0.6" uuid: "npm:^8.3.2" - checksum: be3f6549756229033dafd5ac9c746607c757d5702d1ba76beb818ec7cb85805f975c38be822934694ddc6e285f9b28a1caadf2cbf88469b00262beedbff2b8e8 + checksum: 70f06c231977e9215b1b81216a6cabcff5e928df9524f8889079bbc21657bb4c2167ebb20758d31c6cc859647d5d01d5a1022af2590b9d7fbe69ec5bfe71b099 languageName: node linkType: hard -"@metamask/network-controller@npm:^18.0.0, @metamask/network-controller@npm:^18.0.1": +"@metamask/network-controller@patch:@metamask/network-controller@npm%3A18.0.1#~/.yarn/patches/@metamask-network-controller-npm-18.0.1-c4d0cfaecd.patch": version: 18.0.1 - resolution: "@metamask/network-controller@npm:18.0.1" + resolution: "@metamask/network-controller@patch:@metamask/network-controller@npm%3A18.0.1#~/.yarn/patches/@metamask-network-controller-npm-18.0.1-c4d0cfaecd.patch::version=18.0.1&hash=be87e4" dependencies: "@metamask/base-controller": "npm:^5.0.1" "@metamask/controller-utils": "npm:^9.0.1" @@ -4932,7 +4910,7 @@ __metadata: eth-block-tracker: "npm:^8.0.0" immer: "npm:^9.0.6" uuid: "npm:^8.3.2" - checksum: 70f06c231977e9215b1b81216a6cabcff5e928df9524f8889079bbc21657bb4c2167ebb20758d31c6cc859647d5d01d5a1022af2590b9d7fbe69ec5bfe71b099 + checksum: 348114ad32db34d4a197422f57f0f394442d1b7a2c79249768b6b061ce64ea0cf6a39d23b743075ef6b8d5778243545061f11aa74d839ec58c14f0386ed96598 languageName: node linkType: hard @@ -5596,7 +5574,7 @@ __metadata: languageName: node linkType: hard -"@metamask/swappable-obj-proxy@npm:^2.1.0, @metamask/swappable-obj-proxy@npm:^2.2.0": +"@metamask/swappable-obj-proxy@npm:^2.2.0": version: 2.2.0 resolution: "@metamask/swappable-obj-proxy@npm:2.2.0" checksum: bc7a1f496d06327f1db84fe2ed75637b6f2f5db0806d3927f250d5abab9cc70a26ff37283ea7f2db7987e48d2540f6821091d1f3000d6771f29c4d91c402f724 @@ -24743,7 +24721,7 @@ __metadata: "@metamask/message-manager": "npm:^7.3.0" "@metamask/metamask-eth-abis": "npm:^3.0.0" "@metamask/name-controller": "npm:^4.2.0" - "@metamask/network-controller": "npm:^18.0.0" + "@metamask/network-controller": "patch:@metamask/network-controller@npm%3A18.0.1#~/.yarn/patches/@metamask-network-controller-npm-18.0.1-c4d0cfaecd.patch" "@metamask/notification-controller": "npm:^3.0.0" "@metamask/obs-store": "npm:^8.1.0" "@metamask/permission-controller": "npm:^8.0.0"