@metamask/snaps-controllers 16.0.0 → 16.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [16.1.0]
11
+
12
+ ### Added
13
+
14
+ - Add NPM proxy support ([#3695](https://github.com/MetaMask/snaps/pull/3695))
15
+
16
+ ### Changed
17
+
18
+ - Bump `@metamask/permission-controller` from `12.0.0` to `12.1.0` ([#3714](https://github.com/MetaMask/snaps/pull/3714))
19
+ - Bump `@metamask/phishing-controller` from `13.1.0` to `15.0.0` ([#3707](https://github.com/MetaMask/snaps/pull/3707))
20
+
21
+ ### Removed
22
+
23
+ - Remove logic for granting CAIP-25 permissions ([#3723](https://github.com/MetaMask/snaps/pull/3723))
24
+
25
+ ### Fixed
26
+
27
+ - Prevent initial connections from being revoked as unused on update ([#3729](https://github.com/MetaMask/snaps/pull/3729))
28
+ - Keep dynamic permissions on update ([#3726](https://github.com/MetaMask/snaps/pull/3726))
29
+
10
30
  ## [16.0.0]
11
31
 
12
32
  ### Changed
@@ -934,7 +954,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
934
954
  - The version of the package no longer needs to match the version of all other
935
955
  MetaMask Snaps packages.
936
956
 
937
- [Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@16.0.0...HEAD
957
+ [Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@16.1.0...HEAD
958
+ [16.1.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@16.0.0...@metamask/snaps-controllers@16.1.0
938
959
  [16.0.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@15.0.2...@metamask/snaps-controllers@16.0.0
939
960
  [15.0.2]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@15.0.1...@metamask/snaps-controllers@15.0.2
940
961
  [15.0.1]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@15.0.0...@metamask/snaps-controllers@15.0.1
@@ -83,7 +83,7 @@ class SnapController extends base_controller_1.BaseController {
83
83
  #preinstalledSnaps;
84
84
  #trackEvent;
85
85
  #trackSnapExport;
86
- constructor({ closeAllConnections, messenger, state, dynamicPermissions = ['eth_accounts'], environmentEndowmentPermissions = [], excludedPermissions = {}, idleTimeCheckInterval = (0, utils_1.inMilliseconds)(5, utils_1.Duration.Second), maxIdleTime = (0, utils_1.inMilliseconds)(30, utils_1.Duration.Second), maxRequestTime = (0, utils_1.inMilliseconds)(60, utils_1.Duration.Second), fetchFunction = globalThis.fetch.bind(undefined), featureFlags = {}, detectSnapLocation: detectSnapLocationFunction = location_1.detectSnapLocation, preinstalledSnaps = null, encryptor, getMnemonicSeed, getFeatureFlags = () => ({}), clientCryptography, trackEvent, }) {
86
+ constructor({ closeAllConnections, messenger, state, dynamicPermissions = ['endowment:caip25', 'wallet_snap'], environmentEndowmentPermissions = [], excludedPermissions = {}, idleTimeCheckInterval = (0, utils_1.inMilliseconds)(5, utils_1.Duration.Second), maxIdleTime = (0, utils_1.inMilliseconds)(30, utils_1.Duration.Second), maxRequestTime = (0, utils_1.inMilliseconds)(60, utils_1.Duration.Second), fetchFunction = globalThis.fetch.bind(undefined), featureFlags = {}, detectSnapLocation: detectSnapLocationFunction = location_1.detectSnapLocation, preinstalledSnaps = null, encryptor, getMnemonicSeed, getFeatureFlags = () => ({}), clientCryptography, trackEvent, }) {
87
87
  super({
88
88
  messenger,
89
89
  metadata: {
@@ -412,6 +412,7 @@ class SnapController extends base_controller_1.BaseController {
412
412
  versionRange: resolvedVersion,
413
413
  fetch: this.#fetchFunction,
414
414
  allowLocal: false,
415
+ useNpmProxy: true,
415
416
  });
416
417
  await this.#updateSnap({
417
418
  origin: approval_controller_1.ORIGIN_METAMASK,
@@ -2303,12 +2304,41 @@ class SnapController extends base_controller_1.BaseController {
2303
2304
  getStateMutex: new async_mutex_1.Mutex(),
2304
2305
  });
2305
2306
  }
2307
+ /**
2308
+ * Get the desired permissions including dynamic permissions. That is, if a
2309
+ * dynamic permission was previously granted and at least one of its
2310
+ * dependencies is still desired, it will be included in the desired
2311
+ * permissions.
2312
+ *
2313
+ * @param oldPermissions - The old permissions.
2314
+ * @param desiredPermissions - The desired permissions.
2315
+ * @returns The desired permissions including dynamic permissions.
2316
+ */
2317
+ #getDesiredPermissions(oldPermissions, desiredPermissions) {
2318
+ return Object.keys(oldPermissions).reduce((accumulator, permissionName) => {
2319
+ if (this.#dynamicPermissions.includes(permissionName)) {
2320
+ const hasDependencies = (0, utils_1.hasProperty)(constants_1.DYNAMIC_PERMISSION_DEPENDENCIES, permissionName);
2321
+ const hasDependency = constants_1.DYNAMIC_PERMISSION_DEPENDENCIES[permissionName]?.some((dependency) => (0, utils_1.hasProperty)(desiredPermissions, dependency));
2322
+ // If the permission doesn't have dependencies, or if at least one of
2323
+ // its dependencies is desired, include it in the desired permissions.
2324
+ // NOTE: This effectively means that any permissions granted in the manifest
2325
+ // that are considered dynamic, will not be automatically revoked
2326
+ // when the permission is removed from the manifest.
2327
+ // TODO: Deal with this technical debt.
2328
+ if (!hasDependencies || hasDependency) {
2329
+ accumulator[permissionName] = oldPermissions[permissionName];
2330
+ }
2331
+ }
2332
+ return accumulator;
2333
+ }, desiredPermissions);
2334
+ }
2306
2335
  #calculatePermissionsChange(snapId, desiredPermissionsSet) {
2307
2336
  const oldPermissions = this.messenger.call('PermissionController:getPermissions', snapId) ?? {};
2308
- const newPermissions = (0, utils_2.permissionsDiff)(desiredPermissionsSet, oldPermissions);
2309
- // TODO(ritave): The assumption that these are unused only holds so long as we do not
2310
- // permit dynamic permission requests.
2311
- const unusedPermissions = (0, utils_2.permissionsDiff)(oldPermissions, desiredPermissionsSet);
2337
+ const desiredPermissionsSetWithDynamic = this.#getDesiredPermissions(oldPermissions, desiredPermissionsSet);
2338
+ const newPermissions = (0, utils_2.permissionsDiff)(desiredPermissionsSetWithDynamic, oldPermissions);
2339
+ // TODO: The assumption that these are unused only holds so long as we do
2340
+ // not permit dynamic permission requests.
2341
+ const unusedPermissions = (0, utils_2.permissionsDiff)(oldPermissions, desiredPermissionsSetWithDynamic);
2312
2342
  // It's a Set Intersection of oldPermissions and desiredPermissionsSet
2313
2343
  // oldPermissions ∖ (oldPermissions ∖ desiredPermissionsSet) ⟺ oldPermissions ∩ desiredPermissionsSet
2314
2344
  const approvedPermissions = (0, utils_2.permissionsDiff)(oldPermissions, unusedPermissions);
@@ -2335,46 +2365,6 @@ class SnapController extends base_controller_1.BaseController {
2335
2365
  const approvedConnections = (0, utils_2.setDiff)(filteredOldConnections, unusedConnections);
2336
2366
  return { newConnections, unusedConnections, approvedConnections };
2337
2367
  }
2338
- /**
2339
- * Get the permissions to grant to a Snap following an install, update or
2340
- * rollback.
2341
- *
2342
- * @param snapId - The snap ID.
2343
- * @param newPermissions - The new permissions to be granted.
2344
- * @returns The permissions to grant to the Snap.
2345
- */
2346
- #getPermissionsToGrant(snapId, newPermissions) {
2347
- if (Object.keys(newPermissions).includes(snaps_rpc_methods_1.SnapEndowments.EthereumProvider)) {
2348
- // This will return the globally selected network if the Snap doesn't have
2349
- // one set.
2350
- const networkClientId = this.messenger.call('SelectedNetworkController:getNetworkClientIdForDomain', snapId);
2351
- const { configuration } = this.messenger.call('NetworkController:getNetworkClientById', networkClientId);
2352
- const chainId = (0, utils_1.hexToNumber)(configuration.chainId);
2353
- // This needs to be assigned to have proper type inference.
2354
- const modifiedPermissions = {
2355
- ...newPermissions,
2356
- 'endowment:caip25': {
2357
- caveats: [
2358
- {
2359
- type: 'authorizedScopes',
2360
- value: {
2361
- requiredScopes: {},
2362
- optionalScopes: {
2363
- [`eip155:${chainId}`]: {
2364
- accounts: [],
2365
- },
2366
- },
2367
- sessionProperties: {},
2368
- isMultichainOrigin: false,
2369
- },
2370
- },
2371
- ],
2372
- },
2373
- };
2374
- return modifiedPermissions;
2375
- }
2376
- return newPermissions;
2377
- }
2378
2368
  /**
2379
2369
  * Update the permissions for a snap following an install, update or rollback.
2380
2370
  *
@@ -2394,9 +2384,8 @@ class SnapController extends base_controller_1.BaseController {
2394
2384
  });
2395
2385
  }
2396
2386
  if ((0, utils_1.isNonEmptyArray)(Object.keys(newPermissions))) {
2397
- const approvedPermissions = this.#getPermissionsToGrant(snapId, newPermissions);
2398
2387
  this.messenger.call('PermissionController:grantPermissions', {
2399
- approvedPermissions,
2388
+ approvedPermissions: newPermissions,
2400
2389
  subject: { origin: snapId },
2401
2390
  requestData,
2402
2391
  });