@metamask/snaps-jest 4.0.1 → 5.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 (217) hide show
  1. package/CHANGELOG.md +16 -1
  2. package/README.md +66 -179
  3. package/dist/cjs/environment.js +21 -82
  4. package/dist/cjs/environment.js.map +1 -1
  5. package/dist/cjs/helpers.js +118 -43
  6. package/dist/cjs/helpers.js.map +1 -1
  7. package/dist/cjs/internals/environment.js +1 -1
  8. package/dist/cjs/internals/environment.js.map +1 -1
  9. package/dist/cjs/internals/index.js +1 -4
  10. package/dist/cjs/internals/index.js.map +1 -1
  11. package/dist/cjs/internals/request.js +42 -94
  12. package/dist/cjs/internals/request.js.map +1 -1
  13. package/dist/cjs/internals/server.js +0 -4
  14. package/dist/cjs/internals/server.js.map +1 -1
  15. package/dist/cjs/internals/simulation/constants.js +29 -0
  16. package/dist/cjs/internals/simulation/constants.js.map +1 -0
  17. package/dist/cjs/internals/simulation/controllers.js +95 -0
  18. package/dist/cjs/internals/simulation/controllers.js.map +1 -0
  19. package/dist/cjs/internals/simulation/files.js +22 -0
  20. package/dist/cjs/internals/simulation/files.js.map +1 -0
  21. package/dist/cjs/internals/simulation/index.js +24 -0
  22. package/dist/cjs/internals/simulation/index.js.map +1 -0
  23. package/dist/cjs/internals/simulation/interface.js +98 -0
  24. package/dist/cjs/internals/simulation/interface.js.map +1 -0
  25. package/dist/cjs/internals/simulation/methods/constants.js +84 -0
  26. package/dist/cjs/internals/simulation/methods/constants.js.map +1 -0
  27. package/dist/cjs/internals/simulation/methods/hooks/encryption.js +33 -0
  28. package/dist/cjs/internals/simulation/methods/hooks/encryption.js.map +1 -0
  29. package/dist/cjs/internals/simulation/methods/hooks/get-locale.js +17 -0
  30. package/dist/cjs/internals/simulation/methods/hooks/get-locale.js.map +1 -0
  31. package/dist/cjs/internals/simulation/methods/hooks/index.js +25 -0
  32. package/dist/cjs/internals/simulation/methods/hooks/index.js.map +1 -0
  33. package/dist/cjs/internals/simulation/methods/hooks/interface.js +26 -0
  34. package/dist/cjs/internals/simulation/methods/hooks/interface.js.map +1 -0
  35. package/dist/cjs/internals/simulation/methods/hooks/notifications.js +66 -0
  36. package/dist/cjs/internals/simulation/methods/hooks/notifications.js.map +1 -0
  37. package/dist/cjs/internals/simulation/methods/hooks/show-dialog.js +43 -0
  38. package/dist/cjs/internals/simulation/methods/hooks/show-dialog.js.map +1 -0
  39. package/dist/cjs/internals/simulation/methods/hooks/state.js +80 -0
  40. package/dist/cjs/internals/simulation/methods/hooks/state.js.map +1 -0
  41. package/dist/cjs/internals/simulation/methods/index.js +20 -0
  42. package/dist/cjs/internals/simulation/methods/index.js.map +1 -0
  43. package/dist/cjs/internals/simulation/methods/specifications.js +81 -0
  44. package/dist/cjs/internals/simulation/methods/specifications.js.map +1 -0
  45. package/dist/cjs/internals/simulation/middleware/engine.js +31 -0
  46. package/dist/cjs/internals/simulation/middleware/engine.js.map +1 -0
  47. package/dist/cjs/internals/simulation/middleware/index.js +20 -0
  48. package/dist/cjs/internals/simulation/middleware/index.js.map +1 -0
  49. package/dist/cjs/internals/simulation/middleware/internal-methods/accounts.js +30 -0
  50. package/dist/cjs/internals/simulation/middleware/internal-methods/accounts.js.map +1 -0
  51. package/dist/cjs/internals/simulation/middleware/internal-methods/index.js +20 -0
  52. package/dist/cjs/internals/simulation/middleware/internal-methods/index.js.map +1 -0
  53. package/dist/cjs/internals/simulation/middleware/internal-methods/middleware.js +37 -0
  54. package/dist/cjs/internals/simulation/middleware/internal-methods/middleware.js.map +1 -0
  55. package/dist/cjs/internals/simulation/middleware/internal-methods/provider-state.js +23 -0
  56. package/dist/cjs/internals/simulation/middleware/internal-methods/provider-state.js.map +1 -0
  57. package/dist/cjs/internals/simulation/middleware/mock.js +23 -0
  58. package/dist/cjs/internals/simulation/middleware/mock.js.map +1 -0
  59. package/dist/cjs/internals/simulation/options.js +24 -0
  60. package/dist/cjs/internals/simulation/options.js.map +1 -0
  61. package/dist/cjs/internals/simulation/simulation.js +124 -0
  62. package/dist/cjs/internals/simulation/simulation.js.map +1 -0
  63. package/dist/cjs/internals/simulation/store/index.js +23 -0
  64. package/dist/cjs/internals/simulation/store/index.js.map +1 -0
  65. package/dist/cjs/internals/simulation/store/mocks.js +52 -0
  66. package/dist/cjs/internals/simulation/store/mocks.js.map +1 -0
  67. package/dist/cjs/internals/simulation/store/notifications.js +52 -0
  68. package/dist/cjs/internals/simulation/store/notifications.js.map +1 -0
  69. package/dist/cjs/internals/simulation/store/state.js +64 -0
  70. package/dist/cjs/internals/simulation/store/state.js.map +1 -0
  71. package/dist/cjs/internals/simulation/store/store.js +57 -0
  72. package/dist/cjs/internals/simulation/store/store.js.map +1 -0
  73. package/dist/cjs/internals/simulation/store/ui.js +48 -0
  74. package/dist/cjs/internals/simulation/store/ui.js.map +1 -0
  75. package/dist/cjs/internals/structs.js +43 -0
  76. package/dist/cjs/internals/structs.js.map +1 -1
  77. package/dist/cjs/matchers.js +5 -2
  78. package/dist/cjs/matchers.js.map +1 -1
  79. package/dist/cjs/options.js +0 -6
  80. package/dist/cjs/options.js.map +1 -1
  81. package/dist/esm/environment.js +22 -83
  82. package/dist/esm/environment.js.map +1 -1
  83. package/dist/esm/helpers.js +127 -46
  84. package/dist/esm/helpers.js.map +1 -1
  85. package/dist/esm/internals/environment.js +1 -1
  86. package/dist/esm/internals/environment.js.map +1 -1
  87. package/dist/esm/internals/index.js +1 -5
  88. package/dist/esm/internals/index.js.map +1 -1
  89. package/dist/esm/internals/request.js +61 -104
  90. package/dist/esm/internals/request.js.map +1 -1
  91. package/dist/esm/internals/server.js +1 -5
  92. package/dist/esm/internals/server.js.map +1 -1
  93. package/dist/esm/internals/simulation/constants.js +12 -0
  94. package/dist/esm/internals/simulation/constants.js.map +1 -0
  95. package/dist/esm/internals/simulation/controllers.js +90 -0
  96. package/dist/esm/internals/simulation/controllers.js.map +1 -0
  97. package/dist/esm/internals/simulation/files.js +19 -0
  98. package/dist/esm/internals/simulation/files.js.map +1 -0
  99. package/dist/esm/internals/simulation/index.js +7 -0
  100. package/dist/esm/internals/simulation/index.js.map +1 -0
  101. package/dist/esm/internals/simulation/interface.js +95 -0
  102. package/dist/esm/internals/simulation/interface.js.map +1 -0
  103. package/dist/esm/internals/simulation/methods/constants.js +69 -0
  104. package/dist/esm/internals/simulation/methods/constants.js.map +1 -0
  105. package/dist/esm/internals/simulation/methods/hooks/encryption.js +39 -0
  106. package/dist/esm/internals/simulation/methods/hooks/encryption.js.map +1 -0
  107. package/dist/esm/internals/simulation/methods/hooks/get-locale.js +13 -0
  108. package/dist/esm/internals/simulation/methods/hooks/get-locale.js.map +1 -0
  109. package/dist/esm/internals/simulation/methods/hooks/index.js +8 -0
  110. package/dist/esm/internals/simulation/methods/hooks/index.js.map +1 -0
  111. package/dist/esm/internals/simulation/methods/hooks/interface.js +18 -0
  112. package/dist/esm/internals/simulation/methods/hooks/interface.js.map +1 -0
  113. package/dist/esm/internals/simulation/methods/hooks/notifications.js +58 -0
  114. package/dist/esm/internals/simulation/methods/hooks/notifications.js.map +1 -0
  115. package/dist/esm/internals/simulation/methods/hooks/show-dialog.js +38 -0
  116. package/dist/esm/internals/simulation/methods/hooks/show-dialog.js.map +1 -0
  117. package/dist/esm/internals/simulation/methods/hooks/state.js +74 -0
  118. package/dist/esm/internals/simulation/methods/hooks/state.js.map +1 -0
  119. package/dist/esm/internals/simulation/methods/index.js +3 -0
  120. package/dist/esm/internals/simulation/methods/index.js.map +1 -0
  121. package/dist/esm/internals/simulation/methods/specifications.js +84 -0
  122. package/dist/esm/internals/simulation/methods/specifications.js.map +1 -0
  123. package/dist/esm/internals/simulation/middleware/engine.js +33 -0
  124. package/dist/esm/internals/simulation/middleware/engine.js.map +1 -0
  125. package/dist/esm/internals/simulation/middleware/index.js +3 -0
  126. package/dist/esm/internals/simulation/middleware/index.js.map +1 -0
  127. package/dist/esm/internals/simulation/middleware/internal-methods/accounts.js +31 -0
  128. package/dist/esm/internals/simulation/middleware/internal-methods/accounts.js.map +1 -0
  129. package/dist/esm/internals/simulation/middleware/internal-methods/index.js +3 -0
  130. package/dist/esm/internals/simulation/middleware/internal-methods/index.js.map +1 -0
  131. package/dist/esm/internals/simulation/middleware/internal-methods/middleware.js +37 -0
  132. package/dist/esm/internals/simulation/middleware/internal-methods/middleware.js.map +1 -0
  133. package/dist/esm/internals/simulation/middleware/internal-methods/provider-state.js +23 -0
  134. package/dist/esm/internals/simulation/middleware/internal-methods/provider-state.js.map +1 -0
  135. package/dist/esm/internals/simulation/middleware/mock.js +18 -0
  136. package/dist/esm/internals/simulation/middleware/mock.js.map +1 -0
  137. package/dist/esm/internals/simulation/options.js +20 -0
  138. package/dist/esm/internals/simulation/options.js.map +1 -0
  139. package/dist/esm/internals/simulation/simulation.js +128 -0
  140. package/dist/esm/internals/simulation/simulation.js.map +1 -0
  141. package/dist/esm/internals/simulation/store/index.js +6 -0
  142. package/dist/esm/internals/simulation/store/index.js.map +1 -0
  143. package/dist/esm/internals/simulation/store/mocks.js +32 -0
  144. package/dist/esm/internals/simulation/store/mocks.js.map +1 -0
  145. package/dist/esm/internals/simulation/store/notifications.js +30 -0
  146. package/dist/esm/internals/simulation/store/notifications.js.map +1 -0
  147. package/dist/esm/internals/simulation/store/state.js +47 -0
  148. package/dist/esm/internals/simulation/store/state.js.map +1 -0
  149. package/dist/esm/internals/simulation/store/store.js +50 -0
  150. package/dist/esm/internals/simulation/store/store.js.map +1 -0
  151. package/dist/esm/internals/simulation/store/ui.js +21 -0
  152. package/dist/esm/internals/simulation/store/ui.js.map +1 -0
  153. package/dist/esm/internals/structs.js +38 -1
  154. package/dist/esm/internals/structs.js.map +1 -1
  155. package/dist/esm/matchers.js +5 -2
  156. package/dist/esm/matchers.js.map +1 -1
  157. package/dist/esm/options.js +1 -7
  158. package/dist/esm/options.js.map +1 -1
  159. package/dist/esm/types.js.map +1 -1
  160. package/dist/types/environment.d.ts +14 -15
  161. package/dist/types/helpers.d.ts +64 -3
  162. package/dist/types/internals/index.d.ts +1 -4
  163. package/dist/types/internals/request.d.ts +38 -74
  164. package/dist/types/internals/simulation/constants.d.ts +13 -0
  165. package/dist/types/internals/simulation/controllers.d.ts +40 -0
  166. package/dist/types/internals/simulation/files.d.ts +11 -0
  167. package/dist/types/internals/simulation/index.d.ts +5 -0
  168. package/dist/types/internals/simulation/interface.d.ts +25 -0
  169. package/dist/types/internals/simulation/methods/constants.d.ts +10 -0
  170. package/dist/types/internals/simulation/methods/hooks/encryption.d.ts +29 -0
  171. package/dist/types/internals/simulation/methods/hooks/get-locale.d.ts +9 -0
  172. package/dist/types/internals/simulation/methods/hooks/index.d.ts +6 -0
  173. package/dist/types/internals/simulation/methods/hooks/interface.d.ts +16 -0
  174. package/dist/types/internals/simulation/methods/hooks/notifications.d.ts +16 -0
  175. package/dist/types/internals/simulation/methods/hooks/show-dialog.d.ts +9 -0
  176. package/dist/types/internals/simulation/methods/hooks/state.d.ts +22 -0
  177. package/dist/types/internals/simulation/methods/index.d.ts +1 -0
  178. package/dist/types/internals/simulation/methods/specifications.d.ts +56 -0
  179. package/dist/types/internals/simulation/middleware/engine.d.ts +26 -0
  180. package/dist/types/internals/simulation/middleware/index.d.ts +1 -0
  181. package/dist/types/internals/simulation/middleware/internal-methods/accounts.d.ts +18 -0
  182. package/dist/types/internals/simulation/middleware/internal-methods/index.d.ts +1 -0
  183. package/dist/types/internals/simulation/middleware/internal-methods/middleware.d.ts +22 -0
  184. package/dist/types/internals/simulation/middleware/internal-methods/provider-state.d.ts +14 -0
  185. package/dist/types/internals/simulation/middleware/mock.d.ts +10 -0
  186. package/dist/types/internals/simulation/options.d.ts +37 -0
  187. package/dist/types/internals/simulation/simulation.d.ts +98 -0
  188. package/dist/types/internals/simulation/store/index.d.ts +4 -0
  189. package/dist/types/internals/simulation/store/mocks.d.ts +35 -0
  190. package/dist/types/internals/simulation/store/notifications.d.ts +44 -0
  191. package/dist/types/internals/simulation/store/state.d.ts +55 -0
  192. package/dist/types/internals/simulation/store/store.d.ts +22 -0
  193. package/dist/types/internals/simulation/store/ui.d.ts +25 -0
  194. package/dist/types/internals/structs.d.ts +153 -0
  195. package/dist/types/options.d.ts +3 -35
  196. package/dist/types/types.d.ts +88 -41
  197. package/package.json +21 -12
  198. package/dist/cjs/internals/interface.js +0 -103
  199. package/dist/cjs/internals/interface.js.map +0 -1
  200. package/dist/cjs/internals/network.js +0 -148
  201. package/dist/cjs/internals/network.js.map +0 -1
  202. package/dist/cjs/internals/types.js +0 -6
  203. package/dist/cjs/internals/types.js.map +0 -1
  204. package/dist/cjs/internals/wait-for.js +0 -63
  205. package/dist/cjs/internals/wait-for.js.map +0 -1
  206. package/dist/esm/internals/interface.js +0 -100
  207. package/dist/esm/internals/interface.js.map +0 -1
  208. package/dist/esm/internals/network.js +0 -143
  209. package/dist/esm/internals/network.js.map +0 -1
  210. package/dist/esm/internals/types.js +0 -3
  211. package/dist/esm/internals/types.js.map +0 -1
  212. package/dist/esm/internals/wait-for.js +0 -63
  213. package/dist/esm/internals/wait-for.js.map +0 -1
  214. package/dist/types/internals/interface.d.ts +0 -25
  215. package/dist/types/internals/network.d.ts +0 -87
  216. package/dist/types/internals/types.d.ts +0 -18
  217. package/dist/types/internals/wait-for.d.ts +0 -38
@@ -8,58 +8,133 @@ Object.defineProperty(exports, "installSnap", {
8
8
  return installSnap;
9
9
  }
10
10
  });
11
+ const _snapsutils = require("@metamask/snaps-utils");
11
12
  const _utils = require("@metamask/utils");
12
- const _pptrtestinglibrary = require("pptr-testing-library");
13
+ const _superstruct = require("superstruct");
13
14
  const _internals = require("./internals");
14
- // eslint-disable-next-line @typescript-eslint/unbound-method
15
- const { getByTestId } = _pptrtestinglibrary.queries;
15
+ const _mocks = require("./internals/simulation/store/mocks");
16
16
  const log = (0, _utils.createModuleLogger)(_internals.rootLogger, 'helpers');
17
- async function installSnap(snapId = (0, _internals.getEnvironment)().snapId) {
18
- const environment = (0, _internals.getEnvironment)();
19
- log('Installing snap %s.', snapId);
20
- const page = await environment.createPage();
21
- const document = await (0, _pptrtestinglibrary.getDocument)(page);
22
- log('Setting snap ID to %s.', snapId);
23
- await page.evaluate((payload)=>{
24
- window.__SIMULATOR_API__.dispatch({
25
- type: 'configuration/setSnapId',
26
- payload
17
+ /**
18
+ * Get the options for {@link installSnap}.
19
+ *
20
+ * @param snapId - The ID of the Snap, or the options.
21
+ * @param options - The options, if any.
22
+ * @returns The options.
23
+ */ function getOptions(snapId, options) {
24
+ if (typeof snapId === 'object') {
25
+ return [
26
+ undefined,
27
+ snapId
28
+ ];
29
+ }
30
+ return [
31
+ snapId,
32
+ options
33
+ ];
34
+ }
35
+ async function installSnap(snapId, options = {}) {
36
+ const resolvedOptions = getOptions(snapId, options);
37
+ const { snapId: installedSnapId, store, executionService, runSaga, controllerMessenger } = await (0, _internals.getEnvironment)().installSnap(...resolvedOptions);
38
+ const onTransaction = async (request)=>{
39
+ log('Sending transaction %o.', request);
40
+ const { origin: transactionOrigin, chainId, ...transaction } = (0, _superstruct.create)(request, _internals.TransactionOptionsStruct);
41
+ return (0, _internals.handleRequest)({
42
+ snapId: installedSnapId,
43
+ store,
44
+ executionService,
45
+ runSaga,
46
+ controllerMessenger,
47
+ handler: _snapsutils.HandlerType.OnTransaction,
48
+ request: {
49
+ method: '',
50
+ params: {
51
+ chainId,
52
+ transaction,
53
+ transactionOrigin
54
+ }
55
+ }
56
+ });
57
+ };
58
+ const onCronjob = (request)=>{
59
+ log('Running cronjob %o.', options);
60
+ return (0, _internals.handleRequest)({
61
+ snapId: installedSnapId,
62
+ store,
63
+ executionService,
64
+ controllerMessenger,
65
+ runSaga,
66
+ handler: _snapsutils.HandlerType.OnCronjob,
67
+ request
27
68
  });
28
- }, snapId);
29
- log('Waiting for snap to install.');
30
- // eslint-disable-next-line @typescript-eslint/no-misused-promises
31
- await (0, _internals.waitFor)(async ()=>await getByTestId(document, 'status-ok'), {
32
- timeout: 10000,
33
- message: `Timed out waiting for snap to install. Make sure the snap ID ("${snapId}") is correct, and the server is running.`
34
- });
69
+ };
35
70
  return {
36
- request: (options)=>{
37
- log('Sending request %o.', options);
38
- // Note: This function is intentionally not async, so that we can access
39
- // the `getInterface` method on the response.
40
- return (0, _internals.request)(page, options);
41
- },
42
- sendTransaction: async (options = {})=>{
43
- log('Sending transaction %o.', options);
44
- return await (0, _internals.sendTransaction)(page, options);
71
+ request: (request)=>{
72
+ log('Sending request %o.', request);
73
+ return (0, _internals.handleRequest)({
74
+ snapId: installedSnapId,
75
+ store,
76
+ executionService,
77
+ controllerMessenger,
78
+ runSaga,
79
+ handler: _snapsutils.HandlerType.OnRpcRequest,
80
+ request
81
+ });
45
82
  },
46
- runCronjob: (options)=>{
47
- log('Running cronjob %o.', options);
48
- // Note: This function is intentionally not async, so that we can access
49
- // the `getInterface` method on the response.
50
- return (0, _internals.runCronjob)(page, options);
83
+ onTransaction,
84
+ sendTransaction: onTransaction,
85
+ onSignature: async (request)=>{
86
+ log('Requesting signature %o.', request);
87
+ const { origin: signatureOrigin, ...signature } = (0, _superstruct.create)(request, _internals.SignatureOptionsStruct);
88
+ return (0, _internals.handleRequest)({
89
+ snapId: installedSnapId,
90
+ store,
91
+ executionService,
92
+ controllerMessenger,
93
+ runSaga,
94
+ handler: _snapsutils.HandlerType.OnSignature,
95
+ request: {
96
+ method: '',
97
+ params: {
98
+ signature,
99
+ signatureOrigin
100
+ }
101
+ }
102
+ });
51
103
  },
52
- close: async ()=>{
53
- log('Closing page.');
54
- await page.close();
104
+ onCronjob,
105
+ runCronjob: onCronjob,
106
+ onHomePage: async ()=>{
107
+ log('Rendering home page.');
108
+ return (0, _internals.handleRequest)({
109
+ snapId: installedSnapId,
110
+ store,
111
+ executionService,
112
+ controllerMessenger,
113
+ runSaga,
114
+ handler: _snapsutils.HandlerType.OnHomePage,
115
+ request: {
116
+ method: ''
117
+ }
118
+ });
55
119
  },
56
- mock: async (options)=>{
57
- log('Mocking %o.', options);
58
- return await (0, _internals.mock)(page, options);
120
+ mockJsonRpc (mock) {
121
+ log('Mocking JSON-RPC request %o.', mock);
122
+ const { method, result } = (0, _superstruct.create)(mock, _internals.JsonRpcMockOptionsStruct);
123
+ store.dispatch((0, _mocks.addJsonRpcMock)({
124
+ method,
125
+ result
126
+ }));
127
+ return {
128
+ unmock () {
129
+ log('Unmocking JSON-RPC request %o.', mock);
130
+ store.dispatch((0, _mocks.removeJsonRpcMock)(method));
131
+ }
132
+ };
59
133
  },
60
- mockJsonRpc: async (options)=>{
61
- log('Mocking JSON-RPC %o.', options);
62
- return await (0, _internals.mockJsonRpc)(page, options);
134
+ close: async ()=>{
135
+ log('Closing execution service.');
136
+ (0, _snapsutils.logInfo)('Calling `snap.close()` is deprecated, and will be removed in a future release. Snaps are now automatically closed when the test ends.');
137
+ await executionService.terminateAllSnaps();
63
138
  }
64
139
  };
65
140
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/helpers.ts"],"sourcesContent":["import { createModuleLogger } from '@metamask/utils';\nimport { getDocument, queries } from 'pptr-testing-library';\n\nimport {\n getEnvironment,\n mock,\n waitFor,\n request,\n sendTransaction,\n runCronjob,\n mockJsonRpc,\n rootLogger,\n} from './internals';\nimport type { Snap, SnapResponse } from './types';\n\n// eslint-disable-next-line @typescript-eslint/unbound-method\nconst { getByTestId } = queries;\n\nconst log = createModuleLogger(rootLogger, 'helpers');\n\n/**\n * Load a snap into the environment. This is the main entry point for testing\n * snaps: It returns a {@link Snap} object that can be used to interact with the\n * snap.\n *\n * @example\n * ```ts\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * describe('My Snap', () => {\n * it('should do something', async () => {\n * const { request } = await installSnap('local:my-snap');\n * const response = await request({\n * method: 'foo',\n * params: ['bar'],\n * });\n * expect(response).toRespondWith('bar');\n * });\n * });\n * ```\n * @param snapId - The ID of the snap, including the prefix (`local:`). Defaults\n * to the URL of the built-in server, if it is running. This supports both\n * local snap IDs and NPM snap IDs.\n * @returns The snap.\n * @throws If the built-in server is not running, and no snap ID is provided.\n */\nexport async function installSnap(\n snapId: string = getEnvironment().snapId,\n): Promise<Snap> {\n const environment = getEnvironment();\n\n log('Installing snap %s.', snapId);\n\n const page = await environment.createPage();\n const document = await getDocument(page);\n\n log('Setting snap ID to %s.', snapId);\n await page.evaluate((payload) => {\n window.__SIMULATOR_API__.dispatch({\n type: 'configuration/setSnapId',\n payload,\n });\n }, snapId);\n\n log('Waiting for snap to install.');\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n await waitFor(async () => await getByTestId(document, 'status-ok'), {\n timeout: 10000,\n message: `Timed out waiting for snap to install. Make sure the snap ID (\"${snapId}\") is correct, and the server is running.`,\n });\n\n return {\n request: (options) => {\n log('Sending request %o.', options);\n\n // Note: This function is intentionally not async, so that we can access\n // the `getInterface` method on the response.\n return request(page, options);\n },\n\n sendTransaction: async (options = {}): Promise<SnapResponse> => {\n log('Sending transaction %o.', options);\n\n return await sendTransaction(page, options);\n },\n\n runCronjob: (options) => {\n log('Running cronjob %o.', options);\n\n // Note: This function is intentionally not async, so that we can access\n // the `getInterface` method on the response.\n return runCronjob(page, options);\n },\n\n close: async () => {\n log('Closing page.');\n\n await page.close();\n },\n\n mock: async (options) => {\n log('Mocking %o.', options);\n\n return await mock(page, options);\n },\n\n mockJsonRpc: async (options) => {\n log('Mocking JSON-RPC %o.', options);\n\n return await mockJsonRpc(page, options);\n },\n };\n}\n"],"names":["installSnap","getByTestId","queries","log","createModuleLogger","rootLogger","snapId","getEnvironment","environment","page","createPage","document","getDocument","evaluate","payload","window","__SIMULATOR_API__","dispatch","type","waitFor","timeout","message","request","options","sendTransaction","runCronjob","close","mock","mockJsonRpc"],"mappings":";;;;+BA8CsBA;;;eAAAA;;;uBA9Ca;oCACE;2BAW9B;AAGP,6DAA6D;AAC7D,MAAM,EAAEC,WAAW,EAAE,GAAGC,2BAAO;AAE/B,MAAMC,MAAMC,IAAAA,yBAAkB,EAACC,qBAAU,EAAE;AA4BpC,eAAeL,YACpBM,SAAiBC,IAAAA,yBAAc,IAAGD,MAAM;IAExC,MAAME,cAAcD,IAAAA,yBAAc;IAElCJ,IAAI,uBAAuBG;IAE3B,MAAMG,OAAO,MAAMD,YAAYE,UAAU;IACzC,MAAMC,WAAW,MAAMC,IAAAA,+BAAW,EAACH;IAEnCN,IAAI,0BAA0BG;IAC9B,MAAMG,KAAKI,QAAQ,CAAC,CAACC;QACnBC,OAAOC,iBAAiB,CAACC,QAAQ,CAAC;YAChCC,MAAM;YACNJ;QACF;IACF,GAAGR;IAEHH,IAAI;IACJ,kEAAkE;IAClE,MAAMgB,IAAAA,kBAAO,EAAC,UAAY,MAAMlB,YAAYU,UAAU,cAAc;QAClES,SAAS;QACTC,SAAS,CAAC,+DAA+D,EAAEf,OAAO,yCAAyC,CAAC;IAC9H;IAEA,OAAO;QACLgB,SAAS,CAACC;YACRpB,IAAI,uBAAuBoB;YAE3B,wEAAwE;YACxE,6CAA6C;YAC7C,OAAOD,IAAAA,kBAAO,EAACb,MAAMc;QACvB;QAEAC,iBAAiB,OAAOD,UAAU,CAAC,CAAC;YAClCpB,IAAI,2BAA2BoB;YAE/B,OAAO,MAAMC,IAAAA,0BAAe,EAACf,MAAMc;QACrC;QAEAE,YAAY,CAACF;YACXpB,IAAI,uBAAuBoB;YAE3B,wEAAwE;YACxE,6CAA6C;YAC7C,OAAOE,IAAAA,qBAAU,EAAChB,MAAMc;QAC1B;QAEAG,OAAO;YACLvB,IAAI;YAEJ,MAAMM,KAAKiB,KAAK;QAClB;QAEAC,MAAM,OAAOJ;YACXpB,IAAI,eAAeoB;YAEnB,OAAO,MAAMI,IAAAA,eAAI,EAAClB,MAAMc;QAC1B;QAEAK,aAAa,OAAOL;YAClBpB,IAAI,wBAAwBoB;YAE5B,OAAO,MAAMK,IAAAA,sBAAW,EAACnB,MAAMc;QACjC;IACF;AACF"}
1
+ {"version":3,"sources":["../../src/helpers.ts"],"sourcesContent":["import type { AbstractExecutionService } from '@metamask/snaps-controllers';\nimport type { SnapId } from '@metamask/snaps-sdk';\nimport { HandlerType, logInfo } from '@metamask/snaps-utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { create } from 'superstruct';\n\nimport {\n rootLogger,\n handleRequest,\n TransactionOptionsStruct,\n getEnvironment,\n JsonRpcMockOptionsStruct,\n SignatureOptionsStruct,\n} from './internals';\nimport type { InstallSnapOptions } from './internals';\nimport {\n addJsonRpcMock,\n removeJsonRpcMock,\n} from './internals/simulation/store/mocks';\nimport type {\n CronjobOptions,\n JsonRpcMockOptions,\n Snap,\n SnapResponse,\n TransactionOptions,\n} from './types';\n\nconst log = createModuleLogger(rootLogger, 'helpers');\n\n/**\n * Get the options for {@link installSnap}.\n *\n * @param snapId - The ID of the Snap, or the options.\n * @param options - The options, if any.\n * @returns The options.\n */\nfunction getOptions<\n Service extends new (...args: any[]) => InstanceType<\n typeof AbstractExecutionService\n >,\n>(\n snapId: SnapId | Partial<InstallSnapOptions<Service>> | undefined,\n options: Partial<InstallSnapOptions<Service>>,\n): [SnapId | undefined, Partial<InstallSnapOptions<Service>>] {\n if (typeof snapId === 'object') {\n return [undefined, snapId];\n }\n\n return [snapId, options];\n}\n\n/**\n * Load a snap into the environment. This is the main entry point for testing\n * snaps: It returns a {@link Snap} object that can be used to interact with the\n * snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * describe('My Snap', () => {\n * it('should do something', async () => {\n * const { request } = await installSnap('local:my-snap');\n * const response = await request({\n * method: 'foo',\n * params: ['bar'],\n * });\n * expect(response).toRespondWith('bar');\n * });\n * });\n * @returns The snap.\n * @throws If the built-in server is not running, and no snap ID is provided.\n */\nexport async function installSnap(): Promise<Snap>;\n\n/**\n * Load a snap into the environment. This is the main entry point for testing\n * snaps: It returns a {@link Snap} object that can be used to interact with the\n * snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * describe('My Snap', () => {\n * it('should do something', async () => {\n * const { request } = await installSnap('local:my-snap');\n * const response = await request({\n * method: 'foo',\n * params: ['bar'],\n * });\n * expect(response).toRespondWith('bar');\n * });\n * });\n * @param options - The options to use.\n * @param options.executionService - The execution service to use. Defaults to\n * {@link NodeThreadExecutionService}. You do not need to provide this unless\n * you are testing a custom execution service.\n * @param options.executionServiceOptions - The options to use when creating the\n * execution service, if any. This should only include options specific to the\n * provided execution service.\n * @param options.options - The simulation options.\n * @returns The snap.\n * @throws If the built-in server is not running, and no snap ID is provided.\n */\nexport async function installSnap<\n Service extends new (...args: any[]) => InstanceType<\n typeof AbstractExecutionService\n >,\n>(options: Partial<InstallSnapOptions<Service>>): Promise<Snap>;\n\n/**\n * Load a snap into the environment. This is the main entry point for testing\n * snaps: It returns a {@link Snap} object that can be used to interact with the\n * snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * describe('My Snap', () => {\n * it('should do something', async () => {\n * const { request } = await installSnap('local:my-snap');\n * const response = await request({\n * method: 'foo',\n * params: ['bar'],\n * });\n * expect(response).toRespondWith('bar');\n * });\n * });\n * @param snapId - The ID of the snap, including the prefix (`local:`). Defaults\n * to the URL of the built-in server, if it is running. This supports both\n * local snap IDs and NPM snap IDs.\n * @param options - The options to use.\n * @param options.executionService - The execution service to use. Defaults to\n * {@link NodeThreadExecutionService}. You do not need to provide this unless\n * you are testing a custom execution service.\n * @param options.executionServiceOptions - The options to use when creating the\n * execution service, if any. This should only include options specific to the\n * provided execution service.\n * @param options.options - The simulation options.\n * @returns The snap.\n * @throws If the built-in server is not running, and no snap ID is provided.\n */\nexport async function installSnap<\n Service extends new (...args: any[]) => InstanceType<\n typeof AbstractExecutionService\n >,\n>(\n snapId: SnapId,\n options?: Partial<InstallSnapOptions<Service>>,\n): Promise<Snap>;\n\n/**\n * Load a snap into the environment. This is the main entry point for testing\n * snaps: It returns a {@link Snap} object that can be used to interact with the\n * snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * describe('My Snap', () => {\n * it('should do something', async () => {\n * const { request } = await installSnap('local:my-snap');\n * const response = await request({\n * method: 'foo',\n * params: ['bar'],\n * });\n * expect(response).toRespondWith('bar');\n * });\n * });\n * @param snapId - The ID of the snap, including the prefix (`local:`). Defaults\n * to the URL of the built-in server, if it is running. This supports both\n * local snap IDs and NPM snap IDs.\n * @param options - The options to use.\n * @param options.executionService - The execution service to use. Defaults to\n * {@link NodeThreadExecutionService}. You do not need to provide this unless\n * you are testing a custom execution service.\n * @param options.executionServiceOptions - The options to use when creating the\n * execution service, if any. This should only include options specific to the\n * provided execution service.\n * @param options.options - The simulation options.\n * @returns The snap.\n * @throws If the built-in server is not running, and no snap ID is provided.\n */\nexport async function installSnap<\n Service extends new (...args: any[]) => InstanceType<\n typeof AbstractExecutionService\n >,\n>(\n snapId?: SnapId | Partial<InstallSnapOptions<Service>>,\n options: Partial<InstallSnapOptions<Service>> = {},\n): Promise<Snap> {\n const resolvedOptions = getOptions(snapId, options);\n const {\n snapId: installedSnapId,\n store,\n executionService,\n runSaga,\n controllerMessenger,\n } = await getEnvironment().installSnap(...resolvedOptions);\n\n const onTransaction = async (\n request: TransactionOptions,\n ): Promise<SnapResponse> => {\n log('Sending transaction %o.', request);\n\n const {\n origin: transactionOrigin,\n chainId,\n ...transaction\n } = create(request, TransactionOptionsStruct);\n\n return handleRequest({\n snapId: installedSnapId,\n store,\n executionService,\n runSaga,\n controllerMessenger,\n handler: HandlerType.OnTransaction,\n request: {\n method: '',\n params: {\n chainId,\n transaction,\n transactionOrigin,\n },\n },\n });\n };\n\n const onCronjob = (request: CronjobOptions) => {\n log('Running cronjob %o.', options);\n\n return handleRequest({\n snapId: installedSnapId,\n store,\n executionService,\n controllerMessenger,\n runSaga,\n handler: HandlerType.OnCronjob,\n request,\n });\n };\n\n return {\n request: (request) => {\n log('Sending request %o.', request);\n\n return handleRequest({\n snapId: installedSnapId,\n store,\n executionService,\n controllerMessenger,\n runSaga,\n handler: HandlerType.OnRpcRequest,\n request,\n });\n },\n\n onTransaction,\n sendTransaction: onTransaction,\n\n onSignature: async (request: unknown): Promise<SnapResponse> => {\n log('Requesting signature %o.', request);\n\n const { origin: signatureOrigin, ...signature } = create(\n request,\n SignatureOptionsStruct,\n );\n\n return handleRequest({\n snapId: installedSnapId,\n store,\n executionService,\n controllerMessenger,\n runSaga,\n handler: HandlerType.OnSignature,\n request: {\n method: '',\n params: {\n signature,\n signatureOrigin,\n },\n },\n });\n },\n\n onCronjob,\n runCronjob: onCronjob,\n\n onHomePage: async (): Promise<SnapResponse> => {\n log('Rendering home page.');\n\n return handleRequest({\n snapId: installedSnapId,\n store,\n executionService,\n controllerMessenger,\n runSaga,\n handler: HandlerType.OnHomePage,\n request: {\n method: '',\n },\n });\n },\n\n mockJsonRpc(mock: JsonRpcMockOptions) {\n log('Mocking JSON-RPC request %o.', mock);\n\n const { method, result } = create(mock, JsonRpcMockOptionsStruct);\n store.dispatch(addJsonRpcMock({ method, result }));\n\n return {\n unmock() {\n log('Unmocking JSON-RPC request %o.', mock);\n\n store.dispatch(removeJsonRpcMock(method));\n },\n };\n },\n\n close: async () => {\n log('Closing execution service.');\n logInfo(\n 'Calling `snap.close()` is deprecated, and will be removed in a future release. Snaps are now automatically closed when the test ends.',\n );\n\n await executionService.terminateAllSnaps();\n },\n };\n}\n"],"names":["installSnap","log","createModuleLogger","rootLogger","getOptions","snapId","options","undefined","resolvedOptions","installedSnapId","store","executionService","runSaga","controllerMessenger","getEnvironment","onTransaction","request","origin","transactionOrigin","chainId","transaction","create","TransactionOptionsStruct","handleRequest","handler","HandlerType","OnTransaction","method","params","onCronjob","OnCronjob","OnRpcRequest","sendTransaction","onSignature","signatureOrigin","signature","SignatureOptionsStruct","OnSignature","runCronjob","onHomePage","OnHomePage","mockJsonRpc","mock","result","JsonRpcMockOptionsStruct","dispatch","addJsonRpcMock","unmock","removeJsonRpcMock","close","logInfo","terminateAllSnaps"],"mappings":";;;;+BAsLsBA;;;eAAAA;;;4BApLe;uBACF;6BACZ;2BAShB;uBAKA;AASP,MAAMC,MAAMC,IAAAA,yBAAkB,EAACC,qBAAU,EAAE;AAE3C;;;;;;CAMC,GACD,SAASC,WAKPC,MAAiE,EACjEC,OAA6C;IAE7C,IAAI,OAAOD,WAAW,UAAU;QAC9B,OAAO;YAACE;YAAWF;SAAO;IAC5B;IAEA,OAAO;QAACA;QAAQC;KAAQ;AAC1B;AAqIO,eAAeN,YAKpBK,MAAsD,EACtDC,UAAgD,CAAC,CAAC;IAElD,MAAME,kBAAkBJ,WAAWC,QAAQC;IAC3C,MAAM,EACJD,QAAQI,eAAe,EACvBC,KAAK,EACLC,gBAAgB,EAChBC,OAAO,EACPC,mBAAmB,EACpB,GAAG,MAAMC,IAAAA,yBAAc,IAAGd,WAAW,IAAIQ;IAE1C,MAAMO,gBAAgB,OACpBC;QAEAf,IAAI,2BAA2Be;QAE/B,MAAM,EACJC,QAAQC,iBAAiB,EACzBC,OAAO,EACP,GAAGC,aACJ,GAAGC,IAAAA,mBAAM,EAACL,SAASM,mCAAwB;QAE5C,OAAOC,IAAAA,wBAAa,EAAC;YACnBlB,QAAQI;YACRC;YACAC;YACAC;YACAC;YACAW,SAASC,uBAAW,CAACC,aAAa;YAClCV,SAAS;gBACPW,QAAQ;gBACRC,QAAQ;oBACNT;oBACAC;oBACAF;gBACF;YACF;QACF;IACF;IAEA,MAAMW,YAAY,CAACb;QACjBf,IAAI,uBAAuBK;QAE3B,OAAOiB,IAAAA,wBAAa,EAAC;YACnBlB,QAAQI;YACRC;YACAC;YACAE;YACAD;YACAY,SAASC,uBAAW,CAACK,SAAS;YAC9Bd;QACF;IACF;IAEA,OAAO;QACLA,SAAS,CAACA;YACRf,IAAI,uBAAuBe;YAE3B,OAAOO,IAAAA,wBAAa,EAAC;gBACnBlB,QAAQI;gBACRC;gBACAC;gBACAE;gBACAD;gBACAY,SAASC,uBAAW,CAACM,YAAY;gBACjCf;YACF;QACF;QAEAD;QACAiB,iBAAiBjB;QAEjBkB,aAAa,OAAOjB;YAClBf,IAAI,4BAA4Be;YAEhC,MAAM,EAAEC,QAAQiB,eAAe,EAAE,GAAGC,WAAW,GAAGd,IAAAA,mBAAM,EACtDL,SACAoB,iCAAsB;YAGxB,OAAOb,IAAAA,wBAAa,EAAC;gBACnBlB,QAAQI;gBACRC;gBACAC;gBACAE;gBACAD;gBACAY,SAASC,uBAAW,CAACY,WAAW;gBAChCrB,SAAS;oBACPW,QAAQ;oBACRC,QAAQ;wBACNO;wBACAD;oBACF;gBACF;YACF;QACF;QAEAL;QACAS,YAAYT;QAEZU,YAAY;YACVtC,IAAI;YAEJ,OAAOsB,IAAAA,wBAAa,EAAC;gBACnBlB,QAAQI;gBACRC;gBACAC;gBACAE;gBACAD;gBACAY,SAASC,uBAAW,CAACe,UAAU;gBAC/BxB,SAAS;oBACPW,QAAQ;gBACV;YACF;QACF;QAEAc,aAAYC,IAAwB;YAClCzC,IAAI,gCAAgCyC;YAEpC,MAAM,EAAEf,MAAM,EAAEgB,MAAM,EAAE,GAAGtB,IAAAA,mBAAM,EAACqB,MAAME,mCAAwB;YAChElC,MAAMmC,QAAQ,CAACC,IAAAA,qBAAc,EAAC;gBAAEnB;gBAAQgB;YAAO;YAE/C,OAAO;gBACLI;oBACE9C,IAAI,kCAAkCyC;oBAEtChC,MAAMmC,QAAQ,CAACG,IAAAA,wBAAiB,EAACrB;gBACnC;YACF;QACF;QAEAsB,OAAO;YACLhD,IAAI;YACJiD,IAAAA,mBAAO,EACL;YAGF,MAAMvC,iBAAiBwC,iBAAiB;QAC1C;IACF;AACF"}
@@ -12,7 +12,7 @@ const _utils = require("@metamask/utils");
12
12
  function getEnvironment() {
13
13
  // `snapsEnvironment` is a global variable that is set by the Jest
14
14
  // environment.
15
- (0, _utils.assert)(snapsEnvironment, 'Snaps environment not found. Make sure you have configured the environment correctly.');
15
+ (0, _utils.assert)(typeof snapsEnvironment !== 'undefined', 'Snaps environment not found. Make sure you have configured the environment correctly.');
16
16
  return snapsEnvironment;
17
17
  }
18
18
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/internals/environment.ts"],"sourcesContent":["import { assert } from '@metamask/utils';\n\n/**\n * Get the Snaps environment. This asserts that the environment has been\n * configured.\n *\n * @returns The Snaps environment.\n */\nexport function getEnvironment() {\n // `snapsEnvironment` is a global variable that is set by the Jest\n // environment.\n assert(\n snapsEnvironment,\n 'Snaps environment not found. Make sure you have configured the environment correctly.',\n );\n\n return snapsEnvironment;\n}\n"],"names":["getEnvironment","assert","snapsEnvironment"],"mappings":";;;;+BAQgBA;;;eAAAA;;;uBARO;AAQhB,SAASA;IACd,kEAAkE;IAClE,eAAe;IACfC,IAAAA,aAAM,EACJC,kBACA;IAGF,OAAOA;AACT"}
1
+ {"version":3,"sources":["../../../src/internals/environment.ts"],"sourcesContent":["import { assert } from '@metamask/utils';\n\n/**\n * Get the Snaps environment. This asserts that the environment has been\n * configured.\n *\n * @returns The Snaps environment.\n */\nexport function getEnvironment() {\n // `snapsEnvironment` is a global variable that is set by the Jest\n // environment.\n assert(\n typeof snapsEnvironment !== 'undefined',\n 'Snaps environment not found. Make sure you have configured the environment correctly.',\n );\n\n return snapsEnvironment;\n}\n"],"names":["getEnvironment","assert","snapsEnvironment"],"mappings":";;;;+BAQgBA;;;eAAAA;;;uBARO;AAQhB,SAASA;IACd,kEAAkE;IAClE,eAAe;IACfC,IAAAA,aAAM,EACJ,OAAOC,qBAAqB,aAC5B;IAGF,OAAOA;AACT"}
@@ -3,14 +3,11 @@ Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
5
  _export_star(require("./environment"), exports);
6
- _export_star(require("./interface"), exports);
7
6
  _export_star(require("./logger"), exports);
8
- _export_star(require("./network"), exports);
9
7
  _export_star(require("./request"), exports);
10
8
  _export_star(require("./server"), exports);
9
+ _export_star(require("./simulation"), exports);
11
10
  _export_star(require("./structs"), exports);
12
- _export_star(require("./types"), exports);
13
- _export_star(require("./wait-for"), exports);
14
11
  function _export_star(from, to) {
15
12
  Object.keys(from).forEach(function(k) {
16
13
  if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/internals/index.ts"],"sourcesContent":["export * from './environment';\nexport * from './interface';\nexport * from './logger';\nexport * from './network';\nexport * from './request';\nexport * from './server';\nexport * from './structs';\n// eslint-disable-next-line import/export\nexport * from './types';\nexport * from './wait-for';\n"],"names":[],"mappings":";;;;qBAAc;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBAEA;qBACA"}
1
+ {"version":3,"sources":["../../../src/internals/index.ts"],"sourcesContent":["export * from './environment';\nexport * from './logger';\nexport * from './request';\nexport * from './server';\nexport * from './simulation';\nexport * from './structs';\n"],"names":[],"mappings":";;;;qBAAc;qBACA;qBACA;qBACA;qBACA;qBACA"}
@@ -9,113 +9,61 @@ function _export(target, all) {
9
9
  });
10
10
  }
11
11
  _export(exports, {
12
- request: function() {
13
- return request;
12
+ handleRequest: function() {
13
+ return handleRequest;
14
14
  },
15
- sendTransaction: function() {
16
- return sendTransaction;
17
- },
18
- runCronjob: function() {
19
- return runCronjob;
15
+ getContentFromResult: function() {
16
+ return getContentFromResult;
20
17
  }
21
18
  });
22
19
  const _snapsutils = require("@metamask/snaps-utils");
23
20
  const _utils = require("@metamask/utils");
24
- const _pptrtestinglibrary = require("pptr-testing-library");
25
- const _superstruct = require("superstruct");
26
- const _interface = require("./interface");
27
- const _logger = require("./logger");
28
- const _structs = require("./structs");
29
- const _waitfor = require("./wait-for");
30
- const log = (0, _utils.createModuleLogger)(_logger.rootLogger, 'request');
31
- /**
32
- * Send a request to the snap.
33
- *
34
- * @param page - The page to send the request from.
35
- * @param args - The request arguments.
36
- * @returns The request ID.
37
- */ async function sendRequest(page, args) {
38
- const document = await (0, _pptrtestinglibrary.getDocument)(page);
39
- const button = await _pptrtestinglibrary.queries.getByTestId(document, `navigation-${args.handler}`);
40
- // Navigate to the request handler page.
41
- await button.click();
42
- return await page.evaluate((payload)=>{
43
- window.__SIMULATOR_API__.dispatch({
44
- type: 'simulation/sendRequest',
45
- payload
46
- });
47
- return window.__SIMULATOR_API__.getRequestId();
48
- }, args);
49
- }
50
- function request(page, { origin = 'metamask.io', ...options }, handler = _snapsutils.HandlerType.OnRpcRequest) {
51
- const doRequest = async ()=>{
52
- const args = {
53
- origin,
54
- handler,
55
- request: {
56
- jsonrpc: '2.0',
57
- id: 1,
58
- ...options
59
- }
60
- };
61
- log('Sending request %o', args);
62
- const promise = (0, _waitfor.waitForResponse)(page, handler);
63
- const id = await sendRequest(page, args);
64
- const response = await promise;
65
- log('Received response %o', response);
66
- const notifications = await (0, _interface.getNotifications)(page, id);
67
- return {
68
- id,
69
- response,
70
- notifications
71
- };
72
- };
73
- // This is a bit hacky, but it allows us to add the `getInterface` method
74
- // to the response promise.
75
- const response = doRequest();
76
- response.getInterface = async (getInterfaceOptions)=>{
77
- return await (0, _interface.getInterface)(page, getInterfaceOptions);
78
- };
79
- return response;
80
- }
81
- async function sendTransaction(page, options) {
82
- const { origin: transactionOrigin, chainId, ...transaction } = (0, _superstruct.create)(options, _structs.TransactionOptionsStruct);
83
- const args = {
84
- origin: '',
85
- handler: _snapsutils.HandlerType.OnTransaction,
21
+ const _toolkit = require("@reduxjs/toolkit");
22
+ const _simulation = require("./simulation");
23
+ function handleRequest({ snapId, store, executionService, handler, controllerMessenger, runSaga, request: { id = (0, _toolkit.nanoid)(), origin = 'https://metamask.io', ...options } }) {
24
+ const promise = executionService.handleRpcRequest(snapId, {
25
+ origin,
26
+ handler,
86
27
  request: {
87
28
  jsonrpc: '2.0',
88
- method: '',
89
- params: {
90
- chainId,
91
- transaction,
92
- transactionOrigin
93
- }
29
+ id: 1,
30
+ ...options
94
31
  }
95
- };
96
- log('Sending transaction %o', args);
97
- const promise = (0, _waitfor.waitForResponse)(page, _snapsutils.HandlerType.OnTransaction);
98
- const id = await sendRequest(page, args);
99
- const response = await promise;
100
- log('Received response %o', response);
101
- if ((0, _utils.hasProperty)(response, 'error')) {
32
+ }).then((result)=>{
33
+ const notifications = (0, _simulation.getNotifications)(store.getState());
34
+ store.dispatch((0, _simulation.clearNotifications)());
35
+ const content = getContentFromResult(result, snapId, controllerMessenger);
36
+ return {
37
+ id: String(id),
38
+ response: {
39
+ result: (0, _utils.getSafeJson)(result)
40
+ },
41
+ notifications,
42
+ content
43
+ };
44
+ }).catch((error)=>{
45
+ const [unwrappedError] = (0, _snapsutils.unwrapError)(error);
102
46
  return {
103
- id,
104
- response,
47
+ id: String(id),
48
+ response: {
49
+ error: unwrappedError.serialize()
50
+ },
105
51
  notifications: []
106
52
  };
107
- }
108
- (0, _utils.assert)((0, _utils.isPlainObject)(response.result));
109
- (0, _utils.assert)((0, _utils.hasProperty)(response.result, 'content'));
110
- return {
111
- id,
112
- response,
113
- notifications: [],
114
- content: response.result.content
53
+ });
54
+ promise.getInterface = async ()=>{
55
+ return await runSaga(_simulation.getInterface, runSaga, snapId, controllerMessenger).toPromise();
115
56
  };
57
+ return promise;
116
58
  }
117
- function runCronjob(page, options) {
118
- return request(page, options, _snapsutils.HandlerType.OnCronjob);
59
+ function getContentFromResult(result, snapId, controllerMessenger) {
60
+ if ((0, _utils.isPlainObject)(result) && (0, _utils.hasProperty)(result, 'id')) {
61
+ return controllerMessenger.call('SnapInterfaceController:getInterface', snapId, result.id).content;
62
+ }
63
+ if ((0, _utils.isPlainObject)(result) && (0, _utils.hasProperty)(result, 'content')) {
64
+ return result.content;
65
+ }
66
+ return undefined;
119
67
  }
120
68
 
121
69
  //# sourceMappingURL=request.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/internals/request.ts"],"sourcesContent":["import type { Component } from '@metamask/snaps-sdk';\nimport type { SnapRpcHookArgs } from '@metamask/snaps-utils';\nimport { HandlerType } from '@metamask/snaps-utils';\nimport {\n assert,\n createModuleLogger,\n hasProperty,\n isPlainObject,\n} from '@metamask/utils';\nimport { getDocument, queries } from 'pptr-testing-library';\nimport type { Page } from 'puppeteer';\nimport { create } from 'superstruct';\n\nimport type {\n CronjobOptions,\n RequestOptions,\n SnapRequest,\n SnapResponse,\n TransactionOptions,\n} from '../types';\nimport { getInterface, getNotifications } from './interface';\nimport { rootLogger } from './logger';\nimport { TransactionOptionsStruct } from './structs';\nimport { waitForResponse } from './wait-for';\n\nconst log = createModuleLogger(rootLogger, 'request');\n\n/**\n * Send a request to the snap.\n *\n * @param page - The page to send the request from.\n * @param args - The request arguments.\n * @returns The request ID.\n */\nasync function sendRequest(page: Page, args: SnapRpcHookArgs) {\n const document = await getDocument(page);\n const button = await queries.getByTestId(\n document,\n `navigation-${args.handler}`,\n );\n\n // Navigate to the request handler page.\n await button.click();\n\n return await page.evaluate((payload) => {\n window.__SIMULATOR_API__.dispatch({\n type: 'simulation/sendRequest',\n payload,\n });\n\n return window.__SIMULATOR_API__.getRequestId();\n }, args);\n}\n\n/**\n * Send a request to the snap.\n *\n * @param page - The page to send the request from.\n * @param options - The request options.\n * @param options.origin - The origin of the request. Defaults to `metamask.io`.\n * @param handler - The handler to use. Defaults to `onRpcRequest`.\n * @returns The response.\n */\nexport function request(\n page: Page,\n { origin = 'metamask.io', ...options }: RequestOptions,\n handler:\n | HandlerType.OnRpcRequest\n | HandlerType.OnCronjob = HandlerType.OnRpcRequest,\n) {\n const doRequest = async (): Promise<SnapResponse> => {\n const args: SnapRpcHookArgs = {\n origin,\n handler,\n request: {\n jsonrpc: '2.0',\n id: 1,\n ...options,\n },\n };\n\n log('Sending request %o', args);\n\n const promise = waitForResponse(page, handler);\n const id = await sendRequest(page, args);\n const response = await promise;\n\n log('Received response %o', response);\n\n const notifications = await getNotifications(page, id);\n\n return { id, response, notifications };\n };\n\n // This is a bit hacky, but it allows us to add the `getInterface` method\n // to the response promise.\n const response = doRequest() as SnapRequest;\n\n response.getInterface = async (getInterfaceOptions) => {\n return await getInterface(page, getInterfaceOptions);\n };\n\n return response;\n}\n\n/**\n * Send a transaction to the snap.\n *\n * @param page - The page to send the transaction from.\n * @param options - The transaction options.\n * @returns The response.\n */\nexport async function sendTransaction(\n page: Page,\n options: Partial<TransactionOptions>,\n) {\n const {\n origin: transactionOrigin,\n chainId,\n ...transaction\n } = create(options, TransactionOptionsStruct);\n\n const args: SnapRpcHookArgs = {\n origin: '',\n handler: HandlerType.OnTransaction,\n request: {\n jsonrpc: '2.0',\n method: '',\n params: {\n chainId,\n transaction,\n transactionOrigin,\n },\n },\n };\n\n log('Sending transaction %o', args);\n\n const promise = waitForResponse(page, HandlerType.OnTransaction);\n const id = await sendRequest(page, args);\n const response = await promise;\n\n log('Received response %o', response);\n\n if (hasProperty(response, 'error')) {\n return { id, response, notifications: [] };\n }\n\n assert(isPlainObject(response.result));\n assert(hasProperty(response.result, 'content'));\n\n return {\n id,\n response,\n notifications: [],\n content: response.result.content as Component,\n };\n}\n\n/**\n * Run a cronjob.\n *\n * @param page - The page to run the cronjob from.\n * @param options - The request options.\n * @returns The response.\n */\nexport function runCronjob(page: Page, options: CronjobOptions) {\n return request(page, options, HandlerType.OnCronjob);\n}\n"],"names":["request","sendTransaction","runCronjob","log","createModuleLogger","rootLogger","sendRequest","page","args","document","getDocument","button","queries","getByTestId","handler","click","evaluate","payload","window","__SIMULATOR_API__","dispatch","type","getRequestId","origin","options","HandlerType","OnRpcRequest","doRequest","jsonrpc","id","promise","waitForResponse","response","notifications","getNotifications","getInterface","getInterfaceOptions","transactionOrigin","chainId","transaction","create","TransactionOptionsStruct","OnTransaction","method","params","hasProperty","assert","isPlainObject","result","content","OnCronjob"],"mappings":";;;;;;;;;;;IA+DgBA,OAAO;eAAPA;;IAiDMC,eAAe;eAAfA;;IAsDNC,UAAU;eAAVA;;;4BApKY;uBAMrB;oCAC8B;6BAEd;2BASwB;wBACpB;yBACc;yBACT;AAEhC,MAAMC,MAAMC,IAAAA,yBAAkB,EAACC,kBAAU,EAAE;AAE3C;;;;;;CAMC,GACD,eAAeC,YAAYC,IAAU,EAAEC,IAAqB;IAC1D,MAAMC,WAAW,MAAMC,IAAAA,+BAAW,EAACH;IACnC,MAAMI,SAAS,MAAMC,2BAAO,CAACC,WAAW,CACtCJ,UACA,CAAC,WAAW,EAAED,KAAKM,OAAO,CAAC,CAAC;IAG9B,wCAAwC;IACxC,MAAMH,OAAOI,KAAK;IAElB,OAAO,MAAMR,KAAKS,QAAQ,CAAC,CAACC;QAC1BC,OAAOC,iBAAiB,CAACC,QAAQ,CAAC;YAChCC,MAAM;YACNJ;QACF;QAEA,OAAOC,OAAOC,iBAAiB,CAACG,YAAY;IAC9C,GAAGd;AACL;AAWO,SAASR,QACdO,IAAU,EACV,EAAEgB,SAAS,aAAa,EAAE,GAAGC,SAAyB,EACtDV,UAE4BW,uBAAW,CAACC,YAAY;IAEpD,MAAMC,YAAY;QAChB,MAAMnB,OAAwB;YAC5Be;YACAT;YACAd,SAAS;gBACP4B,SAAS;gBACTC,IAAI;gBACJ,GAAGL,OAAO;YACZ;QACF;QAEArB,IAAI,sBAAsBK;QAE1B,MAAMsB,UAAUC,IAAAA,wBAAe,EAACxB,MAAMO;QACtC,MAAMe,KAAK,MAAMvB,YAAYC,MAAMC;QACnC,MAAMwB,WAAW,MAAMF;QAEvB3B,IAAI,wBAAwB6B;QAE5B,MAAMC,gBAAgB,MAAMC,IAAAA,2BAAgB,EAAC3B,MAAMsB;QAEnD,OAAO;YAAEA;YAAIG;YAAUC;QAAc;IACvC;IAEA,yEAAyE;IACzE,2BAA2B;IAC3B,MAAMD,WAAWL;IAEjBK,SAASG,YAAY,GAAG,OAAOC;QAC7B,OAAO,MAAMD,IAAAA,uBAAY,EAAC5B,MAAM6B;IAClC;IAEA,OAAOJ;AACT;AASO,eAAe/B,gBACpBM,IAAU,EACViB,OAAoC;IAEpC,MAAM,EACJD,QAAQc,iBAAiB,EACzBC,OAAO,EACP,GAAGC,aACJ,GAAGC,IAAAA,mBAAM,EAAChB,SAASiB,iCAAwB;IAE5C,MAAMjC,OAAwB;QAC5Be,QAAQ;QACRT,SAASW,uBAAW,CAACiB,aAAa;QAClC1C,SAAS;YACP4B,SAAS;YACTe,QAAQ;YACRC,QAAQ;gBACNN;gBACAC;gBACAF;YACF;QACF;IACF;IAEAlC,IAAI,0BAA0BK;IAE9B,MAAMsB,UAAUC,IAAAA,wBAAe,EAACxB,MAAMkB,uBAAW,CAACiB,aAAa;IAC/D,MAAMb,KAAK,MAAMvB,YAAYC,MAAMC;IACnC,MAAMwB,WAAW,MAAMF;IAEvB3B,IAAI,wBAAwB6B;IAE5B,IAAIa,IAAAA,kBAAW,EAACb,UAAU,UAAU;QAClC,OAAO;YAAEH;YAAIG;YAAUC,eAAe,EAAE;QAAC;IAC3C;IAEAa,IAAAA,aAAM,EAACC,IAAAA,oBAAa,EAACf,SAASgB,MAAM;IACpCF,IAAAA,aAAM,EAACD,IAAAA,kBAAW,EAACb,SAASgB,MAAM,EAAE;IAEpC,OAAO;QACLnB;QACAG;QACAC,eAAe,EAAE;QACjBgB,SAASjB,SAASgB,MAAM,CAACC,OAAO;IAClC;AACF;AASO,SAAS/C,WAAWK,IAAU,EAAEiB,OAAuB;IAC5D,OAAOxB,QAAQO,MAAMiB,SAASC,uBAAW,CAACyB,SAAS;AACrD"}
1
+ {"version":3,"sources":["../../../src/internals/request.ts"],"sourcesContent":["import type { AbstractExecutionService } from '@metamask/snaps-controllers';\nimport type { SnapId, Component } from '@metamask/snaps-sdk';\nimport type { HandlerType } from '@metamask/snaps-utils';\nimport { unwrapError } from '@metamask/snaps-utils';\nimport { getSafeJson, hasProperty, isPlainObject } from '@metamask/utils';\nimport { nanoid } from '@reduxjs/toolkit';\n\nimport type { RequestOptions, SnapRequest } from '../types';\nimport {\n clearNotifications,\n getInterface,\n getNotifications,\n} from './simulation';\nimport type { RunSagaFunction, Store } from './simulation';\nimport type { RootControllerMessenger } from './simulation/controllers';\n\nexport type HandleRequestOptions = {\n snapId: SnapId;\n store: Store;\n executionService: AbstractExecutionService<unknown>;\n handler: HandlerType;\n controllerMessenger: RootControllerMessenger;\n runSaga: RunSagaFunction;\n request: RequestOptions;\n};\n\n/**\n * Send a JSON-RPC request to the Snap, and wrap the response in a\n * {@link SnapResponse} object.\n *\n * @param options - The request options.\n * @param options.snapId - The ID of the Snap to send the request to.\n * @param options.store - The Redux store.\n * @param options.executionService - The execution service to use to send the\n * request.\n * @param options.handler - The handler to use to send the request.\n * @param options.controllerMessenger - The controller messenger used to call actions.\n * @param options.runSaga - A function to run a saga outside the usual Redux\n * flow.\n * @param options.request - The request to send.\n * @param options.request.id - The ID of the request. If not provided, a random\n * ID will be generated.\n * @param options.request.origin - The origin of the request. Defaults to\n * `https://metamask.io`.\n * @returns The response, wrapped in a {@link SnapResponse} object.\n */\nexport function handleRequest({\n snapId,\n store,\n executionService,\n handler,\n controllerMessenger,\n runSaga,\n request: { id = nanoid(), origin = 'https://metamask.io', ...options },\n}: HandleRequestOptions): SnapRequest {\n const promise = executionService\n .handleRpcRequest(snapId, {\n origin,\n handler,\n request: {\n jsonrpc: '2.0',\n id: 1,\n ...options,\n },\n })\n .then((result) => {\n const notifications = getNotifications(store.getState());\n store.dispatch(clearNotifications());\n\n const content = getContentFromResult(result, snapId, controllerMessenger);\n\n return {\n id: String(id),\n response: {\n result: getSafeJson(result),\n },\n notifications,\n content,\n };\n })\n .catch((error) => {\n const [unwrappedError] = unwrapError(error);\n\n return {\n id: String(id),\n response: {\n error: unwrappedError.serialize(),\n },\n notifications: [],\n };\n }) as unknown as SnapRequest;\n\n promise.getInterface = async () => {\n return await runSaga(\n getInterface,\n runSaga,\n snapId,\n controllerMessenger,\n ).toPromise();\n };\n\n return promise;\n}\n\n/**\n * Get the response content either from the SnapInterfaceController or the response object if there is one.\n *\n * @param result - The handler result object.\n * @param snapId - The Snap ID.\n * @param controllerMessenger - The controller messenger.\n * @returns The content components if any.\n */\nexport function getContentFromResult(\n result: unknown,\n snapId: SnapId,\n controllerMessenger: RootControllerMessenger,\n): Component | undefined {\n if (isPlainObject(result) && hasProperty(result, 'id')) {\n return controllerMessenger.call(\n 'SnapInterfaceController:getInterface',\n snapId,\n result.id as string,\n ).content;\n }\n\n if (isPlainObject(result) && hasProperty(result, 'content')) {\n return result.content as Component;\n }\n\n return undefined;\n}\n"],"names":["handleRequest","getContentFromResult","snapId","store","executionService","handler","controllerMessenger","runSaga","request","id","nanoid","origin","options","promise","handleRpcRequest","jsonrpc","then","result","notifications","getNotifications","getState","dispatch","clearNotifications","content","String","response","getSafeJson","catch","error","unwrappedError","unwrapError","serialize","getInterface","toPromise","isPlainObject","hasProperty","call","undefined"],"mappings":";;;;;;;;;;;IA8CgBA,aAAa;eAAbA;;IAkEAC,oBAAoB;eAApBA;;;4BA7GY;uBAC4B;yBACjC;4BAOhB;AAkCA,SAASD,cAAc,EAC5BE,MAAM,EACNC,KAAK,EACLC,gBAAgB,EAChBC,OAAO,EACPC,mBAAmB,EACnBC,OAAO,EACPC,SAAS,EAAEC,KAAKC,IAAAA,eAAM,GAAE,EAAEC,SAAS,qBAAqB,EAAE,GAAGC,SAAS,EACjD;IACrB,MAAMC,UAAUT,iBACbU,gBAAgB,CAACZ,QAAQ;QACxBS;QACAN;QACAG,SAAS;YACPO,SAAS;YACTN,IAAI;YACJ,GAAGG,OAAO;QACZ;IACF,GACCI,IAAI,CAAC,CAACC;QACL,MAAMC,gBAAgBC,IAAAA,4BAAgB,EAAChB,MAAMiB,QAAQ;QACrDjB,MAAMkB,QAAQ,CAACC,IAAAA,8BAAkB;QAEjC,MAAMC,UAAUtB,qBAAqBgB,QAAQf,QAAQI;QAErD,OAAO;YACLG,IAAIe,OAAOf;YACXgB,UAAU;gBACRR,QAAQS,IAAAA,kBAAW,EAACT;YACtB;YACAC;YACAK;QACF;IACF,GACCI,KAAK,CAAC,CAACC;QACN,MAAM,CAACC,eAAe,GAAGC,IAAAA,uBAAW,EAACF;QAErC,OAAO;YACLnB,IAAIe,OAAOf;YACXgB,UAAU;gBACRG,OAAOC,eAAeE,SAAS;YACjC;YACAb,eAAe,EAAE;QACnB;IACF;IAEFL,QAAQmB,YAAY,GAAG;QACrB,OAAO,MAAMzB,QACXyB,wBAAY,EACZzB,SACAL,QACAI,qBACA2B,SAAS;IACb;IAEA,OAAOpB;AACT;AAUO,SAASZ,qBACdgB,MAAe,EACff,MAAc,EACdI,mBAA4C;IAE5C,IAAI4B,IAAAA,oBAAa,EAACjB,WAAWkB,IAAAA,kBAAW,EAAClB,QAAQ,OAAO;QACtD,OAAOX,oBAAoB8B,IAAI,CAC7B,wCACAlC,QACAe,OAAOR,EAAE,EACTc,OAAO;IACX;IAEA,IAAIW,IAAAA,oBAAa,EAACjB,WAAWkB,IAAAA,kBAAW,EAAClB,QAAQ,YAAY;QAC3D,OAAOA,OAAOM,OAAO;IACvB;IAEA,OAAOc;AACT"}
@@ -20,8 +20,6 @@ function _interop_require_default(obj) {
20
20
  default: obj
21
21
  };
22
22
  }
23
- const SNAPS_EXECUTION_ENVIRONMENTS_PATH = (0, _path.resolve)((0, _path.dirname)(require.resolve('@metamask/snaps-execution-environments/package.json')), 'dist', 'browserify', 'iframe');
24
- const SNAPS_SIMULATOR_PATH = (0, _path.resolve)((0, _path.dirname)(require.resolve('@metamask/snaps-simulator/package.json')), 'dist', 'webpack', 'test');
25
23
  /**
26
24
  * Check that:
27
25
  *
@@ -57,8 +55,6 @@ async function startServer(options) {
57
55
  response.header('Access-Control-Allow-Headers', 'Content-Type');
58
56
  next();
59
57
  });
60
- app.use('/environment', _express.default.static(SNAPS_EXECUTION_ENVIRONMENTS_PATH));
61
- app.use('/simulator', _express.default.static(SNAPS_SIMULATOR_PATH));
62
58
  app.use(_express.default.static((0, _path.resolve)(process.cwd(), options.root)));
63
59
  const server = (0, _http.createServer)(app);
64
60
  return await new Promise((resolve, reject)=>{
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/internals/server.ts"],"sourcesContent":["import type { SnapManifest } from '@metamask/snaps-utils';\nimport {\n assertIsSnapManifest,\n isDirectory,\n isFile,\n} from '@metamask/snaps-utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport express from 'express';\nimport { promises as fs } from 'fs';\nimport type { Server } from 'http';\nimport { createServer } from 'http';\nimport { resolve as pathResolve, dirname } from 'path';\n\nimport type { SnapsEnvironmentOptions } from '../options';\nimport { rootLogger } from './logger';\n\nconst SNAPS_EXECUTION_ENVIRONMENTS_PATH = pathResolve(\n dirname(\n require.resolve('@metamask/snaps-execution-environments/package.json'),\n ),\n 'dist',\n 'browserify',\n 'iframe',\n);\n\nconst SNAPS_SIMULATOR_PATH = pathResolve(\n dirname(require.resolve('@metamask/snaps-simulator/package.json')),\n 'dist',\n 'webpack',\n 'test',\n);\n\nexport type ServerOptions = Required<\n // We need a double `Required` for the type to be inferred correctly.\n Required<SnapsEnvironmentOptions>['server']\n>;\n\n/**\n * Check that:\n *\n * - The root directory exists.\n * - The root directory contains a `snap.manifest.json` file.\n * - The file path in the manifest exists.\n *\n * @param root - The root directory.\n * @throws If any of the checks fail.\n */\nasync function assertRoot(root: string) {\n if (!root) {\n throw new Error('You must specify a root directory.');\n }\n\n if (!(await isDirectory(root, false))) {\n throw new Error(`Root directory \"${root}\" is not a directory.`);\n }\n\n const manifestPath = pathResolve(root, 'snap.manifest.json');\n const manifest: SnapManifest = await fs\n .readFile(manifestPath, 'utf8')\n .then(JSON.parse);\n\n assertIsSnapManifest(manifest);\n const filePath = pathResolve(root, manifest.source.location.npm.filePath);\n\n if (!(await isFile(filePath))) {\n throw new Error(\n `File \"${filePath}\" does not exist, or is not a file. Did you forget to build your snap?`,\n );\n }\n}\n\n/**\n * Start an HTTP server on `localhost` with a random port. This is used to serve\n * the static files for the environment.\n *\n * @param options - The options to use.\n * @param options.port - The port to use for the server.\n * @param options.root - The root directory to serve from the server.\n * @returns The HTTP server.\n */\nexport async function startServer(options: ServerOptions) {\n await assertRoot(options.root);\n\n const log = createModuleLogger(rootLogger, 'server');\n const app = express();\n\n app.use((_request, response, next) => {\n response.header('Access-Control-Allow-Origin', '*');\n response.header('Access-Control-Allow-Credentials', 'true');\n response.header('Access-Control-Allow-Methods', 'GET, OPTIONS');\n response.header('Access-Control-Allow-Headers', 'Content-Type');\n\n next();\n });\n\n app.use('/environment', express.static(SNAPS_EXECUTION_ENVIRONMENTS_PATH));\n app.use('/simulator', express.static(SNAPS_SIMULATOR_PATH));\n app.use(express.static(pathResolve(process.cwd(), options.root)));\n\n const server = createServer(app);\n return await new Promise<Server>((resolve, reject) => {\n server.listen(options.port, () => {\n resolve(server);\n });\n\n server.on('error', (error) => {\n log(error);\n reject(error);\n });\n });\n}\n"],"names":["startServer","SNAPS_EXECUTION_ENVIRONMENTS_PATH","pathResolve","dirname","require","resolve","SNAPS_SIMULATOR_PATH","assertRoot","root","Error","isDirectory","manifestPath","manifest","fs","readFile","then","JSON","parse","assertIsSnapManifest","filePath","source","location","npm","isFile","options","log","createModuleLogger","rootLogger","app","express","use","_request","response","next","header","static","process","cwd","server","createServer","Promise","reject","listen","port","on","error"],"mappings":";;;;+BAgFsBA;;;eAAAA;;;4BA3Ef;uBAC4B;gEACf;oBACW;sBAEF;sBACmB;wBAGrB;;;;;;AAE3B,MAAMC,oCAAoCC,IAAAA,aAAW,EACnDC,IAAAA,aAAO,EACLC,QAAQC,OAAO,CAAC,yDAElB,QACA,cACA;AAGF,MAAMC,uBAAuBJ,IAAAA,aAAW,EACtCC,IAAAA,aAAO,EAACC,QAAQC,OAAO,CAAC,4CACxB,QACA,WACA;AAQF;;;;;;;;;CASC,GACD,eAAeE,WAAWC,IAAY;IACpC,IAAI,CAACA,MAAM;QACT,MAAM,IAAIC,MAAM;IAClB;IAEA,IAAI,CAAE,MAAMC,IAAAA,uBAAW,EAACF,MAAM,QAAS;QACrC,MAAM,IAAIC,MAAM,CAAC,gBAAgB,EAAED,KAAK,qBAAqB,CAAC;IAChE;IAEA,MAAMG,eAAeT,IAAAA,aAAW,EAACM,MAAM;IACvC,MAAMI,WAAyB,MAAMC,YAAE,CACpCC,QAAQ,CAACH,cAAc,QACvBI,IAAI,CAACC,KAAKC,KAAK;IAElBC,IAAAA,gCAAoB,EAACN;IACrB,MAAMO,WAAWjB,IAAAA,aAAW,EAACM,MAAMI,SAASQ,MAAM,CAACC,QAAQ,CAACC,GAAG,CAACH,QAAQ;IAExE,IAAI,CAAE,MAAMI,IAAAA,kBAAM,EAACJ,WAAY;QAC7B,MAAM,IAAIV,MACR,CAAC,MAAM,EAAEU,SAAS,sEAAsE,CAAC;IAE7F;AACF;AAWO,eAAenB,YAAYwB,OAAsB;IACtD,MAAMjB,WAAWiB,QAAQhB,IAAI;IAE7B,MAAMiB,MAAMC,IAAAA,yBAAkB,EAACC,kBAAU,EAAE;IAC3C,MAAMC,MAAMC,IAAAA,gBAAO;IAEnBD,IAAIE,GAAG,CAAC,CAACC,UAAUC,UAAUC;QAC3BD,SAASE,MAAM,CAAC,+BAA+B;QAC/CF,SAASE,MAAM,CAAC,oCAAoC;QACpDF,SAASE,MAAM,CAAC,gCAAgC;QAChDF,SAASE,MAAM,CAAC,gCAAgC;QAEhDD;IACF;IAEAL,IAAIE,GAAG,CAAC,gBAAgBD,gBAAO,CAACM,MAAM,CAAClC;IACvC2B,IAAIE,GAAG,CAAC,cAAcD,gBAAO,CAACM,MAAM,CAAC7B;IACrCsB,IAAIE,GAAG,CAACD,gBAAO,CAACM,MAAM,CAACjC,IAAAA,aAAW,EAACkC,QAAQC,GAAG,IAAIb,QAAQhB,IAAI;IAE9D,MAAM8B,SAASC,IAAAA,kBAAY,EAACX;IAC5B,OAAO,MAAM,IAAIY,QAAgB,CAACnC,SAASoC;QACzCH,OAAOI,MAAM,CAAClB,QAAQmB,IAAI,EAAE;YAC1BtC,QAAQiC;QACV;QAEAA,OAAOM,EAAE,CAAC,SAAS,CAACC;YAClBpB,IAAIoB;YACJJ,OAAOI;QACT;IACF;AACF"}
1
+ {"version":3,"sources":["../../../src/internals/server.ts"],"sourcesContent":["import type { SnapManifest } from '@metamask/snaps-utils';\nimport {\n assertIsSnapManifest,\n isDirectory,\n isFile,\n} from '@metamask/snaps-utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport express from 'express';\nimport { promises as fs } from 'fs';\nimport type { Server } from 'http';\nimport { createServer } from 'http';\nimport { resolve as pathResolve } from 'path';\n\nimport type { SnapsEnvironmentOptions } from '../options';\nimport { rootLogger } from './logger';\n\nexport type ServerOptions = Required<\n // We need a double `Required` for the type to be inferred correctly.\n Required<SnapsEnvironmentOptions>['server']\n>;\n\n/**\n * Check that:\n *\n * - The root directory exists.\n * - The root directory contains a `snap.manifest.json` file.\n * - The file path in the manifest exists.\n *\n * @param root - The root directory.\n * @throws If any of the checks fail.\n */\nasync function assertRoot(root: string) {\n if (!root) {\n throw new Error('You must specify a root directory.');\n }\n\n if (!(await isDirectory(root, false))) {\n throw new Error(`Root directory \"${root}\" is not a directory.`);\n }\n\n const manifestPath = pathResolve(root, 'snap.manifest.json');\n const manifest: SnapManifest = await fs\n .readFile(manifestPath, 'utf8')\n .then(JSON.parse);\n\n assertIsSnapManifest(manifest);\n const filePath = pathResolve(root, manifest.source.location.npm.filePath);\n\n if (!(await isFile(filePath))) {\n throw new Error(\n `File \"${filePath}\" does not exist, or is not a file. Did you forget to build your snap?`,\n );\n }\n}\n\n/**\n * Start an HTTP server on `localhost` with a random port. This is used to serve\n * the static files for the environment.\n *\n * @param options - The options to use.\n * @param options.port - The port to use for the server.\n * @param options.root - The root directory to serve from the server.\n * @returns The HTTP server.\n */\nexport async function startServer(options: ServerOptions) {\n await assertRoot(options.root);\n\n const log = createModuleLogger(rootLogger, 'server');\n const app = express();\n\n app.use((_request, response, next) => {\n response.header('Access-Control-Allow-Origin', '*');\n response.header('Access-Control-Allow-Credentials', 'true');\n response.header('Access-Control-Allow-Methods', 'GET, OPTIONS');\n response.header('Access-Control-Allow-Headers', 'Content-Type');\n\n next();\n });\n\n app.use(express.static(pathResolve(process.cwd(), options.root)));\n\n const server = createServer(app);\n return await new Promise<Server>((resolve, reject) => {\n server.listen(options.port, () => {\n resolve(server);\n });\n\n server.on('error', (error) => {\n log(error);\n reject(error);\n });\n });\n}\n"],"names":["startServer","assertRoot","root","Error","isDirectory","manifestPath","pathResolve","manifest","fs","readFile","then","JSON","parse","assertIsSnapManifest","filePath","source","location","npm","isFile","options","log","createModuleLogger","rootLogger","app","express","use","_request","response","next","header","static","process","cwd","server","createServer","Promise","resolve","reject","listen","port","on","error"],"mappings":";;;;+BAgEsBA;;;eAAAA;;;4BA3Df;uBAC4B;gEACf;oBACW;sBAEF;sBACU;wBAGZ;;;;;;AAO3B;;;;;;;;;CASC,GACD,eAAeC,WAAWC,IAAY;IACpC,IAAI,CAACA,MAAM;QACT,MAAM,IAAIC,MAAM;IAClB;IAEA,IAAI,CAAE,MAAMC,IAAAA,uBAAW,EAACF,MAAM,QAAS;QACrC,MAAM,IAAIC,MAAM,CAAC,gBAAgB,EAAED,KAAK,qBAAqB,CAAC;IAChE;IAEA,MAAMG,eAAeC,IAAAA,aAAW,EAACJ,MAAM;IACvC,MAAMK,WAAyB,MAAMC,YAAE,CACpCC,QAAQ,CAACJ,cAAc,QACvBK,IAAI,CAACC,KAAKC,KAAK;IAElBC,IAAAA,gCAAoB,EAACN;IACrB,MAAMO,WAAWR,IAAAA,aAAW,EAACJ,MAAMK,SAASQ,MAAM,CAACC,QAAQ,CAACC,GAAG,CAACH,QAAQ;IAExE,IAAI,CAAE,MAAMI,IAAAA,kBAAM,EAACJ,WAAY;QAC7B,MAAM,IAAIX,MACR,CAAC,MAAM,EAAEW,SAAS,sEAAsE,CAAC;IAE7F;AACF;AAWO,eAAed,YAAYmB,OAAsB;IACtD,MAAMlB,WAAWkB,QAAQjB,IAAI;IAE7B,MAAMkB,MAAMC,IAAAA,yBAAkB,EAACC,kBAAU,EAAE;IAC3C,MAAMC,MAAMC,IAAAA,gBAAO;IAEnBD,IAAIE,GAAG,CAAC,CAACC,UAAUC,UAAUC;QAC3BD,SAASE,MAAM,CAAC,+BAA+B;QAC/CF,SAASE,MAAM,CAAC,oCAAoC;QACpDF,SAASE,MAAM,CAAC,gCAAgC;QAChDF,SAASE,MAAM,CAAC,gCAAgC;QAEhDD;IACF;IAEAL,IAAIE,GAAG,CAACD,gBAAO,CAACM,MAAM,CAACxB,IAAAA,aAAW,EAACyB,QAAQC,GAAG,IAAIb,QAAQjB,IAAI;IAE9D,MAAM+B,SAASC,IAAAA,kBAAY,EAACX;IAC5B,OAAO,MAAM,IAAIY,QAAgB,CAACC,SAASC;QACzCJ,OAAOK,MAAM,CAACnB,QAAQoB,IAAI,EAAE;YAC1BH,QAAQH;QACV;QAEAA,OAAOO,EAAE,CAAC,SAAS,CAACC;YAClBrB,IAAIqB;YACJJ,OAAOI;QACT;IACF;AACF"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * A secret recovery phrase that is used for testing purposes. Do not use this
3
+ * to store any real funds!
4
+ */ "use strict";
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ function _export(target, all) {
9
+ for(var name in all)Object.defineProperty(target, name, {
10
+ enumerable: true,
11
+ get: all[name]
12
+ });
13
+ }
14
+ _export(exports, {
15
+ DEFAULT_SRP: function() {
16
+ return DEFAULT_SRP;
17
+ },
18
+ DEFAULT_LOCALE: function() {
19
+ return DEFAULT_LOCALE;
20
+ },
21
+ DEFAULT_JSON_RPC_ENDPOINT: function() {
22
+ return DEFAULT_JSON_RPC_ENDPOINT;
23
+ }
24
+ });
25
+ const DEFAULT_SRP = 'test test test test test test test test test test test ball';
26
+ const DEFAULT_LOCALE = 'en';
27
+ const DEFAULT_JSON_RPC_ENDPOINT = 'https://cloudflare-eth.com/';
28
+
29
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/internals/simulation/constants.ts"],"sourcesContent":["/**\n * A secret recovery phrase that is used for testing purposes. Do not use this\n * to store any real funds!\n */\nexport const DEFAULT_SRP =\n 'test test test test test test test test test test test ball';\n\n/**\n * The default locale.\n */\nexport const DEFAULT_LOCALE = 'en';\n\n/**\n * The default JSON-RPC endpoint for Ethereum requests.\n */\nexport const DEFAULT_JSON_RPC_ENDPOINT = 'https://cloudflare-eth.com/';\n"],"names":["DEFAULT_SRP","DEFAULT_LOCALE","DEFAULT_JSON_RPC_ENDPOINT"],"mappings":"AAAA;;;CAGC;;;;;;;;;;;IACYA,WAAW;eAAXA;;IAMAC,cAAc;eAAdA;;IAKAC,yBAAyB;eAAzBA;;;AAXN,MAAMF,cACX;AAKK,MAAMC,iBAAiB;AAKvB,MAAMC,4BAA4B"}