diff --git a/packages/snaps-controllers/package.json b/packages/snaps-controllers/package.json index cec30b479c..df12c52272 100644 --- a/packages/snaps-controllers/package.json +++ b/packages/snaps-controllers/package.json @@ -57,11 +57,13 @@ "@metamask/base-controller": "^6.0.2", "@metamask/json-rpc-engine": "^9.0.2", "@metamask/json-rpc-middleware-stream": "^8.0.2", + "@metamask/network-controller": "^20.1.0", "@metamask/object-multiplex": "^2.0.0", "@metamask/permission-controller": "^11.0.0", "@metamask/phishing-controller": "^10.1.1", "@metamask/post-message-stream": "^8.1.0", "@metamask/rpc-errors": "^6.3.1", + "@metamask/selected-network-controller": "^17.0.0", "@metamask/snaps-registry": "^3.2.1", "@metamask/snaps-rpc-methods": "workspace:^", "@metamask/snaps-sdk": "workspace:^", diff --git a/packages/snaps-controllers/src/snaps/SnapController.ts b/packages/snaps-controllers/src/snaps/SnapController.ts index 41e20cadc3..96550e2ab8 100644 --- a/packages/snaps-controllers/src/snaps/SnapController.ts +++ b/packages/snaps-controllers/src/snaps/SnapController.ts @@ -4,6 +4,7 @@ import type { } from '@metamask/approval-controller'; import type { RestrictedControllerMessenger } from '@metamask/base-controller'; import { BaseController } from '@metamask/base-controller'; +import type { NetworkControllerGetNetworkClientByIdAction } from '@metamask/network-controller'; import type { Caveat, GetEndowments, @@ -26,6 +27,7 @@ import type { } from '@metamask/permission-controller'; import { SubjectType } from '@metamask/permission-controller'; import { rpcErrors } from '@metamask/rpc-errors'; +import type { SelectedNetworkControllerGetNetworkClientIdForDomainAction } from '@metamask/selected-network-controller'; import type { BlockReason } from '@metamask/snaps-registry'; import { WALLET_SNAP_PERMISSION_KEY, @@ -556,7 +558,9 @@ export type AllowedActions = | Update | ResolveVersion | CreateInterface - | GetInterface; + | GetInterface + | NetworkControllerGetNetworkClientByIdAction + | SelectedNetworkControllerGetNetworkClientIdForDomainAction; export type AllowedEvents = | ExecutionServiceEvents @@ -3624,7 +3628,50 @@ export class SnapController extends BaseController< } /** - * Updates the permissions for a snap following an install, update or rollback. + * Get the permissions to grant to a Snap following an install, update or + * rollback. + * + * @param snapId - The snap ID. + * @param newPermissions - The new permissions to be granted. + * @returns The permissions to grant to the Snap. + */ + #getPermissionsToGrant(snapId: SnapId, newPermissions: RequestedPermissions) { + if (Object.keys(newPermissions).includes(SnapEndowments.EthereumProvider)) { + const networkClientId = this.messagingSystem.call( + 'SelectedNetworkController:getNetworkClientIdForDomain', + snapId, + ); + + const { configuration } = this.messagingSystem.call( + 'NetworkController:getNetworkClientById', + networkClientId, + ); + + // This needs to be assigned to have proper type inference. + const modifiedPermissions: RequestedPermissions = { + ...newPermissions, + permittedChains: { + caveats: [ + { + type: 'restrictNetworkSwitching', + value: [configuration.chainId], + }, + ], + date: Date.now(), + id: nanoid(), + invoker: snapId, + parentCapability: 'permittedChains', + }, + }; + + return modifiedPermissions; + } + + return newPermissions; + } + + /** + * Update the permissions for a snap following an install, update or rollback. * * Grants newly requested permissions and revokes unused/revoked permissions. * @@ -3657,8 +3704,13 @@ export class SnapController extends BaseController< } if (isNonEmptyArray(Object.keys(newPermissions))) { + const approvedPermissions = this.#getPermissionsToGrant( + snapId, + newPermissions, + ); + this.messagingSystem.call('PermissionController:grantPermissions', { - approvedPermissions: newPermissions, + approvedPermissions, subject: { origin: snapId }, requestData, }); diff --git a/yarn.lock b/yarn.lock index 994934591a..aa64c19d56 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4422,6 +4422,49 @@ __metadata: languageName: node linkType: hard +"@metamask/eth-block-tracker@npm:^9.0.3": + version: 9.0.3 + resolution: "@metamask/eth-block-tracker@npm:9.0.3" + dependencies: + "@metamask/eth-json-rpc-provider": ^3.0.2 + "@metamask/safe-event-emitter": ^3.0.0 + "@metamask/utils": ^8.1.0 + json-rpc-random-id: ^1.0.1 + pify: ^5.0.0 + checksum: edd3d59a0416752d90c8e2d8c10c31635dbe3eb323fcb054c401528afe4cbbb6a5a85aedd6ffee4a504d9779656bfab027f2274fd95981c90bf56b6f565dbca2 + languageName: node + linkType: hard + +"@metamask/eth-json-rpc-infura@npm:^9.1.0": + version: 9.1.0 + resolution: "@metamask/eth-json-rpc-infura@npm:9.1.0" + dependencies: + "@metamask/eth-json-rpc-provider": ^2.1.0 + "@metamask/json-rpc-engine": ^7.1.1 + "@metamask/rpc-errors": ^6.0.0 + "@metamask/utils": ^8.1.0 + node-fetch: ^2.7.0 + checksum: 58f2a6b6ce9c545c9210b2ab3f8c0946cc82ed02c82a096406d8c7146c89c1eba1a13e472048a6e252906dd5eb336e63238d9a5446407c1d46b1d6a40e2a64f4 + languageName: node + linkType: hard + +"@metamask/eth-json-rpc-middleware@npm:^12.1.1": + version: 12.1.2 + resolution: "@metamask/eth-json-rpc-middleware@npm:12.1.2" + dependencies: + "@metamask/eth-block-tracker": ^9.0.3 + "@metamask/eth-json-rpc-provider": ^3.0.2 + "@metamask/eth-sig-util": ^7.0.0 + "@metamask/json-rpc-engine": ^8.0.2 + "@metamask/rpc-errors": ^6.0.0 + "@metamask/utils": ^8.1.0 + klona: ^2.0.6 + pify: ^5.0.0 + safe-stable-stringify: ^2.4.3 + checksum: 0334fa8e51d73488e42e1cd663e90012f4055c5cd04cb4ff371ecb3552b82cd271f27a88ff0187ad23f195cfbbba467126711c08b20c1124083a706a85524a82 + languageName: node + linkType: hard + "@metamask/eth-json-rpc-middleware@npm:^13.0.0": version: 13.0.0 resolution: "@metamask/eth-json-rpc-middleware@npm:13.0.0" @@ -4441,16 +4484,38 @@ __metadata: languageName: node linkType: hard -"@metamask/eth-json-rpc-provider@npm:^4.0.0": - version: 4.1.2 - resolution: "@metamask/eth-json-rpc-provider@npm:4.1.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: + "@metamask/json-rpc-engine": ^7.3.2 + "@metamask/safe-event-emitter": ^3.0.0 + "@metamask/utils": ^8.3.0 + checksum: e6731271aad3b972d85b9230c26d35a9b88722f3bd3024675ad2f568e634e9fdfef4717ef2892f3cc512d381cf17a4e20dbd5eb808ced765082bea3379ad6ddc + languageName: node + linkType: hard + +"@metamask/eth-json-rpc-provider@npm:^3.0.2": + version: 3.0.2 + resolution: "@metamask/eth-json-rpc-provider@npm:3.0.2" + dependencies: + "@metamask/json-rpc-engine": ^8.0.2 + "@metamask/safe-event-emitter": ^3.0.0 + "@metamask/utils": ^8.3.0 + checksum: 0321eaad6fa205a9d3ddcfaf28e63c05291614893cb2e116151185a4acbd6bb6a508d6e556b3cb8bc4d3caef4bf0a638202d9b6bdc127fbcb81715eb2660a809 + languageName: node + linkType: hard + +"@metamask/eth-json-rpc-provider@npm:^4.0.0, @metamask/eth-json-rpc-provider@npm:^4.1.2": + version: 4.1.3 + resolution: "@metamask/eth-json-rpc-provider@npm:4.1.3" dependencies: "@metamask/json-rpc-engine": ^9.0.2 "@metamask/rpc-errors": ^6.3.1 "@metamask/safe-event-emitter": ^3.0.0 "@metamask/utils": ^9.1.0 uuid: ^8.3.2 - checksum: d7092ce64fc185796a0be3f339da1718e280159f06e8fdf29a002b4573abd0903219a527a4c5890952d5e66dbe56b5c3e53d42aa8a4bbc25acbdf6efadcff6ea + checksum: 788c1f983d8021a10922f414f7c5aa93f79e14000219bd5155f027c1964e73d08e931cb98749057f57fb4001441098724aedacbe2198ab5a0b28cc3fcb4d262d languageName: node linkType: hard @@ -4881,6 +4946,28 @@ __metadata: languageName: unknown linkType: soft +"@metamask/json-rpc-engine@npm:^7.1.1, @metamask/json-rpc-engine@npm:^7.3.2": + version: 7.3.3 + resolution: "@metamask/json-rpc-engine@npm:7.3.3" + dependencies: + "@metamask/rpc-errors": ^6.2.1 + "@metamask/safe-event-emitter": ^3.0.0 + "@metamask/utils": ^8.3.0 + checksum: 7bab8b4d2341a6243ba451bc58283f0a6905b09f7257857859848a51a795444ca6899b1a6908b15f8ed236fb574ab85a630c9cb28d127ab52c4630e496c16006 + languageName: node + linkType: hard + +"@metamask/json-rpc-engine@npm:^8.0.2": + version: 8.0.2 + resolution: "@metamask/json-rpc-engine@npm:8.0.2" + dependencies: + "@metamask/rpc-errors": ^6.2.1 + "@metamask/safe-event-emitter": ^3.0.0 + "@metamask/utils": ^8.3.0 + checksum: c240d298ad503d93922a94a62cf59f0344b6d6644a523bc8ea3c0f321bea7172b89f2747a5618e2861b2e8152ae5086b76f391a10e4566529faa50b8850c051d + languageName: node + linkType: hard + "@metamask/json-rpc-engine@npm:^9.0.0, @metamask/json-rpc-engine@npm:^9.0.1, @metamask/json-rpc-engine@npm:^9.0.2": version: 9.0.2 resolution: "@metamask/json-rpc-engine@npm:9.0.2" @@ -5135,6 +5222,29 @@ __metadata: languageName: unknown linkType: soft +"@metamask/network-controller@npm:^20.1.0": + version: 20.1.0 + resolution: "@metamask/network-controller@npm:20.1.0" + dependencies: + "@metamask/base-controller": ^6.0.2 + "@metamask/controller-utils": ^11.0.2 + "@metamask/eth-block-tracker": ^9.0.3 + "@metamask/eth-json-rpc-infura": ^9.1.0 + "@metamask/eth-json-rpc-middleware": ^12.1.1 + "@metamask/eth-json-rpc-provider": ^4.1.2 + "@metamask/eth-query": ^4.0.0 + "@metamask/json-rpc-engine": ^9.0.2 + "@metamask/rpc-errors": ^6.3.1 + "@metamask/swappable-obj-proxy": ^2.2.0 + "@metamask/utils": ^9.1.0 + async-mutex: ^0.5.0 + immer: ^9.0.6 + loglevel: ^1.8.1 + uuid: ^8.3.2 + checksum: 41aa7f2cd693850b3f3ce3a0937b67bdca482bf573b1b96fa36cbf75728c3593c2082b2cd99497cf2cb182912f73e784a6cc8c4db0357bf452caa2d5890329c7 + languageName: node + linkType: hard + "@metamask/network-example-snap@workspace:^, @metamask/network-example-snap@workspace:packages/examples/packages/network-access": version: 0.0.0-use.local resolution: "@metamask/network-example-snap@workspace:packages/examples/packages/network-access" @@ -5337,7 +5447,7 @@ __metadata: languageName: unknown linkType: soft -"@metamask/rpc-errors@npm:^6.0.0, @metamask/rpc-errors@npm:^6.3.1": +"@metamask/rpc-errors@npm:^6.0.0, @metamask/rpc-errors@npm:^6.2.1, @metamask/rpc-errors@npm:^6.3.1": version: 6.3.1 resolution: "@metamask/rpc-errors@npm:6.3.1" dependencies: @@ -5364,6 +5474,21 @@ __metadata: languageName: node linkType: hard +"@metamask/selected-network-controller@npm:^17.0.0": + version: 17.0.0 + resolution: "@metamask/selected-network-controller@npm:17.0.0" + dependencies: + "@metamask/base-controller": ^6.0.2 + "@metamask/json-rpc-engine": ^9.0.2 + "@metamask/swappable-obj-proxy": ^2.2.0 + "@metamask/utils": ^9.1.0 + peerDependencies: + "@metamask/network-controller": ^20.0.0 + "@metamask/permission-controller": ^11.0.0 + checksum: 8ad6a64c4e51a7538e85b81065e1b2fc3648bc771f8406eafd2d53064b09739b2c6d1b2b6d6b1e8e17bad5400cee0206235f82cad4e51308263306d8fac32845 + languageName: node + linkType: hard + "@metamask/signature-insights-example-snap@workspace:^, @metamask/signature-insights-example-snap@workspace:packages/examples/packages/signature-insights": version: 0.0.0-use.local resolution: "@metamask/signature-insights-example-snap@workspace:packages/examples/packages/signature-insights" @@ -5562,11 +5687,13 @@ __metadata: "@metamask/eslint-config-typescript": ^12.1.0 "@metamask/json-rpc-engine": ^9.0.2 "@metamask/json-rpc-middleware-stream": ^8.0.2 + "@metamask/network-controller": ^20.1.0 "@metamask/object-multiplex": ^2.0.0 "@metamask/permission-controller": ^11.0.0 "@metamask/phishing-controller": ^10.1.1 "@metamask/post-message-stream": ^8.1.0 "@metamask/rpc-errors": ^6.3.1 + "@metamask/selected-network-controller": ^17.0.0 "@metamask/snaps-registry": ^3.2.1 "@metamask/snaps-rpc-methods": "workspace:^" "@metamask/snaps-sdk": "workspace:^" @@ -6162,6 +6289,13 @@ __metadata: languageName: node linkType: hard +"@metamask/swappable-obj-proxy@npm:^2.2.0": + version: 2.2.0 + resolution: "@metamask/swappable-obj-proxy@npm:2.2.0" + checksum: 343c95f72c96776980ef3e70600f7fa312be9a75683c132404a66ddd3c507abadee9c4deba1385246f73bded1938a7958e5a89fc407c19dfc352dd9b398e216f + languageName: node + linkType: hard + "@metamask/template-snap@npm:^0.7.0": version: 0.7.0 resolution: "@metamask/template-snap@npm:0.7.0" @@ -6255,7 +6389,7 @@ __metadata: languageName: unknown linkType: soft -"@metamask/utils@npm:^8.1.0, @metamask/utils@npm:^8.2.0, @metamask/utils@npm:^8.2.1": +"@metamask/utils@npm:^8.1.0, @metamask/utils@npm:^8.2.0, @metamask/utils@npm:^8.2.1, @metamask/utils@npm:^8.3.0": version: 8.5.0 resolution: "@metamask/utils@npm:8.5.0" dependencies: @@ -9442,6 +9576,15 @@ __metadata: languageName: node linkType: hard +"async-mutex@npm:^0.5.0": + version: 0.5.0 + resolution: "async-mutex@npm:0.5.0" + dependencies: + tslib: ^2.4.0 + checksum: be1587f4875f3bb15e34e9fcce82eac2966daef4432c8d0046e61947fb9a1b95405284601bc7ce4869319249bc07c75100880191db6af11d1498931ac2a2f9ea + languageName: node + linkType: hard + "async@npm:^3.2.3, async@npm:^3.2.4": version: 3.2.4 resolution: "async@npm:3.2.4" @@ -16904,10 +17047,10 @@ __metadata: languageName: node linkType: hard -"loglevel@npm:^1.6.0": - version: 1.8.1 - resolution: "loglevel@npm:1.8.1" - checksum: a1a62db40291aaeaef2f612334c49e531bff71cc1d01a2acab689ab80d59e092f852ab164a5aedc1a752fdc46b7b162cb097d8a9eb2cf0b299511106c29af61d +"loglevel@npm:^1.6.0, loglevel@npm:^1.8.1": + version: 1.9.1 + resolution: "loglevel@npm:1.9.1" + checksum: e1c8586108c4d566122e91f8a79c8df728920e3a714875affa5120566761a24077ec8ec9e5fc388b022e39fc411ec6e090cde1b5775871241b045139771eeb06 languageName: node linkType: hard @@ -17822,7 +17965,7 @@ __metadata: languageName: node linkType: hard -"node-fetch@npm:^2.6.11, node-fetch@npm:^2.6.12": +"node-fetch@npm:^2.6.11, node-fetch@npm:^2.6.12, node-fetch@npm:^2.7.0": version: 2.7.0 resolution: "node-fetch@npm:2.7.0" dependencies: