@metamask/snaps-controllers 18.0.1 → 18.0.2

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,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [18.0.2]
11
+
12
+ ### Changed
13
+
14
+ - Bump `@metamask/json-rpc-engine` from `10.2.2` to `10.2.3` ([#3884](https://github.com/MetaMask/snaps/pull/3884))
15
+
16
+ ### Fixed
17
+
18
+ - Recover if preinstalled Snaps source code is missing ([#3886](https://github.com/MetaMask/snaps/pull/3886))
19
+
10
20
  ## [18.0.1]
11
21
 
12
22
  ### Changed
@@ -1053,7 +1063,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1053
1063
  - The version of the package no longer needs to match the version of all other
1054
1064
  MetaMask Snaps packages.
1055
1065
 
1056
- [Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@18.0.1...HEAD
1066
+ [Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@18.0.2...HEAD
1067
+ [18.0.2]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@18.0.1...@metamask/snaps-controllers@18.0.2
1057
1068
  [18.0.1]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@18.0.0...@metamask/snaps-controllers@18.0.1
1058
1069
  [18.0.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@17.2.1...@metamask/snaps-controllers@18.0.0
1059
1070
  [17.2.1]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@17.2.0...@metamask/snaps-controllers@17.2.1
@@ -337,9 +337,16 @@ class SnapController extends base_controller_1.BaseController {
337
337
  const existingSnap = this.get(snapId);
338
338
  const isAlreadyInstalled = existingSnap !== undefined;
339
339
  const isUpdate = isAlreadyInstalled && (0, utils_1.gtVersion)(manifest.version, existingSnap.version);
340
+ const isPreinstalled = existingSnap?.preinstalled === true;
341
+ const isMissingSource = isAlreadyInstalled &&
342
+ isPreinstalled &&
343
+ !(await this.#hasSourceCode(snapId));
340
344
  // Disallow downgrades and overwriting non preinstalled snaps
345
+ // As a mitigation for state corruption on mobile, if the source code is missing
346
+ // we allow overwriting and potentially downgrading the current version of the preinstalled Snap.
341
347
  if (isAlreadyInstalled &&
342
- (!isUpdate || existingSnap.preinstalled !== true)) {
348
+ !isMissingSource &&
349
+ (!isUpdate || !isPreinstalled)) {
343
350
  continue;
344
351
  }
345
352
  const manifestFile = new snaps_utils_1.VirtualFile({
@@ -393,9 +400,13 @@ class SnapController extends base_controller_1.BaseController {
393
400
  if (isUpdate) {
394
401
  this.messenger.publish('SnapController:snapUpdated', this.getTruncatedExpect(snapId), existingSnap.version, constants_1.METAMASK_ORIGIN, true);
395
402
  }
396
- else {
403
+ else if (!isMissingSource) {
397
404
  this.messenger.publish('SnapController:snapInstalled', this.getTruncatedExpect(snapId), constants_1.METAMASK_ORIGIN, true);
398
405
  }
406
+ if (isMissingSource) {
407
+ (0, snaps_utils_1.logWarning)(`The source code for "${snapId}" was missing and has been automatically restored. If you see this message, please file a bug report.`);
408
+ this.messenger.captureException?.(new Error(`The source code for "${snapId}" was missing and has been automatically restored. This could indicate persistence issues.`));
409
+ }
399
410
  }
400
411
  // Ensure all preinstalled Snaps have their expected permissions.
401
412
  for (const snap of Object.values(this.state.snaps).filter(({ preinstalled }) => preinstalled)) {
@@ -2572,6 +2583,16 @@ class SnapController extends base_controller_1.BaseController {
2572
2583
  runtime.state = undefined;
2573
2584
  }
2574
2585
  }
2586
+ /**
2587
+ * Check whether a Snap has valid source code in storage.
2588
+ *
2589
+ * @param snapId - The Snap ID.
2590
+ * @returns True if the source code is valid, otherwise false.
2591
+ */
2592
+ async #hasSourceCode(snapId) {
2593
+ const sourceCode = await this.#getSourceCode(snapId).catch(() => null);
2594
+ return typeof sourceCode === 'string';
2595
+ }
2575
2596
  /**
2576
2597
  * Retrieve the source code for a Snap from storage.
2577
2598
  *