@metamask/snaps-controllers 8.0.0 → 8.1.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.
Files changed (117) hide show
  1. package/CHANGELOG.md +18 -1
  2. package/dist/{chunk-GZ3RVSUA.js → chunk-2UAU42DO.js} +15 -22
  3. package/dist/chunk-2UAU42DO.js.map +1 -0
  4. package/dist/{chunk-JQLPWQIR.mjs → chunk-3Y4IJKZY.mjs} +2 -2
  5. package/dist/{chunk-DVTMXCTZ.js → chunk-74GN6MIJ.js} +3 -3
  6. package/dist/{chunk-JMP6XYRL.js → chunk-A6RUJL4K.js} +15 -5
  7. package/dist/chunk-A6RUJL4K.js.map +1 -0
  8. package/dist/{chunk-FOT4VRMQ.js → chunk-E5RRFMGF.js} +3 -3
  9. package/dist/{chunk-IRVUYBSV.mjs → chunk-FCCGRGQS.mjs} +19 -13
  10. package/dist/chunk-FCCGRGQS.mjs.map +1 -0
  11. package/dist/{chunk-M2NMZ4ER.js → chunk-FCRPOA4I.js} +12 -4
  12. package/dist/chunk-FCRPOA4I.js.map +1 -0
  13. package/dist/{chunk-DQLRXCST.js → chunk-G4S6UXQ2.js} +3 -3
  14. package/dist/{chunk-MD2JCQBG.mjs → chunk-P5MRZOGW.mjs} +2 -2
  15. package/dist/{chunk-ABKWEVW4.js → chunk-PAFO2KIN.js} +3 -3
  16. package/dist/{chunk-PGQXTXAQ.mjs → chunk-PXKCSAT6.mjs} +2 -2
  17. package/dist/{chunk-6QZJC5I2.mjs → chunk-QLEQIXCE.mjs} +2 -2
  18. package/dist/{chunk-SD6JM5ZU.mjs → chunk-QP5LV734.mjs} +17 -24
  19. package/dist/chunk-QP5LV734.mjs.map +1 -0
  20. package/dist/{chunk-HT7X5NPH.mjs → chunk-RS3WN6D3.mjs} +2 -2
  21. package/dist/{chunk-JZCXZEFV.js → chunk-SIW7ZXQF.js} +19 -13
  22. package/dist/chunk-SIW7ZXQF.js.map +1 -0
  23. package/dist/{chunk-MB23XAVD.mjs → chunk-TO6ZEBIA.mjs} +11 -3
  24. package/dist/chunk-TO6ZEBIA.mjs.map +1 -0
  25. package/dist/chunk-U4DZUKNN.js +80 -0
  26. package/dist/chunk-U4DZUKNN.js.map +1 -0
  27. package/dist/{chunk-HBNET6MY.mjs → chunk-WMT2TIOI.mjs} +15 -5
  28. package/dist/chunk-WMT2TIOI.mjs.map +1 -0
  29. package/dist/{chunk-7DLODFQK.mjs → chunk-X5MFC3VX.mjs} +2 -2
  30. package/dist/{chunk-CXT7XBMN.js → chunk-Y7ZOSPEN.js} +3 -3
  31. package/dist/chunk-ZQNBP53T.mjs +80 -0
  32. package/dist/chunk-ZQNBP53T.mjs.map +1 -0
  33. package/dist/{chunk-PRJADV7W.js → chunk-ZVGZG25U.js} +3 -3
  34. package/dist/cronjob/CronjobController.js +8 -8
  35. package/dist/cronjob/CronjobController.mjs +8 -8
  36. package/dist/cronjob/index.js +8 -8
  37. package/dist/cronjob/index.mjs +8 -8
  38. package/dist/index.js +9 -9
  39. package/dist/index.mjs +8 -8
  40. package/dist/interface/SnapInterfaceController.js +3 -3
  41. package/dist/interface/SnapInterfaceController.mjs +2 -2
  42. package/dist/interface/index.js +3 -3
  43. package/dist/interface/index.mjs +2 -2
  44. package/dist/interface/utils.js +2 -4
  45. package/dist/interface/utils.mjs +5 -7
  46. package/dist/node.js +11 -11
  47. package/dist/node.mjs +10 -10
  48. package/dist/react-native.js +10 -10
  49. package/dist/react-native.mjs +9 -9
  50. package/dist/services/AbstractExecutionService.js +2 -2
  51. package/dist/services/AbstractExecutionService.mjs +1 -1
  52. package/dist/services/browser.js +7 -7
  53. package/dist/services/browser.mjs +6 -6
  54. package/dist/services/iframe/IframeExecutionService.js +3 -3
  55. package/dist/services/iframe/IframeExecutionService.mjs +2 -2
  56. package/dist/services/iframe/index.js +3 -3
  57. package/dist/services/iframe/index.mjs +2 -2
  58. package/dist/services/index.js +6 -6
  59. package/dist/services/index.mjs +5 -5
  60. package/dist/services/node-js/NodeProcessExecutionService.js +7 -7
  61. package/dist/services/node-js/NodeProcessExecutionService.mjs +6 -6
  62. package/dist/services/node-js/NodeThreadExecutionService.js +7 -7
  63. package/dist/services/node-js/NodeThreadExecutionService.mjs +6 -6
  64. package/dist/services/node-js/index.js +8 -8
  65. package/dist/services/node-js/index.mjs +7 -7
  66. package/dist/services/node.js +8 -8
  67. package/dist/services/node.mjs +7 -7
  68. package/dist/services/offscreen/OffscreenExecutionService.js +4 -4
  69. package/dist/services/offscreen/OffscreenExecutionService.mjs +3 -3
  70. package/dist/services/offscreen/index.js +4 -4
  71. package/dist/services/offscreen/index.mjs +3 -3
  72. package/dist/services/proxy/ProxyExecutionService.js +3 -3
  73. package/dist/services/proxy/ProxyExecutionService.mjs +2 -2
  74. package/dist/services/react-native.js +7 -7
  75. package/dist/services/react-native.mjs +6 -6
  76. package/dist/services/webview/WebViewExecutionService.js +4 -4
  77. package/dist/services/webview/WebViewExecutionService.mjs +3 -3
  78. package/dist/services/webview/index.js +4 -4
  79. package/dist/services/webview/index.mjs +3 -3
  80. package/dist/services/webworker/WebWorkerExecutionService.js +3 -3
  81. package/dist/services/webworker/WebWorkerExecutionService.mjs +2 -2
  82. package/dist/services/webworker/index.js +3 -3
  83. package/dist/services/webworker/index.mjs +2 -2
  84. package/dist/snaps/SnapController.js +2 -2
  85. package/dist/snaps/SnapController.mjs +1 -1
  86. package/dist/snaps/index.js +2 -2
  87. package/dist/snaps/index.mjs +1 -1
  88. package/dist/tsconfig.build.tsbuildinfo +1 -1
  89. package/dist/types/interface/SnapInterfaceController.d.ts +5 -4
  90. package/dist/types/interface/utils.d.ts +11 -20
  91. package/dist/types/services/AbstractExecutionService.d.ts +2 -1
  92. package/dist/types/snaps/SnapController.d.ts +1 -1
  93. package/package.json +7 -7
  94. package/dist/chunk-GZ3RVSUA.js.map +0 -1
  95. package/dist/chunk-HBNET6MY.mjs.map +0 -1
  96. package/dist/chunk-IRVUYBSV.mjs.map +0 -1
  97. package/dist/chunk-JMP6XYRL.js.map +0 -1
  98. package/dist/chunk-JZCXZEFV.js.map +0 -1
  99. package/dist/chunk-KLK7ZRMH.js +0 -55
  100. package/dist/chunk-KLK7ZRMH.js.map +0 -1
  101. package/dist/chunk-M2NMZ4ER.js.map +0 -1
  102. package/dist/chunk-MB23XAVD.mjs.map +0 -1
  103. package/dist/chunk-RIU3ZIXZ.mjs +0 -55
  104. package/dist/chunk-RIU3ZIXZ.mjs.map +0 -1
  105. package/dist/chunk-SD6JM5ZU.mjs.map +0 -1
  106. /package/dist/{chunk-JQLPWQIR.mjs.map → chunk-3Y4IJKZY.mjs.map} +0 -0
  107. /package/dist/{chunk-DVTMXCTZ.js.map → chunk-74GN6MIJ.js.map} +0 -0
  108. /package/dist/{chunk-FOT4VRMQ.js.map → chunk-E5RRFMGF.js.map} +0 -0
  109. /package/dist/{chunk-DQLRXCST.js.map → chunk-G4S6UXQ2.js.map} +0 -0
  110. /package/dist/{chunk-MD2JCQBG.mjs.map → chunk-P5MRZOGW.mjs.map} +0 -0
  111. /package/dist/{chunk-ABKWEVW4.js.map → chunk-PAFO2KIN.js.map} +0 -0
  112. /package/dist/{chunk-PGQXTXAQ.mjs.map → chunk-PXKCSAT6.mjs.map} +0 -0
  113. /package/dist/{chunk-6QZJC5I2.mjs.map → chunk-QLEQIXCE.mjs.map} +0 -0
  114. /package/dist/{chunk-HT7X5NPH.mjs.map → chunk-RS3WN6D3.mjs.map} +0 -0
  115. /package/dist/{chunk-7DLODFQK.mjs.map → chunk-X5MFC3VX.mjs.map} +0 -0
  116. /package/dist/{chunk-CXT7XBMN.js.map → chunk-Y7ZOSPEN.js.map} +0 -0
  117. /package/dist/{chunk-PRJADV7W.js.map → chunk-ZVGZG25U.js.map} +0 -0
@@ -1,11 +1,11 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunkJZCXZEFVjs = require('./chunk-JZCXZEFV.js');
3
+ var _chunkSIW7ZXQFjs = require('./chunk-SIW7ZXQF.js');
4
4
 
5
5
  // src/services/iframe/IframeExecutionService.ts
6
6
  var _postmessagestream = require('@metamask/post-message-stream');
7
7
  var _snapsutils = require('@metamask/snaps-utils');
8
- var IframeExecutionService = class extends _chunkJZCXZEFVjs.AbstractExecutionService {
8
+ var IframeExecutionService = class extends _chunkSIW7ZXQFjs.AbstractExecutionService {
9
9
  constructor({
10
10
  iframeUrl,
11
11
  messenger,
@@ -35,4 +35,4 @@ var IframeExecutionService = class extends _chunkJZCXZEFVjs.AbstractExecutionSer
35
35
 
36
36
 
37
37
  exports.IframeExecutionService = IframeExecutionService;
38
- //# sourceMappingURL=chunk-ABKWEVW4.js.map
38
+ //# sourceMappingURL=chunk-PAFO2KIN.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  AbstractExecutionService
3
- } from "./chunk-IRVUYBSV.mjs";
3
+ } from "./chunk-FCCGRGQS.mjs";
4
4
  import {
5
5
  __require
6
6
  } from "./chunk-YRZVIDCF.mjs";
@@ -35,4 +35,4 @@ var NodeProcessExecutionService = class extends AbstractExecutionService {
35
35
  export {
36
36
  NodeProcessExecutionService
37
37
  };
38
- //# sourceMappingURL=chunk-PGQXTXAQ.mjs.map
38
+ //# sourceMappingURL=chunk-PXKCSAT6.mjs.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  AbstractExecutionService
3
- } from "./chunk-IRVUYBSV.mjs";
3
+ } from "./chunk-FCCGRGQS.mjs";
4
4
 
5
5
  // src/services/iframe/IframeExecutionService.ts
6
6
  import { WindowPostMessageStream } from "@metamask/post-message-stream";
@@ -35,4 +35,4 @@ var IframeExecutionService = class extends AbstractExecutionService {
35
35
  export {
36
36
  IframeExecutionService
37
37
  };
38
- //# sourceMappingURL=chunk-6QZJC5I2.mjs.map
38
+ //# sourceMappingURL=chunk-QLEQIXCE.mjs.map
@@ -1,6 +1,7 @@
1
1
  import {
2
- constructState
3
- } from "./chunk-RIU3ZIXZ.mjs";
2
+ constructState,
3
+ getJsxInterface
4
+ } from "./chunk-ZQNBP53T.mjs";
4
5
  import {
5
6
  __privateAdd,
6
7
  __privateMethod
@@ -8,15 +9,10 @@ import {
8
9
 
9
10
  // src/interface/SnapInterfaceController.ts
10
11
  import { BaseController } from "@metamask/base-controller";
11
- import {
12
- getJsonSizeUnsafe,
13
- getTotalTextLength,
14
- validateComponentLinks
15
- } from "@metamask/snaps-utils";
12
+ import { getJsonSizeUnsafe, validateJsxLinks } from "@metamask/snaps-utils";
16
13
  import { assert } from "@metamask/utils";
17
14
  import { nanoid } from "nanoid";
18
15
  var MAX_UI_CONTENT_SIZE = 1e7;
19
- var MAX_TEXT_LENGTH = 5e4;
20
16
  var controllerName = "SnapInterfaceController";
21
17
  var _registerMessageHandlers, registerMessageHandlers_fn, _validateArgs, validateArgs_fn, _triggerPhishingListUpdate, triggerPhishingListUpdate_fn, _checkPhishingList, checkPhishingList_fn, _validateContent, validateContent_fn;
22
18
  var SnapInterfaceController = class extends BaseController {
@@ -56,7 +52,7 @@ var SnapInterfaceController = class extends BaseController {
56
52
  * Utility function to validate the components of an interface.
57
53
  * Throws if something is invalid.
58
54
  *
59
- * @param content - The components to verify.
55
+ * @param element - The JSX element to verify.
60
56
  */
61
57
  __privateAdd(this, _validateContent);
62
58
  __privateMethod(this, _registerMessageHandlers, registerMessageHandlers_fn).call(this);
@@ -69,13 +65,14 @@ var SnapInterfaceController = class extends BaseController {
69
65
  * @returns The newly interface id.
70
66
  */
71
67
  async createInterface(snapId, content) {
72
- await __privateMethod(this, _validateContent, validateContent_fn).call(this, content);
68
+ const element = getJsxInterface(content);
69
+ await __privateMethod(this, _validateContent, validateContent_fn).call(this, element);
73
70
  const id = nanoid();
74
- const componentState = constructState({}, content);
71
+ const componentState = constructState({}, element);
75
72
  this.update((draftState) => {
76
73
  draftState.interfaces[id] = {
77
74
  snapId,
78
- content,
75
+ content: element,
79
76
  state: componentState
80
77
  };
81
78
  });
@@ -101,12 +98,13 @@ var SnapInterfaceController = class extends BaseController {
101
98
  */
102
99
  async updateInterface(snapId, id, content) {
103
100
  __privateMethod(this, _validateArgs, validateArgs_fn).call(this, snapId, id);
104
- await __privateMethod(this, _validateContent, validateContent_fn).call(this, content);
101
+ const element = getJsxInterface(content);
102
+ await __privateMethod(this, _validateContent, validateContent_fn).call(this, element);
105
103
  const oldState = this.state.interfaces[id].state;
106
- const newState = constructState(oldState, content);
104
+ const newState = constructState(oldState, element);
107
105
  this.update((draftState) => {
108
106
  draftState.interfaces[id].state = newState;
109
- draftState.interfaces[id].content = content;
107
+ draftState.interfaces[id].content = element;
110
108
  });
111
109
  }
112
110
  /**
@@ -175,22 +173,17 @@ checkPhishingList_fn = function(origin) {
175
173
  return this.messagingSystem.call("PhishingController:testOrigin", origin).result;
176
174
  };
177
175
  _validateContent = new WeakSet();
178
- validateContent_fn = async function(content) {
179
- const size = getJsonSizeUnsafe(content);
176
+ validateContent_fn = async function(element) {
177
+ const size = getJsonSizeUnsafe(element);
180
178
  assert(
181
179
  size <= MAX_UI_CONTENT_SIZE,
182
180
  `A Snap UI may not be larger than ${MAX_UI_CONTENT_SIZE / 1e6} MB.`
183
181
  );
184
- const textSize = getTotalTextLength(content);
185
- assert(
186
- textSize <= MAX_TEXT_LENGTH,
187
- `The text in a Snap UI may not be larger than ${MAX_TEXT_LENGTH / 1e3} kB.`
188
- );
189
182
  await __privateMethod(this, _triggerPhishingListUpdate, triggerPhishingListUpdate_fn).call(this);
190
- validateComponentLinks(content, __privateMethod(this, _checkPhishingList, checkPhishingList_fn).bind(this));
183
+ validateJsxLinks(element, __privateMethod(this, _checkPhishingList, checkPhishingList_fn).bind(this));
191
184
  };
192
185
 
193
186
  export {
194
187
  SnapInterfaceController
195
188
  };
196
- //# sourceMappingURL=chunk-SD6JM5ZU.mjs.map
189
+ //# sourceMappingURL=chunk-QP5LV734.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/interface/SnapInterfaceController.ts"],"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"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  AbstractExecutionService
3
- } from "./chunk-IRVUYBSV.mjs";
3
+ } from "./chunk-FCCGRGQS.mjs";
4
4
  import {
5
5
  ProxyPostMessageStream
6
6
  } from "./chunk-ZVOYOZFT.mjs";
@@ -102,4 +102,4 @@ export {
102
102
  WORKER_POOL_ID,
103
103
  WebWorkerExecutionService
104
104
  };
105
- //# sourceMappingURL=chunk-HT7X5NPH.mjs.map
105
+ //# sourceMappingURL=chunk-RS3WN6D3.mjs.map
@@ -31,14 +31,15 @@ var _utils = require('@metamask/utils');
31
31
  var _nanoid = require('nanoid');
32
32
  var _readablestream = require('readable-stream');
33
33
  var controllerName = "ExecutionService";
34
- var _snapRpcHooks, _snapToJobMap, _jobToSnapMap, _messenger, _initTimeout, _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;
35
35
  var AbstractExecutionService = class {
36
36
  constructor({
37
37
  setupSnapProvider,
38
38
  messenger,
39
39
  initTimeout = _utils.inMilliseconds.call(void 0, 60, _utils.Duration.Second),
40
40
  pingTimeout = _utils.inMilliseconds.call(void 0, 2, _utils.Duration.Second),
41
- terminationTimeout = _utils.inMilliseconds.call(void 0, 1, _utils.Duration.Second)
41
+ terminationTimeout = _utils.inMilliseconds.call(void 0, 1, _utils.Duration.Second),
42
+ usePing = true
42
43
  }) {
43
44
  _chunkEXN2TFDJjs.__privateAdd.call(void 0, this, _removeSnapHooks);
44
45
  _chunkEXN2TFDJjs.__privateAdd.call(void 0, this, _createSnapHooks);
@@ -51,6 +52,7 @@ var AbstractExecutionService = class {
51
52
  _chunkEXN2TFDJjs.__privateAdd.call(void 0, this, _initTimeout, void 0);
52
53
  _chunkEXN2TFDJjs.__privateAdd.call(void 0, this, _pingTimeout, void 0);
53
54
  _chunkEXN2TFDJjs.__privateAdd.call(void 0, this, _terminationTimeout, void 0);
55
+ _chunkEXN2TFDJjs.__privateAdd.call(void 0, this, _usePing, void 0);
54
56
  _chunkEXN2TFDJjs.__privateSet.call(void 0, this, _snapRpcHooks, /* @__PURE__ */ new Map());
55
57
  this.jobs = /* @__PURE__ */ new Map();
56
58
  this.setupSnapProvider = setupSnapProvider;
@@ -60,6 +62,7 @@ var AbstractExecutionService = class {
60
62
  _chunkEXN2TFDJjs.__privateSet.call(void 0, this, _initTimeout, initTimeout);
61
63
  _chunkEXN2TFDJjs.__privateSet.call(void 0, this, _pingTimeout, pingTimeout);
62
64
  _chunkEXN2TFDJjs.__privateSet.call(void 0, this, _terminationTimeout, terminationTimeout);
65
+ _chunkEXN2TFDJjs.__privateSet.call(void 0, this, _usePing, usePing);
63
66
  this.registerMessageHandlers();
64
67
  }
65
68
  /**
@@ -268,16 +271,18 @@ var AbstractExecutionService = class {
268
271
  const timer = new (0, _chunkBOFPNIRXjs.Timer)(_chunkEXN2TFDJjs.__privateGet.call(void 0, this, _initTimeout));
269
272
  const job = await this.initJob(jobId, timer);
270
273
  _chunkEXN2TFDJjs.__privateMethod.call(void 0, this, _mapSnapAndJob, mapSnapAndJob_fn).call(this, snapId, job.id);
271
- const pingResult = await _chunk4DPX4O3Tjs.withTimeout.call(void 0,
272
- this.command(job.id, {
273
- jsonrpc: "2.0",
274
- method: "ping",
275
- id: _nanoid.nanoid.call(void 0, )
276
- }),
277
- _chunkEXN2TFDJjs.__privateGet.call(void 0, this, _pingTimeout)
278
- );
279
- if (pingResult === _chunk4DPX4O3Tjs.hasTimedOut) {
280
- throw new Error("The Snaps execution environment failed to start.");
274
+ if (_chunkEXN2TFDJjs.__privateGet.call(void 0, this, _usePing)) {
275
+ const pingResult = await _chunk4DPX4O3Tjs.withTimeout.call(void 0,
276
+ this.command(job.id, {
277
+ jsonrpc: "2.0",
278
+ method: "ping",
279
+ id: _nanoid.nanoid.call(void 0, )
280
+ }),
281
+ _chunkEXN2TFDJjs.__privateGet.call(void 0, this, _pingTimeout)
282
+ );
283
+ if (pingResult === _chunk4DPX4O3Tjs.hasTimedOut) {
284
+ throw new Error("The Snaps execution environment failed to start.");
285
+ }
281
286
  }
282
287
  const rpcStream = job.streams.rpc;
283
288
  this.setupSnapProvider(snapId, rpcStream);
@@ -341,6 +346,7 @@ _messenger = new WeakMap();
341
346
  _initTimeout = new WeakMap();
342
347
  _pingTimeout = new WeakMap();
343
348
  _terminationTimeout = new WeakMap();
349
+ _usePing = new WeakMap();
344
350
  _removeSnapHooks = new WeakSet();
345
351
  removeSnapHooks_fn = function(snapId) {
346
352
  _chunkEXN2TFDJjs.__privateGet.call(void 0, this, _snapRpcHooks).delete(snapId);
@@ -391,4 +397,4 @@ function setupMultiplex(connectionStream, streamName) {
391
397
 
392
398
 
393
399
  exports.AbstractExecutionService = AbstractExecutionService; exports.setupMultiplex = setupMultiplex;
394
- //# sourceMappingURL=chunk-JZCXZEFV.js.map
400
+ //# sourceMappingURL=chunk-SIW7ZXQF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/services/AbstractExecutionService.ts"],"names":[],"mappings":"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","sourcesContent":["import { JsonRpcEngine } from '@metamask/json-rpc-engine';\nimport { createStreamMiddleware } from '@metamask/json-rpc-middleware-stream';\nimport ObjectMultiplex from '@metamask/object-multiplex';\nimport type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { JsonRpcError } from '@metamask/rpc-errors';\nimport type { SnapRpcHook, SnapRpcHookArgs } from '@metamask/snaps-utils';\nimport { SNAP_STREAM_NAMES, logError } from '@metamask/snaps-utils';\nimport type {\n Json,\n JsonRpcNotification,\n JsonRpcRequest,\n PendingJsonRpcResponse,\n} from '@metamask/utils';\nimport {\n Duration,\n assertIsJsonRpcRequest,\n inMilliseconds,\n isJsonRpcNotification,\n isObject,\n} from '@metamask/utils';\nimport { nanoid } from 'nanoid';\nimport { pipeline } from 'readable-stream';\nimport type { Duplex } from 'readable-stream';\n\nimport { log } from '../logging';\nimport { Timer } from '../snaps/Timer';\nimport { hasTimedOut, withTimeout } from '../utils';\nimport type {\n ExecutionService,\n ExecutionServiceMessenger,\n SnapErrorJson,\n SnapExecutionData,\n} from './ExecutionService';\n\nconst controllerName = 'ExecutionService';\n\nexport type SetupSnapProvider = (snapId: string, stream: Duplex) => void;\n\nexport type ExecutionServiceArgs = {\n setupSnapProvider: SetupSnapProvider;\n messenger: ExecutionServiceMessenger;\n initTimeout?: number;\n pingTimeout?: number;\n terminationTimeout?: number;\n usePing?: boolean;\n};\n\nexport type JobStreams = {\n command: Duplex;\n rpc: Duplex;\n _connection: BasePostMessageStream;\n};\n\nexport type Job<WorkerType> = {\n id: string;\n streams: JobStreams;\n rpcEngine: JsonRpcEngine;\n worker: WorkerType;\n};\n\nexport type TerminateJobArgs<WorkerType> = Partial<Job<WorkerType>> &\n Pick<Job<WorkerType>, 'id'>;\n\nexport abstract class AbstractExecutionService<WorkerType>\n implements ExecutionService\n{\n #snapRpcHooks: Map<string, SnapRpcHook>;\n\n // Cannot be hash private yet because of tests.\n protected jobs: Map<string, Job<WorkerType>>;\n\n // Cannot be hash private yet because of tests.\n private readonly setupSnapProvider: SetupSnapProvider;\n\n #snapToJobMap: Map<string, string>;\n\n #jobToSnapMap: Map<string, string>;\n\n #messenger: ExecutionServiceMessenger;\n\n #initTimeout: number;\n\n #pingTimeout: number;\n\n #terminationTimeout: number;\n\n #usePing: boolean;\n\n constructor({\n setupSnapProvider,\n messenger,\n initTimeout = inMilliseconds(60, Duration.Second),\n pingTimeout = inMilliseconds(2, Duration.Second),\n terminationTimeout = inMilliseconds(1, Duration.Second),\n usePing = true,\n }: ExecutionServiceArgs) {\n this.#snapRpcHooks = new Map();\n this.jobs = new Map();\n this.setupSnapProvider = setupSnapProvider;\n this.#snapToJobMap = new Map();\n this.#jobToSnapMap = new Map();\n this.#messenger = messenger;\n this.#initTimeout = initTimeout;\n this.#pingTimeout = pingTimeout;\n this.#terminationTimeout = terminationTimeout;\n this.#usePing = usePing;\n\n this.registerMessageHandlers();\n }\n\n /**\n * Constructor helper for registering the controller's messaging system\n * actions.\n */\n private registerMessageHandlers(): void {\n this.#messenger.registerActionHandler(\n `${controllerName}:handleRpcRequest`,\n async (snapId: string, options: SnapRpcHookArgs) =>\n this.handleRpcRequest(snapId, options),\n );\n\n this.#messenger.registerActionHandler(\n `${controllerName}:executeSnap`,\n async (data: SnapExecutionData) => this.executeSnap(data),\n );\n\n this.#messenger.registerActionHandler(\n `${controllerName}:terminateSnap`,\n async (snapId: string) => this.terminateSnap(snapId),\n );\n\n this.#messenger.registerActionHandler(\n `${controllerName}:terminateAllSnaps`,\n async () => this.terminateAllSnaps(),\n );\n }\n\n /**\n * Performs additional necessary work during job termination. **MUST** be\n * implemented by concrete implementations. See\n * {@link AbstractExecutionService.terminate} for details.\n *\n * @param job - The object corresponding to the job to be terminated.\n */\n protected abstract terminateJob(job: TerminateJobArgs<WorkerType>): void;\n\n /**\n * Terminates the job with the specified ID and deletes all its associated\n * data. Any subsequent messages targeting the job will fail with an error.\n * Throws an error if the specified job does not exist, or if termination\n * fails unexpectedly.\n *\n * @param jobId - The id of the job to be terminated.\n */\n public async terminate(jobId: string): Promise<void> {\n const jobWrapper = this.jobs.get(jobId);\n if (!jobWrapper) {\n throw new Error(`Job with id \"${jobId}\" not found.`);\n }\n\n try {\n // Ping worker and tell it to run teardown, continue with termination if it takes too long\n const result = await withTimeout(\n this.command(jobId, {\n jsonrpc: '2.0',\n method: 'terminate',\n params: [],\n id: nanoid(),\n }),\n this.#terminationTimeout,\n );\n\n if (result === hasTimedOut || result !== 'OK') {\n // We tried to shutdown gracefully but failed. This probably means the Snap is in infinite loop and\n // hogging down the whole JS process.\n // TODO(ritave): It might be doing weird things such as posting a lot of setTimeouts. Add a test to ensure that this behaviour\n // doesn't leak into other workers. Especially important in IframeExecutionEnvironment since they all share the same\n // JS process.\n logError(`Job \"${jobId}\" failed to terminate gracefully.`, result);\n }\n } catch {\n // Ignore\n }\n\n Object.values(jobWrapper.streams).forEach((stream) => {\n try {\n !stream.destroyed && stream.destroy();\n stream.removeAllListeners();\n } catch (error) {\n logError('Error while destroying stream', error);\n }\n });\n\n this.terminateJob(jobWrapper);\n\n this.jobs.delete(jobId);\n this.#removeSnapAndJobMapping(jobId);\n log(`Job \"${jobId}\" terminated.`);\n }\n\n /**\n * Initiates a job for a snap.\n *\n * @param jobId - The ID of the job to initiate.\n * @param timer - The timer to use for timeouts.\n * @returns Information regarding the created job.\n * @throws If the execution service returns an error or execution times out.\n */\n protected async initJob(\n jobId: string,\n timer: Timer,\n ): Promise<Job<WorkerType>> {\n const { streams, worker } = await this.initStreams(jobId, timer);\n const rpcEngine = new JsonRpcEngine();\n\n const jsonRpcConnection = createStreamMiddleware();\n\n pipeline(\n jsonRpcConnection.stream,\n streams.command,\n jsonRpcConnection.stream,\n (error) => {\n if (error) {\n logError(`Command stream failure.`, error);\n }\n },\n );\n\n rpcEngine.push(jsonRpcConnection.middleware);\n\n const envMetadata = {\n id: jobId,\n streams,\n rpcEngine,\n worker,\n };\n this.jobs.set(jobId, envMetadata);\n\n return envMetadata;\n }\n\n /**\n * Sets up the streams for an initiated job.\n *\n * @param jobId - The id of the job.\n * @param timer - The timer to use for timeouts.\n * @returns The streams to communicate with the worker and the worker itself.\n * @throws If the execution service returns an error or execution times out.\n */\n protected async initStreams(\n jobId: string,\n timer: Timer,\n ): Promise<{ streams: JobStreams; worker: WorkerType }> {\n const result = await withTimeout(this.initEnvStream(jobId), timer);\n\n if (result === hasTimedOut) {\n // For certain environments, such as the iframe we may have already created the worker and wish to terminate it.\n this.terminateJob({ id: jobId });\n throw new Error('The Snaps execution environment failed to start.');\n }\n\n const { worker, stream: envStream } = result;\n const mux = setupMultiplex(envStream, `Job: \"${jobId}\"`);\n const commandStream = mux.createStream(SNAP_STREAM_NAMES.COMMAND);\n\n // Handle out-of-band errors, i.e. errors thrown from the snap outside of the req/res cycle.\n // Also keep track of outbound request/responses\n const notificationHandler = (\n message:\n | JsonRpcRequest\n | JsonRpcNotification<Json[] | Record<string, Json>>,\n ) => {\n if (!isJsonRpcNotification(message)) {\n return;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const snapId = this.#jobToSnapMap.get(jobId)!;\n if (message.method === 'OutboundRequest') {\n this.#messenger.publish('ExecutionService:outboundRequest', snapId);\n } else if (message.method === 'OutboundResponse') {\n this.#messenger.publish('ExecutionService:outboundResponse', snapId);\n } else if (message.method === 'UnhandledError') {\n if (isObject(message.params) && message.params.error) {\n this.#messenger.publish(\n 'ExecutionService:unhandledError',\n snapId,\n message.params.error as SnapErrorJson,\n );\n commandStream.removeListener('data', notificationHandler);\n } else {\n logError(\n new Error(\n `Received malformed \"${message.method}\" command stream notification.`,\n ),\n );\n }\n } else {\n logError(\n new Error(\n `Received unexpected command stream notification \"${message.method}\".`,\n ),\n );\n }\n };\n\n commandStream.on('data', notificationHandler);\n const rpcStream = mux.createStream(SNAP_STREAM_NAMES.JSON_RPC);\n\n // Typecast: stream type mismatch\n return {\n streams: {\n command: commandStream,\n rpc: rpcStream,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n _connection: envStream,\n },\n worker,\n };\n }\n\n /**\n * Abstract function implemented by implementing class that spins up a new worker for a job.\n *\n * 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.\n */\n protected abstract initEnvStream(jobId: string): Promise<{\n worker: WorkerType;\n stream: BasePostMessageStream;\n }>;\n\n /**\n * Terminates the Snap with the specified ID. May throw an error if\n * termination unexpectedly fails, but will not fail if no job for the snap\n * with the specified ID is found.\n *\n * @param snapId - The ID of the snap to terminate.\n */\n async terminateSnap(snapId: string) {\n const jobId = this.#snapToJobMap.get(snapId);\n if (jobId) {\n await this.terminate(jobId);\n }\n }\n\n async terminateAllSnaps() {\n await Promise.all(\n [...this.jobs.keys()].map(async (jobId) => this.terminate(jobId)),\n );\n this.#snapRpcHooks.clear();\n }\n\n /**\n * Gets the RPC request handler for the given snap.\n *\n * @param snapId - The id of the Snap whose message handler to get.\n * @returns The RPC request handler for the snap.\n */\n private getRpcRequestHandler(snapId: string) {\n return this.#snapRpcHooks.get(snapId);\n }\n\n /**\n * Initializes and executes a snap, setting up the communication channels to the snap etc.\n *\n * @param snapData - Data needed for Snap execution.\n * @param snapData.snapId - The ID of the Snap to execute.\n * @param snapData.sourceCode - The source code of the Snap to execute.\n * @param snapData.endowments - The endowments available to the executing Snap.\n * @returns A string `OK` if execution succeeded.\n * @throws If the execution service returns an error or execution times out.\n */\n async executeSnap({\n snapId,\n sourceCode,\n endowments,\n }: SnapExecutionData): Promise<string> {\n if (this.#snapToJobMap.has(snapId)) {\n throw new Error(`Snap \"${snapId}\" is already being executed.`);\n }\n\n const jobId = nanoid();\n const timer = new Timer(this.#initTimeout);\n\n // This may resolve even if the environment has failed to start up fully\n const job = await this.initJob(jobId, timer);\n\n this.#mapSnapAndJob(snapId, job.id);\n\n // Certain environments use ping as part of their initialization and thus can skip it here\n if (this.#usePing) {\n // Ping the worker to ensure that it started up\n const pingResult = await withTimeout(\n this.command(job.id, {\n jsonrpc: '2.0',\n method: 'ping',\n id: nanoid(),\n }),\n this.#pingTimeout,\n );\n\n if (pingResult === hasTimedOut) {\n throw new Error('The Snaps execution environment failed to start.');\n }\n }\n\n const rpcStream = job.streams.rpc;\n\n this.setupSnapProvider(snapId, rpcStream);\n\n const remainingTime = timer.remaining;\n\n const result = await withTimeout(\n this.command(job.id, {\n jsonrpc: '2.0',\n method: 'executeSnap',\n params: { snapId, sourceCode, endowments },\n id: nanoid(),\n }),\n remainingTime,\n );\n\n if (result === hasTimedOut) {\n throw new Error(`${snapId} failed to start.`);\n }\n\n this.#createSnapHooks(snapId, job.id);\n return result as string;\n }\n\n // Cannot be hash private yet because of tests.\n private async command(\n jobId: string,\n message: JsonRpcRequest,\n ): Promise<Json | undefined> {\n assertIsJsonRpcRequest(message);\n\n const job = this.jobs.get(jobId);\n if (!job) {\n throw new Error(`Job with id \"${jobId}\" not found.`);\n }\n\n log('Parent: Sending Command', message);\n const response: PendingJsonRpcResponse<Json> = await job.rpcEngine.handle(\n message,\n );\n\n if (response.error) {\n throw new JsonRpcError(\n response.error.code,\n response.error.message,\n response.error.data,\n );\n }\n\n return response.result;\n }\n\n #removeSnapHooks(snapId: string) {\n this.#snapRpcHooks.delete(snapId);\n }\n\n #createSnapHooks(snapId: string, workerId: string) {\n const rpcHook = async ({ origin, handler, request }: SnapRpcHookArgs) => {\n return await this.command(workerId, {\n id: nanoid(),\n jsonrpc: '2.0',\n method: 'snapRpc',\n params: {\n origin,\n handler,\n request: request as JsonRpcRequest,\n target: snapId,\n },\n });\n };\n\n this.#snapRpcHooks.set(snapId, rpcHook);\n }\n\n #mapSnapAndJob(snapId: string, jobId: string): void {\n this.#snapToJobMap.set(snapId, jobId);\n this.#jobToSnapMap.set(jobId, snapId);\n }\n\n #removeSnapAndJobMapping(jobId: string): void {\n const snapId = this.#jobToSnapMap.get(jobId);\n if (!snapId) {\n throw new Error(`job: \"${jobId}\" has no mapped snap.`);\n }\n\n this.#jobToSnapMap.delete(jobId);\n this.#snapToJobMap.delete(snapId);\n this.#removeSnapHooks(snapId);\n }\n\n /**\n * Handle RPC request.\n *\n * @param snapId - The ID of the recipient snap.\n * @param options - Bag of options to pass to the RPC handler.\n * @returns Promise that can handle the request.\n */\n public async handleRpcRequest(\n snapId: string,\n options: SnapRpcHookArgs,\n ): Promise<unknown> {\n const rpcRequestHandler = this.getRpcRequestHandler(snapId);\n\n if (!rpcRequestHandler) {\n throw new Error(\n `Snap execution service returned no RPC handler for running snap \"${snapId}\".`,\n );\n }\n\n return rpcRequestHandler(options);\n }\n}\n\n/**\n * Sets up stream multiplexing for the given stream.\n *\n * @param connectionStream - The stream to mux.\n * @param streamName - The name of the stream, for identification in errors.\n * @returns The multiplexed stream.\n */\nexport function setupMultiplex(\n connectionStream: Duplex,\n streamName: string,\n): ObjectMultiplex {\n const mux = new ObjectMultiplex();\n pipeline(connectionStream, mux, connectionStream, (error) => {\n if (error) {\n streamName\n ? logError(`\"${streamName}\" stream failure.`, error)\n : logError(error);\n }\n });\n return mux;\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  AbstractExecutionService
3
- } from "./chunk-IRVUYBSV.mjs";
3
+ } from "./chunk-FCCGRGQS.mjs";
4
4
  import {
5
5
  ProxyPostMessageStream
6
6
  } from "./chunk-ZVOYOZFT.mjs";
@@ -32,7 +32,8 @@ var ProxyExecutionService = class extends AbstractExecutionService {
32
32
  }) {
33
33
  super({
34
34
  messenger,
35
- setupSnapProvider
35
+ setupSnapProvider,
36
+ usePing: false
36
37
  });
37
38
  __privateAdd(this, _stream, void 0);
38
39
  __privateSet(this, _stream, stream);
@@ -63,6 +64,13 @@ var ProxyExecutionService = class extends AbstractExecutionService {
63
64
  stream: __privateGet(this, _stream),
64
65
  jobId
65
66
  });
67
+ await new Promise((resolve) => {
68
+ stream.once("data", resolve);
69
+ stream.write({
70
+ name: "command",
71
+ data: { jsonrpc: "2.0", method: "ping", id: nanoid() }
72
+ });
73
+ });
66
74
  return { worker: jobId, stream };
67
75
  }
68
76
  };
@@ -71,4 +79,4 @@ _stream = new WeakMap();
71
79
  export {
72
80
  ProxyExecutionService
73
81
  };
74
- //# sourceMappingURL=chunk-MB23XAVD.mjs.map
82
+ //# sourceMappingURL=chunk-TO6ZEBIA.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/services/proxy/ProxyExecutionService.ts"],"sourcesContent":["import type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { nanoid } from 'nanoid';\n\nimport type {\n ExecutionServiceArgs,\n TerminateJobArgs,\n} from '../AbstractExecutionService';\nimport { AbstractExecutionService } from '../AbstractExecutionService';\nimport { ProxyPostMessageStream } from '../ProxyPostMessageStream';\n\ntype ProxyExecutionEnvironmentServiceArgs = {\n stream: BasePostMessageStream;\n} & ExecutionServiceArgs;\n\nexport class ProxyExecutionService extends AbstractExecutionService<string> {\n readonly #stream: BasePostMessageStream;\n\n /**\n * Create a new proxy execution service.\n *\n * @param args - The constructor arguments.\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 * @param args.stream - The stream to use for communicating with the proxy\n * executor.\n */\n constructor({\n stream,\n messenger,\n setupSnapProvider,\n }: ProxyExecutionEnvironmentServiceArgs) {\n super({\n messenger,\n setupSnapProvider,\n usePing: false,\n });\n\n this.#stream = stream;\n }\n\n /**\n * Send a termination command to the proxy stream.\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 this.#stream.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 root stream\n * in a stream specific to the job.\n *\n * @param jobId - The job ID.\n */\n protected async initEnvStream(jobId: string) {\n const stream = new ProxyPostMessageStream({\n stream: this.#stream,\n jobId,\n });\n\n // Send a request and await any response before continuing\n // This simulates the behaviour of non-proxy environments by effectively awaiting\n // the load of the environment inside the proxy environment\n // This assumes the proxy environment is already loaded before this function is called\n await new Promise((resolve) => {\n stream.once('data', resolve);\n stream.write({\n name: 'command',\n data: { jsonrpc: '2.0', method: 'ping', id: nanoid() },\n });\n });\n\n return { worker: jobId, stream };\n }\n}\n"],"mappings":";;;;;;;;;;;;;AACA,SAAS,cAAc;AADvB;AAcO,IAAM,wBAAN,cAAoC,yBAAiC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAc1E,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAyC;AACvC,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA,SAAS;AAAA,IACX,CAAC;AAtBH,uBAAS,SAAT;AAwBE,uBAAK,SAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAgB,aAAa,KAA+B;AAG1D,uBAAK,SAAQ,MAAM;AAAA,MACjB,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;AAC3C,UAAM,SAAS,IAAI,uBAAuB;AAAA,MACxC,QAAQ,mBAAK;AAAA,MACb;AAAA,IACF,CAAC;AAMD,UAAM,IAAI,QAAQ,CAAC,YAAY;AAC7B,aAAO,KAAK,QAAQ,OAAO;AAC3B,aAAO,MAAM;AAAA,QACX,MAAM;AAAA,QACN,MAAM,EAAE,SAAS,OAAO,QAAQ,QAAQ,IAAI,OAAO,EAAE;AAAA,MACvD,CAAC;AAAA,IACH,CAAC;AAED,WAAO,EAAE,QAAQ,OAAO,OAAO;AAAA,EACjC;AACF;AAvEW;","names":[]}
@@ -0,0 +1,80 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/interface/utils.ts
2
+ var _snapssdk = require('@metamask/snaps-sdk');
3
+ var _jsx = require('@metamask/snaps-sdk/jsx');
4
+
5
+
6
+
7
+ var _snapsutils = require('@metamask/snaps-utils');
8
+ function getJsxInterface(component) {
9
+ if (_jsx.isJSXElementUnsafe.call(void 0, component)) {
10
+ return component;
11
+ }
12
+ return _snapsutils.getJsxElementFromComponent.call(void 0, component);
13
+ }
14
+ function assertNameIsUnique(state, name) {
15
+ _snapssdk.assert.call(void 0,
16
+ state[name] === void 0,
17
+ `Duplicate component names are not allowed, found multiple instances of: "${name}".`
18
+ );
19
+ }
20
+ function constructInputState(oldState, element) {
21
+ return element.props.value ?? oldState[element.props.name] ?? null;
22
+ }
23
+ function constructFormInputState(oldState, component, form) {
24
+ const oldFormState = oldState[form];
25
+ const oldInputState = oldFormState?.[component.props.name];
26
+ return component.props.value ?? oldInputState ?? null;
27
+ }
28
+ function getFieldInput(element) {
29
+ if (Array.isArray(element.props.children)) {
30
+ return element.props.children[0];
31
+ }
32
+ return element.props.children;
33
+ }
34
+ function constructFormState(oldState, component, form, newState) {
35
+ if (component.type === "Button") {
36
+ return newState;
37
+ }
38
+ const input = getFieldInput(component);
39
+ assertNameIsUnique(newState, input.props.name);
40
+ newState[input.props.name] = constructFormInputState(oldState, input, form);
41
+ return newState;
42
+ }
43
+ function constructState(oldState, component, newState = {}) {
44
+ if (component.type === "Box") {
45
+ const children = _snapsutils.getJsxChildren.call(void 0, component);
46
+ return children.reduce(
47
+ (accumulator, node) => constructState(oldState, node, accumulator),
48
+ newState
49
+ );
50
+ }
51
+ if (component.type === "Form") {
52
+ assertNameIsUnique(newState, component.props.name);
53
+ const children = _snapsutils.getJsxChildren.call(void 0, component);
54
+ newState[component.props.name] = children.reduce(
55
+ (accumulator, node) => {
56
+ return constructFormState(
57
+ oldState,
58
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
59
+ node,
60
+ component.props.name,
61
+ accumulator
62
+ );
63
+ },
64
+ {}
65
+ );
66
+ return newState;
67
+ }
68
+ if (component.type === "Input") {
69
+ assertNameIsUnique(newState, component.props.name);
70
+ newState[component.props.name] = constructInputState(oldState, component);
71
+ }
72
+ return newState;
73
+ }
74
+
75
+
76
+
77
+
78
+
79
+ exports.getJsxInterface = getJsxInterface; exports.assertNameIsUnique = assertNameIsUnique; exports.constructState = constructState;
80
+ //# sourceMappingURL=chunk-U4DZUKNN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/interface/utils.ts"],"names":[],"mappings":";AAAA,SAAS,cAAc;AAYvB,SAAS,0BAA0B;AACnC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAUA,SAAS,gBAAgB,WAA2C;AACzE,MAAI,mBAAmB,SAAS,GAAG;AACjC,WAAO;AAAA,EACT;AAEA,SAAO,2BAA2B,SAAS;AAC7C;AAQO,SAAS,mBAAmB,OAAuB,MAAc;AACtE;AAAA,IACE,MAAM,IAAI,MAAM;AAAA,IAChB,4EAA4E,IAAI;AAAA,EAClF;AACF;AASA,SAAS,oBAAoB,UAA0B,SAAuB;AAC5E,SAAO,QAAQ,MAAM,SAAS,SAAS,QAAQ,MAAM,IAAI,KAAK;AAChE;AAUA,SAAS,wBACP,UACA,WACA,MACA;AACA,QAAM,eAAe,SAAS,IAAI;AAClC,QAAM,gBAAgB,eAAe,UAAU,MAAM,IAAI;AACzD,SAAO,UAAU,MAAM,SAAS,iBAAiB;AACnD;AAQA,SAAS,cAAc,SAAuB;AAC5C,MAAI,MAAM,QAAQ,QAAQ,MAAM,QAAQ,GAAG;AACzC,WAAO,QAAQ,MAAM,SAAS,CAAC;AAAA,EACjC;AAEA,SAAO,QAAQ,MAAM;AACvB;AAWA,SAAS,mBACP,UACA,WACA,MACA,UACW;AACX,MAAI,UAAU,SAAS,UAAU;AAC/B,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,cAAc,SAAS;AACrC,qBAAmB,UAAU,MAAM,MAAM,IAAI;AAE7C,WAAS,MAAM,MAAM,IAAI,IAAI,wBAAwB,UAAU,OAAO,IAAI;AAE1E,SAAO;AACT;AAUO,SAAS,eACd,UACA,WACA,WAA2B,CAAC,GACZ;AAChB,MAAI,UAAU,SAAS,OAAO;AAC5B,UAAM,WAAW,eAAe,SAAS;AACzC,WAAO,SAAS;AAAA,MACd,CAAC,aAAa,SACZ,eAAe,UAAU,MAAoB,WAAW;AAAA,MAC1D;AAAA,IACF;AAAA,EACF;AAEA,MAAI,UAAU,SAAS,QAAQ;AAC7B,uBAAmB,UAAU,UAAU,MAAM,IAAI;AAEjD,UAAM,WAAW,eAAe,SAAS;AACzC,aAAS,UAAU,MAAM,IAAI,IAAI,SAAS;AAAA,MACxC,CAAC,aAAa,SAAS;AACrB,eAAO;AAAA,UACL;AAAA;AAAA,UAEA;AAAA,UACA,UAAU,MAAM;AAAA,UAChB;AAAA,QACF;AAAA,MACF;AAAA,MACA,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AAEA,MAAI,UAAU,SAAS,SAAS;AAC9B,uBAAmB,UAAU,UAAU,MAAM,IAAI;AACjD,aAAS,UAAU,MAAM,IAAI,IAAI,oBAAoB,UAAU,SAAS;AAAA,EAC1E;AAEA,SAAO;AACT","sourcesContent":["import { assert } from '@metamask/snaps-sdk';\nimport type {\n FormState,\n InterfaceState,\n ComponentOrElement,\n} from '@metamask/snaps-sdk';\nimport type {\n ButtonElement,\n FieldElement,\n InputElement,\n JSXElement,\n} from '@metamask/snaps-sdk/jsx';\nimport { isJSXElementUnsafe } from '@metamask/snaps-sdk/jsx';\nimport {\n getJsxChildren,\n getJsxElementFromComponent,\n} from '@metamask/snaps-utils';\n\n/**\n * Get a JSX element from a component or JSX element. If the component is a\n * JSX element, it is returned as is. Otherwise, the component is converted to\n * a JSX element.\n *\n * @param component - The component to convert.\n * @returns The JSX element.\n */\nexport function getJsxInterface(component: ComponentOrElement): JSXElement {\n if (isJSXElementUnsafe(component)) {\n return component;\n }\n\n return getJsxElementFromComponent(component);\n}\n\n/**\n * Assert that the component name is unique in state.\n *\n * @param state - The interface state to verify against.\n * @param name - The component name to verify.\n */\nexport function assertNameIsUnique(state: InterfaceState, name: string) {\n assert(\n state[name] === undefined,\n `Duplicate component names are not allowed, found multiple instances of: \"${name}\".`,\n );\n}\n\n/**\n * Construct the state for an input field.\n *\n * @param oldState - The previous state.\n * @param element - The input element.\n * @returns The input state.\n */\nfunction constructInputState(oldState: InterfaceState, element: InputElement) {\n return element.props.value ?? oldState[element.props.name] ?? null;\n}\n\n/**\n * Construct the state for a form input.\n *\n * @param oldState - The previous state.\n * @param component - The input element.\n * @param form - The parent form name of the input.\n * @returns The input state.\n */\nfunction constructFormInputState(\n oldState: InterfaceState,\n component: InputElement,\n form: string,\n) {\n const oldFormState = oldState[form] as FormState;\n const oldInputState = oldFormState?.[component.props.name];\n return component.props.value ?? oldInputState ?? null;\n}\n\n/**\n * Get the input field from a field element.\n *\n * @param element - The field element.\n * @returns The input element.\n */\nfunction getFieldInput(element: FieldElement) {\n if (Array.isArray(element.props.children)) {\n return element.props.children[0];\n }\n\n return element.props.children;\n}\n\n/**\n * Construct the state for a form input.\n *\n * @param oldState - The previous state.\n * @param component - The field element.\n * @param form - The parent form name of the input.\n * @param newState - The new state.\n * @returns The input state.\n */\nfunction constructFormState(\n oldState: InterfaceState,\n component: FieldElement | ButtonElement,\n form: string,\n newState: FormState,\n): FormState {\n if (component.type === 'Button') {\n return newState;\n }\n\n const input = getFieldInput(component);\n assertNameIsUnique(newState, input.props.name);\n\n newState[input.props.name] = constructFormInputState(oldState, input, form);\n\n return newState;\n}\n\n/**\n * Construct the interface state for a given component tree.\n *\n * @param oldState - The previous state.\n * @param component - The UI component to construct state from.\n * @param newState - The state that is being constructed.\n * @returns The interface state of the passed component.\n */\nexport function constructState(\n oldState: InterfaceState,\n component: JSXElement,\n newState: InterfaceState = {},\n): InterfaceState {\n if (component.type === 'Box') {\n const children = getJsxChildren(component);\n return children.reduce(\n (accumulator, node) =>\n constructState(oldState, node as JSXElement, accumulator),\n newState,\n );\n }\n\n if (component.type === 'Form') {\n assertNameIsUnique(newState, component.props.name);\n\n const children = getJsxChildren(component);\n newState[component.props.name] = children.reduce<FormState>(\n (accumulator, node) => {\n return constructFormState(\n oldState,\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n node as FieldElement | ButtonElement,\n component.props.name,\n accumulator,\n );\n },\n {},\n );\n\n return newState;\n }\n\n if (component.type === 'Input') {\n assertNameIsUnique(newState, component.props.name);\n newState[component.props.name] = constructInputState(oldState, component);\n }\n\n return newState;\n}\n"]}
@@ -117,7 +117,7 @@ function truncateSnap(snap) {
117
117
  return truncatedSnap;
118
118
  }
119
119
  var name = "SnapController";
120
- var _closeAllConnections, _dynamicPermissions, _environmentEndowmentPermissions, _excludedPermissions, _featureFlags, _fetchFunction, _idleTimeCheckInterval, _maxIdleTime, _encryptor, _getMnemonic, _detectSnapLocation, _snapsRuntimeData, _rollbackSnapshots, _timeoutForLastRequestStatus, _statusMachine, _initializeStateMachine, initializeStateMachine_fn, _registerMessageHandlers, registerMessageHandlers_fn, _handlePreinstalledSnaps, handlePreinstalledSnaps_fn, _pollForLastRequestStatus, pollForLastRequestStatus_fn, _blockSnap, blockSnap_fn, _unblockSnap, unblockSnap_fn, _assertIsInstallAllowed, assertIsInstallAllowed_fn, _stopSnapsLastRequestPastMax, stopSnapsLastRequestPastMax_fn, _transition, transition_fn, _terminateSnap, terminateSnap_fn, _getSnapEncryptionKey, getSnapEncryptionKey_fn, _decryptSnapState, decryptSnapState_fn, _encryptSnapState, encryptSnapState_fn, _handleInitialConnections, handleInitialConnections_fn, _addSnapToSubject, addSnapToSubject_fn, _removeSnapFromSubjects, removeSnapFromSubjects_fn, _revokeAllSnapPermissions, revokeAllSnapPermissions_fn, _createApproval, createApproval_fn, _updateApproval, updateApproval_fn, _resolveAllowlistVersion, resolveAllowlistVersion_fn, _add, add_fn, _startSnap, startSnap_fn, _getEndowments, getEndowments_fn, _set, set_fn, _validateSnapPermissions, validateSnapPermissions_fn, _getExecutionTimeout, getExecutionTimeout_fn, _getRpcRequestHandler, getRpcRequestHandler_fn, _createInterface, createInterface_fn, _assertInterfaceExists, assertInterfaceExists_fn, _transformSnapRpcRequestResult, transformSnapRpcRequestResult_fn, _assertSnapRpcRequestResult, assertSnapRpcRequestResult_fn, _recordSnapRpcRequestStart, recordSnapRpcRequestStart_fn, _recordSnapRpcRequestFinish, recordSnapRpcRequestFinish_fn, _getRollbackSnapshot, getRollbackSnapshot_fn, _createRollbackSnapshot, createRollbackSnapshot_fn, _rollbackSnap, rollbackSnap_fn, _rollbackSnaps, rollbackSnaps_fn, _getRuntime, getRuntime_fn, _getRuntimeExpect, getRuntimeExpect_fn, _setupRuntime, setupRuntime_fn, _calculatePermissionsChange, calculatePermissionsChange_fn, _updatePermissions, updatePermissions_fn, _isValidUpdate, isValidUpdate_fn, _callLifecycleHook, callLifecycleHook_fn;
120
+ var _closeAllConnections, _dynamicPermissions, _environmentEndowmentPermissions, _excludedPermissions, _featureFlags, _fetchFunction, _idleTimeCheckInterval, _maxIdleTime, _encryptor, _getMnemonic, _detectSnapLocation, _snapsRuntimeData, _rollbackSnapshots, _timeoutForLastRequestStatus, _statusMachine, _preinstalledSnaps, _initializeStateMachine, initializeStateMachine_fn, _registerMessageHandlers, registerMessageHandlers_fn, _handlePreinstalledSnaps, handlePreinstalledSnaps_fn, _pollForLastRequestStatus, pollForLastRequestStatus_fn, _blockSnap, blockSnap_fn, _unblockSnap, unblockSnap_fn, _assertIsInstallAllowed, assertIsInstallAllowed_fn, _stopSnapsLastRequestPastMax, stopSnapsLastRequestPastMax_fn, _transition, transition_fn, _terminateSnap, terminateSnap_fn, _getSnapEncryptionKey, getSnapEncryptionKey_fn, _decryptSnapState, decryptSnapState_fn, _encryptSnapState, encryptSnapState_fn, _handleInitialConnections, handleInitialConnections_fn, _addSnapToSubject, addSnapToSubject_fn, _removeSnapFromSubjects, removeSnapFromSubjects_fn, _revokeAllSnapPermissions, revokeAllSnapPermissions_fn, _createApproval, createApproval_fn, _updateApproval, updateApproval_fn, _resolveAllowlistVersion, resolveAllowlistVersion_fn, _add, add_fn, _startSnap, startSnap_fn, _getEndowments, getEndowments_fn, _set, set_fn, _validateSnapPermissions, validateSnapPermissions_fn, _getExecutionTimeout, getExecutionTimeout_fn, _getRpcRequestHandler, getRpcRequestHandler_fn, _createInterface, createInterface_fn, _assertInterfaceExists, assertInterfaceExists_fn, _transformSnapRpcRequestResult, transformSnapRpcRequestResult_fn, _assertSnapRpcRequestResult, assertSnapRpcRequestResult_fn, _recordSnapRpcRequestStart, recordSnapRpcRequestStart_fn, _recordSnapRpcRequestFinish, recordSnapRpcRequestFinish_fn, _getRollbackSnapshot, getRollbackSnapshot_fn, _createRollbackSnapshot, createRollbackSnapshot_fn, _rollbackSnap, rollbackSnap_fn, _rollbackSnaps, rollbackSnaps_fn, _getRuntime, getRuntime_fn, _getRuntimeExpect, getRuntimeExpect_fn, _setupRuntime, setupRuntime_fn, _calculatePermissionsChange, calculatePermissionsChange_fn, _updatePermissions, updatePermissions_fn, _isValidUpdate, isValidUpdate_fn, _callLifecycleHook, callLifecycleHook_fn;
121
121
  var SnapController = class extends BaseController {
122
122
  constructor({
123
123
  closeAllConnections,
@@ -132,7 +132,7 @@ var SnapController = class extends BaseController {
132
132
  fetchFunction = globalThis.fetch.bind(globalThis),
133
133
  featureFlags = {},
134
134
  detectSnapLocation: detectSnapLocationFunction = detectSnapLocation,
135
- preinstalledSnaps,
135
+ preinstalledSnaps = null,
136
136
  encryptor,
137
137
  getMnemonic
138
138
  }) {
@@ -448,6 +448,7 @@ var SnapController = class extends BaseController {
448
448
  __privateAdd(this, _rollbackSnapshots, void 0);
449
449
  __privateAdd(this, _timeoutForLastRequestStatus, void 0);
450
450
  __privateAdd(this, _statusMachine, void 0);
451
+ __privateAdd(this, _preinstalledSnaps, void 0);
451
452
  __privateSet(this, _closeAllConnections, closeAllConnections);
452
453
  __privateSet(this, _dynamicPermissions, dynamicPermissions);
453
454
  __privateSet(this, _environmentEndowmentPermissions, environmentEndowmentPermissions);
@@ -460,6 +461,7 @@ var SnapController = class extends BaseController {
460
461
  __privateSet(this, _detectSnapLocation, detectSnapLocationFunction);
461
462
  __privateSet(this, _encryptor, encryptor);
462
463
  __privateSet(this, _getMnemonic, getMnemonic);
464
+ __privateSet(this, _preinstalledSnaps, preinstalledSnaps);
463
465
  this._onUnhandledSnapError = this._onUnhandledSnapError.bind(this);
464
466
  this._onOutboundRequest = this._onOutboundRequest.bind(this);
465
467
  this._onOutboundResponse = this._onOutboundResponse.bind(this);
@@ -498,8 +500,8 @@ var SnapController = class extends BaseController {
498
500
  });
499
501
  __privateMethod(this, _initializeStateMachine, initializeStateMachine_fn).call(this);
500
502
  __privateMethod(this, _registerMessageHandlers, registerMessageHandlers_fn).call(this);
501
- if (preinstalledSnaps) {
502
- __privateMethod(this, _handlePreinstalledSnaps, handlePreinstalledSnaps_fn).call(this, preinstalledSnaps);
503
+ if (__privateGet(this, _preinstalledSnaps)) {
504
+ __privateMethod(this, _handlePreinstalledSnaps, handlePreinstalledSnaps_fn).call(this, __privateGet(this, _preinstalledSnaps));
503
505
  }
504
506
  Object.values(this.state?.snaps ?? {}).forEach(
505
507
  (snap) => __privateMethod(this, _setupRuntime, setupRuntime_fn).call(this, snap.id)
@@ -801,6 +803,13 @@ var SnapController = class extends BaseController {
801
803
  state.snaps = {};
802
804
  state.snapStates = {};
803
805
  });
806
+ __privateGet(this, _snapsRuntimeData).clear();
807
+ if (__privateGet(this, _preinstalledSnaps)) {
808
+ __privateMethod(this, _handlePreinstalledSnaps, handlePreinstalledSnaps_fn).call(this, __privateGet(this, _preinstalledSnaps));
809
+ Object.values(this.state?.snaps).forEach(
810
+ (snap) => __privateMethod(this, _setupRuntime, setupRuntime_fn).call(this, snap.id)
811
+ );
812
+ }
804
813
  }
805
814
  /**
806
815
  * Removes the given snap from state, and clears all associated handlers
@@ -1420,6 +1429,7 @@ _snapsRuntimeData = new WeakMap();
1420
1429
  _rollbackSnapshots = new WeakMap();
1421
1430
  _timeoutForLastRequestStatus = new WeakMap();
1422
1431
  _statusMachine = new WeakMap();
1432
+ _preinstalledSnaps = new WeakMap();
1423
1433
  _initializeStateMachine = new WeakSet();
1424
1434
  initializeStateMachine_fn = function() {
1425
1435
  const disableGuard = ({ snapId }) => {
@@ -2434,4 +2444,4 @@ export {
2434
2444
  SNAP_APPROVAL_RESULT,
2435
2445
  SnapController
2436
2446
  };
2437
- //# sourceMappingURL=chunk-HBNET6MY.mjs.map
2447
+ //# sourceMappingURL=chunk-WMT2TIOI.mjs.map