@metamask/snaps-controllers 20.0.0 → 20.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,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [20.0.2]
11
+
12
+ ### Fixed
13
+
14
+ - Increase iframe unload timeout ([#3971](https://github.com/MetaMask/snaps/pull/3971))
15
+
16
+ ## [20.0.1]
17
+
18
+ ### Fixed
19
+
20
+ - Skip refetching the registry in `handleRegistryUpdate` ([#3961](https://github.com/MetaMask/snaps/pull/3961))
21
+
10
22
  ## [20.0.0]
11
23
 
12
24
  ### Changed
@@ -1189,7 +1201,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1189
1201
  - The version of the package no longer needs to match the version of all other
1190
1202
  MetaMask Snaps packages.
1191
1203
 
1192
- [Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@20.0.0...HEAD
1204
+ [Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@20.0.2...HEAD
1205
+ [20.0.2]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@20.0.1...@metamask/snaps-controllers@20.0.2
1206
+ [20.0.1]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@20.0.0...@metamask/snaps-controllers@20.0.1
1193
1207
  [20.0.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@19.0.1...@metamask/snaps-controllers@20.0.0
1194
1208
  [19.0.1]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@19.0.0...@metamask/snaps-controllers@19.0.1
1195
1209
  [19.0.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@18.0.4...@metamask/snaps-controllers@19.0.0
@@ -24,7 +24,7 @@ class IframeExecutionService extends ExecutionService_1.ExecutionService {
24
24
  await (0, utils_1.withTimeout)(new Promise((resolve) => {
25
25
  iframe.addEventListener('load', () => resolve(), { once: true });
26
26
  iframe.src = 'about:blank';
27
- }), 10);
27
+ }), 1000);
28
28
  iframe.remove();
29
29
  }
30
30
  async initEnvStream(snapId) {
@@ -1 +1 @@
1
- {"version":3,"file":"IframeExecutionService.cjs","sourceRoot":"","sources":["../../../src/services/iframe/IframeExecutionService.ts"],"names":[],"mappings":";;;AACA,uEAAwE;AACxE,uDAAqD;AAErD,2CAA0C;AAK1C,8DAAuD;AAMvD,MAAa,sBAAuB,SAAQ,mCAAwB;IAC3D,SAAS,CAAM;IAEtB,YAAY,EACV,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,GAAG,IAAI,EAC+B;QACtC,KAAK,CAAC;YACJ,GAAG,IAAI;YACP,SAAS;YACT,iBAAiB;SAClB,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAES,KAAK,CAAC,YAAY,CAC1B,UAAoC;QAEpC,MAAM,MAAM,GAAG,QAAQ,CAAC,cAAc,CACpC,UAAU,CAAC,EAAE,CACc,CAAC;QAE9B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QAED,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;QAEf,MAAM,IAAA,mBAAW,EACf,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAC5B,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACjE,MAAM,CAAC,GAAG,GAAG,aAAa,CAAC;QAC7B,CAAC,CAAC,EACF,EAAE,CACH,CAAC;QAEF,MAAM,CAAC,MAAM,EAAE,CAAC;IAClB,CAAC;IAES,KAAK,CAAC,aAAa,CAAC,MAAc;QAI1C,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAE3C,MAAM,YAAY,GAAG,MAAM,IAAA,0BAAY,EAAC;YACtC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE;YAC9B,EAAE,EAAE,MAAM;SACX,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,IAAI,6CAAuB,CAAC;YACzC,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,OAAO;YACf,YAAY,EAAE,YAAY;YAC1B,YAAY,EAAE,GAAG;SAClB,CAAC,CAAC;QAEH,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;IAC1C,CAAC;CACF;AA7DD,wDA6DC","sourcesContent":["import type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { WindowPostMessageStream } from '@metamask/post-message-stream';\nimport { createWindow } from '@metamask/snaps-utils';\n\nimport { withTimeout } from '../../utils';\nimport type {\n ExecutionServiceArgs,\n TerminateJobArgs,\n} from '../ExecutionService';\nimport { ExecutionService } from '../ExecutionService';\n\ntype IframeExecutionEnvironmentServiceArgs = {\n iframeUrl: URL;\n} & ExecutionServiceArgs;\n\nexport class IframeExecutionService extends ExecutionService<Window> {\n public iframeUrl: URL;\n\n constructor({\n iframeUrl,\n messenger,\n setupSnapProvider,\n ...args\n }: IframeExecutionEnvironmentServiceArgs) {\n super({\n ...args,\n messenger,\n setupSnapProvider,\n });\n this.iframeUrl = iframeUrl;\n }\n\n protected async terminateJob(\n jobWrapper: TerminateJobArgs<Window>,\n ): Promise<void> {\n const iframe = document.getElementById(\n jobWrapper.id,\n ) as HTMLIFrameElement | null;\n\n if (!iframe) {\n return;\n }\n\n iframe.id = '';\n\n await withTimeout(\n new Promise<void>((resolve) => {\n iframe.addEventListener('load', () => resolve(), { once: true });\n iframe.src = 'about:blank';\n }),\n 10,\n );\n\n iframe.remove();\n }\n\n protected async initEnvStream(snapId: string): Promise<{\n worker: Window;\n stream: BasePostMessageStream;\n }> {\n this.setSnapStatus(snapId, 'initializing');\n\n const iframeWindow = await createWindow({\n uri: this.iframeUrl.toString(),\n id: snapId,\n });\n\n const stream = new WindowPostMessageStream({\n name: 'parent',\n target: 'child',\n targetWindow: iframeWindow,\n targetOrigin: '*',\n });\n\n return { worker: iframeWindow, stream };\n }\n}\n"]}
1
+ {"version":3,"file":"IframeExecutionService.cjs","sourceRoot":"","sources":["../../../src/services/iframe/IframeExecutionService.ts"],"names":[],"mappings":";;;AACA,uEAAwE;AACxE,uDAAqD;AAErD,2CAA0C;AAK1C,8DAAuD;AAMvD,MAAa,sBAAuB,SAAQ,mCAAwB;IAC3D,SAAS,CAAM;IAEtB,YAAY,EACV,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,GAAG,IAAI,EAC+B;QACtC,KAAK,CAAC;YACJ,GAAG,IAAI;YACP,SAAS;YACT,iBAAiB;SAClB,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAES,KAAK,CAAC,YAAY,CAC1B,UAAoC;QAEpC,MAAM,MAAM,GAAG,QAAQ,CAAC,cAAc,CACpC,UAAU,CAAC,EAAE,CACc,CAAC;QAE9B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QAED,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;QAEf,MAAM,IAAA,mBAAW,EACf,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAC5B,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACjE,MAAM,CAAC,GAAG,GAAG,aAAa,CAAC;QAC7B,CAAC,CAAC,EACF,IAAK,CACN,CAAC;QAEF,MAAM,CAAC,MAAM,EAAE,CAAC;IAClB,CAAC;IAES,KAAK,CAAC,aAAa,CAAC,MAAc;QAI1C,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAE3C,MAAM,YAAY,GAAG,MAAM,IAAA,0BAAY,EAAC;YACtC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE;YAC9B,EAAE,EAAE,MAAM;SACX,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,IAAI,6CAAuB,CAAC;YACzC,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,OAAO;YACf,YAAY,EAAE,YAAY;YAC1B,YAAY,EAAE,GAAG;SAClB,CAAC,CAAC;QAEH,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;IAC1C,CAAC;CACF;AA7DD,wDA6DC","sourcesContent":["import type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { WindowPostMessageStream } from '@metamask/post-message-stream';\nimport { createWindow } from '@metamask/snaps-utils';\n\nimport { withTimeout } from '../../utils';\nimport type {\n ExecutionServiceArgs,\n TerminateJobArgs,\n} from '../ExecutionService';\nimport { ExecutionService } from '../ExecutionService';\n\ntype IframeExecutionEnvironmentServiceArgs = {\n iframeUrl: URL;\n} & ExecutionServiceArgs;\n\nexport class IframeExecutionService extends ExecutionService<Window> {\n public iframeUrl: URL;\n\n constructor({\n iframeUrl,\n messenger,\n setupSnapProvider,\n ...args\n }: IframeExecutionEnvironmentServiceArgs) {\n super({\n ...args,\n messenger,\n setupSnapProvider,\n });\n this.iframeUrl = iframeUrl;\n }\n\n protected async terminateJob(\n jobWrapper: TerminateJobArgs<Window>,\n ): Promise<void> {\n const iframe = document.getElementById(\n jobWrapper.id,\n ) as HTMLIFrameElement | null;\n\n if (!iframe) {\n return;\n }\n\n iframe.id = '';\n\n await withTimeout(\n new Promise<void>((resolve) => {\n iframe.addEventListener('load', () => resolve(), { once: true });\n iframe.src = 'about:blank';\n }),\n 1_000,\n );\n\n iframe.remove();\n }\n\n protected async initEnvStream(snapId: string): Promise<{\n worker: Window;\n stream: BasePostMessageStream;\n }> {\n this.setSnapStatus(snapId, 'initializing');\n\n const iframeWindow = await createWindow({\n uri: this.iframeUrl.toString(),\n id: snapId,\n });\n\n const stream = new WindowPostMessageStream({\n name: 'parent',\n target: 'child',\n targetWindow: iframeWindow,\n targetOrigin: '*',\n });\n\n return { worker: iframeWindow, stream };\n }\n}\n"]}
@@ -21,7 +21,7 @@ export class IframeExecutionService extends ExecutionService {
21
21
  await withTimeout(new Promise((resolve) => {
22
22
  iframe.addEventListener('load', () => resolve(), { once: true });
23
23
  iframe.src = 'about:blank';
24
- }), 10);
24
+ }), 1000);
25
25
  iframe.remove();
26
26
  }
27
27
  async initEnvStream(snapId) {
@@ -1 +1 @@
1
- {"version":3,"file":"IframeExecutionService.mjs","sourceRoot":"","sources":["../../../src/services/iframe/IframeExecutionService.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,sCAAsC;AACxE,OAAO,EAAE,YAAY,EAAE,8BAA8B;AAErD,OAAO,EAAE,WAAW,EAAE,wBAAoB;AAK1C,OAAO,EAAE,gBAAgB,EAAE,gCAA4B;AAMvD,MAAM,OAAO,sBAAuB,SAAQ,gBAAwB;IAC3D,SAAS,CAAM;IAEtB,YAAY,EACV,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,GAAG,IAAI,EAC+B;QACtC,KAAK,CAAC;YACJ,GAAG,IAAI;YACP,SAAS;YACT,iBAAiB;SAClB,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAES,KAAK,CAAC,YAAY,CAC1B,UAAoC;QAEpC,MAAM,MAAM,GAAG,QAAQ,CAAC,cAAc,CACpC,UAAU,CAAC,EAAE,CACc,CAAC;QAE9B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QAED,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;QAEf,MAAM,WAAW,CACf,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAC5B,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACjE,MAAM,CAAC,GAAG,GAAG,aAAa,CAAC;QAC7B,CAAC,CAAC,EACF,EAAE,CACH,CAAC;QAEF,MAAM,CAAC,MAAM,EAAE,CAAC;IAClB,CAAC;IAES,KAAK,CAAC,aAAa,CAAC,MAAc;QAI1C,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAE3C,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC;YACtC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE;YAC9B,EAAE,EAAE,MAAM;SACX,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,IAAI,uBAAuB,CAAC;YACzC,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,OAAO;YACf,YAAY,EAAE,YAAY;YAC1B,YAAY,EAAE,GAAG;SAClB,CAAC,CAAC;QAEH,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;IAC1C,CAAC;CACF","sourcesContent":["import type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { WindowPostMessageStream } from '@metamask/post-message-stream';\nimport { createWindow } from '@metamask/snaps-utils';\n\nimport { withTimeout } from '../../utils';\nimport type {\n ExecutionServiceArgs,\n TerminateJobArgs,\n} from '../ExecutionService';\nimport { ExecutionService } from '../ExecutionService';\n\ntype IframeExecutionEnvironmentServiceArgs = {\n iframeUrl: URL;\n} & ExecutionServiceArgs;\n\nexport class IframeExecutionService extends ExecutionService<Window> {\n public iframeUrl: URL;\n\n constructor({\n iframeUrl,\n messenger,\n setupSnapProvider,\n ...args\n }: IframeExecutionEnvironmentServiceArgs) {\n super({\n ...args,\n messenger,\n setupSnapProvider,\n });\n this.iframeUrl = iframeUrl;\n }\n\n protected async terminateJob(\n jobWrapper: TerminateJobArgs<Window>,\n ): Promise<void> {\n const iframe = document.getElementById(\n jobWrapper.id,\n ) as HTMLIFrameElement | null;\n\n if (!iframe) {\n return;\n }\n\n iframe.id = '';\n\n await withTimeout(\n new Promise<void>((resolve) => {\n iframe.addEventListener('load', () => resolve(), { once: true });\n iframe.src = 'about:blank';\n }),\n 10,\n );\n\n iframe.remove();\n }\n\n protected async initEnvStream(snapId: string): Promise<{\n worker: Window;\n stream: BasePostMessageStream;\n }> {\n this.setSnapStatus(snapId, 'initializing');\n\n const iframeWindow = await createWindow({\n uri: this.iframeUrl.toString(),\n id: snapId,\n });\n\n const stream = new WindowPostMessageStream({\n name: 'parent',\n target: 'child',\n targetWindow: iframeWindow,\n targetOrigin: '*',\n });\n\n return { worker: iframeWindow, stream };\n }\n}\n"]}
1
+ {"version":3,"file":"IframeExecutionService.mjs","sourceRoot":"","sources":["../../../src/services/iframe/IframeExecutionService.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,sCAAsC;AACxE,OAAO,EAAE,YAAY,EAAE,8BAA8B;AAErD,OAAO,EAAE,WAAW,EAAE,wBAAoB;AAK1C,OAAO,EAAE,gBAAgB,EAAE,gCAA4B;AAMvD,MAAM,OAAO,sBAAuB,SAAQ,gBAAwB;IAC3D,SAAS,CAAM;IAEtB,YAAY,EACV,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,GAAG,IAAI,EAC+B;QACtC,KAAK,CAAC;YACJ,GAAG,IAAI;YACP,SAAS;YACT,iBAAiB;SAClB,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAES,KAAK,CAAC,YAAY,CAC1B,UAAoC;QAEpC,MAAM,MAAM,GAAG,QAAQ,CAAC,cAAc,CACpC,UAAU,CAAC,EAAE,CACc,CAAC;QAE9B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QAED,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;QAEf,MAAM,WAAW,CACf,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAC5B,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACjE,MAAM,CAAC,GAAG,GAAG,aAAa,CAAC;QAC7B,CAAC,CAAC,EACF,IAAK,CACN,CAAC;QAEF,MAAM,CAAC,MAAM,EAAE,CAAC;IAClB,CAAC;IAES,KAAK,CAAC,aAAa,CAAC,MAAc;QAI1C,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAE3C,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC;YACtC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE;YAC9B,EAAE,EAAE,MAAM;SACX,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,IAAI,uBAAuB,CAAC;YACzC,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,OAAO;YACf,YAAY,EAAE,YAAY;YAC1B,YAAY,EAAE,GAAG;SAClB,CAAC,CAAC;QAEH,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC;IAC1C,CAAC;CACF","sourcesContent":["import type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { WindowPostMessageStream } from '@metamask/post-message-stream';\nimport { createWindow } from '@metamask/snaps-utils';\n\nimport { withTimeout } from '../../utils';\nimport type {\n ExecutionServiceArgs,\n TerminateJobArgs,\n} from '../ExecutionService';\nimport { ExecutionService } from '../ExecutionService';\n\ntype IframeExecutionEnvironmentServiceArgs = {\n iframeUrl: URL;\n} & ExecutionServiceArgs;\n\nexport class IframeExecutionService extends ExecutionService<Window> {\n public iframeUrl: URL;\n\n constructor({\n iframeUrl,\n messenger,\n setupSnapProvider,\n ...args\n }: IframeExecutionEnvironmentServiceArgs) {\n super({\n ...args,\n messenger,\n setupSnapProvider,\n });\n this.iframeUrl = iframeUrl;\n }\n\n protected async terminateJob(\n jobWrapper: TerminateJobArgs<Window>,\n ): Promise<void> {\n const iframe = document.getElementById(\n jobWrapper.id,\n ) as HTMLIFrameElement | null;\n\n if (!iframe) {\n return;\n }\n\n iframe.id = '';\n\n await withTimeout(\n new Promise<void>((resolve) => {\n iframe.addEventListener('load', () => resolve(), { once: true });\n iframe.src = 'about:blank';\n }),\n 1_000,\n );\n\n iframe.remove();\n }\n\n protected async initEnvStream(snapId: string): Promise<{\n worker: Window;\n stream: BasePostMessageStream;\n }> {\n this.setSnapStatus(snapId, 'initializing');\n\n const iframeWindow = await createWindow({\n uri: this.iframeUrl.toString(),\n id: snapId,\n });\n\n const stream = new WindowPostMessageStream({\n name: 'parent',\n target: 'child',\n targetWindow: iframeWindow,\n targetOrigin: '*',\n });\n\n return { worker: iframeWindow, stream };\n }\n}\n"]}
@@ -499,7 +499,7 @@ class SnapController extends base_controller_1.BaseController {
499
499
  checksum: snap.manifest.source.shasum,
500
500
  };
501
501
  return blockListArg;
502
- }, {}));
502
+ }, {}), true);
503
503
  await Promise.all(Object.entries(blockedSnaps).map(async ([snapId, { status, reason }]) => {
504
504
  if (status === registry_1.SnapRegistryStatus.Blocked) {
505
505
  return this.#blockSnap(snapId, reason);
@@ -513,7 +513,7 @@ class SnapController extends base_controller_1.BaseController {
513
513
  await Promise.allSettled(Object.values(this.state.snaps)
514
514
  .filter((snap) => snap.preinstalled)
515
515
  .map(async (snap) => {
516
- const resolvedVersion = await this.#resolveAllowlistVersion(snap.id, preinstalledVersionRange);
516
+ const resolvedVersion = await this.#resolveAllowlistVersion(snap.id, preinstalledVersionRange, true);
517
517
  if (resolvedVersion !== preinstalledVersionRange &&
518
518
  (0, utils_1.gtVersion)(resolvedVersion, snap.version)) {
519
519
  const location = this.#detectSnapLocation(snap.id, {
@@ -1640,8 +1640,8 @@ class SnapController extends base_controller_1.BaseController {
1640
1640
  throw error;
1641
1641
  }
1642
1642
  }
1643
- async #resolveAllowlistVersion(snapId, versionRange) {
1644
- return await this.messenger.call('SnapRegistryController:resolveVersion', snapId, versionRange);
1643
+ async #resolveAllowlistVersion(snapId, versionRange, skipRefetch = false) {
1644
+ return await this.messenger.call('SnapRegistryController:resolveVersion', snapId, versionRange, skipRefetch);
1645
1645
  }
1646
1646
  /**
1647
1647
  * Returns a promise representing the complete installation of the requested snap.