@metamask/snaps-controllers 7.0.1 → 8.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -1
- package/dist/{chunk-Q2ON6SMV.js → chunk-2UAU42DO.js} +17 -25
- package/dist/chunk-2UAU42DO.js.map +1 -0
- package/dist/{chunk-Y5KX5ICF.mjs → chunk-3Y4IJKZY.mjs} +3 -3
- package/dist/chunk-3Y4IJKZY.mjs.map +1 -0
- package/dist/{chunk-XE5IWVNV.js → chunk-4DPX4O3T.js} +17 -6
- package/dist/chunk-4DPX4O3T.js.map +1 -0
- package/dist/{chunk-YVNRYLOC.js → chunk-74GN6MIJ.js} +3 -3
- package/dist/{chunk-NOLPMHXS.js → chunk-BOFPNIRX.js} +21 -3
- package/dist/chunk-BOFPNIRX.js.map +1 -0
- package/dist/{chunk-3ZC4LB7T.js → chunk-E5RRFMGF.js} +3 -3
- package/dist/chunk-E5RRFMGF.js.map +1 -0
- package/dist/{chunk-WVGK5B5P.mjs → chunk-FCCGRGQS.mjs} +83 -48
- package/dist/chunk-FCCGRGQS.mjs.map +1 -0
- package/dist/{chunk-NSLYI2LS.js → chunk-FCRPOA4I.js} +12 -4
- package/dist/chunk-FCRPOA4I.js.map +1 -0
- package/dist/{chunk-63GNCRER.js → chunk-G4S6UXQ2.js} +4 -4
- package/dist/chunk-G4S6UXQ2.js.map +1 -0
- package/dist/{chunk-MYWDTEX2.js → chunk-GRBWVPLF.js} +4 -4
- package/dist/{chunk-36YC4Z3T.mjs → chunk-GTDDODNP.mjs} +13 -2
- package/dist/chunk-GTDDODNP.mjs.map +1 -0
- package/dist/{chunk-5MVIYRYL.mjs → chunk-IPYO7FKR.mjs} +40 -26
- package/dist/chunk-IPYO7FKR.mjs.map +1 -0
- package/dist/{chunk-75VM3O4K.mjs → chunk-P5MRZOGW.mjs} +2 -2
- package/dist/{chunk-Z6SOB3SY.js → chunk-PAFO2KIN.js} +3 -3
- package/dist/chunk-PAFO2KIN.js.map +1 -0
- package/dist/{chunk-25LS4KZK.mjs → chunk-PXKCSAT6.mjs} +3 -3
- package/dist/chunk-PXKCSAT6.mjs.map +1 -0
- package/dist/{chunk-BJOQRBH2.mjs → chunk-QLEQIXCE.mjs} +2 -2
- package/dist/chunk-QLEQIXCE.mjs.map +1 -0
- package/dist/{chunk-K276CM3B.mjs → chunk-QP5LV734.mjs} +20 -28
- package/dist/chunk-QP5LV734.mjs.map +1 -0
- package/dist/{chunk-SCERVW3B.mjs → chunk-RS3WN6D3.mjs} +2 -2
- package/dist/chunk-RS3WN6D3.mjs.map +1 -0
- package/dist/{chunk-54TYYPAN.js → chunk-SIW7ZXQF.js} +83 -48
- package/dist/chunk-SIW7ZXQF.js.map +1 -0
- package/dist/{chunk-Q4I5QTVC.mjs → chunk-TO6ZEBIA.mjs} +11 -3
- package/dist/chunk-TO6ZEBIA.mjs.map +1 -0
- package/dist/chunk-U4DZUKNN.js +80 -0
- package/dist/chunk-U4DZUKNN.js.map +1 -0
- package/dist/{chunk-2KCUVQFS.mjs → chunk-X5MFC3VX.mjs} +2 -2
- package/dist/{chunk-VOZOZKRC.mjs → chunk-XO7KDFBY.mjs} +21 -3
- package/dist/chunk-XO7KDFBY.mjs.map +1 -0
- package/dist/{chunk-ZETJVFUS.mjs → chunk-XSFI32LB.mjs} +2 -2
- package/dist/{chunk-WQYMF7QP.js → chunk-Y7ZOSPEN.js} +3 -3
- package/dist/{chunk-CJN25EXL.js → chunk-YP37KUG5.js} +46 -32
- package/dist/chunk-YP37KUG5.js.map +1 -0
- package/dist/chunk-ZQNBP53T.mjs +80 -0
- package/dist/chunk-ZQNBP53T.mjs.map +1 -0
- package/dist/{chunk-N7WIJNHY.js → chunk-ZVGZG25U.js} +4 -4
- package/dist/chunk-ZVGZG25U.js.map +1 -0
- package/dist/cronjob/CronjobController.js +12 -12
- package/dist/cronjob/CronjobController.mjs +11 -11
- package/dist/cronjob/index.js +12 -12
- package/dist/cronjob/index.mjs +11 -11
- package/dist/index.js +14 -12
- package/dist/index.mjs +13 -11
- package/dist/interface/SnapInterfaceController.js +3 -3
- package/dist/interface/SnapInterfaceController.mjs +2 -2
- package/dist/interface/index.js +3 -3
- package/dist/interface/index.mjs +2 -2
- package/dist/interface/utils.js +2 -4
- package/dist/interface/utils.mjs +5 -7
- package/dist/node.js +16 -14
- package/dist/node.mjs +15 -13
- package/dist/react-native.js +15 -13
- package/dist/react-native.mjs +14 -12
- package/dist/services/AbstractExecutionService.js +4 -4
- package/dist/services/AbstractExecutionService.mjs +3 -3
- package/dist/services/browser.js +9 -9
- package/dist/services/browser.mjs +8 -8
- package/dist/services/iframe/IframeExecutionService.js +5 -5
- package/dist/services/iframe/IframeExecutionService.mjs +4 -4
- package/dist/services/iframe/index.js +5 -5
- package/dist/services/iframe/index.mjs +4 -4
- package/dist/services/index.js +8 -8
- package/dist/services/index.mjs +7 -7
- package/dist/services/node-js/NodeProcessExecutionService.js +9 -9
- package/dist/services/node-js/NodeProcessExecutionService.mjs +8 -8
- package/dist/services/node-js/NodeThreadExecutionService.js +9 -9
- package/dist/services/node-js/NodeThreadExecutionService.mjs +8 -8
- package/dist/services/node-js/index.js +10 -10
- package/dist/services/node-js/index.mjs +9 -9
- package/dist/services/node.js +10 -10
- package/dist/services/node.mjs +9 -9
- package/dist/services/offscreen/OffscreenExecutionService.js +6 -6
- package/dist/services/offscreen/OffscreenExecutionService.mjs +5 -5
- package/dist/services/offscreen/index.js +6 -6
- package/dist/services/offscreen/index.mjs +5 -5
- package/dist/services/proxy/ProxyExecutionService.js +5 -5
- package/dist/services/proxy/ProxyExecutionService.mjs +4 -4
- package/dist/services/react-native.js +9 -9
- package/dist/services/react-native.mjs +8 -8
- package/dist/services/webview/WebViewExecutionService.js +6 -6
- package/dist/services/webview/WebViewExecutionService.mjs +5 -5
- package/dist/services/webview/index.js +6 -6
- package/dist/services/webview/index.mjs +5 -5
- package/dist/services/webworker/WebWorkerExecutionService.js +5 -5
- package/dist/services/webworker/WebWorkerExecutionService.mjs +4 -4
- package/dist/services/webworker/index.js +5 -5
- package/dist/services/webworker/index.mjs +4 -4
- package/dist/snaps/SnapController.js +4 -4
- package/dist/snaps/SnapController.mjs +3 -3
- package/dist/snaps/Timer.js +2 -2
- package/dist/snaps/Timer.mjs +1 -1
- package/dist/snaps/index.js +4 -4
- package/dist/snaps/index.mjs +3 -3
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types/interface/SnapInterfaceController.d.ts +5 -4
- package/dist/types/interface/utils.d.ts +11 -20
- package/dist/types/services/AbstractExecutionService.d.ts +18 -12
- package/dist/types/services/ExecutionService.d.ts +1 -1
- package/dist/types/services/iframe/IframeExecutionService.d.ts +2 -2
- package/dist/types/services/node-js/NodeProcessExecutionService.d.ts +2 -2
- package/dist/types/services/node-js/NodeThreadExecutionService.d.ts +2 -2
- package/dist/types/services/proxy/ProxyExecutionService.d.ts +2 -2
- package/dist/types/services/webworker/WebWorkerExecutionService.d.ts +2 -2
- package/dist/types/snaps/SnapController.d.ts +5 -6
- package/dist/types/snaps/Timer.d.ts +7 -0
- package/dist/types/utils.d.ts +12 -0
- package/dist/utils.js +5 -3
- package/dist/utils.mjs +4 -2
- package/package.json +8 -7
- package/dist/chunk-25LS4KZK.mjs.map +0 -1
- package/dist/chunk-36YC4Z3T.mjs.map +0 -1
- package/dist/chunk-3ZC4LB7T.js.map +0 -1
- package/dist/chunk-54TYYPAN.js.map +0 -1
- package/dist/chunk-5MVIYRYL.mjs.map +0 -1
- package/dist/chunk-63GNCRER.js.map +0 -1
- package/dist/chunk-BJOQRBH2.mjs.map +0 -1
- package/dist/chunk-CJN25EXL.js.map +0 -1
- package/dist/chunk-K276CM3B.mjs.map +0 -1
- package/dist/chunk-KLK7ZRMH.js +0 -55
- package/dist/chunk-KLK7ZRMH.js.map +0 -1
- package/dist/chunk-N7WIJNHY.js.map +0 -1
- package/dist/chunk-NOLPMHXS.js.map +0 -1
- package/dist/chunk-NSLYI2LS.js.map +0 -1
- package/dist/chunk-Q2ON6SMV.js.map +0 -1
- package/dist/chunk-Q4I5QTVC.mjs.map +0 -1
- package/dist/chunk-RIU3ZIXZ.mjs +0 -55
- package/dist/chunk-RIU3ZIXZ.mjs.map +0 -1
- package/dist/chunk-SCERVW3B.mjs.map +0 -1
- package/dist/chunk-VOZOZKRC.mjs.map +0 -1
- package/dist/chunk-WVGK5B5P.mjs.map +0 -1
- package/dist/chunk-XE5IWVNV.js.map +0 -1
- package/dist/chunk-Y5KX5ICF.mjs.map +0 -1
- package/dist/chunk-Z6SOB3SY.js.map +0 -1
- /package/dist/{chunk-YVNRYLOC.js.map → chunk-74GN6MIJ.js.map} +0 -0
- /package/dist/{chunk-MYWDTEX2.js.map → chunk-GRBWVPLF.js.map} +0 -0
- /package/dist/{chunk-75VM3O4K.mjs.map → chunk-P5MRZOGW.mjs.map} +0 -0
- /package/dist/{chunk-2KCUVQFS.mjs.map → chunk-X5MFC3VX.mjs.map} +0 -0
- /package/dist/{chunk-ZETJVFUS.mjs.map → chunk-XSFI32LB.mjs.map} +0 -0
- /package/dist/{chunk-WQYMF7QP.js.map → chunk-Y7ZOSPEN.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [8.1.0]
|
|
10
|
+
### Added
|
|
11
|
+
- Add JSX support for custom UI ([#2258](https://github.com/MetaMask/snaps/pull/2258))
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- Bump `@metamask/approval-controller` from `6.0.1` to `6.0.2` ([#2380](https://github.com/MetaMask/snaps/pull/2380))
|
|
15
|
+
- Bump `@metamask/base-controller` from `5.0.1` to `5.0.2` ([#2375](https://github.com/MetaMask/snaps/pull/2375))
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
- Fix an issue where certain types of executors would be timed out too quickly ([#2389](https://github.com/MetaMask/snaps/pull/2389))
|
|
19
|
+
|
|
20
|
+
## [8.0.0]
|
|
21
|
+
### Changed
|
|
22
|
+
- **BREAKING:** Move `maxInitTime` constructor argument from `SnapController` to `ExecutionService` ([#2348](https://github.com/MetaMask/snaps/pull/2348))
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
- Increase max UI size limit from 250 KB to 10 MB ([#2342](https://github.com/MetaMask/snaps/pull/2342))
|
|
26
|
+
- Consider caveats in permissions difference calculation ([#2345](https://github.com/MetaMask/snaps/pull/2345))
|
|
27
|
+
- This fixes a bug where certain caveats would not be correctly applied when updating Snaps.
|
|
28
|
+
- Gracefully handle errors for multiple simultaneous failing requests ([#2346](https://github.com/MetaMask/snaps/pull/2346))
|
|
29
|
+
- Properly handle termination of Snaps that are currently executing ([#2304](https://github.com/MetaMask/snaps/pull/2304))
|
|
30
|
+
- Properly tear down partially initialized executors and improve stability when executor initialization fails ([#2348](https://github.com/MetaMask/snaps/pull/2348))
|
|
31
|
+
|
|
9
32
|
## [7.0.1]
|
|
10
33
|
### Fixed
|
|
11
34
|
- Fix encryption key caching issues ([#2326](https://github.com/MetaMask/snaps/pull/2326))
|
|
@@ -234,7 +257,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
234
257
|
- The version of the package no longer needs to match the version of all other
|
|
235
258
|
MetaMask Snaps packages.
|
|
236
259
|
|
|
237
|
-
[Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@
|
|
260
|
+
[Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@8.1.0...HEAD
|
|
261
|
+
[8.1.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@8.0.0...@metamask/snaps-controllers@8.1.0
|
|
262
|
+
[8.0.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@7.0.1...@metamask/snaps-controllers@8.0.0
|
|
238
263
|
[7.0.1]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@7.0.0...@metamask/snaps-controllers@7.0.1
|
|
239
264
|
[7.0.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@6.0.4...@metamask/snaps-controllers@7.0.0
|
|
240
265
|
[6.0.4]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-controllers@6.0.3...@metamask/snaps-controllers@6.0.4
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
var _chunkU4DZUKNNjs = require('./chunk-U4DZUKNN.js');
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
|
|
@@ -8,14 +9,10 @@ var _chunkEXN2TFDJjs = require('./chunk-EXN2TFDJ.js');
|
|
|
8
9
|
|
|
9
10
|
// src/interface/SnapInterfaceController.ts
|
|
10
11
|
var _basecontroller = require('@metamask/base-controller');
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
12
|
var _snapsutils = require('@metamask/snaps-utils');
|
|
15
13
|
var _utils = require('@metamask/utils');
|
|
16
14
|
var _nanoid = require('nanoid');
|
|
17
|
-
var MAX_UI_CONTENT_SIZE =
|
|
18
|
-
var MAX_TEXT_LENGTH = 5e4;
|
|
15
|
+
var MAX_UI_CONTENT_SIZE = 1e7;
|
|
19
16
|
var controllerName = "SnapInterfaceController";
|
|
20
17
|
var _registerMessageHandlers, registerMessageHandlers_fn, _validateArgs, validateArgs_fn, _triggerPhishingListUpdate, triggerPhishingListUpdate_fn, _checkPhishingList, checkPhishingList_fn, _validateContent, validateContent_fn;
|
|
21
18
|
var SnapInterfaceController = class extends _basecontroller.BaseController {
|
|
@@ -55,9 +52,7 @@ var SnapInterfaceController = class extends _basecontroller.BaseController {
|
|
|
55
52
|
* Utility function to validate the components of an interface.
|
|
56
53
|
* Throws if something is invalid.
|
|
57
54
|
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* @param content - The components to verify.
|
|
55
|
+
* @param element - The JSX element to verify.
|
|
61
56
|
*/
|
|
62
57
|
_chunkEXN2TFDJjs.__privateAdd.call(void 0, this, _validateContent);
|
|
63
58
|
_chunkEXN2TFDJjs.__privateMethod.call(void 0, this, _registerMessageHandlers, registerMessageHandlers_fn).call(this);
|
|
@@ -70,13 +65,14 @@ var SnapInterfaceController = class extends _basecontroller.BaseController {
|
|
|
70
65
|
* @returns The newly interface id.
|
|
71
66
|
*/
|
|
72
67
|
async createInterface(snapId, content) {
|
|
73
|
-
|
|
68
|
+
const element = _chunkU4DZUKNNjs.getJsxInterface.call(void 0, content);
|
|
69
|
+
await _chunkEXN2TFDJjs.__privateMethod.call(void 0, this, _validateContent, validateContent_fn).call(this, element);
|
|
74
70
|
const id = _nanoid.nanoid.call(void 0, );
|
|
75
|
-
const componentState =
|
|
71
|
+
const componentState = _chunkU4DZUKNNjs.constructState.call(void 0, {}, element);
|
|
76
72
|
this.update((draftState) => {
|
|
77
73
|
draftState.interfaces[id] = {
|
|
78
74
|
snapId,
|
|
79
|
-
content,
|
|
75
|
+
content: element,
|
|
80
76
|
state: componentState
|
|
81
77
|
};
|
|
82
78
|
});
|
|
@@ -102,12 +98,13 @@ var SnapInterfaceController = class extends _basecontroller.BaseController {
|
|
|
102
98
|
*/
|
|
103
99
|
async updateInterface(snapId, id, content) {
|
|
104
100
|
_chunkEXN2TFDJjs.__privateMethod.call(void 0, this, _validateArgs, validateArgs_fn).call(this, snapId, id);
|
|
105
|
-
|
|
101
|
+
const element = _chunkU4DZUKNNjs.getJsxInterface.call(void 0, content);
|
|
102
|
+
await _chunkEXN2TFDJjs.__privateMethod.call(void 0, this, _validateContent, validateContent_fn).call(this, element);
|
|
106
103
|
const oldState = this.state.interfaces[id].state;
|
|
107
|
-
const newState =
|
|
104
|
+
const newState = _chunkU4DZUKNNjs.constructState.call(void 0, oldState, element);
|
|
108
105
|
this.update((draftState) => {
|
|
109
106
|
draftState.interfaces[id].state = newState;
|
|
110
|
-
draftState.interfaces[id].content =
|
|
107
|
+
draftState.interfaces[id].content = element;
|
|
111
108
|
});
|
|
112
109
|
}
|
|
113
110
|
/**
|
|
@@ -176,22 +173,17 @@ checkPhishingList_fn = function(origin) {
|
|
|
176
173
|
return this.messagingSystem.call("PhishingController:testOrigin", origin).result;
|
|
177
174
|
};
|
|
178
175
|
_validateContent = new WeakSet();
|
|
179
|
-
validateContent_fn = async function(
|
|
180
|
-
const size =
|
|
176
|
+
validateContent_fn = async function(element) {
|
|
177
|
+
const size = _snapsutils.getJsonSizeUnsafe.call(void 0, element);
|
|
181
178
|
_utils.assert.call(void 0,
|
|
182
179
|
size <= MAX_UI_CONTENT_SIZE,
|
|
183
|
-
`A Snap UI may not be larger than ${MAX_UI_CONTENT_SIZE /
|
|
184
|
-
);
|
|
185
|
-
const textSize = _snapsutils.getTotalTextLength.call(void 0, content);
|
|
186
|
-
_utils.assert.call(void 0,
|
|
187
|
-
textSize <= MAX_TEXT_LENGTH,
|
|
188
|
-
`The text in a Snap UI may not be larger than ${MAX_TEXT_LENGTH / 1e3} kB.`
|
|
180
|
+
`A Snap UI may not be larger than ${MAX_UI_CONTENT_SIZE / 1e6} MB.`
|
|
189
181
|
);
|
|
190
182
|
await _chunkEXN2TFDJjs.__privateMethod.call(void 0, this, _triggerPhishingListUpdate, triggerPhishingListUpdate_fn).call(this);
|
|
191
|
-
_snapsutils.
|
|
183
|
+
_snapsutils.validateJsxLinks.call(void 0, element, _chunkEXN2TFDJjs.__privateMethod.call(void 0, this, _checkPhishingList, checkPhishingList_fn).bind(this));
|
|
192
184
|
};
|
|
193
185
|
|
|
194
186
|
|
|
195
187
|
|
|
196
188
|
exports.SnapInterfaceController = SnapInterfaceController;
|
|
197
|
-
//# sourceMappingURL=chunk-
|
|
189
|
+
//# sourceMappingURL=chunk-2UAU42DO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/interface/SnapInterfaceController.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RestrictedControllerMessenger } from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type {\n MaybeUpdateState,\n TestOrigin,\n} from '@metamask/phishing-controller';\nimport type {\n InterfaceState,\n SnapId,\n ComponentOrElement,\n} from '@metamask/snaps-sdk';\nimport type { JSXElement } from '@metamask/snaps-sdk/jsx';\nimport { getJsonSizeUnsafe, validateJsxLinks } from '@metamask/snaps-utils';\nimport { assert } from '@metamask/utils';\nimport { nanoid } from 'nanoid';\n\nimport { constructState, getJsxInterface } from './utils';\n\nconst MAX_UI_CONTENT_SIZE = 10_000_000; // 10 mb\n\nconst controllerName = 'SnapInterfaceController';\n\nexport type CreateInterface = {\n type: `${typeof controllerName}:createInterface`;\n handler: SnapInterfaceController['createInterface'];\n};\n\nexport type GetInterface = {\n type: `${typeof controllerName}:getInterface`;\n handler: SnapInterfaceController['getInterface'];\n};\n\nexport type UpdateInterface = {\n type: `${typeof controllerName}:updateInterface`;\n handler: SnapInterfaceController['updateInterface'];\n};\n\nexport type DeleteInterface = {\n type: `${typeof controllerName}:deleteInterface`;\n handler: SnapInterfaceController['deleteInterface'];\n};\n\nexport type UpdateInterfaceState = {\n type: `${typeof controllerName}:updateInterfaceState`;\n handler: SnapInterfaceController['updateInterfaceState'];\n};\n\nexport type SnapInterfaceControllerAllowedActions =\n | TestOrigin\n | MaybeUpdateState;\n\nexport type SnapInterfaceControllerActions =\n | CreateInterface\n | GetInterface\n | UpdateInterface\n | DeleteInterface\n | UpdateInterfaceState;\n\nexport type SnapInterfaceControllerMessenger = RestrictedControllerMessenger<\n typeof controllerName,\n SnapInterfaceControllerActions | SnapInterfaceControllerAllowedActions,\n never,\n SnapInterfaceControllerAllowedActions['type'],\n never\n>;\n\nexport type StoredInterface = {\n snapId: SnapId;\n content: JSXElement;\n state: InterfaceState;\n};\n\nexport type SnapInterfaceControllerState = {\n interfaces: Record<string, StoredInterface>;\n};\n\nexport type SnapInterfaceControllerArgs = {\n messenger: SnapInterfaceControllerMessenger;\n state?: SnapInterfaceControllerState;\n};\n\n/**\n * Use this controller to manage snaps UI interfaces using RPC method hooks.\n */\nexport class SnapInterfaceController extends BaseController<\n typeof controllerName,\n SnapInterfaceControllerState,\n SnapInterfaceControllerMessenger\n> {\n constructor({ messenger, state }: SnapInterfaceControllerArgs) {\n super({\n messenger,\n metadata: {\n interfaces: { persist: false, anonymous: false },\n },\n name: controllerName,\n state: { interfaces: {}, ...state },\n });\n\n this.#registerMessageHandlers();\n }\n\n /**\n * Constructor helper for registering this controller's messaging system\n * actions.\n */\n #registerMessageHandlers() {\n this.messagingSystem.registerActionHandler(\n `${controllerName}:createInterface`,\n this.createInterface.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:getInterface`,\n this.getInterface.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateInterface`,\n this.updateInterface.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:deleteInterface`,\n this.deleteInterface.bind(this),\n );\n\n this.messagingSystem.registerActionHandler(\n `${controllerName}:updateInterfaceState`,\n this.updateInterfaceState.bind(this),\n );\n }\n\n /**\n * Create an interface in the controller state with the associated data.\n *\n * @param snapId - The snap id that created the interface.\n * @param content - The interface content.\n * @returns The newly interface id.\n */\n async createInterface(snapId: SnapId, content: ComponentOrElement) {\n const element = getJsxInterface(content);\n await this.#validateContent(element);\n\n const id = nanoid();\n const componentState = constructState({}, element);\n\n this.update((draftState) => {\n // @ts-expect-error - TS2589: Type instantiation is excessively deep and\n // possibly infinite.\n draftState.interfaces[id] = {\n snapId,\n content: element,\n state: componentState,\n };\n });\n\n return id;\n }\n\n /**\n * Get the data of a given interface id.\n *\n * @param snapId - The snap id requesting the interface data.\n * @param id - The interface id.\n * @returns The interface state.\n */\n getInterface(snapId: SnapId, id: string) {\n this.#validateArgs(snapId, id);\n\n return this.state.interfaces[id];\n }\n\n /**\n * Update the interface with the given content.\n *\n * @param snapId - The snap id requesting the update.\n * @param id - The interface id.\n * @param content - The new content.\n */\n async updateInterface(\n snapId: SnapId,\n id: string,\n content: ComponentOrElement,\n ) {\n this.#validateArgs(snapId, id);\n const element = getJsxInterface(content);\n await this.#validateContent(element);\n\n const oldState = this.state.interfaces[id].state;\n const newState = constructState(oldState, element);\n\n this.update((draftState) => {\n draftState.interfaces[id].state = newState;\n draftState.interfaces[id].content = element;\n });\n }\n\n /**\n * Delete an interface from state.\n *\n * @param id - The interface id.\n */\n deleteInterface(id: string) {\n this.update((draftState) => {\n delete draftState.interfaces[id];\n });\n }\n\n /**\n * Update the interface state.\n *\n * @param id - The interface id.\n * @param state - The new state.\n */\n updateInterfaceState(id: string, state: InterfaceState) {\n this.update((draftState) => {\n draftState.interfaces[id].state = state;\n });\n }\n\n /**\n * Utility function to validate the args passed to the other methods.\n *\n * @param snapId - The snap id.\n * @param id - The interface id.\n */\n #validateArgs(snapId: SnapId, id: string) {\n const existingInterface = this.state.interfaces[id];\n\n assert(\n existingInterface !== undefined,\n `Interface with id '${id}' not found.`,\n );\n assert(\n existingInterface.snapId === snapId,\n `Interface not created by ${snapId}.`,\n );\n }\n\n /**\n * Trigger a Phishing list update if needed.\n */\n async #triggerPhishingListUpdate() {\n await this.messagingSystem.call('PhishingController:maybeUpdateState');\n }\n\n /**\n * Check an origin against the phishing list.\n *\n * @param origin - The origin to check.\n * @returns True if the origin is on the phishing list, otherwise false.\n */\n #checkPhishingList(origin: string) {\n return this.messagingSystem.call('PhishingController:testOrigin', origin)\n .result;\n }\n\n /**\n * Utility function to validate the components of an interface.\n * Throws if something is invalid.\n *\n * @param element - The JSX element to verify.\n */\n async #validateContent(element: JSXElement) {\n // We assume the validity of this JSON to be validated by the caller.\n // E.g., in the RPC method implementation.\n const size = getJsonSizeUnsafe(element);\n assert(\n size <= MAX_UI_CONTENT_SIZE,\n `A Snap UI may not be larger than ${MAX_UI_CONTENT_SIZE / 1000000} MB.`,\n );\n\n await this.#triggerPhishingListUpdate();\n validateJsxLinks(element, this.#checkPhishingList.bind(this));\n }\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AbstractExecutionService
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-FCCGRGQS.mjs";
|
|
4
4
|
import {
|
|
5
5
|
__require
|
|
6
6
|
} from "./chunk-YRZVIDCF.mjs";
|
|
@@ -29,11 +29,11 @@ var NodeThreadExecutionService = class extends AbstractExecutionService {
|
|
|
29
29
|
return Promise.resolve({ worker, stream });
|
|
30
30
|
}
|
|
31
31
|
async terminateJob(jobWrapper) {
|
|
32
|
-
await jobWrapper.worker
|
|
32
|
+
await jobWrapper.worker?.terminate();
|
|
33
33
|
}
|
|
34
34
|
};
|
|
35
35
|
|
|
36
36
|
export {
|
|
37
37
|
NodeThreadExecutionService
|
|
38
38
|
};
|
|
39
|
-
//# sourceMappingURL=chunk-
|
|
39
|
+
//# sourceMappingURL=chunk-3Y4IJKZY.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/services/node-js/NodeThreadExecutionService.ts"],"sourcesContent":["import type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { ThreadParentMessageStream } from '@metamask/post-message-stream';\n// eslint-disable-next-line @typescript-eslint/no-shadow\nimport { Worker } from 'worker_threads';\n\nimport type { TerminateJobArgs } from '..';\nimport { AbstractExecutionService } from '..';\n\nexport class NodeThreadExecutionService extends AbstractExecutionService<Worker> {\n protected async initEnvStream(): Promise<{\n worker: Worker;\n stream: BasePostMessageStream;\n }> {\n const worker = new Worker(\n require.resolve(\n '@metamask/snaps-execution-environments/dist/browserify/node-thread/bundle.js',\n ),\n {\n stdout: true,\n stderr: true,\n },\n );\n\n // Capturing `stdout` and `stderr` from the worker prevents the worker from\n // writing to them directly, making it easier to capture them Jest.\n worker.stdout.on('data', (data) => {\n // eslint-disable-next-line no-console\n console.log(data.toString());\n });\n\n worker.stderr.on('data', (data) => {\n // eslint-disable-next-line no-console\n console.error(data.toString());\n });\n\n const stream = new ThreadParentMessageStream({ thread: worker });\n return Promise.resolve({ worker, stream });\n }\n\n protected async terminateJob(\n jobWrapper: TerminateJobArgs<Worker>,\n ): Promise<void> {\n await jobWrapper.worker?.terminate();\n }\n}\n"],"mappings":";;;;;;;;AACA,SAAS,iCAAiC;AAE1C,SAAS,cAAc;AAKhB,IAAM,6BAAN,cAAyC,yBAAiC;AAAA,EAC/E,MAAgB,gBAGb;AACD,UAAM,SAAS,IAAI;AAAA,MACjB,UAAQ;AAAA,QACN;AAAA,MACF;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,IACF;AAIA,WAAO,OAAO,GAAG,QAAQ,CAAC,SAAS;AAEjC,cAAQ,IAAI,KAAK,SAAS,CAAC;AAAA,IAC7B,CAAC;AAED,WAAO,OAAO,GAAG,QAAQ,CAAC,SAAS;AAEjC,cAAQ,MAAM,KAAK,SAAS,CAAC;AAAA,IAC/B,CAAC;AAED,UAAM,SAAS,IAAI,0BAA0B,EAAE,QAAQ,OAAO,CAAC;AAC/D,WAAO,QAAQ,QAAQ,EAAE,QAAQ,OAAO,CAAC;AAAA,EAC3C;AAAA,EAEA,MAAgB,aACd,YACe;AACf,UAAM,WAAW,QAAQ,UAAU;AAAA,EACrC;AACF;","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkBOFPNIRXjs = require('./chunk-BOFPNIRX.js');
|
|
4
4
|
|
|
5
5
|
// src/utils.ts
|
|
6
6
|
var _snapssdk = require('@metamask/snaps-sdk');
|
|
@@ -9,6 +9,7 @@ var _snapssdk = require('@metamask/snaps-sdk');
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
var _snapsutils = require('@metamask/snaps-utils');
|
|
12
|
+
var _fastdeepequal = require('fast-deep-equal'); var _fastdeepequal2 = _interopRequireDefault(_fastdeepequal);
|
|
12
13
|
function setDiff(objectA, objectB) {
|
|
13
14
|
return Object.entries(objectA).reduce(
|
|
14
15
|
(acc, [key, value]) => {
|
|
@@ -20,8 +21,17 @@ function setDiff(objectA, objectB) {
|
|
|
20
21
|
{}
|
|
21
22
|
);
|
|
22
23
|
}
|
|
24
|
+
function permissionsDiff(permissionsA, permissionsB) {
|
|
25
|
+
return Object.entries(permissionsA).reduce((acc, [key, value]) => {
|
|
26
|
+
const isIncluded = key in permissionsB;
|
|
27
|
+
if (!isIncluded || isIncluded && !_fastdeepequal2.default.call(void 0, value.caveats ?? [], permissionsB[key].caveats ?? [])) {
|
|
28
|
+
acc[key] = value;
|
|
29
|
+
}
|
|
30
|
+
return acc;
|
|
31
|
+
}, {});
|
|
32
|
+
}
|
|
23
33
|
function delay(ms, result) {
|
|
24
|
-
return delayWithTimer(new (0,
|
|
34
|
+
return delayWithTimer(new (0, _chunkBOFPNIRXjs.Timer)(ms), result);
|
|
25
35
|
}
|
|
26
36
|
function delayWithTimer(timer, result) {
|
|
27
37
|
let rejectFunc;
|
|
@@ -43,7 +53,7 @@ var hasTimedOut = Symbol(
|
|
|
43
53
|
"Used to check if the requested promise has timeout (see withTimeout)"
|
|
44
54
|
);
|
|
45
55
|
async function withTimeout(promise, timerOrMs) {
|
|
46
|
-
const timer = typeof timerOrMs === "number" ? new (0,
|
|
56
|
+
const timer = typeof timerOrMs === "number" ? new (0, _chunkBOFPNIRXjs.Timer)(timerOrMs) : timerOrMs;
|
|
47
57
|
const delayPromise = delayWithTimer(timer, hasTimedOut);
|
|
48
58
|
try {
|
|
49
59
|
return await Promise.race([promise, delayPromise]);
|
|
@@ -105,5 +115,6 @@ async function fetchSnap(snapId, location) {
|
|
|
105
115
|
|
|
106
116
|
|
|
107
117
|
|
|
108
|
-
|
|
109
|
-
|
|
118
|
+
|
|
119
|
+
exports.setDiff = setDiff; exports.permissionsDiff = permissionsDiff; exports.delay = delay; exports.delayWithTimer = delayWithTimer; exports.hasTimedOut = hasTimedOut; exports.withTimeout = withTimeout; exports.getSnapFiles = getSnapFiles; exports.fetchSnap = fetchSnap;
|
|
120
|
+
//# sourceMappingURL=chunk-4DPX4O3T.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PermissionConstraint } from '@metamask/permission-controller';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { getErrorMessage } from '@metamask/snaps-sdk';\nimport {\n encodeBase64,\n getValidatedLocalizationFiles,\n validateFetchedSnap,\n} from '@metamask/snaps-utils';\nimport deepEqual from 'fast-deep-equal';\n\nimport type { SnapLocation } from './snaps';\nimport { Timer } from './snaps/Timer';\n\n/**\n * Takes two objects and does a Set Difference of them.\n * Set Difference is generally defined as follows:\n * ```\n * 𝑥 ∈ A ∖ B ⟺ 𝑥 ∈ A ∧ 𝑥 ∉ B\n * ```\n * Meaning that the returned object contains all properties of A expect those that also\n * appear in B. Notice that properties that appear in B, but not in A, have no effect.\n *\n * @see [Set Difference]{@link https://proofwiki.org/wiki/Definition:Set_Difference}\n * @param objectA - The object on which the difference is being calculated.\n * @param objectB - The object whose properties will be removed from objectA.\n * @returns The objectA without properties from objectB.\n */\nexport function setDiff<\n ObjectA extends Record<any, unknown>,\n ObjectB extends Record<any, unknown>,\n>(objectA: ObjectA, objectB: ObjectB): Diff<ObjectA, ObjectB> {\n return Object.entries(objectA).reduce<Record<any, unknown>>(\n (acc, [key, value]) => {\n if (!(key in objectB)) {\n acc[key] = value;\n }\n return acc;\n },\n {},\n ) as Diff<ObjectA, ObjectB>;\n}\n\n/**\n * Calculate a difference between two permissions objects.\n *\n * Similar to `setDiff` except for one additional condition:\n * Permissions in B should be removed from A if they exist in both and have differing caveats.\n *\n * @param permissionsA - An object containing one or more partial permissions.\n * @param permissionsB - An object containing one or more partial permissions to be subtracted from A.\n * @returns The permissions set A without properties from B.\n */\nexport function permissionsDiff<\n PermissionsA extends Record<string, Pick<PermissionConstraint, 'caveats'>>,\n PermissionsB extends Record<string, Pick<PermissionConstraint, 'caveats'>>,\n>(\n permissionsA: PermissionsA,\n permissionsB: PermissionsB,\n): Diff<PermissionsA, PermissionsB> {\n return Object.entries(permissionsA).reduce<\n Record<string, Pick<PermissionConstraint, 'caveats'>>\n >((acc, [key, value]) => {\n const isIncluded = key in permissionsB;\n if (\n !isIncluded ||\n (isIncluded &&\n !deepEqual(value.caveats ?? [], permissionsB[key].caveats ?? []))\n ) {\n acc[key] = value;\n }\n return acc;\n }, {}) as Diff<PermissionsA, PermissionsB>;\n}\n\n/**\n * A Promise that delays its return for a given amount of milliseconds.\n *\n * @param ms - Milliseconds to delay the execution for.\n * @param result - The result to return from the Promise after delay.\n * @returns A promise that is void if no result provided, result otherwise.\n * @template Result - The `result`.\n */\nexport function delay<Result = void>(\n ms: number,\n result?: Result,\n): Promise<Result> & { cancel: () => void } {\n return delayWithTimer(new Timer(ms), result);\n}\n\n/**\n * A Promise that delays it's return by using a pausable Timer.\n *\n * @param timer - Timer used to control the delay.\n * @param result - The result to return from the Promise after delay.\n * @returns A promise that is void if no result provided, result otherwise.\n * @template Result - The `result`.\n */\nexport function delayWithTimer<Result = void>(\n timer: Timer,\n result?: Result,\n): Promise<Result> & { cancel: () => void } {\n let rejectFunc: (reason: Error) => void;\n const promise: any = new Promise<Result>((resolve: any, reject) => {\n timer.start(() => {\n result === undefined ? resolve() : resolve(result);\n });\n rejectFunc = reject;\n });\n\n promise.cancel = () => {\n if (timer.status !== 'finished') {\n timer.cancel();\n rejectFunc(new Error('The delay has been canceled.'));\n }\n };\n return promise;\n}\n\n/*\n * We use a Symbol instead of rejecting the promise so that Errors thrown\n * by the main promise will propagate.\n */\nexport const hasTimedOut = Symbol(\n 'Used to check if the requested promise has timeout (see withTimeout)',\n);\n\n/**\n * Executes the given Promise, if the Timer expires before the Promise settles, we return earlier.\n *\n * NOTE:** The given Promise is not cancelled or interrupted, and will continue to execute uninterrupted. We will just discard its result if it does not complete before the timeout.\n *\n * @param promise - The promise that you want to execute.\n * @param timerOrMs - The timer controlling the timeout or a ms value.\n * @returns The resolved `PromiseValue`, or the hasTimedOut symbol if\n * returning early.\n * @template PromiseValue - The value of the Promise.\n */\nexport async function withTimeout<PromiseValue = void>(\n promise: Promise<PromiseValue>,\n timerOrMs: Timer | number,\n): Promise<PromiseValue | typeof hasTimedOut> {\n const timer =\n typeof timerOrMs === 'number' ? new Timer(timerOrMs) : timerOrMs;\n const delayPromise = delayWithTimer(timer, hasTimedOut);\n try {\n return await Promise.race([promise, delayPromise]);\n } finally {\n delayPromise.cancel();\n }\n}\n\n/**\n * Checks whether the type is composed of literal types\n *\n * @returns @type {true} if whole type is composed of literals, @type {false} if whole type is not literals, @type {boolean} if mixed\n * @example\n * ```\n * type t1 = IsLiteral<1 | 2 | \"asd\" | true>;\n * // t1 = true\n *\n * type t2 = IsLiteral<number | string>;\n * // t2 = false\n *\n * type t3 = IsLiteral<1 | string>;\n * // t3 = boolean\n *\n * const s = Symbol();\n * type t4 = IsLiteral<typeof s>;\n * // t4 = true\n *\n * type t5 = IsLiteral<symbol>\n * // t5 = false;\n * ```\n */\ntype IsLiteral<Type> = Type extends string | number | boolean | symbol\n ? Extract<string | number | boolean | symbol, Type> extends never\n ? true\n : false\n : false;\n\n/**\n * Returns all keys of an object, that are literal, as an union\n *\n * @example\n * ```\n * type t1 = _LiteralKeys<{a: number, b: 0, c: 'foo', d: string}>\n * // t1 = 'b' | 'c'\n * ```\n * @see [Literal types]{@link https://www.typescriptlang.org/docs/handbook/literal-types.html}\n */\ntype LiteralKeys<Type> = NonNullable<\n {\n [Key in keyof Type]: IsLiteral<Key> extends true ? Key : never;\n }[keyof Type]\n>;\n\n/**\n * Returns all keys of an object, that are not literal, as an union\n *\n * @example\n * ```\n * type t1 = _NonLiteralKeys<{a: number, b: 0, c: 'foo', d: string}>\n * // t1 = 'a' | 'd'\n * ```\n * @see [Literal types]{@link https://www.typescriptlang.org/docs/handbook/literal-types.html}\n */\ntype NonLiteralKeys<Type> = NonNullable<\n {\n [Key in keyof Type]: IsLiteral<Key> extends false ? Key : never;\n }[keyof Type]\n>;\n\n/**\n * A set difference of two objects based on their keys\n *\n * @example\n * ```\n * type t1 = Diff<{a: string, b: string}, {a: number}>\n * // t1 = {b: string};\n * type t2 = Diff<{a: string, 0: string}, Record<string, unknown>>;\n * // t2 = { a?: string, 0: string};\n * type t3 = Diff<{a: string, 0: string, 1: string}, Record<1 | string, unknown>>;\n * // t3 = {a?: string, 0: string}\n * ```\n * @see {@link setDiff} for the main use-case\n */\nexport type Diff<First, Second> = Omit<First, LiteralKeys<Second>> &\n Partial<Pick<First, Extract<keyof First, NonLiteralKeys<Second>>>>;\n\n/**\n * Makes every specified property of the specified object type mutable.\n *\n * @template Type - The object whose readonly properties to make mutable.\n * @template TargetKey - The property key(s) to make mutable.\n */\nexport type Mutable<\n Type extends Record<string, unknown>,\n TargetKey extends string,\n> = {\n -readonly [Key in keyof Pick<Type, TargetKey>]: Type[Key];\n} & {\n [Key in keyof Omit<Type, TargetKey>]: Type[Key];\n};\n\n/**\n * Get all files in a Snap from an array of file paths.\n *\n * @param location - The location of the Snap.\n * @param files - The array of file paths.\n * @returns The array of files as {@link VirtualFile}s.\n */\nexport async function getSnapFiles(\n location: SnapLocation,\n files?: string[] | undefined,\n) {\n if (!files || files.length === 0) {\n return [];\n }\n\n return await Promise.all(\n files.map(async (filePath) => location.fetch(filePath)),\n );\n}\n\n/**\n * Fetch the Snap manifest, source code, and any other files from the given\n * location.\n *\n * @param snapId - The ID of the Snap to fetch.\n * @param location - The location of the Snap.\n * @returns The Snap files and location.\n * @throws If the Snap files are invalid, or if the Snap could not be fetched.\n */\nexport async function fetchSnap(snapId: SnapId, location: SnapLocation) {\n try {\n const manifest = await location.manifest();\n const sourceCode = await location.fetch(\n manifest.result.source.location.npm.filePath,\n );\n const { iconPath } = manifest.result.source.location.npm;\n const svgIcon = iconPath ? await location.fetch(iconPath) : undefined;\n\n const auxiliaryFiles = await getSnapFiles(\n location,\n manifest.result.source.files,\n );\n\n await Promise.all(\n auxiliaryFiles.map(async (file) => {\n // This should still be safe\n // eslint-disable-next-line require-atomic-updates\n file.data.base64 = await encodeBase64(file);\n }),\n );\n\n const localizationFiles = await getSnapFiles(\n location,\n manifest.result.source.locales,\n );\n\n const validatedLocalizationFiles =\n getValidatedLocalizationFiles(localizationFiles);\n\n const files = {\n manifest,\n sourceCode,\n svgIcon,\n auxiliaryFiles,\n localizationFiles: validatedLocalizationFiles,\n };\n\n await validateFetchedSnap(files);\n\n return files;\n } catch (error) {\n throw new Error(\n `Failed to fetch snap \"${snapId}\": ${getErrorMessage(error)}.`,\n );\n }\n}\n"]}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
var _chunkC4D6GBMYjs = require('./chunk-C4D6GBMY.js');
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunkFCRPOA4Ijs = require('./chunk-FCRPOA4I.js');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
@@ -13,7 +13,7 @@ var _chunkEXN2TFDJjs = require('./chunk-EXN2TFDJ.js');
|
|
|
13
13
|
|
|
14
14
|
// src/services/webview/WebViewExecutionService.ts
|
|
15
15
|
var _getWebView, _ensureWebViewLoaded, ensureWebViewLoaded_fn;
|
|
16
|
-
var WebViewExecutionService = class extends
|
|
16
|
+
var WebViewExecutionService = class extends _chunkFCRPOA4Ijs.ProxyExecutionService {
|
|
17
17
|
constructor({
|
|
18
18
|
messenger,
|
|
19
19
|
setupSnapProvider,
|
|
@@ -55,4 +55,4 @@ ensureWebViewLoaded_fn = async function() {
|
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
exports.WebViewExecutionService = WebViewExecutionService;
|
|
58
|
-
//# sourceMappingURL=chunk-
|
|
58
|
+
//# sourceMappingURL=chunk-74GN6MIJ.js.map
|
|
@@ -19,6 +19,9 @@ var Timer = class {
|
|
|
19
19
|
get status() {
|
|
20
20
|
return this.state.value;
|
|
21
21
|
}
|
|
22
|
+
get remaining() {
|
|
23
|
+
return this.state.remaining;
|
|
24
|
+
}
|
|
22
25
|
/**
|
|
23
26
|
* Cancels the currently running timer and marks it finished.
|
|
24
27
|
*
|
|
@@ -31,6 +34,18 @@ var Timer = class {
|
|
|
31
34
|
);
|
|
32
35
|
this.onFinish(false);
|
|
33
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Marks the timer as finished prematurely and triggers the callback.
|
|
39
|
+
*
|
|
40
|
+
* @throws {@link Error}. If it wasn't running or paused.
|
|
41
|
+
*/
|
|
42
|
+
finish() {
|
|
43
|
+
_utils.assert.call(void 0,
|
|
44
|
+
this.status !== "finished",
|
|
45
|
+
new Error("Tried to finish a finished Timer.")
|
|
46
|
+
);
|
|
47
|
+
this.onFinish(true);
|
|
48
|
+
}
|
|
34
49
|
/**
|
|
35
50
|
* Pauses a currently running timer, allowing it to resume later.
|
|
36
51
|
*
|
|
@@ -87,8 +102,11 @@ var Timer = class {
|
|
|
87
102
|
if (this.state.value === "running" && this.state.timeout !== void 0) {
|
|
88
103
|
clearTimeout(this.state.timeout);
|
|
89
104
|
}
|
|
90
|
-
const { callback } = this.state;
|
|
91
|
-
this.state = {
|
|
105
|
+
const { callback, remaining } = this.state;
|
|
106
|
+
this.state = {
|
|
107
|
+
value: "finished",
|
|
108
|
+
remaining: this.state.value === "running" ? remaining - (Date.now() - this.state.start) : remaining
|
|
109
|
+
};
|
|
92
110
|
if (shouldCall) {
|
|
93
111
|
callback();
|
|
94
112
|
}
|
|
@@ -98,4 +116,4 @@ var Timer = class {
|
|
|
98
116
|
|
|
99
117
|
|
|
100
118
|
exports.Timer = Timer;
|
|
101
|
-
//# sourceMappingURL=chunk-
|
|
119
|
+
//# sourceMappingURL=chunk-BOFPNIRX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/snaps/Timer.ts"],"names":[],"mappings":";AAAA,SAAS,cAAc;AAIhB,IAAM,QAAN,MAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwBjB,YAAY,IAAY;AACtB;AAAA,MACE,CAAC,OAAO,MAAM,EAAE;AAAA,MAChB,IAAI,UAAU,mCAAmC;AAAA,IACnD;AACA,WAAO,MAAM,GAAG,IAAI,UAAU,wCAAwC,CAAC;AACvE,SAAK,QAAQ,EAAE,OAAO,WAAW,WAAW,GAAG;AAAA,EACjD;AAAA,EAEA,IAAI,SAAsB;AACxB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,YAAoB;AACtB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,SAAS;AACP;AAAA,MACE,KAAK,WAAW,YAAY,KAAK,WAAW;AAAA,MAC5C,IAAI,MAAM,qCAAqC;AAAA,IACjD;AACA,SAAK,SAAS,KAAK;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,SAAS;AACP;AAAA,MACE,KAAK,WAAW;AAAA,MAChB,IAAI,MAAM,mCAAmC;AAAA,IAC/C;AACA,SAAK,SAAS,IAAI;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAQ;AACN;AAAA,MACE,KAAK,MAAM,UAAU;AAAA,MACrB,IAAI,MAAM,oCAAoC;AAAA,IAChD;AAEA,UAAM,EAAE,UAAU,OAAO,SAAS,UAAU,IAAI,KAAK;AAErD,gBAAY,UAAa,aAAa,OAAc;AACpD,SAAK,QAAQ;AAAA,MACX,OAAO;AAAA,MACP;AAAA,MACA,WAAW,aAAa,KAAK,IAAI,IAAI;AAAA,IACvC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,UAAsB;AAC1B;AAAA,MACE,KAAK,MAAM,UAAU;AAAA,MACrB,IAAI,MAAM,yCAAyC;AAAA,IACrD;AAEA,UAAM,EAAE,UAAU,IAAI,KAAK;AAC3B,SAAK,QAAQ,EAAE,OAAO,UAAU,WAAW,SAAS;AACpD,SAAK,OAAO;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,SAAS;AACP;AAAA,MACE,KAAK,MAAM,UAAU;AAAA,MACrB,IAAI,MAAM,kCAAkC;AAAA,IAC9C;AACA,UAAM,EAAE,WAAW,SAAS,IAAI,KAAK;AACrC,UAAM,QAAQ,KAAK,IAAI;AAEvB,QAAI;AAEJ,QAAI,cAAc,OAAO,mBAAmB;AAC1C,gBAAU,WAAW,MAAM,KAAK,SAAS,IAAI,GAAG,SAAS;AAAA,IAC3D;AAEA,SAAK,QAAQ,EAAE,OAAO,WAAW,UAAU,WAAW,OAAO,QAAQ;AAAA,EACvE;AAAA,EAEQ,SAAS,YAAqB;AACpC,WAAO,KAAK,MAAM,UAAU,aAAa,KAAK,MAAM,UAAU,QAAQ;AAEtE,QAAI,KAAK,MAAM,UAAU,aAAa,KAAK,MAAM,YAAY,QAAW;AACtE,mBAAa,KAAK,MAAM,OAAc;AAAA,IACxC;AAEA,UAAM,EAAE,UAAU,UAAU,IAAI,KAAK;AACrC,SAAK,QAAQ;AAAA,MACX,OAAO;AAAA,MACP,WACE,KAAK,MAAM,UAAU,YACjB,aAAa,KAAK,IAAI,IAAI,KAAK,MAAM,SACrC;AAAA,IACR;AAEA,QAAI,YAAY;AACd,eAAS;AAAA,IACX;AAAA,EACF;AACF","sourcesContent":["import { assert } from '@metamask/utils';\n\nexport type TimerStatus = 'stopped' | 'paused' | 'running' | 'finished';\n\nexport class Timer {\n private state:\n | { value: 'stopped'; remaining: number }\n | {\n value: 'paused';\n remaining: number;\n callback: () => void;\n }\n | {\n value: 'running';\n remaining: number;\n callback: () => void;\n start: number;\n timeout?: unknown;\n }\n | { value: 'finished'; remaining: number };\n\n /**\n * If `ms` is smaller or equal to zero (including -Infinity), the callback is added to the event loop and executed async immediately\n * If `ms` is +Infinity the timer never finishes.\n *\n * @throws {@link TypeError}. If `ms` is NaN or negative.\n * @param ms - The number of milliseconds before the callback is called after started.\n */\n constructor(ms: number) {\n assert(\n !Number.isNaN(ms),\n new TypeError(\"Can't start a timer with NaN time\"),\n );\n assert(ms >= 0, new TypeError(\"Can't start a timer with negative time\"));\n this.state = { value: 'stopped', remaining: ms };\n }\n\n get status(): TimerStatus {\n return this.state.value;\n }\n\n get remaining(): number {\n return this.state.remaining;\n }\n\n /**\n * Cancels the currently running timer and marks it finished.\n *\n * @throws {@link Error}. If it wasn't running or paused.\n */\n cancel() {\n assert(\n this.status === 'paused' || this.status === 'running',\n new Error('Tried to cancel a not running Timer'),\n );\n this.onFinish(false);\n }\n\n /**\n * Marks the timer as finished prematurely and triggers the callback.\n *\n * @throws {@link Error}. If it wasn't running or paused.\n */\n finish() {\n assert(\n this.status !== 'finished',\n new Error('Tried to finish a finished Timer.'),\n );\n this.onFinish(true);\n }\n\n /**\n * Pauses a currently running timer, allowing it to resume later.\n *\n * @throws {@link Error}. If it wasn't running.\n */\n pause() {\n assert(\n this.state.value === 'running',\n new Error('Tried to pause a not running Timer'),\n );\n\n const { callback, start, timeout, remaining } = this.state;\n\n timeout !== undefined && clearTimeout(timeout as any);\n this.state = {\n value: 'paused',\n callback,\n remaining: remaining - (Date.now() - start),\n };\n }\n\n /**\n * Starts the timer.\n *\n * @param callback - The function that will be called after the timer finishes.\n * @throws {@link Error}. If it was already started.\n */\n start(callback: () => void) {\n assert(\n this.state.value === 'stopped',\n new Error('Tried to start an already running Timer'),\n );\n\n const { remaining } = this.state;\n this.state = { value: 'paused', remaining, callback };\n this.resume();\n }\n\n /**\n * Resumes a currently paused timer.\n *\n * @throws {@link Error}. If it wasn't paused.\n */\n resume() {\n assert(\n this.state.value === 'paused',\n new Error('Tried to resume not paused Timer'),\n );\n const { remaining, callback } = this.state;\n const start = Date.now();\n\n let timeout: unknown;\n // setTimeout returns immediately on +Infinity which we use\n if (remaining !== Number.POSITIVE_INFINITY) {\n timeout = setTimeout(() => this.onFinish(true), remaining);\n }\n\n this.state = { value: 'running', callback, remaining, start, timeout };\n }\n\n private onFinish(shouldCall: boolean) {\n assert(this.state.value === 'running' || this.state.value === 'paused');\n\n if (this.state.value === 'running' && this.state.timeout !== undefined) {\n clearTimeout(this.state.timeout as any);\n }\n\n const { callback, remaining } = this.state;\n this.state = {\n value: 'finished',\n remaining:\n this.state.value === 'running'\n ? remaining - (Date.now() - this.state.start)\n : remaining,\n };\n\n if (shouldCall) {\n callback();\n }\n }\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkSIW7ZXQFjs = require('./chunk-SIW7ZXQF.js');
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
var _chunk7Y6P5FRNjs = require('./chunk-7Y6P5FRN.js');
|
|
@@ -17,7 +17,7 @@ var _utils = require('@metamask/utils');
|
|
|
17
17
|
var _nanoid = require('nanoid');
|
|
18
18
|
var WORKER_POOL_ID = "snaps-worker-pool";
|
|
19
19
|
var _documentUrl, _runtimeStream;
|
|
20
|
-
var WebWorkerExecutionService = class extends
|
|
20
|
+
var WebWorkerExecutionService = class extends _chunkSIW7ZXQFjs.AbstractExecutionService {
|
|
21
21
|
/**
|
|
22
22
|
* Create a new webworker execution service.
|
|
23
23
|
*
|
|
@@ -102,4 +102,4 @@ _runtimeStream = new WeakMap();
|
|
|
102
102
|
|
|
103
103
|
|
|
104
104
|
exports.WORKER_POOL_ID = WORKER_POOL_ID; exports.WebWorkerExecutionService = WebWorkerExecutionService;
|
|
105
|
-
//# sourceMappingURL=chunk-
|
|
105
|
+
//# sourceMappingURL=chunk-E5RRFMGF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/services/webworker/WebWorkerExecutionService.ts"],"names":[],"mappings":";;;;;;;;;;;;;AACA,SAAS,+BAA+B;AACxC,SAAS,oBAAoB;AAC7B,SAAS,cAAc;AACvB,SAAS,cAAc;AAahB,IAAM,iBAAiB;AAjB9B;AAmBO,IAAM,4BAAN,cAAwC,yBAAiC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgB9E,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAA6C;AAC3C,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,IACF,CAAC;AAvBH;AAEA;AAuBE,uBAAK,cAAe;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAgB,aAAa,KAA+B;AAG1D,WAAO,mBAAK,iBAAgB,iCAAiC;AAC7D,uBAAK,gBAAe,MAAM;AAAA,MACxB,OAAO,IAAI;AAAA,MACX,MAAM;AAAA,QACJ,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,IAAI,OAAO;AAAA,MACb;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAgB,cAAc,OAAe;AAE3C,UAAM,KAAK,eAAe;AAG1B,WAAO,mBAAK,iBAAgB,iCAAiC;AAE7D,UAAM,SAAS,IAAI,uBAAuB;AAAA,MACxC,QAAQ,mBAAK;AAAA,MACb;AAAA,IACF,CAAC;AAED,WAAO,EAAE,QAAQ,OAAO,OAAO;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,iBAAiB;AAE7B,QAAI,SAAS,eAAe,cAAc,GAAG;AAC3C;AAAA,IACF;AAEA,UAAM,SAAS,MAAM;AAAA,MACnB,mBAAK,cAAa;AAAA,MAClB;AAAA,MACA;AAAA,IACF;AAEA,uBAAK,gBAAiB,IAAI,wBAAwB;AAAA,MAChD,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AACF;AA5FE;AAEA","sourcesContent":["import type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { WindowPostMessageStream } from '@metamask/post-message-stream';\nimport { createWindow } from '@metamask/snaps-utils';\nimport { assert } from '@metamask/utils';\nimport { nanoid } from 'nanoid';\n\nimport type {\n ExecutionServiceArgs,\n TerminateJobArgs,\n} from '../AbstractExecutionService';\nimport { AbstractExecutionService } from '../AbstractExecutionService';\nimport { ProxyPostMessageStream } from '../ProxyPostMessageStream';\n\ntype WebWorkerExecutionEnvironmentServiceArgs = {\n documentUrl: URL;\n} & ExecutionServiceArgs;\n\nexport const WORKER_POOL_ID = 'snaps-worker-pool';\n\nexport class WebWorkerExecutionService extends AbstractExecutionService<string> {\n #documentUrl: URL;\n\n #runtimeStream?: BasePostMessageStream;\n\n /**\n * Create a new webworker execution service.\n *\n * @param args - The constructor arguments.\n * @param args.documentUrl - The URL of the worker pool document to use as the\n * execution environment.\n * @param args.messenger - The messenger to use for communication with the\n * `SnapController`.\n * @param args.setupSnapProvider - The function to use to set up the snap\n * provider.\n */\n constructor({\n documentUrl,\n messenger,\n setupSnapProvider,\n }: WebWorkerExecutionEnvironmentServiceArgs) {\n super({\n messenger,\n setupSnapProvider,\n });\n\n this.#documentUrl = documentUrl;\n }\n\n /**\n * Send a termination command to the worker pool document.\n *\n * @param job - The job to terminate.\n */\n protected async terminateJob(job: TerminateJobArgs<string>) {\n // The `AbstractExecutionService` will have already closed the job stream,\n // so we write to the runtime stream directly.\n assert(this.#runtimeStream, 'Runtime stream not initialized.');\n this.#runtimeStream.write({\n jobId: job.id,\n data: {\n jsonrpc: '2.0',\n method: 'terminateJob',\n id: nanoid(),\n },\n });\n }\n\n /**\n * Create a new stream for the specified job. This wraps the runtime stream\n * in a stream specific to the job.\n *\n * @param jobId - The job ID.\n */\n protected async initEnvStream(jobId: string) {\n // Lazily create the worker pool document.\n await this.createDocument();\n\n // `createDocument` should have initialized the runtime stream.\n assert(this.#runtimeStream, 'Runtime stream not initialized.');\n\n const stream = new ProxyPostMessageStream({\n stream: this.#runtimeStream,\n jobId,\n });\n\n return { worker: jobId, stream };\n }\n\n /**\n * Creates the worker pool document to be used as the execution environment.\n *\n * If the document already exists, this does nothing.\n */\n private async createDocument() {\n // We only want to create a single pool.\n if (document.getElementById(WORKER_POOL_ID)) {\n return;\n }\n\n const window = await createWindow(\n this.#documentUrl.href,\n WORKER_POOL_ID,\n false,\n );\n\n this.#runtimeStream = new WindowPostMessageStream({\n name: 'parent',\n target: 'child',\n targetWindow: window,\n targetOrigin: '*',\n });\n }\n}\n"]}
|
|
@@ -4,7 +4,10 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
hasTimedOut,
|
|
6
6
|
withTimeout
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-GTDDODNP.mjs";
|
|
8
|
+
import {
|
|
9
|
+
Timer
|
|
10
|
+
} from "./chunk-XO7KDFBY.mjs";
|
|
8
11
|
import {
|
|
9
12
|
__privateAdd,
|
|
10
13
|
__privateGet,
|
|
@@ -28,13 +31,15 @@ import {
|
|
|
28
31
|
import { nanoid } from "nanoid";
|
|
29
32
|
import { pipeline } from "readable-stream";
|
|
30
33
|
var controllerName = "ExecutionService";
|
|
31
|
-
var _snapRpcHooks, _snapToJobMap, _jobToSnapMap, _messenger, _pingTimeout, _terminationTimeout, _removeSnapHooks, removeSnapHooks_fn, _createSnapHooks, createSnapHooks_fn, _mapSnapAndJob, mapSnapAndJob_fn, _removeSnapAndJobMapping, removeSnapAndJobMapping_fn;
|
|
34
|
+
var _snapRpcHooks, _snapToJobMap, _jobToSnapMap, _messenger, _initTimeout, _pingTimeout, _terminationTimeout, _usePing, _removeSnapHooks, removeSnapHooks_fn, _createSnapHooks, createSnapHooks_fn, _mapSnapAndJob, mapSnapAndJob_fn, _removeSnapAndJobMapping, removeSnapAndJobMapping_fn;
|
|
32
35
|
var AbstractExecutionService = class {
|
|
33
36
|
constructor({
|
|
34
37
|
setupSnapProvider,
|
|
35
38
|
messenger,
|
|
39
|
+
initTimeout = inMilliseconds(60, Duration.Second),
|
|
36
40
|
pingTimeout = inMilliseconds(2, Duration.Second),
|
|
37
|
-
terminationTimeout = inMilliseconds(1, Duration.Second)
|
|
41
|
+
terminationTimeout = inMilliseconds(1, Duration.Second),
|
|
42
|
+
usePing = true
|
|
38
43
|
}) {
|
|
39
44
|
__privateAdd(this, _removeSnapHooks);
|
|
40
45
|
__privateAdd(this, _createSnapHooks);
|
|
@@ -44,16 +49,20 @@ var AbstractExecutionService = class {
|
|
|
44
49
|
__privateAdd(this, _snapToJobMap, void 0);
|
|
45
50
|
__privateAdd(this, _jobToSnapMap, void 0);
|
|
46
51
|
__privateAdd(this, _messenger, void 0);
|
|
52
|
+
__privateAdd(this, _initTimeout, void 0);
|
|
47
53
|
__privateAdd(this, _pingTimeout, void 0);
|
|
48
54
|
__privateAdd(this, _terminationTimeout, void 0);
|
|
55
|
+
__privateAdd(this, _usePing, void 0);
|
|
49
56
|
__privateSet(this, _snapRpcHooks, /* @__PURE__ */ new Map());
|
|
50
57
|
this.jobs = /* @__PURE__ */ new Map();
|
|
51
58
|
this.setupSnapProvider = setupSnapProvider;
|
|
52
59
|
__privateSet(this, _snapToJobMap, /* @__PURE__ */ new Map());
|
|
53
60
|
__privateSet(this, _jobToSnapMap, /* @__PURE__ */ new Map());
|
|
54
61
|
__privateSet(this, _messenger, messenger);
|
|
62
|
+
__privateSet(this, _initTimeout, initTimeout);
|
|
55
63
|
__privateSet(this, _pingTimeout, pingTimeout);
|
|
56
64
|
__privateSet(this, _terminationTimeout, terminationTimeout);
|
|
65
|
+
__privateSet(this, _usePing, usePing);
|
|
57
66
|
this.registerMessageHandlers();
|
|
58
67
|
}
|
|
59
68
|
/**
|
|
@@ -67,7 +76,7 @@ var AbstractExecutionService = class {
|
|
|
67
76
|
);
|
|
68
77
|
__privateGet(this, _messenger).registerActionHandler(
|
|
69
78
|
`${controllerName}:executeSnap`,
|
|
70
|
-
async (
|
|
79
|
+
async (data) => this.executeSnap(data)
|
|
71
80
|
);
|
|
72
81
|
__privateGet(this, _messenger).registerActionHandler(
|
|
73
82
|
`${controllerName}:terminateSnap`,
|
|
@@ -91,17 +100,20 @@ var AbstractExecutionService = class {
|
|
|
91
100
|
if (!jobWrapper) {
|
|
92
101
|
throw new Error(`Job with id "${jobId}" not found.`);
|
|
93
102
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
try {
|
|
104
|
+
const result = await withTimeout(
|
|
105
|
+
this.command(jobId, {
|
|
106
|
+
jsonrpc: "2.0",
|
|
107
|
+
method: "terminate",
|
|
108
|
+
params: [],
|
|
109
|
+
id: nanoid()
|
|
110
|
+
}),
|
|
111
|
+
__privateGet(this, _terminationTimeout)
|
|
112
|
+
);
|
|
113
|
+
if (result === hasTimedOut || result !== "OK") {
|
|
114
|
+
logError(`Job "${jobId}" failed to terminate gracefully.`, result);
|
|
115
|
+
}
|
|
116
|
+
} catch {
|
|
105
117
|
}
|
|
106
118
|
Object.values(jobWrapper.streams).forEach((stream) => {
|
|
107
119
|
try {
|
|
@@ -112,20 +124,20 @@ var AbstractExecutionService = class {
|
|
|
112
124
|
}
|
|
113
125
|
});
|
|
114
126
|
this.terminateJob(jobWrapper);
|
|
115
|
-
__privateMethod(this, _removeSnapAndJobMapping, removeSnapAndJobMapping_fn).call(this, jobId);
|
|
116
127
|
this.jobs.delete(jobId);
|
|
128
|
+
__privateMethod(this, _removeSnapAndJobMapping, removeSnapAndJobMapping_fn).call(this, jobId);
|
|
117
129
|
log(`Job "${jobId}" terminated.`);
|
|
118
130
|
}
|
|
119
131
|
/**
|
|
120
132
|
* Initiates a job for a snap.
|
|
121
133
|
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
134
|
+
* @param jobId - The ID of the job to initiate.
|
|
135
|
+
* @param timer - The timer to use for timeouts.
|
|
124
136
|
* @returns Information regarding the created job.
|
|
137
|
+
* @throws If the execution service returns an error or execution times out.
|
|
125
138
|
*/
|
|
126
|
-
async initJob() {
|
|
127
|
-
const
|
|
128
|
-
const { streams, worker } = await this.initStreams(jobId);
|
|
139
|
+
async initJob(jobId, timer) {
|
|
140
|
+
const { streams, worker } = await this.initStreams(jobId, timer);
|
|
129
141
|
const rpcEngine = new JsonRpcEngine();
|
|
130
142
|
const jsonRpcConnection = createStreamMiddleware();
|
|
131
143
|
pipeline(
|
|
@@ -151,13 +163,18 @@ var AbstractExecutionService = class {
|
|
|
151
163
|
/**
|
|
152
164
|
* Sets up the streams for an initiated job.
|
|
153
165
|
*
|
|
154
|
-
* Depending on the execution environment, this may run forever if the Snap fails to start up properly, therefore any call to this function should be wrapped in a timeout.
|
|
155
|
-
*
|
|
156
166
|
* @param jobId - The id of the job.
|
|
167
|
+
* @param timer - The timer to use for timeouts.
|
|
157
168
|
* @returns The streams to communicate with the worker and the worker itself.
|
|
169
|
+
* @throws If the execution service returns an error or execution times out.
|
|
158
170
|
*/
|
|
159
|
-
async initStreams(jobId) {
|
|
160
|
-
const
|
|
171
|
+
async initStreams(jobId, timer) {
|
|
172
|
+
const result = await withTimeout(this.initEnvStream(jobId), timer);
|
|
173
|
+
if (result === hasTimedOut) {
|
|
174
|
+
this.terminateJob({ id: jobId });
|
|
175
|
+
throw new Error("The Snaps execution environment failed to start.");
|
|
176
|
+
}
|
|
177
|
+
const { worker, stream: envStream } = result;
|
|
161
178
|
const mux = setupMultiplex(envStream, `Job: "${jobId}"`);
|
|
162
179
|
const commandStream = mux.createStream(SNAP_STREAM_NAMES.COMMAND);
|
|
163
180
|
const notificationHandler = (message) => {
|
|
@@ -235,38 +252,54 @@ var AbstractExecutionService = class {
|
|
|
235
252
|
/**
|
|
236
253
|
* Initializes and executes a snap, setting up the communication channels to the snap etc.
|
|
237
254
|
*
|
|
238
|
-
* Depending on the execution environment, this may run forever if the Snap fails to start up properly, therefore any call to this function should be wrapped in a timeout.
|
|
239
|
-
*
|
|
240
255
|
* @param snapData - Data needed for Snap execution.
|
|
256
|
+
* @param snapData.snapId - The ID of the Snap to execute.
|
|
257
|
+
* @param snapData.sourceCode - The source code of the Snap to execute.
|
|
258
|
+
* @param snapData.endowments - The endowments available to the executing Snap.
|
|
241
259
|
* @returns A string `OK` if execution succeeded.
|
|
242
|
-
* @throws If the execution service returns an error.
|
|
260
|
+
* @throws If the execution service returns an error or execution times out.
|
|
243
261
|
*/
|
|
244
|
-
async executeSnap(
|
|
245
|
-
|
|
246
|
-
|
|
262
|
+
async executeSnap({
|
|
263
|
+
snapId,
|
|
264
|
+
sourceCode,
|
|
265
|
+
endowments
|
|
266
|
+
}) {
|
|
267
|
+
if (__privateGet(this, _snapToJobMap).has(snapId)) {
|
|
268
|
+
throw new Error(`Snap "${snapId}" is already being executed.`);
|
|
269
|
+
}
|
|
270
|
+
const jobId = nanoid();
|
|
271
|
+
const timer = new Timer(__privateGet(this, _initTimeout));
|
|
272
|
+
const job = await this.initJob(jobId, timer);
|
|
273
|
+
__privateMethod(this, _mapSnapAndJob, mapSnapAndJob_fn).call(this, snapId, job.id);
|
|
274
|
+
if (__privateGet(this, _usePing)) {
|
|
275
|
+
const pingResult = await withTimeout(
|
|
276
|
+
this.command(job.id, {
|
|
277
|
+
jsonrpc: "2.0",
|
|
278
|
+
method: "ping",
|
|
279
|
+
id: nanoid()
|
|
280
|
+
}),
|
|
281
|
+
__privateGet(this, _pingTimeout)
|
|
282
|
+
);
|
|
283
|
+
if (pingResult === hasTimedOut) {
|
|
284
|
+
throw new Error("The Snaps execution environment failed to start.");
|
|
285
|
+
}
|
|
247
286
|
}
|
|
248
|
-
const
|
|
249
|
-
|
|
250
|
-
const
|
|
287
|
+
const rpcStream = job.streams.rpc;
|
|
288
|
+
this.setupSnapProvider(snapId, rpcStream);
|
|
289
|
+
const remainingTime = timer.remaining;
|
|
290
|
+
const result = await withTimeout(
|
|
251
291
|
this.command(job.id, {
|
|
252
292
|
jsonrpc: "2.0",
|
|
253
|
-
method: "
|
|
293
|
+
method: "executeSnap",
|
|
294
|
+
params: { snapId, sourceCode, endowments },
|
|
254
295
|
id: nanoid()
|
|
255
296
|
}),
|
|
256
|
-
|
|
297
|
+
remainingTime
|
|
257
298
|
);
|
|
258
|
-
if (
|
|
259
|
-
throw new Error(
|
|
299
|
+
if (result === hasTimedOut) {
|
|
300
|
+
throw new Error(`${snapId} failed to start.`);
|
|
260
301
|
}
|
|
261
|
-
|
|
262
|
-
this.setupSnapProvider(snapData.snapId, rpcStream);
|
|
263
|
-
const result = await this.command(job.id, {
|
|
264
|
-
jsonrpc: "2.0",
|
|
265
|
-
method: "executeSnap",
|
|
266
|
-
params: snapData,
|
|
267
|
-
id: nanoid()
|
|
268
|
-
});
|
|
269
|
-
__privateMethod(this, _createSnapHooks, createSnapHooks_fn).call(this, snapData.snapId, job.id);
|
|
302
|
+
__privateMethod(this, _createSnapHooks, createSnapHooks_fn).call(this, snapId, job.id);
|
|
270
303
|
return result;
|
|
271
304
|
}
|
|
272
305
|
// Cannot be hash private yet because of tests.
|
|
@@ -310,8 +343,10 @@ _snapRpcHooks = new WeakMap();
|
|
|
310
343
|
_snapToJobMap = new WeakMap();
|
|
311
344
|
_jobToSnapMap = new WeakMap();
|
|
312
345
|
_messenger = new WeakMap();
|
|
346
|
+
_initTimeout = new WeakMap();
|
|
313
347
|
_pingTimeout = new WeakMap();
|
|
314
348
|
_terminationTimeout = new WeakMap();
|
|
349
|
+
_usePing = new WeakMap();
|
|
315
350
|
_removeSnapHooks = new WeakSet();
|
|
316
351
|
removeSnapHooks_fn = function(snapId) {
|
|
317
352
|
__privateGet(this, _snapRpcHooks).delete(snapId);
|
|
@@ -362,4 +397,4 @@ export {
|
|
|
362
397
|
AbstractExecutionService,
|
|
363
398
|
setupMultiplex
|
|
364
399
|
};
|
|
365
|
-
//# sourceMappingURL=chunk-
|
|
400
|
+
//# sourceMappingURL=chunk-FCCGRGQS.mjs.map
|