@metamask/snaps-controllers 1.0.0 → 1.0.1
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
|
@@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.0.1]
|
|
10
|
+
### Fixed
|
|
11
|
+
- Fix parallel usage of registry ([#1669](https://github.com/MetaMask/snaps/pull/1669))
|
|
12
|
+
|
|
9
13
|
## [1.0.0]
|
|
10
14
|
### Changed
|
|
11
15
|
- Make `updateBlockedSnaps` update the registry ([#1625](https://github.com/MetaMask/snaps/pull/1625))
|
|
@@ -515,7 +519,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
515
519
|
### Added
|
|
516
520
|
- First semi-stable release.
|
|
517
521
|
|
|
518
|
-
[Unreleased]: https://github.com/MetaMask/snaps/compare/v1.0.
|
|
522
|
+
[Unreleased]: https://github.com/MetaMask/snaps/compare/v1.0.1...HEAD
|
|
523
|
+
[1.0.1]: https://github.com/MetaMask/snaps/compare/v1.0.0...v1.0.1
|
|
519
524
|
[1.0.0]: https://github.com/MetaMask/snaps/compare/v1.0.0-prerelease.1...v1.0.0
|
|
520
525
|
[1.0.0-prerelease.1]: https://github.com/MetaMask/snaps/compare/v0.32.2...v1.0.0-prerelease.1
|
|
521
526
|
[0.32.2]: https://github.com/MetaMask/snaps/compare/v0.32.1...v0.32.2
|
|
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
10
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
11
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
12
|
};
|
|
13
|
-
var _JsonSnapsRegistry_instances, _JsonSnapsRegistry_url, _JsonSnapsRegistry_publicKey, _JsonSnapsRegistry_fetchFunction, _JsonSnapsRegistry_recentFetchThreshold, _JsonSnapsRegistry_refetchOnAllowlistMiss, _JsonSnapsRegistry_failOnUnavailableRegistry, _JsonSnapsRegistry_wasRecentlyFetched, _JsonSnapsRegistry_update, _JsonSnapsRegistry_getDatabase, _JsonSnapsRegistry_getSingle, _JsonSnapsRegistry_get, _JsonSnapsRegistry_getMetadata, _JsonSnapsRegistry_verifySignature, _JsonSnapsRegistry_safeFetch;
|
|
13
|
+
var _JsonSnapsRegistry_instances, _JsonSnapsRegistry_url, _JsonSnapsRegistry_publicKey, _JsonSnapsRegistry_fetchFunction, _JsonSnapsRegistry_recentFetchThreshold, _JsonSnapsRegistry_refetchOnAllowlistMiss, _JsonSnapsRegistry_failOnUnavailableRegistry, _JsonSnapsRegistry_currentUpdate, _JsonSnapsRegistry_wasRecentlyFetched, _JsonSnapsRegistry_triggerUpdate, _JsonSnapsRegistry_update, _JsonSnapsRegistry_getDatabase, _JsonSnapsRegistry_getSingle, _JsonSnapsRegistry_get, _JsonSnapsRegistry_getMetadata, _JsonSnapsRegistry_verifySignature, _JsonSnapsRegistry_safeFetch;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.JsonSnapsRegistry = void 0;
|
|
16
16
|
const base_controller_1 = require("@metamask/base-controller");
|
|
@@ -49,22 +49,48 @@ class JsonSnapsRegistry extends base_controller_1.BaseControllerV2 {
|
|
|
49
49
|
_JsonSnapsRegistry_recentFetchThreshold.set(this, void 0);
|
|
50
50
|
_JsonSnapsRegistry_refetchOnAllowlistMiss.set(this, void 0);
|
|
51
51
|
_JsonSnapsRegistry_failOnUnavailableRegistry.set(this, void 0);
|
|
52
|
+
_JsonSnapsRegistry_currentUpdate.set(this, void 0);
|
|
52
53
|
__classPrivateFieldSet(this, _JsonSnapsRegistry_url, url, "f");
|
|
53
54
|
__classPrivateFieldSet(this, _JsonSnapsRegistry_publicKey, publicKey, "f");
|
|
54
55
|
__classPrivateFieldSet(this, _JsonSnapsRegistry_fetchFunction, fetchFunction, "f");
|
|
55
56
|
__classPrivateFieldSet(this, _JsonSnapsRegistry_recentFetchThreshold, recentFetchThreshold, "f");
|
|
56
57
|
__classPrivateFieldSet(this, _JsonSnapsRegistry_refetchOnAllowlistMiss, refetchOnAllowlistMiss, "f");
|
|
57
58
|
__classPrivateFieldSet(this, _JsonSnapsRegistry_failOnUnavailableRegistry, failOnUnavailableRegistry, "f");
|
|
59
|
+
__classPrivateFieldSet(this, _JsonSnapsRegistry_currentUpdate, null, "f");
|
|
58
60
|
this.messagingSystem.registerActionHandler('SnapsRegistry:get', async (...args) => __classPrivateFieldGet(this, _JsonSnapsRegistry_instances, "m", _JsonSnapsRegistry_get).call(this, ...args));
|
|
59
61
|
this.messagingSystem.registerActionHandler('SnapsRegistry:getMetadata', async (...args) => __classPrivateFieldGet(this, _JsonSnapsRegistry_instances, "m", _JsonSnapsRegistry_getMetadata).call(this, ...args));
|
|
60
|
-
this.messagingSystem.registerActionHandler('SnapsRegistry:update', async () => __classPrivateFieldGet(this, _JsonSnapsRegistry_instances, "m",
|
|
62
|
+
this.messagingSystem.registerActionHandler('SnapsRegistry:update', async () => __classPrivateFieldGet(this, _JsonSnapsRegistry_instances, "m", _JsonSnapsRegistry_triggerUpdate).call(this));
|
|
61
63
|
}
|
|
62
64
|
}
|
|
63
65
|
exports.JsonSnapsRegistry = JsonSnapsRegistry;
|
|
64
|
-
_JsonSnapsRegistry_url = new WeakMap(), _JsonSnapsRegistry_publicKey = new WeakMap(), _JsonSnapsRegistry_fetchFunction = new WeakMap(), _JsonSnapsRegistry_recentFetchThreshold = new WeakMap(), _JsonSnapsRegistry_refetchOnAllowlistMiss = new WeakMap(), _JsonSnapsRegistry_failOnUnavailableRegistry = new WeakMap(), _JsonSnapsRegistry_instances = new WeakSet(), _JsonSnapsRegistry_wasRecentlyFetched = function _JsonSnapsRegistry_wasRecentlyFetched() {
|
|
66
|
+
_JsonSnapsRegistry_url = new WeakMap(), _JsonSnapsRegistry_publicKey = new WeakMap(), _JsonSnapsRegistry_fetchFunction = new WeakMap(), _JsonSnapsRegistry_recentFetchThreshold = new WeakMap(), _JsonSnapsRegistry_refetchOnAllowlistMiss = new WeakMap(), _JsonSnapsRegistry_failOnUnavailableRegistry = new WeakMap(), _JsonSnapsRegistry_currentUpdate = new WeakMap(), _JsonSnapsRegistry_instances = new WeakSet(), _JsonSnapsRegistry_wasRecentlyFetched = function _JsonSnapsRegistry_wasRecentlyFetched() {
|
|
65
67
|
return (this.state.lastUpdated &&
|
|
66
68
|
Date.now() - this.state.lastUpdated < __classPrivateFieldGet(this, _JsonSnapsRegistry_recentFetchThreshold, "f"));
|
|
67
|
-
},
|
|
69
|
+
}, _JsonSnapsRegistry_triggerUpdate =
|
|
70
|
+
/**
|
|
71
|
+
* Triggers an update of the registry database.
|
|
72
|
+
*
|
|
73
|
+
* If an existing update is in progress this function will await that update.
|
|
74
|
+
*/
|
|
75
|
+
async function _JsonSnapsRegistry_triggerUpdate() {
|
|
76
|
+
// If an update is ongoing, wait for that.
|
|
77
|
+
if (__classPrivateFieldGet(this, _JsonSnapsRegistry_currentUpdate, "f")) {
|
|
78
|
+
await __classPrivateFieldGet(this, _JsonSnapsRegistry_currentUpdate, "f");
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
// If no update exists, create promise and store globally.
|
|
82
|
+
if (__classPrivateFieldGet(this, _JsonSnapsRegistry_currentUpdate, "f") === null) {
|
|
83
|
+
__classPrivateFieldSet(this, _JsonSnapsRegistry_currentUpdate, __classPrivateFieldGet(this, _JsonSnapsRegistry_instances, "m", _JsonSnapsRegistry_update).call(this), "f");
|
|
84
|
+
}
|
|
85
|
+
await __classPrivateFieldGet(this, _JsonSnapsRegistry_currentUpdate, "f");
|
|
86
|
+
__classPrivateFieldSet(this, _JsonSnapsRegistry_currentUpdate, null, "f");
|
|
87
|
+
}, _JsonSnapsRegistry_update =
|
|
88
|
+
/**
|
|
89
|
+
* Updates the registry database if the registry hasn't been updated recently.
|
|
90
|
+
*
|
|
91
|
+
* NOTE: SHOULD NOT be called directly, instead `triggerUpdate` should be used.
|
|
92
|
+
*/
|
|
93
|
+
async function _JsonSnapsRegistry_update() {
|
|
68
94
|
// No-op if we recently fetched the registry.
|
|
69
95
|
if (__classPrivateFieldGet(this, _JsonSnapsRegistry_instances, "m", _JsonSnapsRegistry_wasRecentlyFetched).call(this)) {
|
|
70
96
|
return;
|
|
@@ -85,7 +111,7 @@ _JsonSnapsRegistry_url = new WeakMap(), _JsonSnapsRegistry_publicKey = new WeakM
|
|
|
85
111
|
}
|
|
86
112
|
}, _JsonSnapsRegistry_getDatabase = async function _JsonSnapsRegistry_getDatabase() {
|
|
87
113
|
if (this.state.database === null) {
|
|
88
|
-
await __classPrivateFieldGet(this, _JsonSnapsRegistry_instances, "m",
|
|
114
|
+
await __classPrivateFieldGet(this, _JsonSnapsRegistry_instances, "m", _JsonSnapsRegistry_triggerUpdate).call(this);
|
|
89
115
|
}
|
|
90
116
|
// If the database is still null and we require it, throw.
|
|
91
117
|
if (__classPrivateFieldGet(this, _JsonSnapsRegistry_failOnUnavailableRegistry, "f") && this.state.database === null) {
|
|
@@ -114,7 +140,7 @@ _JsonSnapsRegistry_url = new WeakMap(), _JsonSnapsRegistry_publicKey = new WeakM
|
|
|
114
140
|
}
|
|
115
141
|
// For now, if we have an allowlist miss, we can refetch once and try again.
|
|
116
142
|
if (__classPrivateFieldGet(this, _JsonSnapsRegistry_refetchOnAllowlistMiss, "f") && !refetch) {
|
|
117
|
-
await __classPrivateFieldGet(this, _JsonSnapsRegistry_instances, "m",
|
|
143
|
+
await __classPrivateFieldGet(this, _JsonSnapsRegistry_instances, "m", _JsonSnapsRegistry_triggerUpdate).call(this);
|
|
118
144
|
return __classPrivateFieldGet(this, _JsonSnapsRegistry_instances, "m", _JsonSnapsRegistry_getSingle).call(this, snapId, snapInfo, true);
|
|
119
145
|
}
|
|
120
146
|
return { status: registry_1.SnapsRegistryStatus.Unverified };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json.js","sourceRoot":"","sources":["../../../src/snaps/registry/json.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BaseControllerV2 as BaseController,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport { SnapsRegistryDatabase, verify } from '@metamask/snaps-registry';\nimport { SnapId } from '@metamask/snaps-utils';\nimport {\n assert,\n Duration,\n Hex,\n inMilliseconds,\n satisfiesVersionRange,\n} from '@metamask/utils';\n\nimport {\n SnapsRegistry,\n SnapsRegistryInfo,\n SnapsRegistryMetadata,\n SnapsRegistryRequest,\n SnapsRegistryResult,\n SnapsRegistryStatus,\n} 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 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\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.#update(),\n );\n }\n\n #wasRecentlyFetched() {\n return (\n this.state.lastUpdated &&\n Date.now() - this.state.lastUpdated < this.#recentFetchThreshold\n );\n }\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.#update();\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.#update();\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"]}
|
|
1
|
+
{"version":3,"file":"json.js","sourceRoot":"","sources":["../../../src/snaps/registry/json.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BaseControllerV2 as BaseController,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport { SnapsRegistryDatabase, verify } from '@metamask/snaps-registry';\nimport { SnapId } from '@metamask/snaps-utils';\nimport {\n assert,\n Duration,\n Hex,\n inMilliseconds,\n satisfiesVersionRange,\n} from '@metamask/utils';\n\nimport {\n SnapsRegistry,\n SnapsRegistryInfo,\n SnapsRegistryMetadata,\n SnapsRegistryRequest,\n SnapsRegistryResult,\n SnapsRegistryStatus,\n} 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"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask/snaps-controllers",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Controllers for MetaMask Snaps.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
"@metamask/object-multiplex": "^1.2.0",
|
|
40
40
|
"@metamask/permission-controller": "^4.0.0",
|
|
41
41
|
"@metamask/post-message-stream": "^6.1.2",
|
|
42
|
-
"@metamask/rpc-methods": "^1.0.
|
|
43
|
-
"@metamask/snaps-execution-environments": "^1.0.
|
|
42
|
+
"@metamask/rpc-methods": "^1.0.1",
|
|
43
|
+
"@metamask/snaps-execution-environments": "^1.0.1",
|
|
44
44
|
"@metamask/snaps-registry": "^1.2.1",
|
|
45
|
-
"@metamask/snaps-utils": "^1.0.
|
|
45
|
+
"@metamask/snaps-utils": "^1.0.1",
|
|
46
46
|
"@metamask/utils": "^6.0.1",
|
|
47
47
|
"@xstate/fsm": "^2.0.0",
|
|
48
48
|
"concat-stream": "^2.0.0",
|