@metamask/snaps-controllers 0.38.0-flask.1 → 1.0.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 (317) hide show
  1. package/CHANGELOG.md +568 -11
  2. package/dist/{types/cronjob → cronjob}/CronjobController.d.ts +6 -7
  3. package/dist/cronjob/CronjobController.js +248 -0
  4. package/dist/cronjob/CronjobController.js.map +1 -0
  5. package/dist/cronjob/index.js +18 -0
  6. package/dist/cronjob/index.js.map +1 -0
  7. package/dist/{types/fsm.d.ts → fsm.d.ts} +1 -1
  8. package/dist/fsm.js +75 -0
  9. package/dist/fsm.js.map +1 -0
  10. package/dist/{types/index.d.ts → index.d.ts} +1 -0
  11. package/dist/index.js +22 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/logging.js +13 -0
  14. package/dist/logging.js.map +1 -0
  15. package/dist/multichain/MultiChainController.d.ts +137 -0
  16. package/dist/multichain/MultiChainController.js +339 -0
  17. package/dist/multichain/MultiChainController.js.map +1 -0
  18. package/dist/multichain/index.d.ts +3 -0
  19. package/dist/multichain/index.js +20 -0
  20. package/dist/multichain/index.js.map +1 -0
  21. package/dist/multichain/matching.d.ts +9 -0
  22. package/dist/multichain/matching.js +57 -0
  23. package/dist/multichain/matching.js.map +1 -0
  24. package/dist/multichain/middleware.d.ts +14 -0
  25. package/dist/multichain/middleware.js +42 -0
  26. package/dist/multichain/middleware.js.map +1 -0
  27. package/dist/{types/services → services}/AbstractExecutionService.d.ts +4 -4
  28. package/dist/services/AbstractExecutionService.js +318 -0
  29. package/dist/services/AbstractExecutionService.js.map +1 -0
  30. package/dist/{types/services → services}/ExecutionService.d.ts +3 -3
  31. package/dist/services/ExecutionService.js +4 -0
  32. package/dist/services/ExecutionService.js.map +1 -0
  33. package/dist/{types/services → services}/browser.d.ts +0 -2
  34. package/dist/services/browser.js +22 -0
  35. package/dist/services/browser.js.map +1 -0
  36. package/dist/{types/services → services}/iframe/IframeExecutionService.d.ts +2 -3
  37. package/dist/services/iframe/IframeExecutionService.js +30 -0
  38. package/dist/services/iframe/IframeExecutionService.js.map +1 -0
  39. package/dist/services/iframe/index.js +18 -0
  40. package/dist/services/iframe/index.js.map +1 -0
  41. package/dist/{types/services → services}/index.d.ts +0 -2
  42. package/dist/services/index.js +22 -0
  43. package/dist/services/index.js.map +1 -0
  44. package/dist/{types/services → services}/node/NodeProcessExecutionService.d.ts +3 -4
  45. package/dist/services/node/NodeProcessExecutionService.js +18 -0
  46. package/dist/services/node/NodeProcessExecutionService.js.map +1 -0
  47. package/dist/{types/services → services}/node/NodeThreadExecutionService.d.ts +2 -3
  48. package/dist/services/node/NodeThreadExecutionService.js +19 -0
  49. package/dist/services/node/NodeThreadExecutionService.js.map +1 -0
  50. package/dist/services/node/index.js +19 -0
  51. package/dist/services/node/index.js.map +1 -0
  52. package/dist/{types/services → services}/offscreen/OffscreenExecutionService.d.ts +3 -4
  53. package/dist/services/offscreen/OffscreenExecutionService.js +100 -0
  54. package/dist/services/offscreen/OffscreenExecutionService.js.map +1 -0
  55. package/dist/{types/services/ProxyPostMessageStream.d.ts → services/offscreen/OffscreenPostMessageStream.d.ts} +10 -10
  56. package/dist/services/offscreen/OffscreenPostMessageStream.js +66 -0
  57. package/dist/services/offscreen/OffscreenPostMessageStream.js.map +1 -0
  58. package/dist/services/offscreen/index.d.ts +2 -0
  59. package/dist/services/offscreen/index.js +19 -0
  60. package/dist/services/offscreen/index.js.map +1 -0
  61. package/dist/snaps/RequestQueue.js +44 -0
  62. package/dist/snaps/RequestQueue.js.map +1 -0
  63. package/dist/{types/snaps → snaps}/SnapController.d.ts +38 -62
  64. package/dist/snaps/SnapController.js +1478 -0
  65. package/dist/snaps/SnapController.js.map +1 -0
  66. package/dist/snaps/Timer.js +86 -0
  67. package/dist/snaps/Timer.js.map +1 -0
  68. package/dist/{types/snaps → snaps}/endowments/cronjob.d.ts +3 -5
  69. package/dist/snaps/endowments/cronjob.js +105 -0
  70. package/dist/snaps/endowments/cronjob.js.map +1 -0
  71. package/dist/{types/snaps → snaps}/endowments/enum.d.ts +2 -2
  72. package/dist/snaps/endowments/enum.js +15 -0
  73. package/dist/snaps/endowments/enum.js.map +1 -0
  74. package/dist/{types/snaps → snaps}/endowments/ethereum-provider.d.ts +1 -2
  75. package/dist/snaps/endowments/ethereum-provider.js +32 -0
  76. package/dist/snaps/endowments/ethereum-provider.js.map +1 -0
  77. package/dist/{types/snaps → snaps}/endowments/index.d.ts +14 -11
  78. package/dist/snaps/endowments/index.js +60 -0
  79. package/dist/snaps/endowments/index.js.map +1 -0
  80. package/dist/snaps/endowments/keyring.d.ts +40 -0
  81. package/dist/snaps/endowments/keyring.js +103 -0
  82. package/dist/snaps/endowments/keyring.js.map +1 -0
  83. package/dist/{types/snaps → snaps}/endowments/long-running.d.ts +1 -2
  84. package/dist/snaps/endowments/long-running.js +29 -0
  85. package/dist/snaps/endowments/long-running.js.map +1 -0
  86. package/dist/{types/snaps → snaps}/endowments/network-access.d.ts +1 -2
  87. package/dist/snaps/endowments/network-access.js +30 -0
  88. package/dist/snaps/endowments/network-access.js.map +1 -0
  89. package/dist/{types/snaps → snaps}/endowments/rpc.d.ts +3 -5
  90. package/dist/snaps/endowments/rpc.js +92 -0
  91. package/dist/snaps/endowments/rpc.js.map +1 -0
  92. package/dist/{types/snaps → snaps}/endowments/transaction-insight.d.ts +2 -3
  93. package/dist/snaps/endowments/transaction-insight.js +106 -0
  94. package/dist/snaps/endowments/transaction-insight.js.map +1 -0
  95. package/dist/{types/snaps → snaps}/endowments/web-assembly.d.ts +1 -2
  96. package/dist/snaps/endowments/web-assembly.js +31 -0
  97. package/dist/snaps/endowments/web-assembly.js.map +1 -0
  98. package/dist/{types/snaps → snaps}/index.d.ts +0 -2
  99. package/dist/snaps/index.js +21 -0
  100. package/dist/snaps/index.js.map +1 -0
  101. package/dist/{types/snaps → snaps}/location/http.d.ts +2 -3
  102. package/dist/{esm/snaps → snaps}/location/http.js +31 -52
  103. package/dist/snaps/location/http.js.map +1 -0
  104. package/dist/snaps/location/index.js +21 -0
  105. package/dist/snaps/location/index.js.map +1 -0
  106. package/dist/{types/snaps → snaps}/location/local.d.ts +3 -3
  107. package/dist/snaps/location/local.js +51 -0
  108. package/dist/snaps/location/local.js.map +1 -0
  109. package/dist/{types/snaps → snaps}/location/location.d.ts +2 -2
  110. package/dist/snaps/location/location.js +34 -0
  111. package/dist/snaps/location/location.js.map +1 -0
  112. package/dist/snaps/location/npm.d.ts +28 -0
  113. package/dist/{esm/snaps → snaps}/location/npm.js +117 -141
  114. package/dist/snaps/location/npm.js.map +1 -0
  115. package/dist/snaps/registry/index.js +19 -0
  116. package/dist/snaps/registry/index.js.map +1 -0
  117. package/dist/{types/snaps → snaps}/registry/json.d.ts +4 -5
  118. package/dist/snaps/registry/json.js +171 -0
  119. package/dist/snaps/registry/json.js.map +1 -0
  120. package/dist/{types/snaps → snaps}/registry/registry.d.ts +5 -5
  121. package/dist/snaps/registry/registry.js +11 -0
  122. package/dist/snaps/registry/registry.js.map +1 -0
  123. package/dist/snaps/selectors.d.ts +2 -0
  124. package/dist/snaps/selectors.js +6 -0
  125. package/dist/snaps/selectors.js.map +1 -0
  126. package/dist/{types/utils.d.ts → utils.d.ts} +14 -14
  127. package/dist/{esm/utils.js → utils.js} +30 -21
  128. package/dist/utils.js.map +1 -0
  129. package/package.json +32 -46
  130. package/dist/cjs/cronjob/CronjobController.js +0 -290
  131. package/dist/cjs/cronjob/CronjobController.js.map +0 -1
  132. package/dist/cjs/cronjob/index.js +0 -20
  133. package/dist/cjs/cronjob/index.js.map +0 -1
  134. package/dist/cjs/fsm.js +0 -69
  135. package/dist/cjs/fsm.js.map +0 -1
  136. package/dist/cjs/index.js +0 -23
  137. package/dist/cjs/index.js.map +0 -1
  138. package/dist/cjs/logging.js +0 -15
  139. package/dist/cjs/logging.js.map +0 -1
  140. package/dist/cjs/services/AbstractExecutionService.js +0 -386
  141. package/dist/cjs/services/AbstractExecutionService.js.map +0 -1
  142. package/dist/cjs/services/ExecutionService.js +0 -7
  143. package/dist/cjs/services/ExecutionService.js.map +0 -1
  144. package/dist/cjs/services/ProxyPostMessageStream.js +0 -116
  145. package/dist/cjs/services/ProxyPostMessageStream.js.map +0 -1
  146. package/dist/cjs/services/browser.js +0 -32
  147. package/dist/cjs/services/browser.js.map +0 -1
  148. package/dist/cjs/services/iframe/IframeExecutionService.js +0 -54
  149. package/dist/cjs/services/iframe/IframeExecutionService.js.map +0 -1
  150. package/dist/cjs/services/iframe/index.js +0 -20
  151. package/dist/cjs/services/iframe/index.js.map +0 -1
  152. package/dist/cjs/services/index.js +0 -32
  153. package/dist/cjs/services/index.js.map +0 -1
  154. package/dist/cjs/services/node/NodeProcessExecutionService.js +0 -30
  155. package/dist/cjs/services/node/NodeProcessExecutionService.js.map +0 -1
  156. package/dist/cjs/services/node/NodeThreadExecutionService.js +0 -30
  157. package/dist/cjs/services/node/NodeThreadExecutionService.js.map +0 -1
  158. package/dist/cjs/services/node/index.js +0 -21
  159. package/dist/cjs/services/node/index.js.map +0 -1
  160. package/dist/cjs/services/offscreen/OffscreenExecutionService.js +0 -159
  161. package/dist/cjs/services/offscreen/OffscreenExecutionService.js.map +0 -1
  162. package/dist/cjs/services/offscreen/index.js +0 -20
  163. package/dist/cjs/services/offscreen/index.js.map +0 -1
  164. package/dist/cjs/services/webworker/WebWorkerExecutionService.js +0 -148
  165. package/dist/cjs/services/webworker/WebWorkerExecutionService.js.map +0 -1
  166. package/dist/cjs/services/webworker/index.js +0 -20
  167. package/dist/cjs/services/webworker/index.js.map +0 -1
  168. package/dist/cjs/snaps/RequestQueue.js +0 -63
  169. package/dist/cjs/snaps/RequestQueue.js.map +0 -1
  170. package/dist/cjs/snaps/SnapController.js +0 -1735
  171. package/dist/cjs/snaps/SnapController.js.map +0 -1
  172. package/dist/cjs/snaps/Timer.js +0 -117
  173. package/dist/cjs/snaps/Timer.js.map +0 -1
  174. package/dist/cjs/snaps/endowments/cronjob.js +0 -100
  175. package/dist/cjs/snaps/endowments/cronjob.js.map +0 -1
  176. package/dist/cjs/snaps/endowments/enum.js +0 -23
  177. package/dist/cjs/snaps/endowments/enum.js.map +0 -1
  178. package/dist/cjs/snaps/endowments/ethereum-provider.js +0 -43
  179. package/dist/cjs/snaps/endowments/ethereum-provider.js.map +0 -1
  180. package/dist/cjs/snaps/endowments/index.js +0 -82
  181. package/dist/cjs/snaps/endowments/index.js.map +0 -1
  182. package/dist/cjs/snaps/endowments/lifecycle-hooks.js +0 -37
  183. package/dist/cjs/snaps/endowments/lifecycle-hooks.js.map +0 -1
  184. package/dist/cjs/snaps/endowments/long-running.js +0 -38
  185. package/dist/cjs/snaps/endowments/long-running.js.map +0 -1
  186. package/dist/cjs/snaps/endowments/network-access.js +0 -44
  187. package/dist/cjs/snaps/endowments/network-access.js.map +0 -1
  188. package/dist/cjs/snaps/endowments/rpc.js +0 -99
  189. package/dist/cjs/snaps/endowments/rpc.js.map +0 -1
  190. package/dist/cjs/snaps/endowments/transaction-insight.js +0 -106
  191. package/dist/cjs/snaps/endowments/transaction-insight.js.map +0 -1
  192. package/dist/cjs/snaps/endowments/web-assembly.js +0 -42
  193. package/dist/cjs/snaps/endowments/web-assembly.js.map +0 -1
  194. package/dist/cjs/snaps/index.js +0 -25
  195. package/dist/cjs/snaps/index.js.map +0 -1
  196. package/dist/cjs/snaps/location/http.js +0 -106
  197. package/dist/cjs/snaps/location/http.js.map +0 -1
  198. package/dist/cjs/snaps/location/index.js +0 -23
  199. package/dist/cjs/snaps/location/index.js.map +0 -1
  200. package/dist/cjs/snaps/location/local.js +0 -93
  201. package/dist/cjs/snaps/location/local.js.map +0 -1
  202. package/dist/cjs/snaps/location/location.js +0 -34
  203. package/dist/cjs/snaps/location/location.js.map +0 -1
  204. package/dist/cjs/snaps/location/npm.js +0 -291
  205. package/dist/cjs/snaps/location/npm.js.map +0 -1
  206. package/dist/cjs/snaps/permissions.js +0 -61
  207. package/dist/cjs/snaps/permissions.js.map +0 -1
  208. package/dist/cjs/snaps/registry/index.js +0 -21
  209. package/dist/cjs/snaps/registry/index.js.map +0 -1
  210. package/dist/cjs/snaps/registry/json.js +0 -250
  211. package/dist/cjs/snaps/registry/json.js.map +0 -1
  212. package/dist/cjs/snaps/registry/registry.js +0 -18
  213. package/dist/cjs/snaps/registry/registry.js.map +0 -1
  214. package/dist/cjs/snaps/selectors.js +0 -13
  215. package/dist/cjs/snaps/selectors.js.map +0 -1
  216. package/dist/cjs/utils.js +0 -70
  217. package/dist/cjs/utils.js.map +0 -1
  218. package/dist/esm/cronjob/CronjobController.js +0 -275
  219. package/dist/esm/cronjob/CronjobController.js.map +0 -1
  220. package/dist/esm/cronjob/index.js +0 -3
  221. package/dist/esm/cronjob/index.js.map +0 -1
  222. package/dist/esm/fsm.js +0 -70
  223. package/dist/esm/fsm.js.map +0 -1
  224. package/dist/esm/index.js +0 -6
  225. package/dist/esm/index.js.map +0 -1
  226. package/dist/esm/logging.js +0 -10
  227. package/dist/esm/logging.js.map +0 -1
  228. package/dist/esm/services/AbstractExecutionService.js +0 -369
  229. package/dist/esm/services/AbstractExecutionService.js.map +0 -1
  230. package/dist/esm/services/ExecutionService.js +0 -4
  231. package/dist/esm/services/ExecutionService.js.map +0 -1
  232. package/dist/esm/services/ProxyPostMessageStream.js +0 -109
  233. package/dist/esm/services/ProxyPostMessageStream.js.map +0 -1
  234. package/dist/esm/services/browser.js +0 -9
  235. package/dist/esm/services/browser.js.map +0 -1
  236. package/dist/esm/services/iframe/IframeExecutionService.js +0 -44
  237. package/dist/esm/services/iframe/IframeExecutionService.js.map +0 -1
  238. package/dist/esm/services/iframe/index.js +0 -3
  239. package/dist/esm/services/iframe/index.js.map +0 -1
  240. package/dist/esm/services/index.js +0 -9
  241. package/dist/esm/services/index.js.map +0 -1
  242. package/dist/esm/services/node/NodeProcessExecutionService.js +0 -20
  243. package/dist/esm/services/node/NodeProcessExecutionService.js.map +0 -1
  244. package/dist/esm/services/node/NodeThreadExecutionService.js +0 -21
  245. package/dist/esm/services/node/NodeThreadExecutionService.js.map +0 -1
  246. package/dist/esm/services/node/index.js +0 -4
  247. package/dist/esm/services/node/index.js.map +0 -1
  248. package/dist/esm/services/offscreen/OffscreenExecutionService.js +0 -149
  249. package/dist/esm/services/offscreen/OffscreenExecutionService.js.map +0 -1
  250. package/dist/esm/services/offscreen/index.js +0 -3
  251. package/dist/esm/services/offscreen/index.js.map +0 -1
  252. package/dist/esm/services/webworker/WebWorkerExecutionService.js +0 -130
  253. package/dist/esm/services/webworker/WebWorkerExecutionService.js.map +0 -1
  254. package/dist/esm/services/webworker/index.js +0 -3
  255. package/dist/esm/services/webworker/index.js.map +0 -1
  256. package/dist/esm/snaps/RequestQueue.js +0 -53
  257. package/dist/esm/snaps/RequestQueue.js.map +0 -1
  258. package/dist/esm/snaps/SnapController.js +0 -1714
  259. package/dist/esm/snaps/SnapController.js.map +0 -1
  260. package/dist/esm/snaps/Timer.js +0 -107
  261. package/dist/esm/snaps/Timer.js.map +0 -1
  262. package/dist/esm/snaps/endowments/cronjob.js +0 -99
  263. package/dist/esm/snaps/endowments/cronjob.js.map +0 -1
  264. package/dist/esm/snaps/endowments/enum.js +0 -13
  265. package/dist/esm/snaps/endowments/enum.js.map +0 -1
  266. package/dist/esm/snaps/endowments/ethereum-provider.js +0 -33
  267. package/dist/esm/snaps/endowments/ethereum-provider.js.map +0 -1
  268. package/dist/esm/snaps/endowments/index.js +0 -41
  269. package/dist/esm/snaps/endowments/index.js.map +0 -1
  270. package/dist/esm/snaps/endowments/lifecycle-hooks.js +0 -27
  271. package/dist/esm/snaps/endowments/lifecycle-hooks.js.map +0 -1
  272. package/dist/esm/snaps/endowments/long-running.js +0 -28
  273. package/dist/esm/snaps/endowments/long-running.js.map +0 -1
  274. package/dist/esm/snaps/endowments/network-access.js +0 -34
  275. package/dist/esm/snaps/endowments/network-access.js.map +0 -1
  276. package/dist/esm/snaps/endowments/rpc.js +0 -88
  277. package/dist/esm/snaps/endowments/rpc.js.map +0 -1
  278. package/dist/esm/snaps/endowments/transaction-insight.js +0 -99
  279. package/dist/esm/snaps/endowments/transaction-insight.js.map +0 -1
  280. package/dist/esm/snaps/endowments/web-assembly.js +0 -32
  281. package/dist/esm/snaps/endowments/web-assembly.js.map +0 -1
  282. package/dist/esm/snaps/index.js +0 -8
  283. package/dist/esm/snaps/index.js.map +0 -1
  284. package/dist/esm/snaps/location/http.js.map +0 -1
  285. package/dist/esm/snaps/location/index.js +0 -6
  286. package/dist/esm/snaps/location/index.js.map +0 -1
  287. package/dist/esm/snaps/location/local.js +0 -83
  288. package/dist/esm/snaps/location/local.js.map +0 -1
  289. package/dist/esm/snaps/location/location.js +0 -30
  290. package/dist/esm/snaps/location/location.js.map +0 -1
  291. package/dist/esm/snaps/location/npm.js.map +0 -1
  292. package/dist/esm/snaps/permissions.js +0 -50
  293. package/dist/esm/snaps/permissions.js.map +0 -1
  294. package/dist/esm/snaps/registry/index.js +0 -4
  295. package/dist/esm/snaps/registry/index.js.map +0 -1
  296. package/dist/esm/snaps/registry/json.js +0 -240
  297. package/dist/esm/snaps/registry/json.js.map +0 -1
  298. package/dist/esm/snaps/registry/registry.js +0 -8
  299. package/dist/esm/snaps/registry/registry.js.map +0 -1
  300. package/dist/esm/snaps/selectors.js +0 -3
  301. package/dist/esm/snaps/selectors.js.map +0 -1
  302. package/dist/esm/utils.js.map +0 -1
  303. package/dist/types/services/offscreen/index.d.ts +0 -1
  304. package/dist/types/services/webworker/WebWorkerExecutionService.d.ts +0 -45
  305. package/dist/types/services/webworker/index.d.ts +0 -1
  306. package/dist/types/snaps/endowments/lifecycle-hooks.d.ts +0 -15
  307. package/dist/types/snaps/location/npm.d.ts +0 -49
  308. package/dist/types/snaps/permissions.d.ts +0 -16
  309. package/dist/types/snaps/selectors.d.ts +0 -2
  310. /package/dist/{types/cronjob → cronjob}/index.d.ts +0 -0
  311. /package/dist/{types/logging.d.ts → logging.d.ts} +0 -0
  312. /package/dist/{types/services → services}/iframe/index.d.ts +0 -0
  313. /package/dist/{types/services → services}/node/index.d.ts +0 -0
  314. /package/dist/{types/snaps → snaps}/RequestQueue.d.ts +0 -0
  315. /package/dist/{types/snaps → snaps}/Timer.d.ts +0 -0
  316. /package/dist/{types/snaps → snaps}/location/index.d.ts +0 -0
  317. /package/dist/{types/snaps → snaps}/registry/index.d.ts +0 -0
@@ -0,0 +1,248 @@
1
+ "use strict";
2
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
+ if (kind === "m") throw new TypeError("Private method is not writable");
4
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
+ };
8
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
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
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
+ };
13
+ var _CronjobController_messenger, _CronjobController_dailyTimer, _CronjobController_timers, _CronjobController_snapIds;
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.CronjobController = exports.DAILY_TIMEOUT = void 0;
16
+ const base_controller_1 = require("@metamask/base-controller");
17
+ const snaps_utils_1 = require("@metamask/snaps-utils");
18
+ const utils_1 = require("@metamask/utils");
19
+ const __1 = require("..");
20
+ const cronjob_1 = require("../snaps/endowments/cronjob");
21
+ const Timer_1 = require("../snaps/Timer");
22
+ exports.DAILY_TIMEOUT = (0, utils_1.inMilliseconds)(24, utils_1.Duration.Hour);
23
+ const controllerName = 'CronjobController';
24
+ /**
25
+ * Use this controller to register and schedule periodically executed jobs
26
+ * using RPC method hooks.
27
+ */
28
+ class CronjobController extends base_controller_1.BaseControllerV2 {
29
+ constructor({ messenger, state }) {
30
+ super({
31
+ messenger,
32
+ metadata: {
33
+ jobs: { persist: true, anonymous: false },
34
+ },
35
+ name: controllerName,
36
+ state: {
37
+ jobs: {},
38
+ ...state,
39
+ },
40
+ });
41
+ _CronjobController_messenger.set(this, void 0);
42
+ _CronjobController_dailyTimer.set(this, void 0);
43
+ _CronjobController_timers.set(this, void 0);
44
+ // Mapping from jobId to snapId
45
+ _CronjobController_snapIds.set(this, void 0);
46
+ __classPrivateFieldSet(this, _CronjobController_timers, new Map(), "f");
47
+ __classPrivateFieldSet(this, _CronjobController_snapIds, new Map(), "f");
48
+ __classPrivateFieldSet(this, _CronjobController_messenger, messenger, "f");
49
+ this._handleEventSnapInstalled = this._handleEventSnapInstalled.bind(this);
50
+ this._handleEventSnapRemoved = this._handleEventSnapRemoved.bind(this);
51
+ this._handleEventSnapUpdated = this._handleEventSnapUpdated.bind(this);
52
+ // Subscribe to Snap events
53
+ /* eslint-disable @typescript-eslint/unbound-method */
54
+ this.messagingSystem.subscribe('SnapController:snapInstalled', this._handleEventSnapInstalled);
55
+ this.messagingSystem.subscribe('SnapController:snapRemoved', this._handleEventSnapRemoved);
56
+ this.messagingSystem.subscribe('SnapController:snapUpdated', this._handleEventSnapUpdated);
57
+ /* eslint-enable @typescript-eslint/unbound-method */
58
+ this.dailyCheckIn().catch((error) => {
59
+ (0, snaps_utils_1.logError)(error);
60
+ });
61
+ }
62
+ /**
63
+ * Retrieve all cronjob specifications for all runnable snaps.
64
+ *
65
+ * @returns Array of Cronjob specifications.
66
+ */
67
+ getAllJobs() {
68
+ const snaps = this.messagingSystem.call('SnapController:getAll');
69
+ const filteredSnaps = (0, __1.getRunnableSnaps)(snaps);
70
+ const jobs = filteredSnaps.map((snap) => this.getSnapJobs(snap.id));
71
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
72
+ return jobs.flat().filter((job) => job !== undefined);
73
+ }
74
+ /**
75
+ * Retrieve all Cronjob specifications for a Snap.
76
+ *
77
+ * @param snapId - ID of a Snap.
78
+ * @returns Array of Cronjob specifications.
79
+ */
80
+ getSnapJobs(snapId) {
81
+ const permissions = __classPrivateFieldGet(this, _CronjobController_messenger, "f").call('PermissionController:getPermissions', snapId);
82
+ const permission = permissions?.[__1.SnapEndowments.Cronjob];
83
+ const definitions = (0, cronjob_1.getCronjobCaveatJobs)(permission);
84
+ return definitions?.map((definition, idx) => {
85
+ return { ...definition, id: `${snapId}-${idx}`, snapId };
86
+ });
87
+ }
88
+ /**
89
+ * Register cron jobs for a given snap by getting specification from a permission caveats.
90
+ * Once registered, each job will be scheduled.
91
+ *
92
+ * @param snapId - ID of a snap.
93
+ */
94
+ register(snapId) {
95
+ const jobs = this.getSnapJobs(snapId);
96
+ jobs?.forEach((job) => this.schedule(job));
97
+ }
98
+ /**
99
+ * Schedule a new job.
100
+ * This will interpret the cron expression and tell the timer to execute the job
101
+ * at the next suitable point in time.
102
+ * Job last run state will be initialized afterwards.
103
+ *
104
+ * Note: Schedule will be skipped if the job's execution time is too far in the future and
105
+ * will be revisited on a daily check.
106
+ *
107
+ * @param job - Cronjob specification.
108
+ */
109
+ schedule(job) {
110
+ if (__classPrivateFieldGet(this, _CronjobController_timers, "f").has(job.id)) {
111
+ return;
112
+ }
113
+ const parsed = (0, snaps_utils_1.parseCronExpression)(job.expression);
114
+ const next = parsed.next();
115
+ const now = new Date();
116
+ const ms = next.getTime() - now.getTime();
117
+ // Don't schedule this job yet as it is too far in the future
118
+ if (ms > exports.DAILY_TIMEOUT) {
119
+ return;
120
+ }
121
+ const timer = new Timer_1.Timer(ms);
122
+ timer.start(() => {
123
+ this.executeCronjob(job).catch((error) => {
124
+ // TODO: Decide how to handle errors.
125
+ (0, snaps_utils_1.logError)(error);
126
+ });
127
+ __classPrivateFieldGet(this, _CronjobController_timers, "f").delete(job.id);
128
+ this.schedule(job);
129
+ });
130
+ this.updateJobLastRunState(job.id, 0); // 0 for init, never ran actually
131
+ __classPrivateFieldGet(this, _CronjobController_timers, "f").set(job.id, timer);
132
+ __classPrivateFieldGet(this, _CronjobController_snapIds, "f").set(job.id, job.snapId);
133
+ }
134
+ /**
135
+ * Execute job.
136
+ *
137
+ * @param job - Cronjob specification.
138
+ */
139
+ async executeCronjob(job) {
140
+ this.updateJobLastRunState(job.id, Date.now());
141
+ await __classPrivateFieldGet(this, _CronjobController_messenger, "f").call('SnapController:handleRequest', {
142
+ snapId: job.snapId,
143
+ origin: '',
144
+ handler: snaps_utils_1.HandlerType.OnCronjob,
145
+ request: job.request,
146
+ });
147
+ }
148
+ /**
149
+ * Unregister all jobs related to the given snapId.
150
+ *
151
+ * @param snapId - ID of a snap.
152
+ */
153
+ unregister(snapId) {
154
+ const jobs = [...__classPrivateFieldGet(this, _CronjobController_snapIds, "f").entries()].filter(([_, jobSnapId]) => jobSnapId === snapId);
155
+ if (jobs.length) {
156
+ jobs.forEach(([id]) => {
157
+ const timer = __classPrivateFieldGet(this, _CronjobController_timers, "f").get(id);
158
+ if (timer) {
159
+ timer.cancel();
160
+ __classPrivateFieldGet(this, _CronjobController_timers, "f").delete(id);
161
+ __classPrivateFieldGet(this, _CronjobController_snapIds, "f").delete(id);
162
+ }
163
+ });
164
+ }
165
+ }
166
+ /**
167
+ * Update time of a last run for the Cronjob specified by ID.
168
+ *
169
+ * @param jobId - ID of a cron job.
170
+ * @param lastRun - Unix timestamp when the job was last ran.
171
+ */
172
+ updateJobLastRunState(jobId, lastRun) {
173
+ this.update((state) => {
174
+ state.jobs[jobId] = {
175
+ lastRun,
176
+ };
177
+ });
178
+ }
179
+ /**
180
+ * Runs every 24 hours to check if new jobs need to be scheduled.
181
+ *
182
+ * This is necesary for longer running jobs that execute with more than 24 hours between them.
183
+ */
184
+ async dailyCheckIn() {
185
+ const jobs = this.getAllJobs();
186
+ for (const job of jobs) {
187
+ const parsed = (0, snaps_utils_1.parseCronExpression)(job.expression);
188
+ const lastRun = this.state.jobs[job.id]?.lastRun;
189
+ // If a job was supposed to run while we were shut down but wasn't we run it now
190
+ if (lastRun !== undefined &&
191
+ parsed.hasPrev() &&
192
+ parsed.prev().getTime() > lastRun) {
193
+ await this.executeCronjob(job);
194
+ }
195
+ // Try scheduling, will fail if an existing scheduled job is found
196
+ this.schedule(job);
197
+ }
198
+ __classPrivateFieldSet(this, _CronjobController_dailyTimer, new Timer_1.Timer(exports.DAILY_TIMEOUT), "f");
199
+ __classPrivateFieldGet(this, _CronjobController_dailyTimer, "f").start(() => {
200
+ this.dailyCheckIn().catch((error) => {
201
+ // TODO: Decide how to handle errors.
202
+ (0, snaps_utils_1.logError)(error);
203
+ });
204
+ });
205
+ }
206
+ /**
207
+ * Run controller teardown process and unsubscribe from Snap events.
208
+ */
209
+ destroy() {
210
+ super.destroy();
211
+ /* eslint-disable @typescript-eslint/unbound-method */
212
+ this.messagingSystem.unsubscribe('SnapController:snapInstalled', this._handleEventSnapInstalled);
213
+ this.messagingSystem.unsubscribe('SnapController:snapRemoved', this._handleEventSnapRemoved);
214
+ this.messagingSystem.unsubscribe('SnapController:snapUpdated', this._handleEventSnapUpdated);
215
+ /* eslint-enable @typescript-eslint/unbound-method */
216
+ __classPrivateFieldGet(this, _CronjobController_snapIds, "f").forEach((snapId) => {
217
+ this.unregister(snapId);
218
+ });
219
+ }
220
+ /**
221
+ * Handle cron jobs on 'snapInstalled' event.
222
+ *
223
+ * @param snap - Basic Snap information.
224
+ */
225
+ _handleEventSnapInstalled(snap) {
226
+ this.register(snap.id);
227
+ }
228
+ /**
229
+ * Handle cron jobs on 'snapRemoved' event.
230
+ *
231
+ * @param snap - Basic Snap information.
232
+ */
233
+ _handleEventSnapRemoved(snap) {
234
+ this.unregister(snap.id);
235
+ }
236
+ /**
237
+ * Handle cron jobs on 'snapUpdated' event.
238
+ *
239
+ * @param snap - Basic Snap information.
240
+ */
241
+ _handleEventSnapUpdated(snap) {
242
+ this.unregister(snap.id);
243
+ this.register(snap.id);
244
+ }
245
+ }
246
+ exports.CronjobController = CronjobController;
247
+ _CronjobController_messenger = new WeakMap(), _CronjobController_dailyTimer = new WeakMap(), _CronjobController_timers = new WeakMap(), _CronjobController_snapIds = new WeakMap();
248
+ //# sourceMappingURL=CronjobController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CronjobController.js","sourceRoot":"","sources":["../../src/cronjob/CronjobController.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BaseControllerV2 as BaseController,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport { GetPermissions } from '@metamask/permission-controller';\nimport {\n HandlerType,\n SnapId,\n TruncatedSnap,\n CronjobSpecification,\n parseCronExpression,\n logError,\n} from '@metamask/snaps-utils';\nimport { Duration, inMilliseconds } from '@metamask/utils';\n\nimport {\n GetAllSnaps,\n getRunnableSnaps,\n HandleSnapRequest,\n SnapEndowments,\n SnapInstalled,\n SnapRemoved,\n SnapUpdated,\n} from '..';\nimport { getCronjobCaveatJobs } from '../snaps/endowments/cronjob';\nimport { Timer } from '../snaps/Timer';\n\nexport type CronjobControllerActions =\n | GetAllSnaps\n | HandleSnapRequest\n | GetPermissions;\n\nexport type CronjobControllerEvents = SnapInstalled | SnapRemoved | SnapUpdated;\n\nexport type CronjobControllerMessenger = RestrictedControllerMessenger<\n 'CronjobController',\n CronjobControllerActions,\n CronjobControllerEvents,\n CronjobControllerActions['type'],\n CronjobControllerEvents['type']\n>;\n\nexport const DAILY_TIMEOUT = inMilliseconds(24, Duration.Hour);\n\nexport type CronjobControllerArgs = {\n messenger: CronjobControllerMessenger;\n /**\n * Persisted state that will be used for rehydration.\n */\n state?: CronjobControllerState;\n};\n\nexport type Cronjob = {\n timer?: Timer;\n id: string;\n snapId: SnapId;\n} & CronjobSpecification;\n\nexport type StoredJobInformation = {\n lastRun: number;\n};\n\nexport type CronjobControllerState = {\n jobs: Record<string, StoredJobInformation>;\n};\n\nconst controllerName = 'CronjobController';\n\n/**\n * Use this controller to register and schedule periodically executed jobs\n * using RPC method hooks.\n */\nexport class CronjobController extends BaseController<\n typeof controllerName,\n CronjobControllerState,\n CronjobControllerMessenger\n> {\n #messenger: CronjobControllerMessenger;\n\n #dailyTimer!: Timer;\n\n #timers: Map<string, Timer>;\n\n // Mapping from jobId to snapId\n #snapIds: Map<string, string>;\n\n constructor({ messenger, state }: CronjobControllerArgs) {\n super({\n messenger,\n metadata: {\n jobs: { persist: true, anonymous: false },\n },\n name: controllerName,\n state: {\n jobs: {},\n ...state,\n },\n });\n this.#timers = new Map();\n this.#snapIds = new Map();\n this.#messenger = messenger;\n\n this._handleEventSnapInstalled = this._handleEventSnapInstalled.bind(this);\n this._handleEventSnapRemoved = this._handleEventSnapRemoved.bind(this);\n this._handleEventSnapUpdated = this._handleEventSnapUpdated.bind(this);\n\n // Subscribe to Snap events\n /* eslint-disable @typescript-eslint/unbound-method */\n this.messagingSystem.subscribe(\n 'SnapController:snapInstalled',\n this._handleEventSnapInstalled,\n );\n\n this.messagingSystem.subscribe(\n 'SnapController:snapRemoved',\n this._handleEventSnapRemoved,\n );\n\n this.messagingSystem.subscribe(\n 'SnapController:snapUpdated',\n this._handleEventSnapUpdated,\n );\n /* eslint-enable @typescript-eslint/unbound-method */\n\n this.dailyCheckIn().catch((error) => {\n logError(error);\n });\n }\n\n /**\n * Retrieve all cronjob specifications for all runnable snaps.\n *\n * @returns Array of Cronjob specifications.\n */\n private getAllJobs(): Cronjob[] {\n const snaps = this.messagingSystem.call('SnapController:getAll');\n const filteredSnaps = getRunnableSnaps(snaps);\n\n const jobs = filteredSnaps.map((snap) => this.getSnapJobs(snap.id));\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n return jobs.flat().filter((job) => job !== undefined) as Cronjob[];\n }\n\n /**\n * Retrieve all Cronjob specifications for a Snap.\n *\n * @param snapId - ID of a Snap.\n * @returns Array of Cronjob specifications.\n */\n private getSnapJobs(snapId: SnapId): Cronjob[] | undefined {\n const permissions = this.#messenger.call(\n 'PermissionController:getPermissions',\n snapId,\n );\n\n const permission = permissions?.[SnapEndowments.Cronjob];\n const definitions = getCronjobCaveatJobs(permission);\n\n return definitions?.map((definition, idx) => {\n return { ...definition, id: `${snapId}-${idx}`, snapId };\n });\n }\n\n /**\n * Register cron jobs for a given snap by getting specification from a permission caveats.\n * Once registered, each job will be scheduled.\n *\n * @param snapId - ID of a snap.\n */\n register(snapId: SnapId) {\n const jobs = this.getSnapJobs(snapId);\n jobs?.forEach((job) => this.schedule(job));\n }\n\n /**\n * Schedule a new job.\n * This will interpret the cron expression and tell the timer to execute the job\n * at the next suitable point in time.\n * Job last run state will be initialized afterwards.\n *\n * Note: Schedule will be skipped if the job's execution time is too far in the future and\n * will be revisited on a daily check.\n *\n * @param job - Cronjob specification.\n */\n private schedule(job: Cronjob) {\n if (this.#timers.has(job.id)) {\n return;\n }\n\n const parsed = parseCronExpression(job.expression);\n const next = parsed.next();\n const now = new Date();\n const ms = next.getTime() - now.getTime();\n\n // Don't schedule this job yet as it is too far in the future\n if (ms > DAILY_TIMEOUT) {\n return;\n }\n\n const timer = new Timer(ms);\n timer.start(() => {\n this.executeCronjob(job).catch((error) => {\n // TODO: Decide how to handle errors.\n logError(error);\n });\n\n this.#timers.delete(job.id);\n this.schedule(job);\n });\n\n this.updateJobLastRunState(job.id, 0); // 0 for init, never ran actually\n this.#timers.set(job.id, timer);\n this.#snapIds.set(job.id, job.snapId);\n }\n\n /**\n * Execute job.\n *\n * @param job - Cronjob specification.\n */\n private async executeCronjob(job: Cronjob) {\n this.updateJobLastRunState(job.id, Date.now());\n await this.#messenger.call('SnapController:handleRequest', {\n snapId: job.snapId,\n origin: '',\n handler: HandlerType.OnCronjob,\n request: job.request,\n });\n }\n\n /**\n * Unregister all jobs related to the given snapId.\n *\n * @param snapId - ID of a snap.\n */\n unregister(snapId: SnapId) {\n const jobs = [...this.#snapIds.entries()].filter(\n ([_, jobSnapId]) => jobSnapId === snapId,\n );\n\n if (jobs.length) {\n jobs.forEach(([id]) => {\n const timer = this.#timers.get(id);\n if (timer) {\n timer.cancel();\n this.#timers.delete(id);\n this.#snapIds.delete(id);\n }\n });\n }\n }\n\n /**\n * Update time of a last run for the Cronjob specified by ID.\n *\n * @param jobId - ID of a cron job.\n * @param lastRun - Unix timestamp when the job was last ran.\n */\n private updateJobLastRunState(jobId: string, lastRun: number) {\n this.update((state) => {\n state.jobs[jobId] = {\n lastRun,\n };\n });\n }\n\n /**\n * Runs every 24 hours to check if new jobs need to be scheduled.\n *\n * This is necesary for longer running jobs that execute with more than 24 hours between them.\n */\n async dailyCheckIn() {\n const jobs = this.getAllJobs();\n\n for (const job of jobs) {\n const parsed = parseCronExpression(job.expression);\n const lastRun = this.state.jobs[job.id]?.lastRun;\n // If a job was supposed to run while we were shut down but wasn't we run it now\n if (\n lastRun !== undefined &&\n parsed.hasPrev() &&\n parsed.prev().getTime() > lastRun\n ) {\n await this.executeCronjob(job);\n }\n\n // Try scheduling, will fail if an existing scheduled job is found\n this.schedule(job);\n }\n\n this.#dailyTimer = new Timer(DAILY_TIMEOUT);\n this.#dailyTimer.start(() => {\n this.dailyCheckIn().catch((error) => {\n // TODO: Decide how to handle errors.\n logError(error);\n });\n });\n }\n\n /**\n * Run controller teardown process and unsubscribe from Snap events.\n */\n destroy() {\n super.destroy();\n\n /* eslint-disable @typescript-eslint/unbound-method */\n this.messagingSystem.unsubscribe(\n 'SnapController:snapInstalled',\n this._handleEventSnapInstalled,\n );\n\n this.messagingSystem.unsubscribe(\n 'SnapController:snapRemoved',\n this._handleEventSnapRemoved,\n );\n\n this.messagingSystem.unsubscribe(\n 'SnapController:snapUpdated',\n this._handleEventSnapUpdated,\n );\n /* eslint-enable @typescript-eslint/unbound-method */\n\n this.#snapIds.forEach((snapId) => {\n this.unregister(snapId);\n });\n }\n\n /**\n * Handle cron jobs on 'snapInstalled' event.\n *\n * @param snap - Basic Snap information.\n */\n private _handleEventSnapInstalled(snap: TruncatedSnap) {\n this.register(snap.id);\n }\n\n /**\n * Handle cron jobs on 'snapRemoved' event.\n *\n * @param snap - Basic Snap information.\n */\n private _handleEventSnapRemoved(snap: TruncatedSnap) {\n this.unregister(snap.id);\n }\n\n /**\n * Handle cron jobs on 'snapUpdated' event.\n *\n * @param snap - Basic Snap information.\n */\n private _handleEventSnapUpdated(snap: TruncatedSnap) {\n this.unregister(snap.id);\n this.register(snap.id);\n }\n}\n"]}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./CronjobController"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cronjob/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,sDAAoC","sourcesContent":["export * from './CronjobController';\n"]}
@@ -1,4 +1,4 @@
1
- import type { EventObject, StateMachine, Typestate } from '@xstate/fsm';
1
+ import { EventObject, StateMachine, Typestate } from '@xstate/fsm';
2
2
  /**
3
3
  * Validates the set-up of a @xstate/fsm machine.
4
4
  *
package/dist/fsm.js ADDED
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.forceStrict = exports.validateMachine = void 0;
4
+ const utils_1 = require("@metamask/utils");
5
+ const fsm_1 = require("@xstate/fsm");
6
+ /**
7
+ * Validates the set-up of a @xstate/fsm machine.
8
+ *
9
+ * 1. Ensures that all named actions in the config have a provided implementation.
10
+ *
11
+ * @param machine - The machine to validate.
12
+ * @throws {@link AssertionError}. If the validation fails.
13
+ */
14
+ function validateMachine(machine) {
15
+ (0, utils_1.assert)('_options' in machine, 'The machine is not an @xstate/fsm machine');
16
+ const typed = machine;
17
+ // 1.
18
+ const toArray = (obj) => {
19
+ if (Array.isArray(obj)) {
20
+ return obj;
21
+ }
22
+ else if (obj === undefined || obj === null) {
23
+ return [];
24
+ }
25
+ return [obj];
26
+ };
27
+ const allActions = new Set();
28
+ const addActions = (actions) => toArray(actions)
29
+ .flatMap((action) => {
30
+ if (typeof action === 'string') {
31
+ return [action];
32
+ }
33
+ (0, utils_1.assert)(typeof action === 'function');
34
+ return [];
35
+ })
36
+ .forEach(allActions.add.bind(allActions));
37
+ for (const state of Object.values(typed.config.states)) {
38
+ addActions(state.entry);
39
+ addActions(state.exit);
40
+ for (const transition of Object.values(state.on ?? {})) {
41
+ addActions(transition.actions);
42
+ }
43
+ }
44
+ allActions.forEach((action) => (0, utils_1.assert)(typed._options.actions !== undefined && action in typed._options.actions, `Action "${action}" doesn't have an implementation`));
45
+ }
46
+ exports.validateMachine = validateMachine;
47
+ /**
48
+ * Ensure that the interpreter is strict.
49
+ * Strict means that the transition must occur.
50
+ * The event must exist in .on {} state config and it's guard must succeed.
51
+ *
52
+ * The error will be thrown when an invalid `interpreter.send()` is called
53
+ * and will be bubbled there.
54
+ *
55
+ * TODO(ritave): Doesn't support self transitions.
56
+ *
57
+ * @param interpreter - The interpreter that will be force into strict mode.
58
+ * @throws {@link Error} Thrown when the transition is invalid.
59
+ */
60
+ function forceStrict(interpreter) {
61
+ // As soon as a listener subscribes, it is called. It might be called in
62
+ // an initial state which doesn't have the .changed property
63
+ let onInitialCalled = false;
64
+ interpreter.subscribe((state) => {
65
+ (0, utils_1.assert)(!onInitialCalled || state.changed, 'Invalid state transition');
66
+ onInitialCalled = true;
67
+ });
68
+ const ogSend = interpreter.send.bind(interpreter);
69
+ interpreter.send = (...args) => {
70
+ (0, utils_1.assert)(interpreter.status === fsm_1.InterpreterStatus.Running, 'Interpreter is stopped');
71
+ return ogSend(...args);
72
+ };
73
+ }
74
+ exports.forceStrict = forceStrict;
75
+ //# sourceMappingURL=fsm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fsm.js","sourceRoot":"","sources":["../src/fsm.ts"],"names":[],"mappings":";;;AAAA,2CAAyC;AACzC,qCAKqB;AAErB;;;;;;;GAOG;AACH,SAAgB,eAAe,CAI7B,OAAuD;IACvD,IAAA,cAAM,EAAC,UAAU,IAAI,OAAO,EAAE,2CAA2C,CAAC,CAAC;IAC3E,MAAM,KAAK,GAAG,OAEb,CAAC;IAEF,KAAK;IACL,MAAM,OAAO,GAAG,CAAI,GAAY,EAAO,EAAE;QACvC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YACtB,OAAO,GAAG,CAAC;SACZ;aAAM,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI,EAAE;YAC5C,OAAO,EAAE,CAAC;SACX;QACD,OAAO,CAAC,GAAG,CAAC,CAAC;IACf,CAAC,CAAC;IACF,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,MAAM,UAAU,GAAG,CAAC,OAAY,EAAE,EAAE,CAClC,OAAO,CAAC,OAAO,CAAC;SACb,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;QAClB,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;YAC9B,OAAO,CAAC,MAAM,CAAC,CAAC;SACjB;QACD,IAAA,cAAM,EAAC,OAAO,MAAM,KAAK,UAAU,CAAC,CAAC;QACrC,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;SACD,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAE9C,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAC/B,KAAK,CAAC,MAAM,CAAC,MAAM,CACpB,EAAE;QACD,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACxB,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACvB,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,MAAM,CAAM,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;YAC3D,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;SAChC;KACF;IAED,UAAU,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAC5B,IAAA,cAAM,EACJ,KAAK,CAAC,QAAQ,CAAC,OAAO,KAAK,SAAS,IAAI,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,EACxE,WAAW,MAAM,kCAAkC,CACpD,CACF,CAAC;AACJ,CAAC;AA/CD,0CA+CC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,WAAW,CAAC,WAAgD;IAC1E,wEAAwE;IACxE,4DAA4D;IAC5D,IAAI,eAAe,GAAG,KAAK,CAAC;IAC5B,WAAW,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;QAC9B,IAAA,cAAM,EAAC,CAAC,eAAe,IAAI,KAAK,CAAC,OAAO,EAAE,0BAA0B,CAAC,CAAC;QACtE,eAAe,GAAG,IAAI,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAClD,WAAW,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE;QAC7B,IAAA,cAAM,EACJ,WAAW,CAAC,MAAM,KAAK,uBAAiB,CAAC,OAAO,EAChD,wBAAwB,CACzB,CAAC;QACF,OAAO,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;IACzB,CAAC,CAAC;AACJ,CAAC;AAjBD,kCAiBC","sourcesContent":["import { assert } from '@metamask/utils';\nimport {\n EventObject,\n InterpreterStatus,\n StateMachine,\n Typestate,\n} from '@xstate/fsm';\n\n/**\n * Validates the set-up of a @xstate/fsm machine.\n *\n * 1. Ensures that all named actions in the config have a provided implementation.\n *\n * @param machine - The machine to validate.\n * @throws {@link AssertionError}. If the validation fails.\n */\nexport function validateMachine<\n TContext extends object,\n TEvent extends EventObject,\n TState extends Typestate<TContext>,\n>(machine: StateMachine.Machine<TContext, TEvent, TState>) {\n assert('_options' in machine, 'The machine is not an @xstate/fsm machine');\n const typed = machine as StateMachine.Machine<TContext, TEvent, TState> & {\n _options: { actions?: StateMachine.ActionMap<TContext, TEvent> };\n };\n\n // 1.\n const toArray = <T>(obj: T | T[]): T[] => {\n if (Array.isArray(obj)) {\n return obj;\n } else if (obj === undefined || obj === null) {\n return [];\n }\n return [obj];\n };\n const allActions = new Set<string>();\n const addActions = (actions: any) =>\n toArray(actions)\n .flatMap((action) => {\n if (typeof action === 'string') {\n return [action];\n }\n assert(typeof action === 'function');\n return [];\n })\n .forEach(allActions.add.bind(allActions));\n\n for (const state of Object.values<typeof typed.config.states[string]>(\n typed.config.states,\n )) {\n addActions(state.entry);\n addActions(state.exit);\n for (const transition of Object.values<any>(state.on ?? {})) {\n addActions(transition.actions);\n }\n }\n\n allActions.forEach((action) =>\n assert(\n typed._options.actions !== undefined && action in typed._options.actions,\n `Action \"${action}\" doesn't have an implementation`,\n ),\n );\n}\n\n/**\n * Ensure that the interpreter is strict.\n * Strict means that the transition must occur.\n * The event must exist in .on {} state config and it's guard must succeed.\n *\n * The error will be thrown when an invalid `interpreter.send()` is called\n * and will be bubbled there.\n *\n * TODO(ritave): Doesn't support self transitions.\n *\n * @param interpreter - The interpreter that will be force into strict mode.\n * @throws {@link Error} Thrown when the transition is invalid.\n */\nexport function forceStrict(interpreter: StateMachine.Service<any, any, any>) {\n // As soon as a listener subscribes, it is called. It might be called in\n // an initial state which doesn't have the .changed property\n let onInitialCalled = false;\n interpreter.subscribe((state) => {\n assert(!onInitialCalled || state.changed, 'Invalid state transition');\n onInitialCalled = true;\n });\n\n const ogSend = interpreter.send.bind(interpreter);\n interpreter.send = (...args) => {\n assert(\n interpreter.status === InterpreterStatus.Running,\n 'Interpreter is stopped',\n );\n return ogSend(...args);\n };\n}\n"]}
@@ -2,4 +2,5 @@ export type { Json } from '@metamask/utils';
2
2
  export * from './services';
3
3
  export * from './snaps';
4
4
  export * from './utils';
5
+ export * from './multichain';
5
6
  export * from './cronjob';
package/dist/index.js ADDED
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./services"), exports);
18
+ __exportStar(require("./snaps"), exports);
19
+ __exportStar(require("./utils"), exports);
20
+ __exportStar(require("./multichain"), exports);
21
+ __exportStar(require("./cronjob"), exports);
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AACA,6CAA2B;AAC3B,0CAAwB;AACxB,0CAAwB;AACxB,+CAA6B;AAC7B,4CAA0B","sourcesContent":["export type { Json } from '@metamask/utils';\nexport * from './services';\nexport * from './snaps';\nexport * from './utils';\nexport * from './multichain';\nexport * from './cronjob';\n"]}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.log = void 0;
4
+ const snaps_utils_1 = require("@metamask/snaps-utils");
5
+ const utils_1 = require("@metamask/utils");
6
+ /**
7
+ * A logging function specific to this package. The log messages don't show up
8
+ * by default, but they can be enabled by setting the environment variable:
9
+ * - `DEBUG=metamask:snaps:snaps-controllers`, or
10
+ * - `DEBUG=metamask:snaps:*` to enable all logs from `@metamask/snaps-*`.
11
+ */
12
+ exports.log = (0, utils_1.createModuleLogger)(snaps_utils_1.snapsLogger, 'snaps-controllers');
13
+ //# sourceMappingURL=logging.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.js","sourceRoot":"","sources":["../src/logging.ts"],"names":[],"mappings":";;;AAAA,uDAAoD;AACpD,2CAAqD;AAErD;;;;;GAKG;AACU,QAAA,GAAG,GAAG,IAAA,0BAAkB,EAAC,yBAAW,EAAE,mBAAmB,CAAC,CAAC","sourcesContent":["import { snapsLogger } from '@metamask/snaps-utils';\nimport { createModuleLogger } from '@metamask/utils';\n\n/**\n * A logging function specific to this package. The log messages don't show up\n * by default, but they can be enabled by setting the environment variable:\n * - `DEBUG=metamask:snaps:snaps-controllers`, or\n * - `DEBUG=metamask:snaps:*` to enable all logs from `@metamask/snaps-*`.\n */\nexport const log = createModuleLogger(snapsLogger, 'snaps-controllers');\n"]}
@@ -0,0 +1,137 @@
1
+ import { AddApprovalRequest } from '@metamask/approval-controller';
2
+ import { BaseControllerV2 as BaseController, RestrictedControllerMessenger } from '@metamask/base-controller';
3
+ import { GetPermissions, GrantPermissions, HasPermission } from '@metamask/permission-controller';
4
+ import { ChainId, ConnectArguments, NamespaceId, RequestArguments, RequestNamespace, Session, SnapId } from '@metamask/snaps-utils';
5
+ import { GetAllSnaps, HandleSnapRequest, IncrementActiveReferences, DecrementActiveReferences } from '../snaps';
6
+ declare const controllerName = "MultiChainController";
7
+ declare type AllowedActions = GetAllSnaps | IncrementActiveReferences | DecrementActiveReferences | HandleSnapRequest | GetPermissions | HasPermission | AddApprovalRequest | GrantPermissions;
8
+ declare type MultiChainControllerMessenger = RestrictedControllerMessenger<typeof controllerName, AllowedActions, never, AllowedActions['type'], never>;
9
+ declare type SessionData = {
10
+ origin: string;
11
+ requestedNamespaces: Record<NamespaceId, RequestNamespace>;
12
+ providedNamespaces: Record<NamespaceId, RequestNamespace>;
13
+ handlingSnaps: Record<NamespaceId, SnapId>;
14
+ };
15
+ declare type MultiChainControllerState = {
16
+ sessions: {
17
+ [origin: string]: SessionData;
18
+ };
19
+ };
20
+ declare type Notify = (origin: string, data: {
21
+ method: string;
22
+ params?: Record<string, unknown>;
23
+ }) => Promise<void>;
24
+ declare type MultiChainControllerArgs = {
25
+ notify: Notify;
26
+ messenger: MultiChainControllerMessenger;
27
+ };
28
+ export declare class MultiChainController extends BaseController<typeof controllerName, MultiChainControllerState, MultiChainControllerMessenger> {
29
+ #private;
30
+ /**
31
+ * Construct a new {@link MultiChainController} instance.
32
+ *
33
+ * @param args - The arguments to construct the controller with.
34
+ * @param args.messenger - The controller messenger to use.
35
+ * @param args.notify - A function that should handle JSON-RPC notifications.
36
+ */
37
+ constructor({ messenger, notify }: MultiChainControllerArgs);
38
+ /**
39
+ * Get an open session for the given origin.
40
+ *
41
+ * @param origin - The origin to get the session for.
42
+ * @returns The session, if it exists, or `undefined` otherwise.
43
+ */
44
+ getSession(origin: string): SessionData | undefined;
45
+ /**
46
+ * Close a session for the given origin.
47
+ *
48
+ * @param origin - The origin to close the session for.
49
+ * @throws If the session does not exist.
50
+ */
51
+ closeSession(origin: string): Promise<void>;
52
+ /**
53
+ * Handles a new connection from the given origin. This will create a new
54
+ * session, and close any existing session for the origin.
55
+ *
56
+ * @param origin - The origin to create the session for.
57
+ * @param connection - The connection arguments.
58
+ * @param connection.requiredNamespaces - The namespaces that the origin
59
+ * requires.
60
+ * @returns The session that was created.
61
+ */
62
+ onConnect(origin: string, connection: ConnectArguments): Promise<Session>;
63
+ /**
64
+ * Handle an incoming multichain request from the given origin. This will
65
+ * forward the request to the appropriate Snap, and return the response.
66
+ *
67
+ * @param origin - The origin to handle the request for.
68
+ * @param data - The request data.
69
+ * @param data.chainId - The chain ID for the request.
70
+ * @param data.request - The request arguments, i.e., the method and params.
71
+ * @returns The response from the Snap.
72
+ * @throws If the session does not exist, or the session does not provide the
73
+ * requested namespace.
74
+ */
75
+ onRequest(origin: string, data: {
76
+ chainId: ChainId;
77
+ request: RequestArguments;
78
+ }): Promise<unknown>;
79
+ /**
80
+ * Send a request to the given Snap. This calls the given method with the
81
+ * given arguments on the keyring class in the given Snap.
82
+ *
83
+ * @param options - The request options.
84
+ * @param options.snapId - The ID of the Snap to send the request to.
85
+ * @param options.origin - The origin of the request.
86
+ * @param options.method - The request method.
87
+ * @param options.args - The request params.
88
+ * @returns The response from the Snap.
89
+ */
90
+ private snapRequest;
91
+ /**
92
+ * Get the accounts exposed by the Snap's keyring.
93
+ *
94
+ * This also verifies that the accounts returned by the snap are valid CAIP-10
95
+ * account IDs.
96
+ *
97
+ * @param origin - The origin of the request.
98
+ * @param snapId - The ID of the Snap to get the accounts from.
99
+ * @returns The accounts, or `null` if the Snap does not have any accounts, or
100
+ * the accounts are invalid (i.e., not valid CAIP-10 account IDs).
101
+ */
102
+ private getSnapAccounts;
103
+ /**
104
+ * Get the namespaces for the given Snap, as described in the Snap's manifest.
105
+ *
106
+ * @param snap - The Snap to get the namespaces for.
107
+ * @returns The namespaces, or `null` if the Snap does not have any
108
+ * namespaces.
109
+ */
110
+ private snapToNamespaces;
111
+ /**
112
+ * Maps from an object of namespace IDs and Snap IDs, and an object of
113
+ * namespace IDs and requested namespaces, to an object of namespace IDs and
114
+ * resolved accounts, with the Snap ID providing the accounts.
115
+ *
116
+ * @param origin - The origin of the request.
117
+ * @param namespacesAndSnaps - An object of namespace IDs and Snap IDs
118
+ * providing the namespace.
119
+ * @param requestedNamespaces - An object of namespace IDs and requested
120
+ * namespaces.
121
+ * @returns An object of namespace IDs and resolved accounts, with the Snap ID
122
+ * providing the accounts.
123
+ */
124
+ private namespacesToAccounts;
125
+ /**
126
+ * If multiple Snap IDs are provided for a namespace, this method will
127
+ * determine which Snap ID to use for the namespace, by showing the user a
128
+ * prompt.
129
+ *
130
+ * @param origin - The origin of the request.
131
+ * @param possibleAccounts - An object containing the accounts provided by
132
+ * each Snap ID for each namespace.
133
+ * @returns An object containing the Snap ID to use for each namespace.
134
+ */
135
+ private resolveConflicts;
136
+ }
137
+ export {};