From c2a29343a806b811b9c3d2918d7728b70cec3114 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 9 Oct 2025 10:55:49 +0200 Subject: [PATCH 01/25] feat: add SnapKeyring.setSelectedAccounts support --- app/scripts/metamask-controller.js | 40 ++++++++++++++- package.json | 9 +++- yarn.lock | 81 ++++++++++++++++-------------- 3 files changed, 89 insertions(+), 41 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index fa00a71d24e2..9b86a944658a 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1518,6 +1518,24 @@ export default class MetamaskController extends EventEmitter { } return snapKeyring; } + + /** + * Forward currently selected account group to the Snap keyring. + * + * @param groupId - Currently selected account group. + */ + async forwardSelectedAccountGroupToSnapKeyring(groupId) { + console.log('-- SnapKeyring -- forwarding'); + if (groupId) { + const group = this.accountTreeController.getAccountGroupObject(groupId); + if (group) { + const snapKeyring = await this.getSnapKeyring(); + + console.log('-- SnapKeyring.setSelectedAccounts', group.accounts); + snapKeyring.setSelectedAccounts(group.accounts); + } + } + } ///: END:ONLY_INCLUDE_IF trackInsightSnapView(snapId) { @@ -1822,7 +1840,12 @@ export default class MetamaskController extends EventEmitter { // wallet_notify for solana accountChanged when selected account group changes this.controllerMessenger.subscribe( `${this.accountTreeController.name}:selectedAccountGroupChange`, - () => { + (groupId) => { + // TODO: Move this logic to the SnapKeyring directly. + // Forward selected accounts to the Snap keyring, so each Snaps can fetch those accounts. + // eslint-disable-next-line no-void + void this.forwardSelectedAccountGroupToSnapKeyring(groupId); + const [account] = this.accountTreeController.getAccountsFromSelectedAccountGroup({ scopes: [SolScope.Mainnet], @@ -4237,6 +4260,11 @@ export default class MetamaskController extends EventEmitter { await this.accountsController.updateAccounts(); // Then we can build the initial tree. this.accountTreeController.init(); + // TODO: Move this logic to the SnapKeyring directly. + // Forward selected accounts to the Snap keyring, so each Snaps can fetch those accounts. + await this.forwardSelectedAccountGroupToSnapKeyring( + this.accountTreeController.getSelectedAccountGroup(), + ); return primaryKeyring; } finally { @@ -4620,6 +4648,11 @@ export default class MetamaskController extends EventEmitter { // TODO: Remove this once the `accounts-controller` once only // depends only on keyrings `:stateChange`. this.accountTreeController.reinit(); + // TODO: Move this logic to the SnapKeyring directly. + // Forward selected accounts to the Snap keyring, so each Snaps can fetch those accounts. + await this.forwardSelectedAccountGroupToSnapKeyring( + this.accountTreeController.getSelectedAccountGroup(), + ); if (completedOnboarding) { if (this.isMultichainAccountsFeatureState2Enabled()) { @@ -4974,6 +5007,11 @@ export default class MetamaskController extends EventEmitter { ///: END:ONLY_INCLUDE_IF // Force account-tree refresh after all accounts have been updated. this.accountTreeController.init(); + // TODO: Move this logic to the SnapKeyring directly. + // Forward selected accounts to the Snap keyring, so each Snaps can fetch those accounts. + await this.forwardSelectedAccountGroupToSnapKeyring( + this.accountTreeController.getSelectedAccountGroup(), + ); } async _loginUser(password) { diff --git a/package.json b/package.json index 2675bc0cc788..a0f1574bf85c 100644 --- a/package.json +++ b/package.json @@ -243,7 +243,14 @@ "@endo/env-options@npm:^1.1.8": "patch:@endo/env-options@npm%3A1.1.11#~/.yarn/patches/@endo-env-options-npm-1.1.11-1b7fae374a.patch", "@metamask/jazzicon@npm:^2.0.0": "patch:@metamask/jazzicon@npm%3A2.0.0#~/.yarn/patches/@metamask-jazzicon-npm-2.0.0-36957be38d.patch", "lavamoat-core@npm:^15.2.1": "patch:lavamoat-core@npm%3A16.7.1#~/.yarn/patches/lavamoat-core-npm-16.7.1-9dcb956c6f.patch", - "lavamoat-core@npm:^16.7.1": "patch:lavamoat-core@npm%3A16.7.1#~/.yarn/patches/lavamoat-core-npm-16.7.1-9dcb956c6f.patch" + "lavamoat-core@npm:^16.7.1": "patch:lavamoat-core@npm%3A16.7.1#~/.yarn/patches/lavamoat-core-npm-16.7.1-9dcb956c6f.patch", + "@metamask/keyring-api@^21.0.0": "npm:@metamask-previews/keyring-api@21.0.0-582d075", + "@metamask/keyring-api@21.0.0": "npm:@metamask-previews/keyring-api@21.0.0-582d075", + "@metamask/keyring-api@^20.0.0": "npm:@metamask-previews/keyring-api@21.0.0-582d075", + "@metamask/keyring-api@^20.1.0": "npm:@metamask-previews/keyring-api@21.0.0-582d075", + "@metamask/eth-snap-keyring@^17.2.0": "npm:@metamask-previews/eth-snap-keyring@17.2.0-582d075", + "@metamask/eth-snap-keyring@^17.1.0": "npm:@metamask-previews/eth-snap-keyring@17.2.0-582d075", + "@metamask/eth-snap-keyring@^17.0.0": "npm:@metamask-previews/eth-snap-keyring@17.2.0-582d075" }, "dependencies": { "@babel/runtime": "patch:@babel/runtime@npm%3A7.25.9#~/.yarn/patches/@babel-runtime-npm-7.25.9-fe8c62510a.patch", diff --git a/yarn.lock b/yarn.lock index e8d3f9bdf1db..6ba1a45a3879 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6154,24 +6154,23 @@ __metadata: languageName: node linkType: hard -"@metamask/eth-snap-keyring@npm:^17.0.0, @metamask/eth-snap-keyring@npm:^17.2.0": - version: 17.2.0 - resolution: "@metamask/eth-snap-keyring@npm:17.2.0" +"@metamask/eth-snap-keyring@npm:@metamask-previews/eth-snap-keyring@17.2.0-582d075": + version: 17.2.0-582d075 + resolution: "@metamask-previews/eth-snap-keyring@npm:17.2.0-582d075" dependencies: "@ethereumjs/tx": "npm:^5.4.0" "@metamask/base-controller": "npm:^8.3.0" "@metamask/eth-sig-util": "npm:^8.2.0" - "@metamask/keyring-api": "npm:^21.0.0" - "@metamask/keyring-internal-api": "npm:^9.0.0" - "@metamask/keyring-internal-snap-client": "npm:^7.1.0" - "@metamask/keyring-utils": "npm:^3.1.0" + "@metamask/keyring-api": "npm:21.0.0" + "@metamask/keyring-internal-api": "npm:9.0.0" + "@metamask/keyring-internal-snap-client": "npm:7.1.0" + "@metamask/keyring-snap-sdk": "npm:7.0.0" + "@metamask/keyring-utils": "npm:3.1.0" "@metamask/superstruct": "npm:^3.1.0" "@metamask/utils": "npm:^11.1.0" "@types/uuid": "npm:^9.0.8" uuid: "npm:^9.0.1" - peerDependencies: - "@metamask/keyring-api": ^21.0.0 - checksum: 10/5ef553d895fb1416fee5dafa8424d0d3770ab4271924902f50c3f03652b5e6104aa60cbdaf3a37fdb9cbba4fe86bc3b87ce589f5d14d1b2b8cd671b420a2c922 + checksum: 10/3073182aeaa606f892bd813865f6517db8c55ae5f7b356be2d9aae49b0f5450fab6037d4f5b8802705bd770d35a68c9170d70c0eafa48585e16aadd839a986e0 languageName: node linkType: hard @@ -6546,27 +6545,15 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-api@npm:^20.0.0, @metamask/keyring-api@npm:^20.1.0": - version: 20.1.1 - resolution: "@metamask/keyring-api@npm:20.1.1" +"@metamask/keyring-api@npm:@metamask-previews/keyring-api@21.0.0-582d075": + version: 21.0.0-582d075 + resolution: "@metamask-previews/keyring-api@npm:21.0.0-582d075" dependencies: - "@metamask/keyring-utils": "npm:^3.1.0" + "@metamask/keyring-utils": "npm:3.1.0" "@metamask/superstruct": "npm:^3.1.0" "@metamask/utils": "npm:^11.1.0" bitcoin-address-validation: "npm:^2.2.3" - checksum: 10/f261205687c9aa1c39a2221e30a6edd4f530d2b0afd86a8ab13ea23d2af2a0bf1c89a8c4ad5646368e3b06909613d64195c335063319edd018636c9fa6ee63ee - languageName: node - linkType: hard - -"@metamask/keyring-api@npm:^21.0.0": - version: 21.0.0 - resolution: "@metamask/keyring-api@npm:21.0.0" - dependencies: - "@metamask/keyring-utils": "npm:^3.1.0" - "@metamask/superstruct": "npm:^3.1.0" - "@metamask/utils": "npm:^11.1.0" - bitcoin-address-validation: "npm:^2.2.3" - checksum: 10/896f3f54080f0a450d47df63bfae93d2dd4e7e1bb8aa35c365e46ea6fd32c3fa27753611de095e9f6feae5d526e911e665628c8b304cb2120cb870f2e82ab095 + checksum: 10/080b54871a315e8b02ed73a7d4ff5aabf7291c87a7913d0a4eea6ee8e70648e53b50af7d3fbddf255121e2326afb86130e546b2431c2d478ac3ebc4ec3aaebce languageName: node linkType: hard @@ -6592,29 +6579,29 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-internal-api@npm:^8.1.0": - version: 8.1.0 - resolution: "@metamask/keyring-internal-api@npm:8.1.0" +"@metamask/keyring-internal-api@npm:9.0.0, @metamask/keyring-internal-api@npm:^9.0.0": + version: 9.0.0 + resolution: "@metamask/keyring-internal-api@npm:9.0.0" dependencies: - "@metamask/keyring-api": "npm:^20.1.0" + "@metamask/keyring-api": "npm:^21.0.0" "@metamask/keyring-utils": "npm:^3.1.0" "@metamask/superstruct": "npm:^3.1.0" - checksum: 10/0fb615821a822de914b95a6b9678a1fc72f7f22b4ec694382977b0212e27ee5199887bd5112ea964e9bdd1aab1ba1a9e1ce3d9fd36957dc8ff8cf7c2f7003865 + checksum: 10/2603a3ffa42d53d2c621846288e759e9df2062fb6d46444466062915dbeda5fb3ec5344a48c1d282d37c6a689d7332e953c955be93f10e4bd56879c29ca2bf26 languageName: node linkType: hard -"@metamask/keyring-internal-api@npm:^9.0.0": - version: 9.0.0 - resolution: "@metamask/keyring-internal-api@npm:9.0.0" +"@metamask/keyring-internal-api@npm:^8.1.0": + version: 8.1.0 + resolution: "@metamask/keyring-internal-api@npm:8.1.0" dependencies: - "@metamask/keyring-api": "npm:^21.0.0" + "@metamask/keyring-api": "npm:^20.1.0" "@metamask/keyring-utils": "npm:^3.1.0" "@metamask/superstruct": "npm:^3.1.0" - checksum: 10/2603a3ffa42d53d2c621846288e759e9df2062fb6d46444466062915dbeda5fb3ec5344a48c1d282d37c6a689d7332e953c955be93f10e4bd56879c29ca2bf26 + checksum: 10/0fb615821a822de914b95a6b9678a1fc72f7f22b4ec694382977b0212e27ee5199887bd5112ea964e9bdd1aab1ba1a9e1ce3d9fd36957dc8ff8cf7c2f7003865 languageName: node linkType: hard -"@metamask/keyring-internal-snap-client@npm:^7.0.0, @metamask/keyring-internal-snap-client@npm:^7.1.0": +"@metamask/keyring-internal-snap-client@npm:7.1.0, @metamask/keyring-internal-snap-client@npm:^7.0.0": version: 7.1.0 resolution: "@metamask/keyring-internal-snap-client@npm:7.1.0" dependencies: @@ -6659,7 +6646,23 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-utils@npm:^3.1.0": +"@metamask/keyring-snap-sdk@npm:7.0.0": + version: 7.0.0 + resolution: "@metamask/keyring-snap-sdk@npm:7.0.0" + dependencies: + "@metamask/keyring-utils": "npm:^3.1.0" + "@metamask/snaps-sdk": "npm:^9.0.0" + "@metamask/superstruct": "npm:^3.1.0" + "@metamask/utils": "npm:^11.1.0" + webextension-polyfill: "npm:^0.12.0" + peerDependencies: + "@metamask/keyring-api": ^21.0.0 + "@metamask/providers": ^19.0.0 + checksum: 10/420e4a77bfec8600026b9862dda316764f19cea3ce5990a3bca6b7c8985009f5862446f1ca5ce82266e606ae77e582b03327cf09397774eb47ddb1d631066ae9 + languageName: node + linkType: hard + +"@metamask/keyring-utils@npm:3.1.0, @metamask/keyring-utils@npm:^3.1.0": version: 3.1.0 resolution: "@metamask/keyring-utils@npm:3.1.0" dependencies: From 51b18e7325476ec593c3b800febd78af1a580f4c Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 9 Oct 2025 11:17:49 +0200 Subject: [PATCH 02/25] fix: fix resolutions --- package.json | 1 + yarn.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index a0f1574bf85c..0146782ed530 100644 --- a/package.json +++ b/package.json @@ -248,6 +248,7 @@ "@metamask/keyring-api@21.0.0": "npm:@metamask-previews/keyring-api@21.0.0-582d075", "@metamask/keyring-api@^20.0.0": "npm:@metamask-previews/keyring-api@21.0.0-582d075", "@metamask/keyring-api@^20.1.0": "npm:@metamask-previews/keyring-api@21.0.0-582d075", + "@metamask/keyring-snap-sdk@7.0.0": "npm:@metamask-previews/keyring-snap-sdk@7.0.0-582d075", "@metamask/eth-snap-keyring@^17.2.0": "npm:@metamask-previews/eth-snap-keyring@17.2.0-582d075", "@metamask/eth-snap-keyring@^17.1.0": "npm:@metamask-previews/eth-snap-keyring@17.2.0-582d075", "@metamask/eth-snap-keyring@^17.0.0": "npm:@metamask-previews/eth-snap-keyring@17.2.0-582d075" diff --git a/yarn.lock b/yarn.lock index 6ba1a45a3879..8ad1908fcc95 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6646,19 +6646,19 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-snap-sdk@npm:7.0.0": - version: 7.0.0 - resolution: "@metamask/keyring-snap-sdk@npm:7.0.0" +"@metamask/keyring-snap-sdk@npm:@metamask-previews/keyring-snap-sdk@7.0.0-582d075": + version: 7.0.0-582d075 + resolution: "@metamask-previews/keyring-snap-sdk@npm:7.0.0-582d075" dependencies: - "@metamask/keyring-utils": "npm:^3.1.0" + "@metamask/keyring-api": "npm:21.0.0" + "@metamask/keyring-utils": "npm:3.1.0" "@metamask/snaps-sdk": "npm:^9.0.0" "@metamask/superstruct": "npm:^3.1.0" "@metamask/utils": "npm:^11.1.0" webextension-polyfill: "npm:^0.12.0" peerDependencies: - "@metamask/keyring-api": ^21.0.0 "@metamask/providers": ^19.0.0 - checksum: 10/420e4a77bfec8600026b9862dda316764f19cea3ce5990a3bca6b7c8985009f5862446f1ca5ce82266e606ae77e582b03327cf09397774eb47ddb1d631066ae9 + checksum: 10/26a832653bdea452599a0f02e0104d844f34b6621e7ef5ff09be0f4057ccc4635c4f85bfbf7296346bab079c25fe73f826f079153a6a9ae10d16ebe31b7e4a58 languageName: node linkType: hard From 4485369a7ea9ccd6eaa5453d3e7eb48602d99432 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 9 Oct 2025 11:39:17 +0200 Subject: [PATCH 03/25] fix: fix resolutions --- package.json | 4 ++++ yarn.lock | 38 +++++++++++++++++++------------------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index 0146782ed530..c7f4146afb23 100644 --- a/package.json +++ b/package.json @@ -249,6 +249,10 @@ "@metamask/keyring-api@^20.0.0": "npm:@metamask-previews/keyring-api@21.0.0-582d075", "@metamask/keyring-api@^20.1.0": "npm:@metamask-previews/keyring-api@21.0.0-582d075", "@metamask/keyring-snap-sdk@7.0.0": "npm:@metamask-previews/keyring-snap-sdk@7.0.0-582d075", + "@metamask/keyring-snap-client@^7.0.0": "npm:@metamask-previews/keyring-snap-client@8.0.0-582d075", + "@metamask/keyring-snap-client@^8.0.0": "npm:@metamask-previews/keyring-snap-client@8.0.0-582d075", + "@metamask/keyring-internal-snap-client@^7.0.0": "npm:@metamask-previews/keyring-internal-snap-client@7.1.0-582d075", + "@metamask/keyring-internal-snap-client@7.1.0": "npm:@metamask-previews/keyring-internal-snap-client@7.1.0-582d075", "@metamask/eth-snap-keyring@^17.2.0": "npm:@metamask-previews/eth-snap-keyring@17.2.0-582d075", "@metamask/eth-snap-keyring@^17.1.0": "npm:@metamask-previews/eth-snap-keyring@17.2.0-582d075", "@metamask/eth-snap-keyring@^17.0.0": "npm:@metamask-previews/eth-snap-keyring@17.2.0-582d075" diff --git a/yarn.lock b/yarn.lock index 8ad1908fcc95..6dc4707b97fa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6601,24 +6601,24 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-internal-snap-client@npm:7.1.0, @metamask/keyring-internal-snap-client@npm:^7.0.0": - version: 7.1.0 - resolution: "@metamask/keyring-internal-snap-client@npm:7.1.0" +"@metamask/keyring-internal-snap-client@npm:@metamask-previews/keyring-internal-snap-client@7.1.0-582d075": + version: 7.1.0-582d075 + resolution: "@metamask-previews/keyring-internal-snap-client@npm:7.1.0-582d075" dependencies: "@metamask/base-controller": "npm:^8.3.0" - "@metamask/keyring-api": "npm:^21.0.0" - "@metamask/keyring-internal-api": "npm:^9.0.0" - "@metamask/keyring-snap-client": "npm:^8.0.0" - "@metamask/keyring-utils": "npm:^3.1.0" - checksum: 10/4ac11ecbcf9394de606e35e4b3b666026c6eecf8885ae2ee2185c3a5fa26065e3905374343f8cc2b89c2f9ef0d2519be2cabaec7315b2c15fcd583e353c211df + "@metamask/keyring-api": "npm:21.0.0" + "@metamask/keyring-internal-api": "npm:9.0.0" + "@metamask/keyring-snap-client": "npm:8.0.0" + "@metamask/keyring-utils": "npm:3.1.0" + checksum: 10/ce6cd196ca6cc4e0e2647057be4631a7dde296ca7884b8fbe74acb58fdf1c30452633db6e040d384c4f43173535a8e318e777db5fc8133de6bf7c6e9a2ca24f8 languageName: node linkType: hard -"@metamask/keyring-snap-client@npm:^7.0.0": - version: 7.0.0 - resolution: "@metamask/keyring-snap-client@npm:7.0.0" +"@metamask/keyring-snap-client@npm:8.0.0": + version: 8.0.0 + resolution: "@metamask/keyring-snap-client@npm:8.0.0" dependencies: - "@metamask/keyring-api": "npm:^20.0.0" + "@metamask/keyring-api": "npm:^21.0.0" "@metamask/keyring-utils": "npm:^3.1.0" "@metamask/superstruct": "npm:^3.1.0" "@types/uuid": "npm:^9.0.8" @@ -6626,23 +6626,23 @@ __metadata: webextension-polyfill: "npm:^0.12.0" peerDependencies: "@metamask/providers": ^19.0.0 - checksum: 10/c82a46f61dc211eae6b7b36dd4e8d01b3508217b9a1004e92b361a08025ae88162458ddbddf443bb2b7dab1b2c5bfd95060ec80d5411be7c148bd5703e14858e + checksum: 10/f8735df636554f6c4c387126e033dcca7952f9278cadcaedb693a9ced5402ed21f6a64b14892b65b41b14facf9c6579b477b7fe42d8c602600d5d189206ce377 languageName: node linkType: hard -"@metamask/keyring-snap-client@npm:^8.0.0": - version: 8.0.0 - resolution: "@metamask/keyring-snap-client@npm:8.0.0" +"@metamask/keyring-snap-client@npm:@metamask-previews/keyring-snap-client@8.0.0-582d075": + version: 8.0.0-582d075 + resolution: "@metamask-previews/keyring-snap-client@npm:8.0.0-582d075" dependencies: - "@metamask/keyring-api": "npm:^21.0.0" - "@metamask/keyring-utils": "npm:^3.1.0" + "@metamask/keyring-api": "npm:21.0.0" + "@metamask/keyring-utils": "npm:3.1.0" "@metamask/superstruct": "npm:^3.1.0" "@types/uuid": "npm:^9.0.8" uuid: "npm:^9.0.1" webextension-polyfill: "npm:^0.12.0" peerDependencies: "@metamask/providers": ^19.0.0 - checksum: 10/f8735df636554f6c4c387126e033dcca7952f9278cadcaedb693a9ced5402ed21f6a64b14892b65b41b14facf9c6579b477b7fe42d8c602600d5d189206ce377 + checksum: 10/e8564f6c49fa1b823edfd883c505187ced688767f34a9f752324bef235946375fca8345f5c1dff713bfd88ab81f8f3b8154d2bb6849205fbc266f2dc32661e2d languageName: node linkType: hard From c9b25b145f28ad75d27c853b6270bf3bcf6c3045 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 9 Oct 2025 11:59:11 +0200 Subject: [PATCH 04/25] fix: fix resolutions --- package.json | 1 + yarn.lock | 16 ---------------- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/package.json b/package.json index c7f4146afb23..80a7ddf610e7 100644 --- a/package.json +++ b/package.json @@ -251,6 +251,7 @@ "@metamask/keyring-snap-sdk@7.0.0": "npm:@metamask-previews/keyring-snap-sdk@7.0.0-582d075", "@metamask/keyring-snap-client@^7.0.0": "npm:@metamask-previews/keyring-snap-client@8.0.0-582d075", "@metamask/keyring-snap-client@^8.0.0": "npm:@metamask-previews/keyring-snap-client@8.0.0-582d075", + "@metamask/keyring-snap-client@8.0.0": "npm:@metamask-previews/keyring-snap-client@8.0.0-582d075", "@metamask/keyring-internal-snap-client@^7.0.0": "npm:@metamask-previews/keyring-internal-snap-client@7.1.0-582d075", "@metamask/keyring-internal-snap-client@7.1.0": "npm:@metamask-previews/keyring-internal-snap-client@7.1.0-582d075", "@metamask/eth-snap-keyring@^17.2.0": "npm:@metamask-previews/eth-snap-keyring@17.2.0-582d075", diff --git a/yarn.lock b/yarn.lock index 6dc4707b97fa..bef37e64463c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6614,22 +6614,6 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-snap-client@npm:8.0.0": - version: 8.0.0 - resolution: "@metamask/keyring-snap-client@npm:8.0.0" - dependencies: - "@metamask/keyring-api": "npm:^21.0.0" - "@metamask/keyring-utils": "npm:^3.1.0" - "@metamask/superstruct": "npm:^3.1.0" - "@types/uuid": "npm:^9.0.8" - uuid: "npm:^9.0.1" - webextension-polyfill: "npm:^0.12.0" - peerDependencies: - "@metamask/providers": ^19.0.0 - checksum: 10/f8735df636554f6c4c387126e033dcca7952f9278cadcaedb693a9ced5402ed21f6a64b14892b65b41b14facf9c6579b477b7fe42d8c602600d5d189206ce377 - languageName: node - linkType: hard - "@metamask/keyring-snap-client@npm:@metamask-previews/keyring-snap-client@8.0.0-582d075": version: 8.0.0-582d075 resolution: "@metamask-previews/keyring-snap-client@npm:8.0.0-582d075" From 2eef13518e6309b90bc3d50af83f430727917a1d Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 9 Oct 2025 14:00:34 +0200 Subject: [PATCH 05/25] chore: remove use of preview builds --- package.json | 25 +++------- yarn.lock | 133 +++++++++++++++++++++++++++++++++------------------ 2 files changed, 93 insertions(+), 65 deletions(-) diff --git a/package.json b/package.json index 80a7ddf610e7..f72d0d04fe12 100644 --- a/package.json +++ b/package.json @@ -243,20 +243,7 @@ "@endo/env-options@npm:^1.1.8": "patch:@endo/env-options@npm%3A1.1.11#~/.yarn/patches/@endo-env-options-npm-1.1.11-1b7fae374a.patch", "@metamask/jazzicon@npm:^2.0.0": "patch:@metamask/jazzicon@npm%3A2.0.0#~/.yarn/patches/@metamask-jazzicon-npm-2.0.0-36957be38d.patch", "lavamoat-core@npm:^15.2.1": "patch:lavamoat-core@npm%3A16.7.1#~/.yarn/patches/lavamoat-core-npm-16.7.1-9dcb956c6f.patch", - "lavamoat-core@npm:^16.7.1": "patch:lavamoat-core@npm%3A16.7.1#~/.yarn/patches/lavamoat-core-npm-16.7.1-9dcb956c6f.patch", - "@metamask/keyring-api@^21.0.0": "npm:@metamask-previews/keyring-api@21.0.0-582d075", - "@metamask/keyring-api@21.0.0": "npm:@metamask-previews/keyring-api@21.0.0-582d075", - "@metamask/keyring-api@^20.0.0": "npm:@metamask-previews/keyring-api@21.0.0-582d075", - "@metamask/keyring-api@^20.1.0": "npm:@metamask-previews/keyring-api@21.0.0-582d075", - "@metamask/keyring-snap-sdk@7.0.0": "npm:@metamask-previews/keyring-snap-sdk@7.0.0-582d075", - "@metamask/keyring-snap-client@^7.0.0": "npm:@metamask-previews/keyring-snap-client@8.0.0-582d075", - "@metamask/keyring-snap-client@^8.0.0": "npm:@metamask-previews/keyring-snap-client@8.0.0-582d075", - "@metamask/keyring-snap-client@8.0.0": "npm:@metamask-previews/keyring-snap-client@8.0.0-582d075", - "@metamask/keyring-internal-snap-client@^7.0.0": "npm:@metamask-previews/keyring-internal-snap-client@7.1.0-582d075", - "@metamask/keyring-internal-snap-client@7.1.0": "npm:@metamask-previews/keyring-internal-snap-client@7.1.0-582d075", - "@metamask/eth-snap-keyring@^17.2.0": "npm:@metamask-previews/eth-snap-keyring@17.2.0-582d075", - "@metamask/eth-snap-keyring@^17.1.0": "npm:@metamask-previews/eth-snap-keyring@17.2.0-582d075", - "@metamask/eth-snap-keyring@^17.0.0": "npm:@metamask-previews/eth-snap-keyring@17.2.0-582d075" + "lavamoat-core@npm:^16.7.1": "patch:lavamoat-core@npm%3A16.7.1#~/.yarn/patches/lavamoat-core-npm-16.7.1-9dcb956c6f.patch" }, "dependencies": { "@babel/runtime": "patch:@babel/runtime@npm%3A7.25.9#~/.yarn/patches/@babel-runtime-npm-7.25.9-fe8c62510a.patch", @@ -308,7 +295,7 @@ "@metamask/eth-ledger-bridge-keyring": "11.1.2", "@metamask/eth-qr-keyring": "^1.1.0", "@metamask/eth-sig-util": "^8.2.0", - "@metamask/eth-snap-keyring": "^17.2.0", + "@metamask/eth-snap-keyring": "^17.3.0", "@metamask/eth-token-tracker": "^10.0.2", "@metamask/eth-trezor-keyring": "^9.0.0", "@metamask/etherscan-link": "^3.0.0", @@ -323,11 +310,11 @@ "@metamask/kernel-shims": "^0.3.0", "@metamask/kernel-ui": "^0.3.0", "@metamask/kernel-utils": "^0.3.0", - "@metamask/keyring-api": "^21.0.0", + "@metamask/keyring-api": "^21.1.0", "@metamask/keyring-controller": "^23.1.0", - "@metamask/keyring-internal-api": "^9.0.0", - "@metamask/keyring-internal-snap-client": "^7.0.0", - "@metamask/keyring-snap-client": "^8.0.0", + "@metamask/keyring-internal-api": "^9.1.0", + "@metamask/keyring-internal-snap-client": "^7.2.0", + "@metamask/keyring-snap-client": "^8.1.0", "@metamask/keyring-utils": "^3.1.0", "@metamask/logger": "^0.5.0", "@metamask/logging-controller": "^6.0.4", diff --git a/yarn.lock b/yarn.lock index bef37e64463c..4cd83a41c0f4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6154,23 +6154,25 @@ __metadata: languageName: node linkType: hard -"@metamask/eth-snap-keyring@npm:@metamask-previews/eth-snap-keyring@17.2.0-582d075": - version: 17.2.0-582d075 - resolution: "@metamask-previews/eth-snap-keyring@npm:17.2.0-582d075" +"@metamask/eth-snap-keyring@npm:^17.0.0, @metamask/eth-snap-keyring@npm:^17.3.0": + version: 17.3.0 + resolution: "@metamask/eth-snap-keyring@npm:17.3.0" dependencies: "@ethereumjs/tx": "npm:^5.4.0" "@metamask/base-controller": "npm:^8.3.0" "@metamask/eth-sig-util": "npm:^8.2.0" - "@metamask/keyring-api": "npm:21.0.0" - "@metamask/keyring-internal-api": "npm:9.0.0" - "@metamask/keyring-internal-snap-client": "npm:7.1.0" - "@metamask/keyring-snap-sdk": "npm:7.0.0" - "@metamask/keyring-utils": "npm:3.1.0" + "@metamask/keyring-api": "npm:^21.1.0" + "@metamask/keyring-internal-api": "npm:^9.1.0" + "@metamask/keyring-internal-snap-client": "npm:^7.2.0" + "@metamask/keyring-snap-sdk": "npm:^7.1.0" + "@metamask/keyring-utils": "npm:^3.1.0" "@metamask/superstruct": "npm:^3.1.0" "@metamask/utils": "npm:^11.1.0" "@types/uuid": "npm:^9.0.8" uuid: "npm:^9.0.1" - checksum: 10/3073182aeaa606f892bd813865f6517db8c55ae5f7b356be2d9aae49b0f5450fab6037d4f5b8802705bd770d35a68c9170d70c0eafa48585e16aadd839a986e0 + peerDependencies: + "@metamask/keyring-api": ^21.1.0 + checksum: 10/a9ab4e08acb008ac1d5f7d78a0eb194aa03d125a5fea56dc74fb2978186a1a540b5c75108a9fd035c1a95291916111eb410e3645037aee55a09952c31f6322ae languageName: node linkType: hard @@ -6545,15 +6547,27 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-api@npm:@metamask-previews/keyring-api@21.0.0-582d075": - version: 21.0.0-582d075 - resolution: "@metamask-previews/keyring-api@npm:21.0.0-582d075" +"@metamask/keyring-api@npm:^20.0.0, @metamask/keyring-api@npm:^20.1.0": + version: 20.1.1 + resolution: "@metamask/keyring-api@npm:20.1.1" dependencies: - "@metamask/keyring-utils": "npm:3.1.0" + "@metamask/keyring-utils": "npm:^3.1.0" "@metamask/superstruct": "npm:^3.1.0" "@metamask/utils": "npm:^11.1.0" bitcoin-address-validation: "npm:^2.2.3" - checksum: 10/080b54871a315e8b02ed73a7d4ff5aabf7291c87a7913d0a4eea6ee8e70648e53b50af7d3fbddf255121e2326afb86130e546b2431c2d478ac3ebc4ec3aaebce + checksum: 10/f261205687c9aa1c39a2221e30a6edd4f530d2b0afd86a8ab13ea23d2af2a0bf1c89a8c4ad5646368e3b06909613d64195c335063319edd018636c9fa6ee63ee + languageName: node + linkType: hard + +"@metamask/keyring-api@npm:^21.0.0, @metamask/keyring-api@npm:^21.1.0": + version: 21.1.0 + resolution: "@metamask/keyring-api@npm:21.1.0" + dependencies: + "@metamask/keyring-utils": "npm:^3.1.0" + "@metamask/superstruct": "npm:^3.1.0" + "@metamask/utils": "npm:^11.1.0" + bitcoin-address-validation: "npm:^2.2.3" + checksum: 10/3371a5ab0e9ba0e9b23b30b03a7d83d029e223def5485ab1aa2ec793ba18ff3738422dbe3c47f9cf82411d2ca6ca918928bf998741f0977055071b7bf3042314 languageName: node linkType: hard @@ -6579,7 +6593,18 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-internal-api@npm:9.0.0, @metamask/keyring-internal-api@npm:^9.0.0": +"@metamask/keyring-internal-api@npm:^8.1.0": + version: 8.1.0 + resolution: "@metamask/keyring-internal-api@npm:8.1.0" + dependencies: + "@metamask/keyring-api": "npm:^20.1.0" + "@metamask/keyring-utils": "npm:^3.1.0" + "@metamask/superstruct": "npm:^3.1.0" + checksum: 10/0fb615821a822de914b95a6b9678a1fc72f7f22b4ec694382977b0212e27ee5199887bd5112ea964e9bdd1aab1ba1a9e1ce3d9fd36957dc8ff8cf7c2f7003865 + languageName: node + linkType: hard + +"@metamask/keyring-internal-api@npm:^9.0.0": version: 9.0.0 resolution: "@metamask/keyring-internal-api@npm:9.0.0" dependencies: @@ -6590,63 +6615,79 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-internal-api@npm:^8.1.0": - version: 8.1.0 - resolution: "@metamask/keyring-internal-api@npm:8.1.0" +"@metamask/keyring-internal-api@npm:^9.1.0": + version: 9.1.0 + resolution: "@metamask/keyring-internal-api@npm:9.1.0" dependencies: - "@metamask/keyring-api": "npm:^20.1.0" + "@metamask/keyring-api": "npm:^21.1.0" "@metamask/keyring-utils": "npm:^3.1.0" "@metamask/superstruct": "npm:^3.1.0" - checksum: 10/0fb615821a822de914b95a6b9678a1fc72f7f22b4ec694382977b0212e27ee5199887bd5112ea964e9bdd1aab1ba1a9e1ce3d9fd36957dc8ff8cf7c2f7003865 + checksum: 10/6b19f35f57bc1b5dc73957d7f3185236780c93e6292678e22d84f9eb2fe92e15a98437a9bc4fbe5e5e10143d4db36afa2c420636f2cca4bd984e8455ca4332c6 languageName: node linkType: hard -"@metamask/keyring-internal-snap-client@npm:@metamask-previews/keyring-internal-snap-client@7.1.0-582d075": - version: 7.1.0-582d075 - resolution: "@metamask-previews/keyring-internal-snap-client@npm:7.1.0-582d075" +"@metamask/keyring-internal-snap-client@npm:^7.2.0": + version: 7.2.0 + resolution: "@metamask/keyring-internal-snap-client@npm:7.2.0" dependencies: "@metamask/base-controller": "npm:^8.3.0" - "@metamask/keyring-api": "npm:21.0.0" - "@metamask/keyring-internal-api": "npm:9.0.0" - "@metamask/keyring-snap-client": "npm:8.0.0" - "@metamask/keyring-utils": "npm:3.1.0" - checksum: 10/ce6cd196ca6cc4e0e2647057be4631a7dde296ca7884b8fbe74acb58fdf1c30452633db6e040d384c4f43173535a8e318e777db5fc8133de6bf7c6e9a2ca24f8 + "@metamask/keyring-api": "npm:^21.1.0" + "@metamask/keyring-internal-api": "npm:^9.1.0" + "@metamask/keyring-snap-client": "npm:^8.1.0" + "@metamask/keyring-utils": "npm:^3.1.0" + checksum: 10/ed290df433672dc0686386e23f1e4b98a7bfb033498ffab502b682f6d5414deae23383979e5979ad490032876eb859d21d9f768dfd24f6d02045ad10d2baf29b + languageName: node + linkType: hard + +"@metamask/keyring-snap-client@npm:^7.0.0": + version: 7.0.0 + resolution: "@metamask/keyring-snap-client@npm:7.0.0" + dependencies: + "@metamask/keyring-api": "npm:^20.0.0" + "@metamask/keyring-utils": "npm:^3.1.0" + "@metamask/superstruct": "npm:^3.1.0" + "@types/uuid": "npm:^9.0.8" + uuid: "npm:^9.0.1" + webextension-polyfill: "npm:^0.12.0" + peerDependencies: + "@metamask/providers": ^19.0.0 + checksum: 10/c82a46f61dc211eae6b7b36dd4e8d01b3508217b9a1004e92b361a08025ae88162458ddbddf443bb2b7dab1b2c5bfd95060ec80d5411be7c148bd5703e14858e languageName: node linkType: hard -"@metamask/keyring-snap-client@npm:@metamask-previews/keyring-snap-client@8.0.0-582d075": - version: 8.0.0-582d075 - resolution: "@metamask-previews/keyring-snap-client@npm:8.0.0-582d075" +"@metamask/keyring-snap-client@npm:^8.0.0, @metamask/keyring-snap-client@npm:^8.1.0": + version: 8.1.0 + resolution: "@metamask/keyring-snap-client@npm:8.1.0" dependencies: - "@metamask/keyring-api": "npm:21.0.0" - "@metamask/keyring-utils": "npm:3.1.0" + "@metamask/keyring-api": "npm:^21.1.0" + "@metamask/keyring-utils": "npm:^3.1.0" "@metamask/superstruct": "npm:^3.1.0" "@types/uuid": "npm:^9.0.8" uuid: "npm:^9.0.1" webextension-polyfill: "npm:^0.12.0" peerDependencies: "@metamask/providers": ^19.0.0 - checksum: 10/e8564f6c49fa1b823edfd883c505187ced688767f34a9f752324bef235946375fca8345f5c1dff713bfd88ab81f8f3b8154d2bb6849205fbc266f2dc32661e2d + checksum: 10/e92aa7f6e1454150870e8e0a6d9cf4fac7bbc22280d85a252ca7ee428842dfbaaaccae78dfc5ad773e21d757febfcbe6933a72b966c4478f1a2b3fc0088419a1 languageName: node linkType: hard -"@metamask/keyring-snap-sdk@npm:@metamask-previews/keyring-snap-sdk@7.0.0-582d075": - version: 7.0.0-582d075 - resolution: "@metamask-previews/keyring-snap-sdk@npm:7.0.0-582d075" +"@metamask/keyring-snap-sdk@npm:^7.1.0": + version: 7.1.0 + resolution: "@metamask/keyring-snap-sdk@npm:7.1.0" dependencies: - "@metamask/keyring-api": "npm:21.0.0" - "@metamask/keyring-utils": "npm:3.1.0" + "@metamask/keyring-utils": "npm:^3.1.0" "@metamask/snaps-sdk": "npm:^9.0.0" "@metamask/superstruct": "npm:^3.1.0" "@metamask/utils": "npm:^11.1.0" webextension-polyfill: "npm:^0.12.0" peerDependencies: + "@metamask/keyring-api": ^21.1.0 "@metamask/providers": ^19.0.0 - checksum: 10/26a832653bdea452599a0f02e0104d844f34b6621e7ef5ff09be0f4057ccc4635c4f85bfbf7296346bab079c25fe73f826f079153a6a9ae10d16ebe31b7e4a58 + checksum: 10/1a1809733c1f21af87f3491d292c499c5441afa0780e848718ec2b6aff50d76bb03ea44ee93ecaa80d79453a98926d84cd13ff406256ab6a2136d9e31250faa8 languageName: node linkType: hard -"@metamask/keyring-utils@npm:3.1.0, @metamask/keyring-utils@npm:^3.1.0": +"@metamask/keyring-utils@npm:^3.1.0": version: 3.1.0 resolution: "@metamask/keyring-utils@npm:3.1.0" dependencies: @@ -31315,7 +31356,7 @@ __metadata: "@metamask/eth-ledger-bridge-keyring": "npm:11.1.2" "@metamask/eth-qr-keyring": "npm:^1.1.0" "@metamask/eth-sig-util": "npm:^8.2.0" - "@metamask/eth-snap-keyring": "npm:^17.2.0" + "@metamask/eth-snap-keyring": "npm:^17.3.0" "@metamask/eth-token-tracker": "npm:^10.0.2" "@metamask/eth-trezor-keyring": "npm:^9.0.0" "@metamask/etherscan-link": "npm:^3.0.0" @@ -31332,11 +31373,11 @@ __metadata: "@metamask/kernel-shims": "npm:^0.3.0" "@metamask/kernel-ui": "npm:^0.3.0" "@metamask/kernel-utils": "npm:^0.3.0" - "@metamask/keyring-api": "npm:^21.0.0" + "@metamask/keyring-api": "npm:^21.1.0" "@metamask/keyring-controller": "npm:^23.1.0" - "@metamask/keyring-internal-api": "npm:^9.0.0" - "@metamask/keyring-internal-snap-client": "npm:^7.0.0" - "@metamask/keyring-snap-client": "npm:^8.0.0" + "@metamask/keyring-internal-api": "npm:^9.1.0" + "@metamask/keyring-internal-snap-client": "npm:^7.2.0" + "@metamask/keyring-snap-client": "npm:^8.1.0" "@metamask/keyring-utils": "npm:^3.1.0" "@metamask/logger": "npm:^0.5.0" "@metamask/logging-controller": "npm:^6.0.4" From 44101ee7c5e4e7b0e0eff5c4b26a165c228270e1 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 9 Oct 2025 14:26:04 +0200 Subject: [PATCH 06/25] feat: re-forward selected accounts to the Snap keyring if multichain account group changes --- app/scripts/metamask-controller.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 9b86a944658a..e8d5cf69ce87 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1892,6 +1892,19 @@ export default class MetamaskController extends EventEmitter { }, ); + // TODO: Move this logic to the SnapKeyring directly. + // Forward selected accounts to the Snap keyring, so each Snaps can fetch those accounts. + this.controllerMessenger.subscribe( + `${this.multichainAccountService.name}:multichainAccountGroupUpdated`, (group) => { + // If the current group gets updated, then maybe there are more accounts being "selected" + // now, so we have to forward them to the Snap keyring too! + if (this.accountTreeController.getSelectedAccountGroup() === group.id) { + // eslint-disable-next-line no-void + void this.forwardSelectedAccountGroupToSnapKeyring(group.id); + } + }, + ); + this.controllerMessenger.subscribe( `${this.permissionController.name}:stateChange`, async (currentValue, previousValue) => { From 1cc8c99b5eb65e075d11738f1a65f76fb57a08de Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 9 Oct 2025 14:26:16 +0200 Subject: [PATCH 07/25] chore: logs --- app/scripts/metamask-controller.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index e8d5cf69ce87..0fbf594438a5 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1525,13 +1525,13 @@ export default class MetamaskController extends EventEmitter { * @param groupId - Currently selected account group. */ async forwardSelectedAccountGroupToSnapKeyring(groupId) { - console.log('-- SnapKeyring -- forwarding'); + console.log('@@ SnapKeyring -- forwarding'); if (groupId) { const group = this.accountTreeController.getAccountGroupObject(groupId); if (group) { const snapKeyring = await this.getSnapKeyring(); - console.log('-- SnapKeyring.setSelectedAccounts', group.accounts); + console.log('@@ SnapKeyring.setSelectedAccounts', group.accounts); snapKeyring.setSelectedAccounts(group.accounts); } } @@ -1899,6 +1899,7 @@ export default class MetamaskController extends EventEmitter { // If the current group gets updated, then maybe there are more accounts being "selected" // now, so we have to forward them to the Snap keyring too! if (this.accountTreeController.getSelectedAccountGroup() === group.id) { + console.log('@@ SnapKeyring - groups got updated:', group.id, group.getAccounts()); // eslint-disable-next-line no-void void this.forwardSelectedAccountGroupToSnapKeyring(group.id); } From f61168d2ababf1c46309bf8ea13985587a9c0722 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 9 Oct 2025 14:47:38 +0200 Subject: [PATCH 08/25] refactor: remove logs --- app/scripts/metamask-controller.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 0fbf594438a5..3e05bafff520 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1525,13 +1525,10 @@ export default class MetamaskController extends EventEmitter { * @param groupId - Currently selected account group. */ async forwardSelectedAccountGroupToSnapKeyring(groupId) { - console.log('@@ SnapKeyring -- forwarding'); if (groupId) { const group = this.accountTreeController.getAccountGroupObject(groupId); if (group) { const snapKeyring = await this.getSnapKeyring(); - - console.log('@@ SnapKeyring.setSelectedAccounts', group.accounts); snapKeyring.setSelectedAccounts(group.accounts); } } @@ -1899,7 +1896,6 @@ export default class MetamaskController extends EventEmitter { // If the current group gets updated, then maybe there are more accounts being "selected" // now, so we have to forward them to the Snap keyring too! if (this.accountTreeController.getSelectedAccountGroup() === group.id) { - console.log('@@ SnapKeyring - groups got updated:', group.id, group.getAccounts()); // eslint-disable-next-line no-void void this.forwardSelectedAccountGroupToSnapKeyring(group.id); } From 30a6d81efafd95b1ba1c2e4ae23731d60afbd1ff Mon Sep 17 00:00:00 2001 From: Xavier Brochard Date: Thu, 9 Oct 2025 15:19:58 +0200 Subject: [PATCH 09/25] feat: bump solana snap --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index f72d0d04fe12..90dae366bfe0 100644 --- a/package.json +++ b/package.json @@ -357,7 +357,7 @@ "@metamask/snaps-rpc-methods": "^13.5.2", "@metamask/snaps-sdk": "^10.0.0", "@metamask/snaps-utils": "^11.6.0", - "@metamask/solana-wallet-snap": "^2.4.2", + "@metamask/solana-wallet-snap": "^2.4.3", "@metamask/solana-wallet-standard": "^0.6.0", "@metamask/streams": "^0.4.0", "@metamask/subscription-controller": "^0.5.0", diff --git a/yarn.lock b/yarn.lock index 4cd83a41c0f4..79589c36c390 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7625,10 +7625,10 @@ __metadata: languageName: node linkType: hard -"@metamask/solana-wallet-snap@npm:^2.4.2": - version: 2.4.2 - resolution: "@metamask/solana-wallet-snap@npm:2.4.2" - checksum: 10/a571aa488afb7f29644be72392926c18d067022f7e2837f9b9253d228c518e499b8c2ca07b4397f02a3eb61c7c4d77e5f0f6997fbc41f3c6060d359293291e6e +"@metamask/solana-wallet-snap@npm:^2.4.3": + version: 2.4.3 + resolution: "@metamask/solana-wallet-snap@npm:2.4.3" + checksum: 10/09d6d672c26cb4ae750d2e2a6436ef21fa7f6967dedde8d1511b6a1d11d7f8fc7f60077fa2c3259c1a05c02d7cf3b2289de61d37ea85d0202ae2c4f94d68e97c languageName: node linkType: hard @@ -31422,7 +31422,7 @@ __metadata: "@metamask/snaps-rpc-methods": "npm:^13.5.2" "@metamask/snaps-sdk": "npm:^10.0.0" "@metamask/snaps-utils": "npm:^11.6.0" - "@metamask/solana-wallet-snap": "npm:^2.4.2" + "@metamask/solana-wallet-snap": "npm:^2.4.3" "@metamask/solana-wallet-standard": "npm:^0.6.0" "@metamask/streams": "npm:^0.4.0" "@metamask/subscription-controller": "npm:^0.5.0" From 6a0e8d1ec95081a276fc5d2eb0153e0d87bf845e Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 9 Oct 2025 15:39:08 +0200 Subject: [PATCH 10/25] chore: lavamoat:auto --- lavamoat/browserify/beta/policy.json | 8 ++++++++ lavamoat/browserify/experimental/policy.json | 8 ++++++++ lavamoat/browserify/flask/policy.json | 8 ++++++++ lavamoat/browserify/main/policy.json | 8 ++++++++ 4 files changed, 32 insertions(+) diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index 761a3e8bd1bd..f3348fd28b25 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -1235,6 +1235,7 @@ "@metamask/keyring-api": true, "@metamask/keyring-internal-api": true, "@metamask/keyring-internal-snap-client": true, + "@metamask/eth-snap-keyring>@metamask/keyring-snap-sdk": true, "@metamask/keyring-utils": true, "@metamask/superstruct": true, "@metamask/utils": true, @@ -1457,6 +1458,13 @@ "@metamask/multichain-transactions-controller>@metamask/keyring-snap-client>uuid": true } }, + "@metamask/eth-snap-keyring>@metamask/keyring-snap-sdk": { + "packages": { + "@metamask/keyring-api": true, + "@metamask/keyring-utils": true, + "@metamask/superstruct": true + } + }, "@metamask/keyring-utils": { "globals": { "URL": true diff --git a/lavamoat/browserify/experimental/policy.json b/lavamoat/browserify/experimental/policy.json index 761a3e8bd1bd..f3348fd28b25 100644 --- a/lavamoat/browserify/experimental/policy.json +++ b/lavamoat/browserify/experimental/policy.json @@ -1235,6 +1235,7 @@ "@metamask/keyring-api": true, "@metamask/keyring-internal-api": true, "@metamask/keyring-internal-snap-client": true, + "@metamask/eth-snap-keyring>@metamask/keyring-snap-sdk": true, "@metamask/keyring-utils": true, "@metamask/superstruct": true, "@metamask/utils": true, @@ -1457,6 +1458,13 @@ "@metamask/multichain-transactions-controller>@metamask/keyring-snap-client>uuid": true } }, + "@metamask/eth-snap-keyring>@metamask/keyring-snap-sdk": { + "packages": { + "@metamask/keyring-api": true, + "@metamask/keyring-utils": true, + "@metamask/superstruct": true + } + }, "@metamask/keyring-utils": { "globals": { "URL": true diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index 761a3e8bd1bd..f3348fd28b25 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -1235,6 +1235,7 @@ "@metamask/keyring-api": true, "@metamask/keyring-internal-api": true, "@metamask/keyring-internal-snap-client": true, + "@metamask/eth-snap-keyring>@metamask/keyring-snap-sdk": true, "@metamask/keyring-utils": true, "@metamask/superstruct": true, "@metamask/utils": true, @@ -1457,6 +1458,13 @@ "@metamask/multichain-transactions-controller>@metamask/keyring-snap-client>uuid": true } }, + "@metamask/eth-snap-keyring>@metamask/keyring-snap-sdk": { + "packages": { + "@metamask/keyring-api": true, + "@metamask/keyring-utils": true, + "@metamask/superstruct": true + } + }, "@metamask/keyring-utils": { "globals": { "URL": true diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index 761a3e8bd1bd..f3348fd28b25 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -1235,6 +1235,7 @@ "@metamask/keyring-api": true, "@metamask/keyring-internal-api": true, "@metamask/keyring-internal-snap-client": true, + "@metamask/eth-snap-keyring>@metamask/keyring-snap-sdk": true, "@metamask/keyring-utils": true, "@metamask/superstruct": true, "@metamask/utils": true, @@ -1457,6 +1458,13 @@ "@metamask/multichain-transactions-controller>@metamask/keyring-snap-client>uuid": true } }, + "@metamask/eth-snap-keyring>@metamask/keyring-snap-sdk": { + "packages": { + "@metamask/keyring-api": true, + "@metamask/keyring-utils": true, + "@metamask/superstruct": true + } + }, "@metamask/keyring-utils": { "globals": { "URL": true From 89ba68ce8b0e1de8dcaf0fdf4e9f991e6321679a Mon Sep 17 00:00:00 2001 From: MetaMask Bot Date: Thu, 9 Oct 2025 14:38:40 +0000 Subject: [PATCH 11/25] Update LavaMoat policies --- lavamoat/webpack/policy.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lavamoat/webpack/policy.json b/lavamoat/webpack/policy.json index 54a65a4af37c..c5f31ecb48ad 100644 --- a/lavamoat/webpack/policy.json +++ b/lavamoat/webpack/policy.json @@ -1295,6 +1295,7 @@ "@metamask/keyring-api": true, "@metamask/keyring-internal-api": true, "@metamask/keyring-internal-snap-client": true, + "@metamask/eth-snap-keyring>@metamask/keyring-snap-sdk": true, "@metamask/keyring-utils": true, "@metamask/superstruct": true, "@metamask/utils": true, @@ -1525,6 +1526,13 @@ "@metamask/multichain-transactions-controller>@metamask/keyring-snap-client>uuid": true } }, + "@metamask/eth-snap-keyring>@metamask/keyring-snap-sdk": { + "packages": { + "@metamask/keyring-api": true, + "@metamask/keyring-utils": true, + "@metamask/superstruct": true + } + }, "@metamask/keyring-utils": { "globals": { "URL": true From e5146a22ddf35dc88be211fdceab63731c10afdd Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 9 Oct 2025 16:27:20 +0200 Subject: [PATCH 12/25] chore: lint --- app/scripts/metamask-controller.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 3e05bafff520..98ca2876bb31 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1892,7 +1892,8 @@ export default class MetamaskController extends EventEmitter { // TODO: Move this logic to the SnapKeyring directly. // Forward selected accounts to the Snap keyring, so each Snaps can fetch those accounts. this.controllerMessenger.subscribe( - `${this.multichainAccountService.name}:multichainAccountGroupUpdated`, (group) => { + `${this.multichainAccountService.name}:multichainAccountGroupUpdated`, + (group) => { // If the current group gets updated, then maybe there are more accounts being "selected" // now, so we have to forward them to the Snap keyring too! if (this.accountTreeController.getSelectedAccountGroup() === group.id) { From 8bc4fe5fecce70e6061350e6771e809f07055381 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Thu, 9 Oct 2025 16:27:52 +0200 Subject: [PATCH 13/25] chore: dedupe --- yarn.lock | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/yarn.lock b/yarn.lock index 79589c36c390..7307a6ddb7e3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6604,18 +6604,7 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-internal-api@npm:^9.0.0": - version: 9.0.0 - resolution: "@metamask/keyring-internal-api@npm:9.0.0" - dependencies: - "@metamask/keyring-api": "npm:^21.0.0" - "@metamask/keyring-utils": "npm:^3.1.0" - "@metamask/superstruct": "npm:^3.1.0" - checksum: 10/2603a3ffa42d53d2c621846288e759e9df2062fb6d46444466062915dbeda5fb3ec5344a48c1d282d37c6a689d7332e953c955be93f10e4bd56879c29ca2bf26 - languageName: node - linkType: hard - -"@metamask/keyring-internal-api@npm:^9.1.0": +"@metamask/keyring-internal-api@npm:^9.0.0, @metamask/keyring-internal-api@npm:^9.1.0": version: 9.1.0 resolution: "@metamask/keyring-internal-api@npm:9.1.0" dependencies: From a3af64b4ac6d9c11bd3721575ebf538c1f8383d1 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Fri, 10 Oct 2025 11:18:02 +0200 Subject: [PATCH 14/25] fix: add missing await --- app/scripts/metamask-controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 98ca2876bb31..508dc7b00249 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1529,7 +1529,7 @@ export default class MetamaskController extends EventEmitter { const group = this.accountTreeController.getAccountGroupObject(groupId); if (group) { const snapKeyring = await this.getSnapKeyring(); - snapKeyring.setSelectedAccounts(group.accounts); + await snapKeyring.setSelectedAccounts(group.accounts); } } } From 59db2f54ec1f2e49554e51d95f2e703bcdf9d4df Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Fri, 10 Oct 2025 13:54:51 +0200 Subject: [PATCH 15/25] test: fix tests --- app/scripts/metamask-controller.test.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/scripts/metamask-controller.test.js b/app/scripts/metamask-controller.test.js index bffd4b5e03ca..1bb1f6dc3e2f 100644 --- a/app/scripts/metamask-controller.test.js +++ b/app/scripts/metamask-controller.test.js @@ -73,6 +73,7 @@ import { getPermittedAccountsForScopesByOrigin, } from './controllers/permissions'; import MetaMaskController from './metamask-controller'; +import { KeyringTypes } from '@metamask/keyring-controller'; const { Ganache } = require('../../test/e2e/seeder/ganache'); @@ -5346,7 +5347,9 @@ describe('MetaMaskController', () => { await metamaskController._importAccountsWithBalances(); const { keyrings } = metamaskController.keyringController.state; - const hdIds = keyrings.map((k) => k.metadata.id); + const hdIds = keyrings + .filter((keyring) => keyring.metadata.type === KeyringTypes.hd) + .map((keyring) => keyring.metadata.id); hdIds.forEach((id) => { expect( metamaskController.discoverAndCreateAccounts, @@ -5378,7 +5381,9 @@ describe('MetaMaskController', () => { await metamaskController._importAccountsWithBalances(); const { keyrings } = metamaskController.keyringController.state; - const hdIds = keyrings.map((k) => k.metadata.id); + const hdIds = keyrings + .filter((keyring) => keyring.metadata.type === KeyringTypes.hd) + .map((keyring) => keyring.metadata.id); hdIds.forEach((id) => { expect(metamaskController._addAccountsWithBalance).toHaveBeenCalledWith( id, From 9bb32d536dfe067d0d67c8b100a2f878523b3f29 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Fri, 10 Oct 2025 13:58:44 +0200 Subject: [PATCH 16/25] test: fix HW tests --- app/scripts/metamask-controller.test.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/scripts/metamask-controller.test.js b/app/scripts/metamask-controller.test.js index 1bb1f6dc3e2f..1ddf21d64239 100644 --- a/app/scripts/metamask-controller.test.js +++ b/app/scripts/metamask-controller.test.js @@ -1549,7 +1549,8 @@ describe('MetaMaskController', () => { ); expect( - metamaskController.keyringController.state.keyrings[1].type, + // 0: HD keyring, 1: Snap keyring, 2: Trezor keyring + metamaskController.keyringController.state.keyrings[2].type, ).toBe(TrezorKeyring.type); expect(firstPage).toStrictEqual(KNOWN_PUBLIC_KEY_ADDRESSES); }); @@ -1561,7 +1562,8 @@ describe('MetaMaskController', () => { ); expect( - metamaskController.keyringController.state.keyrings[1].type, + // 0: HD keyring, 1: Snap keyring, 2: Ledger keyring + metamaskController.keyringController.state.keyrings[2].type, ).toBe(LedgerKeyring.type); expect(firstPage).toStrictEqual(KNOWN_PUBLIC_KEY_ADDRESSES); }); @@ -1695,7 +1697,8 @@ describe('MetaMaskController', () => { ); expect( - metamaskController.keyringController.state.keyrings[1] + // 0: HD keyring, 1: Snap keyring, 2: Ledger/Trezor keyring + metamaskController.keyringController.state.keyrings[2] .accounts, ).toStrictEqual([ KNOWN_PUBLIC_KEY_ADDRESSES[ From e01c4de93643bb4748b9bb0015aff420958278b4 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Fri, 10 Oct 2025 14:29:04 +0200 Subject: [PATCH 17/25] test: fix metamask-controller tests --- app/scripts/metamask-controller.test.js | 115 +++++++----------------- 1 file changed, 30 insertions(+), 85 deletions(-) diff --git a/app/scripts/metamask-controller.test.js b/app/scripts/metamask-controller.test.js index 1ddf21d64239..bd6665e3a015 100644 --- a/app/scripts/metamask-controller.test.js +++ b/app/scripts/metamask-controller.test.js @@ -5,6 +5,7 @@ import { cloneDeep } from 'lodash'; import nock from 'nock'; import { obj as createThroughStream } from 'through2'; import { wordlist as englishWordlist } from '@metamask/scure-bip39/dist/wordlists/english'; +import { SnapKeyring } from '@metamask/eth-snap-keyring'; import { ListNames, METAMASK_STALELIST_URL, @@ -74,6 +75,7 @@ import { } from './controllers/permissions'; import MetaMaskController from './metamask-controller'; import { KeyringTypes } from '@metamask/keyring-controller'; +import { setSelectedAccount } from '../../ui/store/actions'; const { Ganache } = require('../../test/e2e/seeder/ganache'); @@ -879,40 +881,6 @@ describe('MetaMaskController', () => { allDetectedTokens: { '0x1': { [TEST_ADDRESS_2]: [{}] } }, }); - const mockSnapKeyring = { - createAccount: jest - .fn() - .mockResolvedValue({ address: 'mockedAddress' }), - }; - - const originalGetKeyringsByType = - metamaskController.keyringController.getKeyringsByType; - let snapKeyringCallCount = 0; - jest - .spyOn(metamaskController.keyringController, 'getKeyringsByType') - .mockImplementation((type) => { - if (type === 'Snap Keyring') { - snapKeyringCallCount += 1; - - if (snapKeyringCallCount === 1) { - // First call - use original implementation to let controller initialize snap keyring - return originalGetKeyringsByType.call( - metamaskController.keyringController, - type, - ); - } - // Second call and beyond - return mock - console.log('returning mocked snap keyring!'); - return [mockSnapKeyring]; - } - - // For other types, always use original implementation - return originalGetKeyringsByType.call( - metamaskController.keyringController, - type, - ); - }); - await metamaskController.createNewVaultAndRestore( 'foobar1337', TEST_SEED, @@ -3514,55 +3482,23 @@ describe('MetaMaskController', () => { .spyOn(metamaskController, 'isMultichainAccountsFeatureState2Enabled') .mockReturnValue(false); - const mockSnapKeyring = { - createAccount: jest - .fn() - .mockResolvedValue({ address: 'mockedAddress' }), - }; - - const originalGetKeyringsByType = - metamaskController.keyringController.getKeyringsByType; - let snapKeyringCallCount = 0; - jest - .spyOn(metamaskController.keyringController, 'getKeyringsByType') - .mockImplementation((type) => { - if (type === 'Snap Keyring') { - snapKeyringCallCount += 1; - - if (snapKeyringCallCount === 1) { - // First call - use original implementation to let controller initialize snap keyring - return originalGetKeyringsByType.call( - metamaskController.keyringController, - type, - ); - } - // Second call and beyond - return mock - console.log('returning mocked snap keyring!'); - return [mockSnapKeyring]; - } - - // For other types, always use original implementation - return originalGetKeyringsByType.call( - metamaskController.keyringController, - type, - ); - }); - await metamaskController.createNewVaultAndRestore(password, TEST_SEED); - const previousKeyrings = - metamaskController.keyringController.state.keyrings; + const previousKeyrings = cloneDeep( + metamaskController.keyringController.state.keyrings, + ); await metamaskController.importMnemonicToVault(TEST_SEED_ALT); const currentKeyrings = metamaskController.keyringController.state.keyrings; + // 0: Primary HD keyring, 1: Snap keyring, 2: Newly imported HD keyring + expect( + metamaskController.keyringController.state.keyrings, + ).toHaveLength(3); const newlyAddedKeyringId = - metamaskController.keyringController.state.keyrings[ - metamaskController.keyringController.state.keyrings.length - 2 // -1 for the snap keyring, -1 for the newly added keyring - ].metadata.id; - + metamaskController.keyringController.state.keyrings[2].metadata.id; const newSRP = Buffer.from( await metamaskController.getSeedPhrase(password, newlyAddedKeyringId), ).toString('utf8'); @@ -3573,7 +3509,7 @@ describe('MetaMaskController', () => { expect( currentKeyrings.filter((kr) => kr.type === 'Snap Keyring'), ).toHaveLength(1); - expect(currentKeyrings).toHaveLength(previousKeyrings.length + 2); + expect(currentKeyrings).toHaveLength(previousKeyrings.length + 1); expect(newSRP).toStrictEqual(TEST_SEED_ALT); }); @@ -3612,10 +3548,11 @@ describe('MetaMaskController', () => { .spyOn(KeyringInternalSnapClient.prototype, 'discoverAccounts') .mockImplementation(mockDiscoverAccounts); - const mockCreateAccount = jest.fn().mockResolvedValue(undefined); - jest - .spyOn(metamaskController, 'getSnapKeyring') - .mockResolvedValue({ createAccount: mockCreateAccount }); + const mockCreateAccount = jest.spyOn( + SnapKeyring.prototype, + 'createAccount', + ); + mockCreateAccount.mockResolvedValue(undefined); await metamaskController.createNewVaultAndRestore(password, TEST_SEED); await metamaskController.importMnemonicToVault(TEST_SEED_ALT); @@ -3693,10 +3630,12 @@ describe('MetaMaskController', () => { .spyOn(KeyringInternalSnapClient.prototype, 'discoverAccounts') .mockImplementation(mockDiscoverAccounts); - const mockCreateAccount = jest.fn().mockResolvedValue(undefined); - jest - .spyOn(metamaskController, 'getSnapKeyring') - .mockResolvedValue({ createAccount: mockCreateAccount }); + const mockCreateAccount = jest.spyOn( + SnapKeyring.prototype, + 'createAccount', + ); + mockCreateAccount.mockResolvedValue(undefined); + await metamaskController.createNewVaultAndRestore(password, TEST_SEED); await metamaskController.importMnemonicToVault(TEST_SEED_ALT); @@ -5044,7 +4983,10 @@ describe('MetaMaskController', () => { }); // Avoid KC.addNewKeyring side-effects and AccountTracker sync touching NetworkController - jest.spyOn(metamaskController, 'getSnapKeyring').mockResolvedValue({}); + jest.spyOn(metamaskController, 'getSnapKeyring').mockResolvedValue({ + // Now required, since it's invoked automatically when new account groups get added. + setSelectedAccounts: jest.fn(), + }); jest .spyOn(metamaskController.accountTrackerController, 'syncWithAddresses') .mockReturnValue(); @@ -5319,7 +5261,10 @@ describe('MetaMaskController', () => { }); // Avoid KC.addNewKeyring side-effects and AccountTracker sync touching NetworkController - jest.spyOn(metamaskController, 'getSnapKeyring').mockResolvedValue({}); + jest.spyOn(metamaskController, 'getSnapKeyring').mockResolvedValue({ + // Now required, since it's invoked automatically when new account groups get added. + setSelectedAccounts: jest.fn(), + }); jest .spyOn(metamaskController.accountTrackerController, 'syncWithAddresses') .mockReturnValue(); From 10e2f24cf58d326675b9fb4d1e3a2352f0d5e728 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Fri, 10 Oct 2025 13:55:31 +0200 Subject: [PATCH 18/25] fix: make getSnapKeyring concurrent-safe --- app/scripts/metamask-controller.js | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 508dc7b00249..84d3573d57fc 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -487,6 +487,9 @@ export default class MetamaskController extends EventEmitter { // lock to ensure only one seedless onboarding operation is running at once this.seedlessOperationMutex = new Mutex(); + // lock to ensure only one Snap keyring operation is running at once + this.snapKeyringMutex = new Mutex(); + this.extension.runtime.onInstalled.addListener((details) => { if (details.reason === 'update') { if (version === '8.1.0') { @@ -1505,18 +1508,23 @@ export default class MetamaskController extends EventEmitter { * @returns {SnapKeyring} */ async getSnapKeyring() { - // TODO: Use `withKeyring` instead - let [snapKeyring] = this.keyringController.getKeyringsByType( - KeyringType.snap, - ); - if (!snapKeyring) { - await this.keyringController.addNewKeyring(KeyringType.snap); + const releaseLock = await this.snapKeyringMutex.acquire(); + try { // TODO: Use `withKeyring` instead - [snapKeyring] = this.keyringController.getKeyringsByType( + let [snapKeyring] = this.keyringController.getKeyringsByType( KeyringType.snap, ); + if (!snapKeyring) { + await this.keyringController.addNewKeyring(KeyringType.snap); + // TODO: Use `withKeyring` instead + [snapKeyring] = this.keyringController.getKeyringsByType( + KeyringType.snap, + ); + } + return snapKeyring; + } finally { + releaseLock(); } - return snapKeyring; } /** @@ -1529,6 +1537,7 @@ export default class MetamaskController extends EventEmitter { const group = this.accountTreeController.getAccountGroupObject(groupId); if (group) { const snapKeyring = await this.getSnapKeyring(); + console.log('@@', snapKeyring); await snapKeyring.setSelectedAccounts(group.accounts); } } From 3b47f0e100778800ad898fda82ec8e4aa7aed1a0 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Fri, 10 Oct 2025 14:36:50 +0200 Subject: [PATCH 19/25] chore: lint --- app/scripts/metamask-controller.test.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/scripts/metamask-controller.test.js b/app/scripts/metamask-controller.test.js index bd6665e3a015..a39fca8ebfad 100644 --- a/app/scripts/metamask-controller.test.js +++ b/app/scripts/metamask-controller.test.js @@ -46,6 +46,7 @@ import { KeyringInternalSnapClient } from '@metamask/keyring-internal-snap-clien import log from 'loglevel'; import { parseCaipAccountId } from '@metamask/utils'; +import { KeyringTypes } from '@metamask/keyring-controller'; import { createTestProviderTools } from '../../test/stub/provider'; import { HardwareDeviceNames, @@ -74,8 +75,6 @@ import { getPermittedAccountsForScopesByOrigin, } from './controllers/permissions'; import MetaMaskController from './metamask-controller'; -import { KeyringTypes } from '@metamask/keyring-controller'; -import { setSelectedAccount } from '../../ui/store/actions'; const { Ganache } = require('../../test/e2e/seeder/ganache'); @@ -3636,7 +3635,6 @@ describe('MetaMaskController', () => { ); mockCreateAccount.mockResolvedValue(undefined); - await metamaskController.createNewVaultAndRestore(password, TEST_SEED); await metamaskController.importMnemonicToVault(TEST_SEED_ALT); From 3e6155bf29c3d493793cd49478d9136817ab87bf Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Fri, 10 Oct 2025 15:09:05 +0200 Subject: [PATCH 20/25] test: fix metamask-controller.actions tests --- app/scripts/metamask-controller.actions.test.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/app/scripts/metamask-controller.actions.test.js b/app/scripts/metamask-controller.actions.test.js index 765c6844b0da..a29ea48f339d 100644 --- a/app/scripts/metamask-controller.actions.test.js +++ b/app/scripts/metamask-controller.actions.test.js @@ -220,8 +220,12 @@ describe('MetaMaskController', function () { await metamaskController.createNewVaultAndRestore('test@123', TEST_SEED); const result2 = metamaskController.keyringController.state; + expect(result1.keyrings).toHaveLength(2); + expect(result1.keyrings[0].metadata.id).toBe(mockULIDs[0]); // 0: Primary HD keyring + expect(result1.keyrings[1].metadata.id).toBe(mockULIDs[1]); // 1: Snap keyring + // On restore, a new keyring metadata is generated. - expect(result1.keyrings[0].metadata.id).toBe(mockULIDs[0]); + const ulidNewIndex = 2; expect(result2).toStrictEqual({ ...result1, keyrings: [ @@ -229,7 +233,14 @@ describe('MetaMaskController', function () { ...result1.keyrings[0], metadata: { ...result1.keyrings[0].metadata, - id: mockULIDs[1], + id: mockULIDs[ulidNewIndex + 0], // 0: New primary HD keyring + }, + }, + { + ...result1.keyrings[1], + metadata: { + ...result1.keyrings[1].metadata, + id: mockULIDs[ulidNewIndex + 1], // 1: New Snap keyring }, }, ], From 4c306c31efef8b2723584acd5e432d903e18f68f Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Fri, 10 Oct 2025 15:51:17 +0200 Subject: [PATCH 21/25] chore: cleanup log --- app/scripts/metamask-controller.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 84d3573d57fc..137fbe503257 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1537,7 +1537,6 @@ export default class MetamaskController extends EventEmitter { const group = this.accountTreeController.getAccountGroupObject(groupId); if (group) { const snapKeyring = await this.getSnapKeyring(); - console.log('@@', snapKeyring); await snapKeyring.setSelectedAccounts(group.accounts); } } From 1cf604a562102d2e5c597eeab2f2fe30ba981ed0 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Fri, 10 Oct 2025 16:33:50 +0200 Subject: [PATCH 22/25] fix: remove use of mutex --- app/scripts/metamask-controller.js | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 137fbe503257..508dc7b00249 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -487,9 +487,6 @@ export default class MetamaskController extends EventEmitter { // lock to ensure only one seedless onboarding operation is running at once this.seedlessOperationMutex = new Mutex(); - // lock to ensure only one Snap keyring operation is running at once - this.snapKeyringMutex = new Mutex(); - this.extension.runtime.onInstalled.addListener((details) => { if (details.reason === 'update') { if (version === '8.1.0') { @@ -1508,23 +1505,18 @@ export default class MetamaskController extends EventEmitter { * @returns {SnapKeyring} */ async getSnapKeyring() { - const releaseLock = await this.snapKeyringMutex.acquire(); - try { + // TODO: Use `withKeyring` instead + let [snapKeyring] = this.keyringController.getKeyringsByType( + KeyringType.snap, + ); + if (!snapKeyring) { + await this.keyringController.addNewKeyring(KeyringType.snap); // TODO: Use `withKeyring` instead - let [snapKeyring] = this.keyringController.getKeyringsByType( + [snapKeyring] = this.keyringController.getKeyringsByType( KeyringType.snap, ); - if (!snapKeyring) { - await this.keyringController.addNewKeyring(KeyringType.snap); - // TODO: Use `withKeyring` instead - [snapKeyring] = this.keyringController.getKeyringsByType( - KeyringType.snap, - ); - } - return snapKeyring; - } finally { - releaseLock(); } + return snapKeyring; } /** From 764f5321ad07fe864cb40865806ce5c0813a762a Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Fri, 10 Oct 2025 17:38:26 +0200 Subject: [PATCH 23/25] refactor: add getSnapKeyringIfAvailable --- app/scripts/metamask-controller.js | 40 +++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index d3a3f1ed9704..5fbd31b956d1 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1308,16 +1308,39 @@ export default class MetamaskController extends EventEmitter { return snapKeyring; } + /** + * Get the snap keyring instance if available. + * + * @returns {SnapKeyring} + */ + getSnapKeyringIfAvailable() { + // Check if the controller has been unlocked, otherwise this will throw. + if (this.keyringController.isUnlocked()) { + // TODO: Use `withKeyring` instead + const [snapKeyring] = this.keyringController.getKeyringsByType( + KeyringType.snap, + ); + + return snapKeyring; + } + return undefined; + } + /** * Forward currently selected account group to the Snap keyring. * + * @param snapKeyring - Snap keyring instance or undefined if not available. * @param groupId - Currently selected account group. */ - async forwardSelectedAccountGroupToSnapKeyring(groupId) { + async forwardSelectedAccountGroupToSnapKeyring(snapKeyring, groupId) { + if (!snapKeyring) { + // Nothing to forward if the Snap keyring is not available. + return; + } + if (groupId) { const group = this.accountTreeController.getAccountGroupObject(groupId); if (group) { - const snapKeyring = await this.getSnapKeyring(); await snapKeyring.setSelectedAccounts(group.accounts); } } @@ -1630,7 +1653,10 @@ export default class MetamaskController extends EventEmitter { // TODO: Move this logic to the SnapKeyring directly. // Forward selected accounts to the Snap keyring, so each Snaps can fetch those accounts. // eslint-disable-next-line no-void - void this.forwardSelectedAccountGroupToSnapKeyring(groupId); + void this.forwardSelectedAccountGroupToSnapKeyring( + this.getSnapKeyringIfAvailable(), + groupId, + ); const [account] = this.accountTreeController.getAccountsFromSelectedAccountGroup({ @@ -1687,7 +1713,10 @@ export default class MetamaskController extends EventEmitter { // now, so we have to forward them to the Snap keyring too! if (this.accountTreeController.getSelectedAccountGroup() === group.id) { // eslint-disable-next-line no-void - void this.forwardSelectedAccountGroupToSnapKeyring(group.id); + void this.forwardSelectedAccountGroupToSnapKeyring( + this.getSnapKeyringIfAvailable(), + group.id, + ); } }, ); @@ -4065,6 +4094,7 @@ export default class MetamaskController extends EventEmitter { // TODO: Move this logic to the SnapKeyring directly. // Forward selected accounts to the Snap keyring, so each Snaps can fetch those accounts. await this.forwardSelectedAccountGroupToSnapKeyring( + await this.getSnapKeyring(), this.accountTreeController.getSelectedAccountGroup(), ); @@ -4453,6 +4483,7 @@ export default class MetamaskController extends EventEmitter { // TODO: Move this logic to the SnapKeyring directly. // Forward selected accounts to the Snap keyring, so each Snaps can fetch those accounts. await this.forwardSelectedAccountGroupToSnapKeyring( + await this.getSnapKeyring(), this.accountTreeController.getSelectedAccountGroup(), ); @@ -4812,6 +4843,7 @@ export default class MetamaskController extends EventEmitter { // TODO: Move this logic to the SnapKeyring directly. // Forward selected accounts to the Snap keyring, so each Snaps can fetch those accounts. await this.forwardSelectedAccountGroupToSnapKeyring( + await this.getSnapKeyring(), this.accountTreeController.getSelectedAccountGroup(), ); } From 40a1ca08881ee3e70d8d43429beb66f5b0b6fb51 Mon Sep 17 00:00:00 2001 From: Charly Chevalier Date: Fri, 10 Oct 2025 18:08:02 +0200 Subject: [PATCH 24/25] test: fix test --- app/scripts/metamask-controller.actions.test.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/scripts/metamask-controller.actions.test.js b/app/scripts/metamask-controller.actions.test.js index a29ea48f339d..e6951dde8cc0 100644 --- a/app/scripts/metamask-controller.actions.test.js +++ b/app/scripts/metamask-controller.actions.test.js @@ -828,6 +828,9 @@ describe('MetaMaskController', function () { ) .mockResolvedValue(); + // We now need the Snap keyring after unlocking the wallet. + jest.spyOn(metamaskController, 'getSnapKeyring').mockReturnValue({}); + const syncAndUnlockResult = await metamaskController.syncPasswordAndUnlockWallet(password); From f1ae84e84b1e951bea4b621522756d903f1abfb8 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Sun, 12 Oct 2025 16:06:16 -0400 Subject: [PATCH 25/25] test: e2e change --- .../page-objects/pages/home/non-evm-homepage.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/e2e/page-objects/pages/home/non-evm-homepage.ts b/test/e2e/page-objects/pages/home/non-evm-homepage.ts index 265204e91506..4ccca833f072 100644 --- a/test/e2e/page-objects/pages/home/non-evm-homepage.ts +++ b/test/e2e/page-objects/pages/home/non-evm-homepage.ts @@ -19,13 +19,13 @@ class NonEvmHomepage extends HomePage { await super.checkPageIsLoaded(); await this.driver.delay(regularDelayMs); // workaround to avoid flakiness if (amount) { - await this.driver.wait(async () => { - await this.driver.waitForSelector({ + await this.driver.waitForSelector( + { + css: this.balanceDiv, text: `${amount}`, - tag: 'span', - }); - return true; - }, 60000); + }, + { timeout: 30000 }, + ); } } @@ -62,16 +62,16 @@ class NonEvmHomepage extends HomePage { async checkGetBalance(balance: string, token: string = 'SOL'): Promise { await this.driver.waitForSelector( { + css: this.balanceDiv, text: balance, - tag: 'span', }, { timeout: 30000 }, ); await this.driver.waitForSelector( { + css: this.balanceDiv, text: token, - tag: 'span', }, { timeout: 30000 }, );