@metamask/snaps-controllers 12.2.0 → 12.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/CHANGELOG.md +16 -1
  2. package/dist/cronjob/CronjobController.cjs +13 -4
  3. package/dist/cronjob/CronjobController.cjs.map +1 -1
  4. package/dist/cronjob/CronjobController.d.cts.map +1 -1
  5. package/dist/cronjob/CronjobController.d.mts.map +1 -1
  6. package/dist/cronjob/CronjobController.mjs +15 -6
  7. package/dist/cronjob/CronjobController.mjs.map +1 -1
  8. package/dist/interface/SnapInterfaceController.cjs +15 -1
  9. package/dist/interface/SnapInterfaceController.cjs.map +1 -1
  10. package/dist/interface/SnapInterfaceController.d.cts +10 -2
  11. package/dist/interface/SnapInterfaceController.d.cts.map +1 -1
  12. package/dist/interface/SnapInterfaceController.d.mts +10 -2
  13. package/dist/interface/SnapInterfaceController.d.mts.map +1 -1
  14. package/dist/interface/SnapInterfaceController.mjs +17 -3
  15. package/dist/interface/SnapInterfaceController.mjs.map +1 -1
  16. package/dist/interface/utils.cjs +104 -4
  17. package/dist/interface/utils.cjs.map +1 -1
  18. package/dist/interface/utils.d.cts +71 -2
  19. package/dist/interface/utils.d.cts.map +1 -1
  20. package/dist/interface/utils.d.mts +71 -2
  21. package/dist/interface/utils.d.mts.map +1 -1
  22. package/dist/interface/utils.mjs +101 -5
  23. package/dist/interface/utils.mjs.map +1 -1
  24. package/dist/services/AbstractExecutionService.cjs +127 -202
  25. package/dist/services/AbstractExecutionService.cjs.map +1 -1
  26. package/dist/services/AbstractExecutionService.d.cts +8 -53
  27. package/dist/services/AbstractExecutionService.d.cts.map +1 -1
  28. package/dist/services/AbstractExecutionService.d.mts +8 -53
  29. package/dist/services/AbstractExecutionService.d.mts.map +1 -1
  30. package/dist/services/AbstractExecutionService.mjs +127 -202
  31. package/dist/services/AbstractExecutionService.mjs.map +1 -1
  32. package/dist/services/iframe/IframeExecutionService.cjs +2 -2
  33. package/dist/services/iframe/IframeExecutionService.cjs.map +1 -1
  34. package/dist/services/iframe/IframeExecutionService.d.cts +1 -1
  35. package/dist/services/iframe/IframeExecutionService.d.cts.map +1 -1
  36. package/dist/services/iframe/IframeExecutionService.d.mts +1 -1
  37. package/dist/services/iframe/IframeExecutionService.d.mts.map +1 -1
  38. package/dist/services/iframe/IframeExecutionService.mjs +2 -2
  39. package/dist/services/iframe/IframeExecutionService.mjs.map +1 -1
  40. package/dist/services/offscreen/OffscreenExecutionService.cjs +5 -5
  41. package/dist/services/offscreen/OffscreenExecutionService.cjs.map +1 -1
  42. package/dist/services/offscreen/OffscreenExecutionService.d.cts +4 -4
  43. package/dist/services/offscreen/OffscreenExecutionService.d.cts.map +1 -1
  44. package/dist/services/offscreen/OffscreenExecutionService.d.mts +4 -4
  45. package/dist/services/offscreen/OffscreenExecutionService.d.mts.map +1 -1
  46. package/dist/services/offscreen/OffscreenExecutionService.mjs +5 -5
  47. package/dist/services/offscreen/OffscreenExecutionService.mjs.map +1 -1
  48. package/dist/services/proxy/ProxyExecutionService.cjs +6 -6
  49. package/dist/services/proxy/ProxyExecutionService.cjs.map +1 -1
  50. package/dist/services/proxy/ProxyExecutionService.d.cts +4 -4
  51. package/dist/services/proxy/ProxyExecutionService.d.cts.map +1 -1
  52. package/dist/services/proxy/ProxyExecutionService.d.mts +4 -4
  53. package/dist/services/proxy/ProxyExecutionService.d.mts.map +1 -1
  54. package/dist/services/proxy/ProxyExecutionService.mjs +6 -6
  55. package/dist/services/proxy/ProxyExecutionService.mjs.map +1 -1
  56. package/dist/services/webview/WebViewExecutionService.cjs +6 -6
  57. package/dist/services/webview/WebViewExecutionService.cjs.map +1 -1
  58. package/dist/services/webview/WebViewExecutionService.d.cts +5 -5
  59. package/dist/services/webview/WebViewExecutionService.d.cts.map +1 -1
  60. package/dist/services/webview/WebViewExecutionService.d.mts +5 -5
  61. package/dist/services/webview/WebViewExecutionService.d.mts.map +1 -1
  62. package/dist/services/webview/WebViewExecutionService.mjs +6 -6
  63. package/dist/services/webview/WebViewExecutionService.mjs.map +1 -1
  64. package/dist/snaps/SnapController.cjs +43 -72
  65. package/dist/snaps/SnapController.cjs.map +1 -1
  66. package/dist/snaps/SnapController.d.cts +5 -9
  67. package/dist/snaps/SnapController.d.cts.map +1 -1
  68. package/dist/snaps/SnapController.d.mts +5 -9
  69. package/dist/snaps/SnapController.d.mts.map +1 -1
  70. package/dist/snaps/SnapController.mjs +43 -72
  71. package/dist/snaps/SnapController.mjs.map +1 -1
  72. package/dist/snaps/registry/json.cjs +4 -2
  73. package/dist/snaps/registry/json.cjs.map +1 -1
  74. package/dist/snaps/registry/json.d.cts.map +1 -1
  75. package/dist/snaps/registry/json.d.mts.map +1 -1
  76. package/dist/snaps/registry/json.mjs +4 -2
  77. package/dist/snaps/registry/json.mjs.map +1 -1
  78. package/package.json +4 -4
  79. package/dist/snaps/RequestQueue.cjs +0 -44
  80. package/dist/snaps/RequestQueue.cjs.map +0 -1
  81. package/dist/snaps/RequestQueue.d.cts +0 -25
  82. package/dist/snaps/RequestQueue.d.cts.map +0 -1
  83. package/dist/snaps/RequestQueue.d.mts +0 -25
  84. package/dist/snaps/RequestQueue.d.mts.map +0 -1
  85. package/dist/snaps/RequestQueue.mjs +0 -40
  86. package/dist/snaps/RequestQueue.mjs.map +0 -1
@@ -10,7 +10,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
11
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
12
  };
13
- var _SnapController_instances, _SnapController_closeAllConnections, _SnapController_dynamicPermissions, _SnapController_environmentEndowmentPermissions, _SnapController_excludedPermissions, _SnapController_featureFlags, _SnapController_fetchFunction, _SnapController_idleTimeCheckInterval, _SnapController_maxIdleTime, _SnapController_encryptor, _SnapController_getMnemonicSeed, _SnapController_getFeatureFlags, _SnapController_clientCryptography, _SnapController_detectSnapLocation, _SnapController_snapsRuntimeData, _SnapController_rollbackSnapshots, _SnapController_timeoutForLastRequestStatus, _SnapController_statusMachine, _SnapController_preinstalledSnaps, _SnapController_trackEvent, _SnapController_trackSnapExport, _SnapController_initializeStateMachine, _SnapController_registerMessageHandlers, _SnapController_handlePreinstalledSnaps, _SnapController_pollForLastRequestStatus, _SnapController_blockSnap, _SnapController_unblockSnap, _SnapController_assertIsInstallAllowed, _SnapController_assertCanInstallSnaps, _SnapController_assertCanUsePlatform, _SnapController_stopSnapsLastRequestPastMax, _SnapController_transition, _SnapController_terminateSnap, _SnapController_hasCachedEncryptionKey, _SnapController_getSnapEncryptionKey, _SnapController_decryptSnapState, _SnapController_encryptSnapState, _SnapController_getStateToPersist, _SnapController_persistSnapState, _SnapController_handleInitialConnections, _SnapController_addSnapToSubject, _SnapController_removeSnapFromSubjects, _SnapController_revokeAllSnapPermissions, _SnapController_createApproval, _SnapController_updateApproval, _SnapController_resolveAllowlistVersion, _SnapController_add, _SnapController_startSnap, _SnapController_getEndowments, _SnapController_set, _SnapController_validateSnapPermissions, _SnapController_validatePlatformVersion, _SnapController_getExecutionTimeout, _SnapController_getRpcRequestHandler, _SnapController_createInterface, _SnapController_assertInterfaceExists, _SnapController_transformSnapRpcResponse, _SnapController_transformOnAssetsLookupResult, _SnapController_transformOnAssetsConversionResult, _SnapController_transformSnapRpcRequest, _SnapController_assertSnapRpcResponse, _SnapController_recordSnapRpcRequestStart, _SnapController_recordSnapRpcRequestFinish, _SnapController_getRollbackSnapshot, _SnapController_createRollbackSnapshot, _SnapController_rollbackSnap, _SnapController_rollbackSnaps, _SnapController_getRuntime, _SnapController_getRuntimeExpect, _SnapController_setupRuntime, _SnapController_calculatePermissionsChange, _SnapController_isSubjectConnectedToSnap, _SnapController_calculateConnectionsChange, _SnapController_getPermissionsToGrant, _SnapController_updatePermissions, _SnapController_isValidUpdate, _SnapController_callLifecycleHook, _SnapController_handleLock;
13
+ var _SnapController_instances, _SnapController_closeAllConnections, _SnapController_dynamicPermissions, _SnapController_environmentEndowmentPermissions, _SnapController_excludedPermissions, _SnapController_featureFlags, _SnapController_fetchFunction, _SnapController_idleTimeCheckInterval, _SnapController_maxIdleTime, _SnapController_encryptor, _SnapController_getMnemonicSeed, _SnapController_getFeatureFlags, _SnapController_clientCryptography, _SnapController_detectSnapLocation, _SnapController_snapsRuntimeData, _SnapController_rollbackSnapshots, _SnapController_timeoutForLastRequestStatus, _SnapController_statusMachine, _SnapController_preinstalledSnaps, _SnapController_trackEvent, _SnapController_trackSnapExport, _SnapController_initializeStateMachine, _SnapController_registerMessageHandlers, _SnapController_handlePreinstalledSnaps, _SnapController_pollForLastRequestStatus, _SnapController_blockSnap, _SnapController_unblockSnap, _SnapController_assertIsInstallAllowed, _SnapController_assertCanInstallSnaps, _SnapController_assertCanUsePlatform, _SnapController_stopSnapsLastRequestPastMax, _SnapController_transition, _SnapController_terminateSnap, _SnapController_hasCachedEncryptionKey, _SnapController_getSnapEncryptionKey, _SnapController_decryptSnapState, _SnapController_encryptSnapState, _SnapController_getStateToPersist, _SnapController_persistSnapState, _SnapController_handleInitialConnections, _SnapController_addSnapToSubject, _SnapController_removeSnapFromSubjects, _SnapController_revokeAllSnapPermissions, _SnapController_createApproval, _SnapController_updateApproval, _SnapController_resolveAllowlistVersion, _SnapController_add, _SnapController_startSnap, _SnapController_getEndowments, _SnapController_set, _SnapController_validateSnapPermissions, _SnapController_validatePlatformVersion, _SnapController_getExecutionTimeout, _SnapController_createInterface, _SnapController_assertInterfaceExists, _SnapController_transformSnapRpcResponse, _SnapController_transformOnAssetsLookupResult, _SnapController_transformOnAssetsConversionResult, _SnapController_transformSnapRpcRequest, _SnapController_assertSnapRpcResponse, _SnapController_recordSnapRpcRequestStart, _SnapController_recordSnapRpcRequestFinish, _SnapController_getRollbackSnapshot, _SnapController_createRollbackSnapshot, _SnapController_rollbackSnap, _SnapController_rollbackSnaps, _SnapController_getRuntime, _SnapController_getRuntimeExpect, _SnapController_setupRuntime, _SnapController_calculatePermissionsChange, _SnapController_isSubjectConnectedToSnap, _SnapController_calculateConnectionsChange, _SnapController_getPermissionsToGrant, _SnapController_updatePermissions, _SnapController_isValidUpdate, _SnapController_callLifecycleHook, _SnapController_handleLock;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.SnapController = exports.SNAP_APPROVAL_RESULT = exports.SNAP_APPROVAL_UPDATE = exports.SNAP_APPROVAL_INSTALL = exports.controllerName = void 0;
16
16
  const base_controller_1 = require("@metamask/base-controller");
@@ -27,7 +27,6 @@ const semver_1 = require("semver");
27
27
  const constants_1 = require("./constants.cjs");
28
28
  const location_1 = require("./location/index.cjs");
29
29
  const registry_1 = require("./registry/index.cjs");
30
- const RequestQueue_1 = require("./RequestQueue.cjs");
31
30
  const selectors_1 = require("./selectors.cjs");
32
31
  const Timer_1 = require("./Timer.cjs");
33
32
  const fsm_2 = require("../fsm.cjs");
@@ -1081,12 +1080,49 @@ class SnapController extends base_controller_1.BaseController {
1081
1080
  constants_1.CLIENT_ONLY_HANDLERS.includes(handlerType)) {
1082
1081
  throw new Error(`"${handlerType}" can only be invoked by MetaMask.`);
1083
1082
  }
1084
- const handler = __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_getRpcRequestHandler).call(this, snapId);
1085
- if (!handler) {
1086
- throw new Error(`Snap RPC message handler not found for snap "${snapId}".`);
1083
+ if (!this.state.snaps[snapId].enabled) {
1084
+ throw new Error(`Snap "${snapId}" is disabled.`);
1085
+ }
1086
+ if (this.state.snaps[snapId].status === snaps_utils_1.SnapStatus.Installing) {
1087
+ throw new Error(`Snap "${snapId}" is currently being installed. Please try again later.`);
1087
1088
  }
1088
1089
  const timeout = __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_getExecutionTimeout).call(this, handlerPermissions);
1089
- return handler({ origin, handler: handlerType, request, timeout });
1090
+ if (!this.isRunning(snapId)) {
1091
+ const runtime = __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_getRuntimeExpect).call(this, snapId);
1092
+ if (!runtime.startPromise) {
1093
+ runtime.startPromise = this.startSnap(snapId);
1094
+ }
1095
+ try {
1096
+ await runtime.startPromise;
1097
+ }
1098
+ finally {
1099
+ runtime.startPromise = null;
1100
+ }
1101
+ }
1102
+ const transformedRequest = __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_transformSnapRpcRequest).call(this, snapId, handlerType, request);
1103
+ const timer = new Timer_1.Timer(timeout);
1104
+ __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_recordSnapRpcRequestStart).call(this, snapId, transformedRequest.id, timer);
1105
+ const handleRpcRequestPromise = this.messagingSystem.call('ExecutionService:handleRpcRequest', snapId, { origin, handler: handlerType, request: transformedRequest });
1106
+ // This will either get the result or reject due to the timeout.
1107
+ try {
1108
+ const result = await (0, utils_2.withTimeout)(handleRpcRequestPromise, timer);
1109
+ if (result === utils_2.hasTimedOut) {
1110
+ throw new Error(`${snapId} failed to respond to the request in time.`);
1111
+ }
1112
+ await __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_assertSnapRpcResponse).call(this, snapId, handlerType, result);
1113
+ const transformedResult = await __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_transformSnapRpcResponse).call(this, snapId, handlerType, transformedRequest, result);
1114
+ __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_recordSnapRpcRequestFinish).call(this, snapId, transformedRequest.id, handlerType, origin, true);
1115
+ return transformedResult;
1116
+ }
1117
+ catch (error) {
1118
+ // We flag the RPC request as finished early since termination may affect pending requests
1119
+ __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_recordSnapRpcRequestFinish).call(this, snapId, transformedRequest.id, handlerType, origin, false);
1120
+ const [jsonRpcError, handled] = (0, snaps_utils_1.unwrapError)(error);
1121
+ if (!handled) {
1122
+ await this.stopSnap(snapId, snaps_utils_1.SnapStatusEvents.Crash);
1123
+ }
1124
+ throw jsonRpcError;
1125
+ }
1090
1126
  }
1091
1127
  }
1092
1128
  exports.SnapController = SnapController;
@@ -1714,71 +1750,6 @@ async function _SnapController_getEndowments(snapId) {
1714
1750
  }
1715
1751
  }, _SnapController_getExecutionTimeout = function _SnapController_getExecutionTimeout(permission) {
1716
1752
  return (0, snaps_rpc_methods_1.getMaxRequestTimeCaveat)(permission) ?? this.maxRequestTime;
1717
- }, _SnapController_getRpcRequestHandler = function _SnapController_getRpcRequestHandler(snapId) {
1718
- const runtime = __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_getRuntimeExpect).call(this, snapId);
1719
- const existingHandler = runtime.rpcHandler;
1720
- if (existingHandler) {
1721
- return existingHandler;
1722
- }
1723
- const requestQueue = new RequestQueue_1.RequestQueue(100);
1724
- // We need to set up this promise map to map snapIds to their respective startPromises,
1725
- // because otherwise we would lose context on the correct startPromise.
1726
- const startPromises = new Map();
1727
- const rpcHandler = async ({ origin, handler: handlerType, request, timeout, }) => {
1728
- if (!this.state.snaps[snapId].enabled) {
1729
- throw new Error(`Snap "${snapId}" is disabled.`);
1730
- }
1731
- if (this.state.snaps[snapId].status === snaps_utils_1.SnapStatus.Installing) {
1732
- throw new Error(`Snap "${snapId}" is currently being installed. Please try again later.`);
1733
- }
1734
- if (!this.isRunning(snapId)) {
1735
- let localStartPromise = startPromises.get(snapId);
1736
- if (!localStartPromise) {
1737
- localStartPromise = this.startSnap(snapId);
1738
- startPromises.set(snapId, localStartPromise);
1739
- }
1740
- else if (requestQueue.get(origin) >= requestQueue.maxQueueSize) {
1741
- throw new Error('Exceeds maximum number of requests waiting to be resolved, please try again.');
1742
- }
1743
- requestQueue.increment(origin);
1744
- try {
1745
- await localStartPromise;
1746
- }
1747
- finally {
1748
- requestQueue.decrement(origin);
1749
- // Only delete startPromise for a snap if its value hasn't changed
1750
- if (startPromises.get(snapId) === localStartPromise) {
1751
- startPromises.delete(snapId);
1752
- }
1753
- }
1754
- }
1755
- const transformedRequest = __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_transformSnapRpcRequest).call(this, snapId, handlerType, request);
1756
- const timer = new Timer_1.Timer(timeout);
1757
- __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_recordSnapRpcRequestStart).call(this, snapId, transformedRequest.id, timer);
1758
- const handleRpcRequestPromise = this.messagingSystem.call('ExecutionService:handleRpcRequest', snapId, { origin, handler: handlerType, request: transformedRequest });
1759
- // This will either get the result or reject due to the timeout.
1760
- try {
1761
- const result = await (0, utils_2.withTimeout)(handleRpcRequestPromise, timer);
1762
- if (result === utils_2.hasTimedOut) {
1763
- throw new Error(`${snapId} failed to respond to the request in time.`);
1764
- }
1765
- await __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_assertSnapRpcResponse).call(this, snapId, handlerType, result);
1766
- const transformedResult = await __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_transformSnapRpcResponse).call(this, snapId, handlerType, transformedRequest, result);
1767
- __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_recordSnapRpcRequestFinish).call(this, snapId, transformedRequest.id, handlerType, origin, true);
1768
- return transformedResult;
1769
- }
1770
- catch (error) {
1771
- // We flag the RPC request as finished early since termination may affect pending requests
1772
- __classPrivateFieldGet(this, _SnapController_instances, "m", _SnapController_recordSnapRpcRequestFinish).call(this, snapId, transformedRequest.id, handlerType, origin, false);
1773
- const [jsonRpcError, handled] = (0, snaps_utils_1.unwrapError)(error);
1774
- if (!handled) {
1775
- await this.stopSnap(snapId, snaps_utils_1.SnapStatusEvents.Crash);
1776
- }
1777
- throw jsonRpcError;
1778
- }
1779
- };
1780
- runtime.rpcHandler = rpcHandler;
1781
- return rpcHandler;
1782
1753
  }, _SnapController_createInterface =
1783
1754
  /**
1784
1755
  * Create a dynamic interface in the SnapInterfaceController.
@@ -2032,7 +2003,7 @@ async function _SnapController_rollbackSnaps(snapIds) {
2032
2003
  (0, fsm_2.forceStrict)(interpreter);
2033
2004
  __classPrivateFieldGet(this, _SnapController_snapsRuntimeData, "f").set(snapId, {
2034
2005
  lastRequest: null,
2035
- rpcHandler: null,
2006
+ startPromise: null,
2036
2007
  installPromise: null,
2037
2008
  encryptionKey: null,
2038
2009
  encryptionSalt: null,