@metamask/snaps-controllers 3.0.0 → 3.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.
Files changed (54) hide show
  1. package/CHANGELOG.md +20 -1
  2. package/dist/cjs/cronjob/CronjobController.js +1 -1
  3. package/dist/cjs/cronjob/CronjobController.js.map +1 -1
  4. package/dist/cjs/services/AbstractExecutionService.js +6 -7
  5. package/dist/cjs/services/AbstractExecutionService.js.map +1 -1
  6. package/dist/cjs/snaps/SnapController.js +73 -82
  7. package/dist/cjs/snaps/SnapController.js.map +1 -1
  8. package/dist/cjs/snaps/endowments/cronjob.js +4 -4
  9. package/dist/cjs/snaps/endowments/cronjob.js.map +1 -1
  10. package/dist/cjs/snaps/endowments/keyring.js +4 -4
  11. package/dist/cjs/snaps/endowments/keyring.js.map +1 -1
  12. package/dist/cjs/snaps/endowments/name-lookup.js +3 -3
  13. package/dist/cjs/snaps/endowments/name-lookup.js.map +1 -1
  14. package/dist/cjs/snaps/endowments/rpc.js +4 -4
  15. package/dist/cjs/snaps/endowments/rpc.js.map +1 -1
  16. package/dist/cjs/snaps/endowments/transaction-insight.js +3 -3
  17. package/dist/cjs/snaps/endowments/transaction-insight.js.map +1 -1
  18. package/dist/cjs/snaps/location/npm.js +41 -14
  19. package/dist/cjs/snaps/location/npm.js.map +1 -1
  20. package/dist/cjs/snaps/permissions.js +5 -5
  21. package/dist/cjs/snaps/permissions.js.map +1 -1
  22. package/dist/cjs/snaps/registry/json.js +30 -1
  23. package/dist/cjs/snaps/registry/json.js.map +1 -1
  24. package/dist/cjs/snaps/registry/registry.js.map +1 -1
  25. package/dist/esm/cronjob/CronjobController.js +1 -1
  26. package/dist/esm/cronjob/CronjobController.js.map +1 -1
  27. package/dist/esm/services/AbstractExecutionService.js +6 -7
  28. package/dist/esm/services/AbstractExecutionService.js.map +1 -1
  29. package/dist/esm/snaps/SnapController.js +70 -79
  30. package/dist/esm/snaps/SnapController.js.map +1 -1
  31. package/dist/esm/snaps/endowments/cronjob.js +4 -4
  32. package/dist/esm/snaps/endowments/cronjob.js.map +1 -1
  33. package/dist/esm/snaps/endowments/keyring.js +4 -4
  34. package/dist/esm/snaps/endowments/keyring.js.map +1 -1
  35. package/dist/esm/snaps/endowments/name-lookup.js +3 -3
  36. package/dist/esm/snaps/endowments/name-lookup.js.map +1 -1
  37. package/dist/esm/snaps/endowments/rpc.js +4 -4
  38. package/dist/esm/snaps/endowments/rpc.js.map +1 -1
  39. package/dist/esm/snaps/endowments/transaction-insight.js +3 -3
  40. package/dist/esm/snaps/endowments/transaction-insight.js.map +1 -1
  41. package/dist/esm/snaps/location/npm.js +42 -15
  42. package/dist/esm/snaps/location/npm.js.map +1 -1
  43. package/dist/esm/snaps/permissions.js +1 -1
  44. package/dist/esm/snaps/permissions.js.map +1 -1
  45. package/dist/esm/snaps/registry/json.js +31 -2
  46. package/dist/esm/snaps/registry/json.js.map +1 -1
  47. package/dist/esm/snaps/registry/registry.js.map +1 -1
  48. package/dist/types/cronjob/CronjobController.d.ts +1 -1
  49. package/dist/types/services/AbstractExecutionService.d.ts +1 -1
  50. package/dist/types/snaps/SnapController.d.ts +20 -32
  51. package/dist/types/snaps/location/npm.d.ts +1 -1
  52. package/dist/types/snaps/registry/json.d.ts +5 -1
  53. package/dist/types/snaps/registry/registry.d.ts +11 -1
  54. package/package.json +29 -22
@@ -50,7 +50,8 @@ function _class_private_method_init(obj, privateSet) {
50
50
  }
51
51
  import { BaseControllerV2 as BaseController } from '@metamask/base-controller';
52
52
  import { verify } from '@metamask/snaps-registry';
53
- import { assert, Duration, inMilliseconds, satisfiesVersionRange } from '@metamask/utils';
53
+ import { getTargetVersion } from '@metamask/snaps-utils';
54
+ import { assert, assertIsSemVerRange, Duration, inMilliseconds, satisfiesVersionRange } from '@metamask/utils';
54
55
  import { SnapsRegistryStatus } from './registry';
55
56
  // TODO: Replace with a Codefi URL
56
57
  const SNAP_REGISTRY_URL = 'https://cdn.jsdelivr.net/gh/MetaMask/snaps-registry@gh-pages/latest/registry.json';
@@ -60,7 +61,7 @@ const defaultState = {
60
61
  database: null,
61
62
  lastUpdated: null
62
63
  };
63
- var _url = /*#__PURE__*/ new WeakMap(), _publicKey = /*#__PURE__*/ new WeakMap(), _fetchFunction = /*#__PURE__*/ new WeakMap(), _recentFetchThreshold = /*#__PURE__*/ new WeakMap(), _refetchOnAllowlistMiss = /*#__PURE__*/ new WeakMap(), _failOnUnavailableRegistry = /*#__PURE__*/ new WeakMap(), _currentUpdate = /*#__PURE__*/ new WeakMap(), _wasRecentlyFetched = /*#__PURE__*/ new WeakSet(), _triggerUpdate = /*#__PURE__*/ new WeakSet(), _update = /*#__PURE__*/ new WeakSet(), _getDatabase = /*#__PURE__*/ new WeakSet(), _getSingle = /*#__PURE__*/ new WeakSet(), _get = /*#__PURE__*/ new WeakSet(), _getMetadata = /*#__PURE__*/ new WeakSet(), _verifySignature = /*#__PURE__*/ new WeakSet(), _safeFetch = /*#__PURE__*/ new WeakSet();
64
+ var _url = /*#__PURE__*/ new WeakMap(), _publicKey = /*#__PURE__*/ new WeakMap(), _fetchFunction = /*#__PURE__*/ new WeakMap(), _recentFetchThreshold = /*#__PURE__*/ new WeakMap(), _refetchOnAllowlistMiss = /*#__PURE__*/ new WeakMap(), _failOnUnavailableRegistry = /*#__PURE__*/ new WeakMap(), _currentUpdate = /*#__PURE__*/ new WeakMap(), _wasRecentlyFetched = /*#__PURE__*/ new WeakSet(), _triggerUpdate = /*#__PURE__*/ new WeakSet(), _update = /*#__PURE__*/ new WeakSet(), _getDatabase = /*#__PURE__*/ new WeakSet(), _getSingle = /*#__PURE__*/ new WeakSet(), _get = /*#__PURE__*/ new WeakSet(), _resolveVersion = /*#__PURE__*/ new WeakSet(), _getMetadata = /*#__PURE__*/ new WeakSet(), _verifySignature = /*#__PURE__*/ new WeakSet(), _safeFetch = /*#__PURE__*/ new WeakSet();
64
65
  export class JsonSnapsRegistry extends BaseController {
65
66
  constructor({ messenger, state, url = {
66
67
  registry: SNAP_REGISTRY_URL,
@@ -99,6 +100,15 @@ export class JsonSnapsRegistry extends BaseController {
99
100
  _class_private_method_init(this, _getSingle);
100
101
  _class_private_method_init(this, _get);
101
102
  /**
103
+ * Find an allowlisted version within a specified version range.
104
+ *
105
+ * @param snapId - The ID of the snap we are trying to resolve a version for.
106
+ * @param versionRange - The version range.
107
+ * @param refetch - An optional flag used to determine if we are refetching the registry.
108
+ * @returns An allowlisted version within the specified version range.
109
+ * @throws If an allowlisted version does not exist within the version range.
110
+ */ _class_private_method_init(this, _resolveVersion);
111
+ /**
102
112
  * Get metadata for the given snap ID.
103
113
  *
104
114
  * @param snapId - The ID of the snap to get metadata for.
@@ -157,6 +167,7 @@ export class JsonSnapsRegistry extends BaseController {
157
167
  _class_private_field_set(this, _currentUpdate, null);
158
168
  this.messagingSystem.registerActionHandler('SnapsRegistry:get', async (...args)=>_class_private_method_get(this, _get, get).call(this, ...args));
159
169
  this.messagingSystem.registerActionHandler('SnapsRegistry:getMetadata', async (...args)=>_class_private_method_get(this, _getMetadata, getMetadata).call(this, ...args));
170
+ this.messagingSystem.registerActionHandler('SnapsRegistry:resolveVersion', async (...args)=>_class_private_method_get(this, _resolveVersion, resolveVersion).call(this, ...args));
160
171
  this.messagingSystem.registerActionHandler('SnapsRegistry:update', async ()=>_class_private_method_get(this, _triggerUpdate, triggerUpdate).call(this));
161
172
  }
162
173
  }
@@ -243,6 +254,24 @@ async function get(snaps) {
243
254
  return acc;
244
255
  }, Promise.resolve({}));
245
256
  }
257
+ async function resolveVersion(snapId, versionRange, refetch = false) {
258
+ const database = await _class_private_method_get(this, _getDatabase, getDatabase).call(this);
259
+ const versions = database?.verifiedSnaps[snapId]?.versions ?? null;
260
+ if (!versions && _class_private_field_get(this, _refetchOnAllowlistMiss) && !refetch) {
261
+ await _class_private_method_get(this, _triggerUpdate, triggerUpdate).call(this);
262
+ return _class_private_method_get(this, _resolveVersion, resolveVersion).call(this, snapId, versionRange, true);
263
+ }
264
+ assert(versions, `Cannot install snap "${snapId}": The snap is not on the allowlist.`);
265
+ const targetVersion = getTargetVersion(Object.keys(versions), versionRange);
266
+ if (!targetVersion && _class_private_field_get(this, _refetchOnAllowlistMiss) && !refetch) {
267
+ await _class_private_method_get(this, _triggerUpdate, triggerUpdate).call(this);
268
+ return _class_private_method_get(this, _resolveVersion, resolveVersion).call(this, snapId, versionRange, true);
269
+ }
270
+ assert(targetVersion, `Cannot install version "${versionRange}" of snap "${snapId}": No matching versions of the snap are on the allowlist.`);
271
+ // A semver version is technically also a valid semver range.
272
+ assertIsSemVerRange(targetVersion);
273
+ return targetVersion;
274
+ }
246
275
  async function getMetadata(snapId) {
247
276
  const database = await _class_private_method_get(this, _getDatabase, getDatabase).call(this);
248
277
  return database?.verifiedSnaps[snapId]?.metadata ?? null;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/snaps/registry/json.ts"],"sourcesContent":["import type { RestrictedControllerMessenger } from '@metamask/base-controller';\nimport { BaseControllerV2 as BaseController } from '@metamask/base-controller';\nimport type { SnapsRegistryDatabase } from '@metamask/snaps-registry';\nimport { verify } from '@metamask/snaps-registry';\nimport type { SnapId } from '@metamask/snaps-utils';\nimport type { Hex } from '@metamask/utils';\nimport {\n assert,\n Duration,\n inMilliseconds,\n satisfiesVersionRange,\n} from '@metamask/utils';\n\nimport type {\n SnapsRegistry,\n SnapsRegistryInfo,\n SnapsRegistryMetadata,\n SnapsRegistryRequest,\n SnapsRegistryResult,\n} from './registry';\nimport { SnapsRegistryStatus } from './registry';\n\n// TODO: Replace with a Codefi URL\nconst SNAP_REGISTRY_URL =\n 'https://cdn.jsdelivr.net/gh/MetaMask/snaps-registry@gh-pages/latest/registry.json';\n\nconst SNAP_REGISTRY_SIGNATURE_URL =\n 'https://cdn.jsdelivr.net/gh/MetaMask/snaps-registry@gh-pages/latest/signature.json';\n\ntype JsonSnapsRegistryUrl = {\n registry: string;\n signature: string;\n};\n\nexport type JsonSnapsRegistryArgs = {\n messenger: SnapsRegistryMessenger;\n state?: SnapsRegistryState;\n fetchFunction?: typeof fetch;\n url?: JsonSnapsRegistryUrl;\n recentFetchThreshold?: number;\n refetchOnAllowlistMiss?: boolean;\n failOnUnavailableRegistry?: boolean;\n publicKey?: Hex;\n};\n\nexport type GetResult = {\n type: `${typeof controllerName}:get`;\n handler: SnapsRegistry['get'];\n};\n\nexport type GetMetadata = {\n type: `${typeof controllerName}:getMetadata`;\n handler: SnapsRegistry['getMetadata'];\n};\n\nexport type Update = {\n type: `${typeof controllerName}:update`;\n handler: SnapsRegistry['update'];\n};\n\nexport type SnapsRegistryActions = GetResult | GetMetadata | Update;\n\nexport type SnapsRegistryEvents = never;\n\nexport type SnapsRegistryMessenger = RestrictedControllerMessenger<\n 'SnapsRegistry',\n SnapsRegistryActions,\n SnapsRegistryEvents,\n SnapsRegistryActions['type'],\n SnapsRegistryEvents['type']\n>;\n\nexport type SnapsRegistryState = {\n database: SnapsRegistryDatabase | null;\n lastUpdated: number | null;\n};\n\nconst controllerName = 'SnapsRegistry';\n\nconst defaultState = {\n database: null,\n lastUpdated: null,\n};\n\nexport class JsonSnapsRegistry extends BaseController<\n typeof controllerName,\n SnapsRegistryState,\n SnapsRegistryMessenger\n> {\n #url: JsonSnapsRegistryUrl;\n\n #publicKey?: Hex;\n\n #fetchFunction: typeof fetch;\n\n #recentFetchThreshold: number;\n\n #refetchOnAllowlistMiss: boolean;\n\n #failOnUnavailableRegistry: boolean;\n\n #currentUpdate: Promise<void> | null;\n\n constructor({\n messenger,\n state,\n url = {\n registry: SNAP_REGISTRY_URL,\n signature: SNAP_REGISTRY_SIGNATURE_URL,\n },\n publicKey,\n fetchFunction = globalThis.fetch.bind(globalThis),\n recentFetchThreshold = inMilliseconds(5, Duration.Minute),\n failOnUnavailableRegistry = true,\n refetchOnAllowlistMiss = true,\n }: JsonSnapsRegistryArgs) {\n super({\n messenger,\n metadata: {\n database: { persist: true, anonymous: false },\n lastUpdated: { persist: true, anonymous: false },\n },\n name: controllerName,\n state: {\n ...defaultState,\n ...state,\n },\n });\n this.#url = url;\n this.#publicKey = publicKey;\n this.#fetchFunction = fetchFunction;\n this.#recentFetchThreshold = recentFetchThreshold;\n this.#refetchOnAllowlistMiss = refetchOnAllowlistMiss;\n this.#failOnUnavailableRegistry = failOnUnavailableRegistry;\n this.#currentUpdate = null;\n\n this.messagingSystem.registerActionHandler(\n 'SnapsRegistry:get',\n async (...args) => this.#get(...args),\n );\n this.messagingSystem.registerActionHandler(\n 'SnapsRegistry:getMetadata',\n async (...args) => this.#getMetadata(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n 'SnapsRegistry:update',\n async () => this.#triggerUpdate(),\n );\n }\n\n #wasRecentlyFetched() {\n return (\n this.state.lastUpdated &&\n Date.now() - this.state.lastUpdated < this.#recentFetchThreshold\n );\n }\n\n /**\n * Triggers an update of the registry database.\n *\n * If an existing update is in progress this function will await that update.\n */\n async #triggerUpdate() {\n // If an update is ongoing, wait for that.\n if (this.#currentUpdate) {\n await this.#currentUpdate;\n return;\n }\n // If no update exists, create promise and store globally.\n if (this.#currentUpdate === null) {\n this.#currentUpdate = this.#update();\n }\n await this.#currentUpdate;\n this.#currentUpdate = null;\n }\n\n /**\n * Updates the registry database if the registry hasn't been updated recently.\n *\n * NOTE: SHOULD NOT be called directly, instead `triggerUpdate` should be used.\n */\n async #update() {\n // No-op if we recently fetched the registry.\n if (this.#wasRecentlyFetched()) {\n return;\n }\n\n try {\n const database = await this.#safeFetch(this.#url.registry);\n\n if (this.#publicKey) {\n const signature = await this.#safeFetch(this.#url.signature);\n await this.#verifySignature(database, signature);\n }\n\n this.update((state) => {\n state.database = JSON.parse(database);\n state.lastUpdated = Date.now();\n });\n } catch {\n // Ignore\n }\n }\n\n async #getDatabase(): Promise<SnapsRegistryDatabase | null> {\n if (this.state.database === null) {\n await this.#triggerUpdate();\n }\n\n // If the database is still null and we require it, throw.\n if (this.#failOnUnavailableRegistry && this.state.database === null) {\n throw new Error('Snaps registry is unavailable, installation blocked.');\n }\n return this.state.database;\n }\n\n async #getSingle(\n snapId: SnapId,\n snapInfo: SnapsRegistryInfo,\n refetch = false,\n ): Promise<SnapsRegistryResult> {\n const database = await this.#getDatabase();\n\n const blockedEntry = database?.blockedSnaps.find((blocked) => {\n if ('id' in blocked) {\n return (\n blocked.id === snapId &&\n satisfiesVersionRange(snapInfo.version, blocked.versionRange)\n );\n }\n\n return blocked.checksum === snapInfo.checksum;\n });\n\n if (blockedEntry) {\n return {\n status: SnapsRegistryStatus.Blocked,\n reason: blockedEntry.reason,\n };\n }\n\n const verified = database?.verifiedSnaps[snapId];\n const version = verified?.versions?.[snapInfo.version];\n if (version && version.checksum === snapInfo.checksum) {\n return { status: SnapsRegistryStatus.Verified };\n }\n // For now, if we have an allowlist miss, we can refetch once and try again.\n if (this.#refetchOnAllowlistMiss && !refetch) {\n await this.#triggerUpdate();\n return this.#getSingle(snapId, snapInfo, true);\n }\n return { status: SnapsRegistryStatus.Unverified };\n }\n\n async #get(\n snaps: SnapsRegistryRequest,\n ): Promise<Record<SnapId, SnapsRegistryResult>> {\n return Object.entries(snaps).reduce<\n Promise<Record<SnapId, SnapsRegistryResult>>\n >(async (previousPromise, [snapId, snapInfo]) => {\n const result = await this.#getSingle(snapId, snapInfo);\n const acc = await previousPromise;\n acc[snapId] = result;\n return acc;\n }, Promise.resolve({}));\n }\n\n /**\n * Get metadata for the given snap ID.\n *\n * @param snapId - The ID of the snap to get metadata for.\n * @returns The metadata for the given snap ID, or `null` if the snap is not\n * verified.\n */\n async #getMetadata(snapId: SnapId): Promise<SnapsRegistryMetadata | null> {\n const database = await this.#getDatabase();\n return database?.verifiedSnaps[snapId]?.metadata ?? null;\n }\n\n /**\n * Verify the signature of the registry.\n *\n * @param database - The registry database.\n * @param signature - The signature of the registry.\n * @throws If the signature is invalid.\n * @private\n */\n async #verifySignature(database: string, signature: string) {\n assert(this.#publicKey, 'No public key provided.');\n\n const valid = await verify({\n registry: database,\n signature: JSON.parse(signature),\n publicKey: this.#publicKey,\n });\n\n assert(valid, 'Invalid registry signature.');\n }\n\n /**\n * Fetch the given URL, throwing if the response is not OK.\n *\n * @param url - The URL to fetch.\n * @returns The response body.\n * @private\n */\n async #safeFetch(url: string) {\n const response = await this.#fetchFunction(url);\n if (!response.ok) {\n throw new Error(`Failed to fetch ${url}.`);\n }\n\n return await response.text();\n }\n}\n"],"names":["BaseControllerV2","BaseController","verify","assert","Duration","inMilliseconds","satisfiesVersionRange","SnapsRegistryStatus","SNAP_REGISTRY_URL","SNAP_REGISTRY_SIGNATURE_URL","controllerName","defaultState","database","lastUpdated","JsonSnapsRegistry","constructor","messenger","state","url","registry","signature","publicKey","fetchFunction","globalThis","fetch","bind","recentFetchThreshold","Minute","failOnUnavailableRegistry","refetchOnAllowlistMiss","metadata","persist","anonymous","name","currentUpdate","messagingSystem","registerActionHandler","args","get","getMetadata","triggerUpdate","Date","now","update","wasRecentlyFetched","safeFetch","verifySignature","JSON","parse","Error","snapId","snapInfo","refetch","getDatabase","blockedEntry","blockedSnaps","find","blocked","id","version","versionRange","checksum","status","Blocked","reason","verified","verifiedSnaps","versions","Verified","getSingle","Unverified","snaps","Object","entries","reduce","previousPromise","result","acc","Promise","resolve","valid","response","ok","text"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/snaps/registry/json.ts"],"sourcesContent":["import type { RestrictedControllerMessenger } from '@metamask/base-controller';\nimport { BaseControllerV2 as BaseController } from '@metamask/base-controller';\nimport type { SnapsRegistryDatabase } from '@metamask/snaps-registry';\nimport { verify } from '@metamask/snaps-registry';\nimport { getTargetVersion, type SnapId } from '@metamask/snaps-utils';\nimport type { Hex, SemVerRange, SemVerVersion } from '@metamask/utils';\nimport {\n assert,\n assertIsSemVerRange,\n Duration,\n inMilliseconds,\n satisfiesVersionRange,\n} from '@metamask/utils';\n\nimport type {\n SnapsRegistry,\n SnapsRegistryInfo,\n SnapsRegistryMetadata,\n SnapsRegistryRequest,\n SnapsRegistryResult,\n} from './registry';\nimport { SnapsRegistryStatus } from './registry';\n\n// TODO: Replace with a Codefi URL\nconst SNAP_REGISTRY_URL =\n 'https://cdn.jsdelivr.net/gh/MetaMask/snaps-registry@gh-pages/latest/registry.json';\n\nconst SNAP_REGISTRY_SIGNATURE_URL =\n 'https://cdn.jsdelivr.net/gh/MetaMask/snaps-registry@gh-pages/latest/signature.json';\n\ntype JsonSnapsRegistryUrl = {\n registry: string;\n signature: string;\n};\n\nexport type JsonSnapsRegistryArgs = {\n messenger: SnapsRegistryMessenger;\n state?: SnapsRegistryState;\n fetchFunction?: typeof fetch;\n url?: JsonSnapsRegistryUrl;\n recentFetchThreshold?: number;\n refetchOnAllowlistMiss?: boolean;\n failOnUnavailableRegistry?: boolean;\n publicKey?: Hex;\n};\n\nexport type GetResult = {\n type: `${typeof controllerName}:get`;\n handler: SnapsRegistry['get'];\n};\n\nexport type ResolveVersion = {\n type: `${typeof controllerName}:resolveVersion`;\n handler: SnapsRegistry['resolveVersion'];\n};\n\nexport type GetMetadata = {\n type: `${typeof controllerName}:getMetadata`;\n handler: SnapsRegistry['getMetadata'];\n};\n\nexport type Update = {\n type: `${typeof controllerName}:update`;\n handler: SnapsRegistry['update'];\n};\n\nexport type SnapsRegistryActions =\n | GetResult\n | GetMetadata\n | Update\n | ResolveVersion;\n\nexport type SnapsRegistryEvents = never;\n\nexport type SnapsRegistryMessenger = RestrictedControllerMessenger<\n 'SnapsRegistry',\n SnapsRegistryActions,\n SnapsRegistryEvents,\n SnapsRegistryActions['type'],\n SnapsRegistryEvents['type']\n>;\n\nexport type SnapsRegistryState = {\n database: SnapsRegistryDatabase | null;\n lastUpdated: number | null;\n};\n\nconst controllerName = 'SnapsRegistry';\n\nconst defaultState = {\n database: null,\n lastUpdated: null,\n};\n\nexport class JsonSnapsRegistry extends BaseController<\n typeof controllerName,\n SnapsRegistryState,\n SnapsRegistryMessenger\n> {\n #url: JsonSnapsRegistryUrl;\n\n #publicKey?: Hex;\n\n #fetchFunction: typeof fetch;\n\n #recentFetchThreshold: number;\n\n #refetchOnAllowlistMiss: boolean;\n\n #failOnUnavailableRegistry: boolean;\n\n #currentUpdate: Promise<void> | null;\n\n constructor({\n messenger,\n state,\n url = {\n registry: SNAP_REGISTRY_URL,\n signature: SNAP_REGISTRY_SIGNATURE_URL,\n },\n publicKey,\n fetchFunction = globalThis.fetch.bind(globalThis),\n recentFetchThreshold = inMilliseconds(5, Duration.Minute),\n failOnUnavailableRegistry = true,\n refetchOnAllowlistMiss = true,\n }: JsonSnapsRegistryArgs) {\n super({\n messenger,\n metadata: {\n database: { persist: true, anonymous: false },\n lastUpdated: { persist: true, anonymous: false },\n },\n name: controllerName,\n state: {\n ...defaultState,\n ...state,\n },\n });\n this.#url = url;\n this.#publicKey = publicKey;\n this.#fetchFunction = fetchFunction;\n this.#recentFetchThreshold = recentFetchThreshold;\n this.#refetchOnAllowlistMiss = refetchOnAllowlistMiss;\n this.#failOnUnavailableRegistry = failOnUnavailableRegistry;\n this.#currentUpdate = null;\n\n this.messagingSystem.registerActionHandler(\n 'SnapsRegistry:get',\n async (...args) => this.#get(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n 'SnapsRegistry:getMetadata',\n async (...args) => this.#getMetadata(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n 'SnapsRegistry:resolveVersion',\n async (...args) => this.#resolveVersion(...args),\n );\n\n this.messagingSystem.registerActionHandler(\n 'SnapsRegistry:update',\n async () => this.#triggerUpdate(),\n );\n }\n\n #wasRecentlyFetched() {\n return (\n this.state.lastUpdated &&\n Date.now() - this.state.lastUpdated < this.#recentFetchThreshold\n );\n }\n\n /**\n * Triggers an update of the registry database.\n *\n * If an existing update is in progress this function will await that update.\n */\n async #triggerUpdate() {\n // If an update is ongoing, wait for that.\n if (this.#currentUpdate) {\n await this.#currentUpdate;\n return;\n }\n // If no update exists, create promise and store globally.\n if (this.#currentUpdate === null) {\n this.#currentUpdate = this.#update();\n }\n await this.#currentUpdate;\n this.#currentUpdate = null;\n }\n\n /**\n * Updates the registry database if the registry hasn't been updated recently.\n *\n * NOTE: SHOULD NOT be called directly, instead `triggerUpdate` should be used.\n */\n async #update() {\n // No-op if we recently fetched the registry.\n if (this.#wasRecentlyFetched()) {\n return;\n }\n\n try {\n const database = await this.#safeFetch(this.#url.registry);\n\n if (this.#publicKey) {\n const signature = await this.#safeFetch(this.#url.signature);\n await this.#verifySignature(database, signature);\n }\n\n this.update((state) => {\n state.database = JSON.parse(database);\n state.lastUpdated = Date.now();\n });\n } catch {\n // Ignore\n }\n }\n\n async #getDatabase(): Promise<SnapsRegistryDatabase | null> {\n if (this.state.database === null) {\n await this.#triggerUpdate();\n }\n\n // If the database is still null and we require it, throw.\n if (this.#failOnUnavailableRegistry && this.state.database === null) {\n throw new Error('Snaps registry is unavailable, installation blocked.');\n }\n return this.state.database;\n }\n\n async #getSingle(\n snapId: SnapId,\n snapInfo: SnapsRegistryInfo,\n refetch = false,\n ): Promise<SnapsRegistryResult> {\n const database = await this.#getDatabase();\n\n const blockedEntry = database?.blockedSnaps.find((blocked) => {\n if ('id' in blocked) {\n return (\n blocked.id === snapId &&\n satisfiesVersionRange(snapInfo.version, blocked.versionRange)\n );\n }\n\n return blocked.checksum === snapInfo.checksum;\n });\n\n if (blockedEntry) {\n return {\n status: SnapsRegistryStatus.Blocked,\n reason: blockedEntry.reason,\n };\n }\n\n const verified = database?.verifiedSnaps[snapId];\n const version = verified?.versions?.[snapInfo.version];\n if (version && version.checksum === snapInfo.checksum) {\n return { status: SnapsRegistryStatus.Verified };\n }\n // For now, if we have an allowlist miss, we can refetch once and try again.\n if (this.#refetchOnAllowlistMiss && !refetch) {\n await this.#triggerUpdate();\n return this.#getSingle(snapId, snapInfo, true);\n }\n return { status: SnapsRegistryStatus.Unverified };\n }\n\n async #get(\n snaps: SnapsRegistryRequest,\n ): Promise<Record<SnapId, SnapsRegistryResult>> {\n return Object.entries(snaps).reduce<\n Promise<Record<SnapId, SnapsRegistryResult>>\n >(async (previousPromise, [snapId, snapInfo]) => {\n const result = await this.#getSingle(snapId, snapInfo);\n const acc = await previousPromise;\n acc[snapId] = result;\n return acc;\n }, Promise.resolve({}));\n }\n\n /**\n * Find an allowlisted version within a specified version range.\n *\n * @param snapId - The ID of the snap we are trying to resolve a version for.\n * @param versionRange - The version range.\n * @param refetch - An optional flag used to determine if we are refetching the registry.\n * @returns An allowlisted version within the specified version range.\n * @throws If an allowlisted version does not exist within the version range.\n */\n async #resolveVersion(\n snapId: SnapId,\n versionRange: SemVerRange,\n refetch = false,\n ): Promise<SemVerRange> {\n const database = await this.#getDatabase();\n const versions = database?.verifiedSnaps[snapId]?.versions ?? null;\n\n if (!versions && this.#refetchOnAllowlistMiss && !refetch) {\n await this.#triggerUpdate();\n return this.#resolveVersion(snapId, versionRange, true);\n }\n\n assert(\n versions,\n `Cannot install snap \"${snapId}\": The snap is not on the allowlist.`,\n );\n\n const targetVersion = getTargetVersion(\n Object.keys(versions) as SemVerVersion[],\n versionRange,\n );\n\n if (!targetVersion && this.#refetchOnAllowlistMiss && !refetch) {\n await this.#triggerUpdate();\n return this.#resolveVersion(snapId, versionRange, true);\n }\n\n assert(\n targetVersion,\n `Cannot install version \"${versionRange}\" of snap \"${snapId}\": No matching versions of the snap are on the allowlist.`,\n );\n\n // A semver version is technically also a valid semver range.\n assertIsSemVerRange(targetVersion);\n return targetVersion;\n }\n\n /**\n * Get metadata for the given snap ID.\n *\n * @param snapId - The ID of the snap to get metadata for.\n * @returns The metadata for the given snap ID, or `null` if the snap is not\n * verified.\n */\n async #getMetadata(snapId: SnapId): Promise<SnapsRegistryMetadata | null> {\n const database = await this.#getDatabase();\n return database?.verifiedSnaps[snapId]?.metadata ?? null;\n }\n\n /**\n * Verify the signature of the registry.\n *\n * @param database - The registry database.\n * @param signature - The signature of the registry.\n * @throws If the signature is invalid.\n * @private\n */\n async #verifySignature(database: string, signature: string) {\n assert(this.#publicKey, 'No public key provided.');\n\n const valid = await verify({\n registry: database,\n signature: JSON.parse(signature),\n publicKey: this.#publicKey,\n });\n\n assert(valid, 'Invalid registry signature.');\n }\n\n /**\n * Fetch the given URL, throwing if the response is not OK.\n *\n * @param url - The URL to fetch.\n * @returns The response body.\n * @private\n */\n async #safeFetch(url: string) {\n const response = await this.#fetchFunction(url);\n if (!response.ok) {\n throw new Error(`Failed to fetch ${url}.`);\n }\n\n return await response.text();\n }\n}\n"],"names":["BaseControllerV2","BaseController","verify","getTargetVersion","assert","assertIsSemVerRange","Duration","inMilliseconds","satisfiesVersionRange","SnapsRegistryStatus","SNAP_REGISTRY_URL","SNAP_REGISTRY_SIGNATURE_URL","controllerName","defaultState","database","lastUpdated","JsonSnapsRegistry","constructor","messenger","state","url","registry","signature","publicKey","fetchFunction","globalThis","fetch","bind","recentFetchThreshold","Minute","failOnUnavailableRegistry","refetchOnAllowlistMiss","metadata","persist","anonymous","name","currentUpdate","messagingSystem","registerActionHandler","args","get","getMetadata","resolveVersion","triggerUpdate","Date","now","update","wasRecentlyFetched","safeFetch","verifySignature","JSON","parse","Error","snapId","snapInfo","refetch","getDatabase","blockedEntry","blockedSnaps","find","blocked","id","version","versionRange","checksum","status","Blocked","reason","verified","verifiedSnaps","versions","Verified","getSingle","Unverified","snaps","Object","entries","reduce","previousPromise","result","acc","Promise","resolve","targetVersion","keys","valid","response","ok","text"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/snaps/registry/registry.ts"],"sourcesContent":["import type {\n BlockReason,\n SnapsRegistryDatabase,\n} from '@metamask/snaps-registry';\nimport type { SnapId, ValidatedSnapId } from '@metamask/snaps-utils';\nimport type { SemVerVersion } from '@metamask/utils';\n\nexport type SnapsRegistryInfo = { version: SemVerVersion; checksum: string };\nexport type SnapsRegistryRequest = Record<SnapId, SnapsRegistryInfo>;\nexport type SnapsRegistryMetadata =\n SnapsRegistryDatabase['verifiedSnaps'][ValidatedSnapId]['metadata'];\n\n// TODO: Decide on names for these\nexport enum SnapsRegistryStatus {\n Unverified = 0,\n Blocked = 1,\n Verified = 2,\n}\n\nexport type SnapsRegistryResult = {\n status: SnapsRegistryStatus;\n reason?: BlockReason;\n};\n\nexport type SnapsRegistry = {\n get(\n snaps: SnapsRegistryRequest,\n ): Promise<Record<ValidatedSnapId, SnapsRegistryResult>>;\n\n update(): Promise<void>;\n\n /**\n * Get metadata for the given snap ID.\n *\n * @param snapId - The ID of the snap to get metadata for.\n * @returns The metadata for the given snap ID, or `null` if the snap is not\n * verified.\n */\n getMetadata(snapId: SnapId): Promise<SnapsRegistryMetadata | null>;\n};\n"],"names":["SnapsRegistryStatus","Unverified","Blocked","Verified"],"mappings":"WAaO;UAAKA,mBAAmB;IAAnBA,oBAAAA,oBACVC,gBAAa,KAAbA;IADUD,oBAAAA,oBAEVE,aAAU,KAAVA;IAFUF,oBAAAA,oBAGVG,cAAW,KAAXA;GAHUH,wBAAAA"}
1
+ {"version":3,"sources":["../../../../src/snaps/registry/registry.ts"],"sourcesContent":["import type {\n BlockReason,\n SnapsRegistryDatabase,\n} from '@metamask/snaps-registry';\nimport type { SnapId, ValidatedSnapId } from '@metamask/snaps-utils';\nimport type { SemVerRange, SemVerVersion } from '@metamask/utils';\n\nexport type SnapsRegistryInfo = { version: SemVerVersion; checksum: string };\nexport type SnapsRegistryRequest = Record<SnapId, SnapsRegistryInfo>;\nexport type SnapsRegistryMetadata =\n SnapsRegistryDatabase['verifiedSnaps'][ValidatedSnapId]['metadata'];\n\n// TODO: Decide on names for these\nexport enum SnapsRegistryStatus {\n Unverified = 0,\n Blocked = 1,\n Verified = 2,\n}\n\nexport type SnapsRegistryResult = {\n status: SnapsRegistryStatus;\n reason?: BlockReason;\n};\n\nexport type SnapsRegistry = {\n get(\n snaps: SnapsRegistryRequest,\n ): Promise<Record<ValidatedSnapId, SnapsRegistryResult>>;\n\n update(): Promise<void>;\n\n /**\n * Find an allowlisted version within a specified version range.\n *\n * @param snapId - The ID of the snap we are trying to resolve a version for.\n * @param versionRange - The version range.\n * @param refetch - An optional flag used to determine if we are refetching the registry.\n * @returns An allowlisted version within the specified version range.\n * @throws If an allowlisted version does not exist within the version range.\n */\n resolveVersion(\n snapId: SnapId,\n versionRange: SemVerRange,\n ): Promise<SemVerRange>;\n\n /**\n * Get metadata for the given snap ID.\n *\n * @param snapId - The ID of the snap to get metadata for.\n * @returns The metadata for the given snap ID, or `null` if the snap is not\n * verified.\n */\n getMetadata(snapId: SnapId): Promise<SnapsRegistryMetadata | null>;\n};\n"],"names":["SnapsRegistryStatus","Unverified","Blocked","Verified"],"mappings":"WAaO;UAAKA,mBAAmB;IAAnBA,oBAAAA,oBACVC,gBAAa,KAAbA;IADUD,oBAAAA,oBAEVE,aAAU,KAAVA;IAFUF,oBAAAA,oBAGVG,cAAW,KAAXA;GAHUH,wBAAAA"}
@@ -88,7 +88,7 @@ export declare class CronjobController extends BaseController<typeof controllerN
88
88
  /**
89
89
  * Runs every 24 hours to check if new jobs need to be scheduled.
90
90
  *
91
- * This is necesary for longer running jobs that execute with more than 24 hours between them.
91
+ * This is necessary for longer running jobs that execute with more than 24 hours between them.
92
92
  */
93
93
  dailyCheckIn(): Promise<void>;
94
94
  /**
@@ -1,8 +1,8 @@
1
1
  /// <reference types="node" />
2
+ import { JsonRpcEngine } from '@metamask/json-rpc-engine';
2
3
  import ObjectMultiplex from '@metamask/object-multiplex';
3
4
  import type { BasePostMessageStream } from '@metamask/post-message-stream';
4
5
  import type { SnapRpcHookArgs } from '@metamask/snaps-utils';
5
- import { JsonRpcEngine } from 'json-rpc-engine';
6
6
  import type { Duplex } from 'stream';
7
7
  import type { ExecutionService, ExecutionServiceMessenger, SnapExecutionData } from './ExecutionService';
8
8
  export declare type SetupSnapProvider = (snapId: string, stream: Duplex) => void;
@@ -4,14 +4,14 @@ import { BaseControllerV2 as BaseController } from '@metamask/base-controller';
4
4
  import type { GetEndowments, GetPermissions, GetSubjectMetadata, GetSubjects, GrantPermissions, HasPermission, HasPermissions, RevokeAllPermissions, RevokePermissionForAllSubjects, RevokePermissions, UpdateCaveat } from '@metamask/permission-controller';
5
5
  import type { BlockReason } from '@metamask/snaps-registry';
6
6
  import type { InstallSnapsResult, PersistedSnap, RequestedSnapPermissions, Snap, SnapId, SnapRpcHook, SnapRpcHookArgs, StatusContext, StatusEvents, StatusStates, TruncatedSnap, ValidatedSnapId } from '@metamask/snaps-utils';
7
- import { SnapStatusEvents } from '@metamask/snaps-utils';
7
+ import { AuxiliaryFileEncoding, SnapStatusEvents } from '@metamask/snaps-utils';
8
8
  import type { Json, NonEmptyArray } from '@metamask/utils';
9
9
  import type { StateMachine } from '@xstate/fsm';
10
10
  import type { Patch } from 'immer';
11
11
  import type { ExecuteSnapAction, ExecutionServiceEvents, HandleRpcRequestAction, SnapErrorJson, TerminateAllSnapsAction, TerminateSnapAction } from '../services';
12
12
  import type { SnapLocation } from './location';
13
13
  import { detectSnapLocation } from './location';
14
- import type { GetMetadata, GetResult, SnapsRegistryMetadata, Update } from './registry';
14
+ import type { GetMetadata, GetResult, ResolveVersion, SnapsRegistryMetadata, Update } from './registry';
15
15
  import { Timer } from './Timer';
16
16
  export declare const controllerName = "SnapController";
17
17
  export declare const SNAP_APPROVAL_INSTALL = "wallet_installSnap";
@@ -70,11 +70,6 @@ declare type StoredSnaps = Record<ValidatedSnapId, Snap>;
70
70
  export declare type SnapControllerState = {
71
71
  snaps: StoredSnaps;
72
72
  snapStates: Record<ValidatedSnapId, string | null>;
73
- snapErrors: {
74
- [internalID: string]: SnapError & {
75
- internalID: string;
76
- };
77
- };
78
73
  };
79
74
  export declare type PersistedSnapControllerState = SnapControllerState & {
80
75
  snaps: Record<ValidatedSnapId, PersistedSnap>;
@@ -161,10 +156,6 @@ export declare type InstallSnaps = {
161
156
  type: `${typeof controllerName}:install`;
162
157
  handler: SnapController['installSnaps'];
163
158
  };
164
- export declare type RemoveSnapError = {
165
- type: `${typeof controllerName}:removeSnapError`;
166
- handler: SnapController['removeSnapError'];
167
- };
168
159
  export declare type GetRegistryMetadata = {
169
160
  type: `${typeof controllerName}:getRegistryMetadata`;
170
161
  handler: SnapController['getRegistryMetadata'];
@@ -177,7 +168,11 @@ export declare type RevokeDynamicPermissions = {
177
168
  type: `${typeof controllerName}:revokeDynamicPermissions`;
178
169
  handler: SnapController['revokeDynamicSnapPermissions'];
179
170
  };
180
- export declare type SnapControllerActions = ClearSnapState | GetSnap | GetSnapState | HandleSnapRequest | HasSnap | UpdateBlockedSnaps | UpdateSnapState | EnableSnap | DisableSnap | RemoveSnap | GetPermittedSnaps | InstallSnaps | RemoveSnapError | GetAllSnaps | IncrementActiveReferences | DecrementActiveReferences | GetRegistryMetadata | DisconnectOrigin | RevokeDynamicPermissions;
171
+ export declare type GetSnapFile = {
172
+ type: `${typeof controllerName}:getFile`;
173
+ handler: SnapController['getSnapFile'];
174
+ };
175
+ export declare type SnapControllerActions = ClearSnapState | GetSnap | GetSnapState | HandleSnapRequest | HasSnap | UpdateBlockedSnaps | UpdateSnapState | EnableSnap | DisableSnap | RemoveSnap | GetPermittedSnaps | InstallSnaps | GetAllSnaps | IncrementActiveReferences | DecrementActiveReferences | GetRegistryMetadata | DisconnectOrigin | RevokeDynamicPermissions | GetSnapFile;
181
176
  export declare type SnapStateChange = {
182
177
  type: `${typeof controllerName}:stateChange`;
183
178
  payload: [SnapControllerState, Patch[]];
@@ -202,7 +197,7 @@ export declare type SnapBlocked = {
202
197
  */
203
198
  export declare type SnapInstalled = {
204
199
  type: `${typeof controllerName}:snapInstalled`;
205
- payload: [snap: TruncatedSnap];
200
+ payload: [snap: TruncatedSnap, origin: string];
206
201
  };
207
202
  /**
208
203
  * Emitted when a snap that has previously been fully installed, is uninstalled.
@@ -231,7 +226,7 @@ export declare type SnapUnblocked = {
231
226
  */
232
227
  export declare type SnapUpdated = {
233
228
  type: `${typeof controllerName}:snapUpdated`;
234
- payload: [snap: TruncatedSnap, oldVersion: string];
229
+ payload: [snap: TruncatedSnap, oldVersion: string, origin: string];
235
230
  };
236
231
  /**
237
232
  * Emitted when a snap is rolled back.
@@ -264,7 +259,7 @@ export declare type SnapDisabled = {
264
259
  payload: [snap: TruncatedSnap];
265
260
  };
266
261
  export declare type SnapControllerEvents = SnapAdded | SnapBlocked | SnapInstalled | SnapUninstalled | SnapRemoved | SnapStateChange | SnapUnblocked | SnapUpdated | SnapRolledback | SnapTerminated | SnapEnabled | SnapDisabled;
267
- export declare type AllowedActions = GetEndowments | GetPermissions | GetSubjects | GetSubjectMetadata | HasPermission | HasPermissions | RevokePermissions | RevokeAllPermissions | RevokePermissionForAllSubjects | GrantPermissions | AddApprovalRequest | HandleRpcRequestAction | ExecuteSnapAction | TerminateAllSnapsAction | TerminateSnapAction | UpdateCaveat | UpdateRequestState | GetResult | GetMetadata | Update;
262
+ export declare type AllowedActions = GetEndowments | GetPermissions | GetSubjects | GetSubjectMetadata | HasPermission | HasPermissions | RevokePermissions | RevokeAllPermissions | RevokePermissionForAllSubjects | GrantPermissions | AddApprovalRequest | HandleRpcRequestAction | ExecuteSnapAction | TerminateAllSnapsAction | TerminateSnapAction | UpdateCaveat | UpdateRequestState | GetResult | GetMetadata | Update | ResolveVersion;
268
263
  export declare type AllowedEvents = ExecutionServiceEvents | SnapInstalled | SnapUpdated;
269
264
  declare type SnapControllerMessenger = RestrictedControllerMessenger<typeof controllerName, SnapControllerActions | AllowedActions, SnapControllerEvents | AllowedEvents, AllowedActions['type'], AllowedEvents['type']>;
270
265
  declare type FeatureFlags = {
@@ -342,7 +337,7 @@ export declare class SnapController extends BaseController<string, SnapControlle
342
337
  * for more information.
343
338
  */
344
339
  updateBlockedSnaps(): Promise<void>;
345
- _onUnhandledSnapError(snapId: SnapId, error: SnapErrorJson): void;
340
+ _onUnhandledSnapError(snapId: SnapId, _error: SnapErrorJson): void;
346
341
  _onOutboundRequest(snapId: SnapId): void;
347
342
  _onOutboundResponse(snapId: SnapId): void;
348
343
  /**
@@ -441,22 +436,6 @@ export declare class SnapController extends BaseController<string, SnapControlle
441
436
  * @param snapId - The id of the Snap whose state should be cleared.
442
437
  */
443
438
  clearSnapState(snapId: ValidatedSnapId): void;
444
- /**
445
- * Adds error from a snap to the SnapController state.
446
- *
447
- * @param snapError - The error to store on the SnapController.
448
- */
449
- addSnapError(snapError: SnapError): void;
450
- /**
451
- * Removes an error by internalID from the SnapControllers state.
452
- *
453
- * @param internalID - The internal error ID to remove on the SnapController.
454
- */
455
- removeSnapError(internalID: string): void;
456
- /**
457
- * Clears all errors from the SnapControllers state.
458
- */
459
- clearSnapErrors(): void;
460
439
  /**
461
440
  * Gets the own state of the snap with the given id.
462
441
  * This is distinct from the state MetaMask uses to manage snaps.
@@ -466,6 +445,15 @@ export declare class SnapController extends BaseController<string, SnapControlle
466
445
  * @throws If the snap state decryption fails.
467
446
  */
468
447
  getSnapState(snapId: ValidatedSnapId): Promise<Json>;
448
+ /**
449
+ * Gets a static auxiliary snap file in a chosen file encoding.
450
+ *
451
+ * @param snapId - The id of the Snap whose state to get.
452
+ * @param path - The path to the requested file.
453
+ * @param encoding - An optional requested file encoding.
454
+ * @returns The file requested in the chosen file encoding or null if the file is not found.
455
+ */
456
+ getSnapFile(snapId: ValidatedSnapId, path: string, encoding?: AuxiliaryFileEncoding): string | null;
469
457
  /**
470
458
  * Completely clear the controller's state: delete all associated data,
471
459
  * handlers, event listeners, and permissions; tear down all snap providers.
@@ -2,7 +2,7 @@ import type { SnapManifest } from '@metamask/snaps-utils';
2
2
  import { VirtualFile } from '@metamask/snaps-utils';
3
3
  import type { SemVerRange } from '@metamask/utils';
4
4
  import type { DetectSnapLocationOptions, SnapLocation } from './location';
5
- export declare const DEFAULT_NPM_REGISTRY = "https://registry.npmjs.org";
5
+ export declare const DEFAULT_NPM_REGISTRY: URL;
6
6
  export interface NpmOptions {
7
7
  /**
8
8
  * @default DEFAULT_REQUESTED_SNAP_VERSION
@@ -21,6 +21,10 @@ export declare type GetResult = {
21
21
  type: `${typeof controllerName}:get`;
22
22
  handler: SnapsRegistry['get'];
23
23
  };
24
+ export declare type ResolveVersion = {
25
+ type: `${typeof controllerName}:resolveVersion`;
26
+ handler: SnapsRegistry['resolveVersion'];
27
+ };
24
28
  export declare type GetMetadata = {
25
29
  type: `${typeof controllerName}:getMetadata`;
26
30
  handler: SnapsRegistry['getMetadata'];
@@ -29,7 +33,7 @@ export declare type Update = {
29
33
  type: `${typeof controllerName}:update`;
30
34
  handler: SnapsRegistry['update'];
31
35
  };
32
- export declare type SnapsRegistryActions = GetResult | GetMetadata | Update;
36
+ export declare type SnapsRegistryActions = GetResult | GetMetadata | Update | ResolveVersion;
33
37
  export declare type SnapsRegistryEvents = never;
34
38
  export declare type SnapsRegistryMessenger = RestrictedControllerMessenger<'SnapsRegistry', SnapsRegistryActions, SnapsRegistryEvents, SnapsRegistryActions['type'], SnapsRegistryEvents['type']>;
35
39
  export declare type SnapsRegistryState = {
@@ -1,6 +1,6 @@
1
1
  import type { BlockReason, SnapsRegistryDatabase } from '@metamask/snaps-registry';
2
2
  import type { SnapId, ValidatedSnapId } from '@metamask/snaps-utils';
3
- import type { SemVerVersion } from '@metamask/utils';
3
+ import type { SemVerRange, SemVerVersion } from '@metamask/utils';
4
4
  export declare type SnapsRegistryInfo = {
5
5
  version: SemVerVersion;
6
6
  checksum: string;
@@ -19,6 +19,16 @@ export declare type SnapsRegistryResult = {
19
19
  export declare type SnapsRegistry = {
20
20
  get(snaps: SnapsRegistryRequest): Promise<Record<ValidatedSnapId, SnapsRegistryResult>>;
21
21
  update(): Promise<void>;
22
+ /**
23
+ * Find an allowlisted version within a specified version range.
24
+ *
25
+ * @param snapId - The ID of the snap we are trying to resolve a version for.
26
+ * @param versionRange - The version range.
27
+ * @param refetch - An optional flag used to determine if we are refetching the registry.
28
+ * @returns An allowlisted version within the specified version range.
29
+ * @throws If an allowlisted version does not exist within the version range.
30
+ */
31
+ resolveVersion(snapId: SnapId, versionRange: SemVerRange): Promise<SemVerRange>;
22
32
  /**
23
33
  * Get metadata for the given snap ID.
24
34
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask/snaps-controllers",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "Controllers for MetaMask Snaps.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -37,32 +37,31 @@
37
37
  "lint": "yarn lint:eslint && yarn lint:misc --check && yarn lint:changelog && yarn lint:dependencies",
38
38
  "lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write",
39
39
  "lint:changelog": "../../scripts/validate-changelog.sh @metamask/snaps-controllers",
40
- "prepare-manifest:preview": "../../scripts/prepare-preview-manifest.sh",
41
40
  "publish:preview": "yarn npm publish --tag preview",
42
41
  "lint:ci": "yarn lint",
43
42
  "lint:dependencies": "depcheck"
44
43
  },
45
44
  "dependencies": {
46
- "@metamask/approval-controller": "^3.5.0",
45
+ "@metamask/approval-controller": "^4.0.0",
47
46
  "@metamask/base-controller": "^3.2.0",
47
+ "@metamask/json-rpc-engine": "^7.1.1",
48
48
  "@metamask/object-multiplex": "^1.2.0",
49
- "@metamask/permission-controller": "^4.1.2",
49
+ "@metamask/permission-controller": "^5.0.0",
50
50
  "@metamask/post-message-stream": "^7.0.0",
51
- "@metamask/rpc-methods": "^3.0.0",
52
- "@metamask/snaps-execution-environments": "^3.0.0",
53
- "@metamask/snaps-registry": "^2.0.0",
54
- "@metamask/snaps-utils": "^3.0.0",
51
+ "@metamask/rpc-errors": "^6.1.0",
52
+ "@metamask/snaps-registry": "^2.1.0",
53
+ "@metamask/snaps-rpc-methods": "^3.1.0",
54
+ "@metamask/snaps-utils": "^3.1.0",
55
55
  "@metamask/utils": "^8.1.0",
56
56
  "@xstate/fsm": "^2.0.0",
57
57
  "concat-stream": "^2.0.0",
58
- "eth-rpc-errors": "^4.0.3",
58
+ "get-npm-tarball-url": "^2.0.3",
59
59
  "gunzip-maybe": "^1.4.2",
60
60
  "immer": "^9.0.6",
61
- "json-rpc-engine": "^6.1.0",
62
- "json-rpc-middleware-stream": "^4.2.0",
61
+ "json-rpc-middleware-stream": "^5.0.0",
63
62
  "nanoid": "^3.1.31",
64
63
  "readable-web-to-node-stream": "^3.0.2",
65
- "tar-stream": "^2.2.0"
64
+ "tar-stream": "^3.1.6"
66
65
  },
67
66
  "devDependencies": {
68
67
  "@esbuild-plugins/node-globals-polyfill": "^0.2.3",
@@ -84,17 +83,17 @@
84
83
  "@types/mocha": "^10.0.1",
85
84
  "@types/node": "18.14.2",
86
85
  "@types/readable-stream": "^2.3.15",
87
- "@types/tar-stream": "^2.2.2",
86
+ "@types/tar-stream": "^3.1.1",
88
87
  "@typescript-eslint/eslint-plugin": "^5.42.1",
89
88
  "@typescript-eslint/parser": "^5.42.1",
90
- "@wdio/browser-runner": "^8.15.9",
91
- "@wdio/cli": "^8.15.9",
92
- "@wdio/globals": "^8.15.9",
93
- "@wdio/mocha-framework": "^8.15.9",
94
- "@wdio/spec-reporter": "^8.15.7",
95
- "@wdio/static-server-service": "^8.15.7",
89
+ "@wdio/browser-runner": "^8.19.0",
90
+ "@wdio/cli": "^8.19.0",
91
+ "@wdio/globals": "^8.19.0",
92
+ "@wdio/mocha-framework": "^8.19.0",
93
+ "@wdio/spec-reporter": "^8.19.0",
94
+ "@wdio/static-server-service": "^8.19.0",
96
95
  "deepmerge": "^4.2.2",
97
- "depcheck": "^1.4.5",
96
+ "depcheck": "^1.4.7",
98
97
  "esbuild": "^0.18.10",
99
98
  "eslint": "^8.27.0",
100
99
  "eslint-config-prettier": "^8.5.0",
@@ -104,7 +103,7 @@
104
103
  "eslint-plugin-n": "^15.7.0",
105
104
  "eslint-plugin-prettier": "^4.2.1",
106
105
  "eslint-plugin-promise": "^6.1.1",
107
- "expect-webdriverio": "^4.1.2",
106
+ "expect-webdriverio": "^4.4.1",
108
107
  "istanbul-lib-coverage": "^3.2.0",
109
108
  "istanbul-lib-report": "^3.0.0",
110
109
  "istanbul-reports": "^3.1.5",
@@ -120,7 +119,15 @@
120
119
  "vite-tsconfig-paths": "^4.0.5",
121
120
  "wdio-chromedriver-service": "^8.1.1",
122
121
  "wdio-geckodriver-service": "^5.0.2",
123
- "webdriverio": "^8.15.9"
122
+ "webdriverio": "^8.19.0"
123
+ },
124
+ "peerDependencies": {
125
+ "@metamask/snaps-execution-environments": "^3.1.0"
126
+ },
127
+ "peerDependenciesMeta": {
128
+ "@metamask/snaps-execution-environments": {
129
+ "optional": true
130
+ }
124
131
  },
125
132
  "engines": {
126
133
  "node": "^18.16 || >=20"