@metamask/snaps-simulation 1.1.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.3.0]
11
+
12
+ ### Added
13
+
14
+ - Add function to test `onNameLookup` ([#2857](https://github.com/MetaMask/snaps/pull/2857))
15
+ - Add function to test `onInstall` and `onUpdate` ([#2849](https://github.com/MetaMask/snaps/pull/2849))
16
+
17
+ ### Changed
18
+
19
+ - Bump MetaMask dependencies ([#2853](https://github.com/MetaMask/snaps/pull/2853))
20
+
21
+ ## [1.2.0]
22
+
23
+ ### Added
24
+
25
+ - Add support for button `form` property ([#2830](https://github.com/MetaMask/snaps/pull/2830))
26
+ - Add function to test `onKeyringRequest` ([#2777](https://github.com/MetaMask/snaps/pull/2777))
27
+ - The `onKeyringRequest` function can be used to test keyring requests.
28
+
10
29
  ## [1.1.1]
11
30
 
12
31
  ### Removed
@@ -37,7 +56,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
37
56
 
38
57
  - Initial release of `@metamask/snaps-simulation` package ([#2727](https://github.com/MetaMask/snaps/pull/2727))
39
58
 
40
- [Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-simulation@1.1.1...HEAD
59
+ [Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-simulation@1.3.0...HEAD
60
+ [1.3.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-simulation@1.2.0...@metamask/snaps-simulation@1.3.0
61
+ [1.2.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-simulation@1.1.1...@metamask/snaps-simulation@1.2.0
41
62
  [1.1.1]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-simulation@1.1.0...@metamask/snaps-simulation@1.1.1
42
63
  [1.1.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-simulation@1.0.1...@metamask/snaps-simulation@1.1.0
43
64
  [1.0.1]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-simulation@1.0.0...@metamask/snaps-simulation@1.0.1
package/dist/helpers.cjs CHANGED
@@ -56,6 +56,19 @@ function getHelpers({ snapId, store, executionService, runSaga, controllerMessen
56
56
  request,
57
57
  });
58
58
  };
59
+ const onKeyringRequest = async (request) => {
60
+ log('Sending keyring request %o.', request);
61
+ const response = await (0, request_1.handleRequest)({
62
+ snapId,
63
+ store,
64
+ executionService,
65
+ runSaga,
66
+ controllerMessenger,
67
+ handler: snaps_utils_1.HandlerType.OnKeyringRequest,
68
+ request,
69
+ });
70
+ return response;
71
+ };
59
72
  return {
60
73
  request: (request) => {
61
74
  log('Sending request %o.', request);
@@ -71,6 +84,54 @@ function getHelpers({ snapId, store, executionService, runSaga, controllerMessen
71
84
  },
72
85
  onTransaction,
73
86
  sendTransaction: onTransaction,
87
+ onKeyringRequest,
88
+ onInstall: (request) => {
89
+ log('Running onInstall handler.');
90
+ return (0, request_1.handleRequest)({
91
+ snapId,
92
+ store,
93
+ executionService,
94
+ controllerMessenger,
95
+ runSaga,
96
+ handler: snaps_utils_1.HandlerType.OnInstall,
97
+ request: {
98
+ method: '',
99
+ ...request,
100
+ },
101
+ });
102
+ },
103
+ onUpdate: (request) => {
104
+ log('Running onUpdate handler.');
105
+ return (0, request_1.handleRequest)({
106
+ snapId,
107
+ store,
108
+ executionService,
109
+ controllerMessenger,
110
+ runSaga,
111
+ handler: snaps_utils_1.HandlerType.OnUpdate,
112
+ request: {
113
+ method: '',
114
+ ...request,
115
+ },
116
+ });
117
+ },
118
+ onNameLookup: async (nameLookupOptions) => {
119
+ log('Requesting name lookup %o.', nameLookupOptions);
120
+ const params = (0, superstruct_1.create)(nameLookupOptions, structs_1.NameLookupOptionsStruct);
121
+ const response = await (0, request_1.handleRequest)({
122
+ snapId,
123
+ store,
124
+ executionService,
125
+ controllerMessenger,
126
+ runSaga,
127
+ handler: snaps_utils_1.HandlerType.OnNameLookup,
128
+ request: {
129
+ method: '',
130
+ params,
131
+ },
132
+ });
133
+ return response;
134
+ },
74
135
  onSignature: async (request) => {
75
136
  log('Requesting signature %o.', request);
76
137
  const { origin: signatureOrigin, ...signature } = (0, superstruct_1.create)(request, structs_1.SignatureOptionsStruct);
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.cjs","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import { HandlerType } from '@metamask/snaps-utils';\nimport { create } from '@metamask/superstruct';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { rootLogger } from './logger';\nimport type { SimulationOptions } from './options';\nimport { handleRequest } from './request';\nimport type { InstalledSnap } from './simulation';\nimport { addJsonRpcMock, removeJsonRpcMock } from './store';\nimport {\n assertIsResponseWithInterface,\n JsonRpcMockOptionsStruct,\n SignatureOptionsStruct,\n TransactionOptionsStruct,\n} from './structs';\nimport type {\n CronjobOptions,\n JsonRpcMockOptions,\n RequestOptions,\n SignatureOptions,\n SnapRequest,\n SnapResponseWithInterface,\n TransactionOptions,\n} from './types';\n\nconst log = createModuleLogger(rootLogger, 'helpers');\n\n/**\n * This is the main entry point to interact with the snap. It is returned by\n * {@link installSnap}, and has methods to send requests to the snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * const snap = await installSnap();\n * const response = await snap.request({ method: 'hello' });\n *\n * expect(response).toRespondWith('Hello, world!');\n */\nexport type SnapHelpers = {\n /**\n * Send a JSON-RPC request to the snap.\n *\n * @param request - The request. This is similar to a JSON-RPC request, but\n * has an extra `origin` field.\n * @returns The response promise, with extra {@link SnapRequestObject} fields.\n */\n request(request: RequestOptions): SnapRequest;\n\n /**\n * Send a transaction to the snap.\n *\n * @param transaction - The transaction. This is similar to an Ethereum\n * transaction object, but has an extra `origin` field. Any missing fields\n * will be filled in with default values.\n * @returns The response.\n */\n onTransaction(\n transaction?: Partial<TransactionOptions>,\n ): Promise<SnapResponseWithInterface>;\n\n /**\n * Send a transaction to the snap.\n *\n * @param transaction - The transaction. This is similar to an Ethereum\n * transaction object, but has an extra `origin` field. Any missing fields\n * will be filled in with default values.\n * @returns The response.\n * @deprecated Use {@link onTransaction} instead.\n */\n sendTransaction(\n transaction?: Partial<TransactionOptions>,\n ): Promise<SnapResponseWithInterface>;\n\n /**\n * Send a signature request to the snap.\n *\n * @param signature - The signature request object. Contains the params from\n * the various signature methods, but has an extra `origin` and `signatureMethod` field.\n * Any missing fields will be filled in with default values.\n * @returns The response.\n */\n onSignature(\n signature?: Partial<SignatureOptions>,\n ): Promise<SnapResponseWithInterface>;\n\n /**\n * Run a cronjob in the snap. This is similar to {@link request}, but the\n * request will be sent to the `onCronjob` method of the snap.\n *\n * @param cronjob - The cronjob request. This is similar to a JSON-RPC\n * request, and is normally specified in the snap manifest, under the\n * `endowment:cronjob` permission.\n * @returns The response promise, with extra {@link SnapRequestObject} fields.\n */\n onCronjob(cronjob?: Partial<CronjobOptions>): SnapRequest;\n\n /**\n * Run a cronjob in the snap. This is similar to {@link request}, but the\n * request will be sent to the `onCronjob` method of the snap.\n *\n * @param cronjob - The cronjob request. This is similar to a JSON-RPC\n * request, and is normally specified in the snap manifest, under the\n * `endowment:cronjob` permission.\n * @returns The response promise, with extra {@link SnapRequestObject} fields.\n * @deprecated Use {@link onCronjob} instead.\n */\n runCronjob(cronjob: CronjobOptions): SnapRequest;\n\n /**\n * Get the response from the snap's `onHomePage` method.\n *\n * @returns The response.\n */\n onHomePage(): Promise<SnapResponseWithInterface>;\n\n /**\n * Mock a JSON-RPC request. This will cause the snap to respond with the\n * specified response when a request with the specified method is sent.\n *\n * @param mock - The mock options.\n * @param mock.method - The JSON-RPC request method.\n * @param mock.result - The JSON-RPC response, which will be returned when a\n * request with the specified method is sent.\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * // In the test\n * const snap = await installSnap();\n * snap.mockJsonRpc({ method: 'eth_accounts', result: ['0x1234'] });\n *\n * // In the Snap\n * const response =\n * await ethereum.request({ method: 'eth_accounts' }); // ['0x1234']\n */\n mockJsonRpc(mock: JsonRpcMockOptions): {\n /**\n * Remove the mock.\n */\n unmock(): void;\n };\n\n /**\n * Close the page running the snap. This is mainly useful for cleaning up\n * the test environment, and calling it is not strictly necessary.\n *\n * @returns A promise that resolves when the page is closed.\n */\n close(): Promise<void>;\n};\n\n/**\n * Get the helper functions for the Snap.\n *\n * @param snap - The installed Snap.\n * @param snap.snapId - The ID of the Snap.\n * @param snap.store - The Redux store.\n * @param snap.executionService - The execution service.\n * @param snap.runSaga - The `runSaga` function.\n * @param snap.controllerMessenger - The controller messenger.\n * @param snap.options - The simulation options.\n * @returns The Snap helpers.\n */\nexport function getHelpers({\n snapId,\n store,\n executionService,\n runSaga,\n controllerMessenger,\n options,\n}: InstalledSnap & { options: SimulationOptions }): SnapHelpers {\n const onTransaction = async (\n request: TransactionOptions,\n ): Promise<SnapResponseWithInterface> => {\n log('Sending transaction %o.', request);\n\n const {\n origin: transactionOrigin,\n chainId,\n ...transaction\n } = create(request, TransactionOptionsStruct);\n\n const response = await handleRequest({\n snapId,\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 assertIsResponseWithInterface(response);\n\n return response;\n };\n\n const onCronjob = (request: CronjobOptions) => {\n log('Running cronjob %o.', options);\n\n return handleRequest({\n snapId,\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,\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 (\n request: unknown,\n ): Promise<SnapResponseWithInterface> => {\n log('Requesting signature %o.', request);\n\n const { origin: signatureOrigin, ...signature } = create(\n request,\n SignatureOptionsStruct,\n );\n\n const response = await handleRequest({\n snapId,\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 assertIsResponseWithInterface(response);\n\n return response;\n },\n\n onCronjob,\n runCronjob: onCronjob,\n\n onHomePage: async (): Promise<SnapResponseWithInterface> => {\n log('Rendering home page.');\n\n const response = await handleRequest({\n snapId,\n store,\n executionService,\n controllerMessenger,\n runSaga,\n handler: HandlerType.OnHomePage,\n request: {\n method: '',\n },\n });\n\n assertIsResponseWithInterface(response);\n\n return response;\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 await executionService.terminateAllSnaps();\n },\n };\n}\n"]}
1
+ {"version":3,"file":"helpers.cjs","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import { HandlerType } from '@metamask/snaps-utils';\nimport { create } from '@metamask/superstruct';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { rootLogger } from './logger';\nimport type { SimulationOptions } from './options';\nimport { handleRequest } from './request';\nimport type { InstalledSnap } from './simulation';\nimport { addJsonRpcMock, removeJsonRpcMock } from './store';\nimport {\n assertIsResponseWithInterface,\n JsonRpcMockOptionsStruct,\n NameLookupOptionsStruct,\n SignatureOptionsStruct,\n TransactionOptionsStruct,\n} from './structs';\nimport type {\n CronjobOptions,\n JsonRpcMockOptions,\n KeyringOptions,\n NameLookupOptions,\n RequestOptions,\n SignatureOptions,\n SnapRequest,\n SnapResponseWithInterface,\n SnapResponseWithoutInterface,\n TransactionOptions,\n} from './types';\n\nconst log = createModuleLogger(rootLogger, 'helpers');\n\n/**\n * This is the main entry point to interact with the snap. It is returned by\n * {@link installSnap}, and has methods to send requests to the snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * const snap = await installSnap();\n * const response = await snap.request({ method: 'hello' });\n *\n * expect(response).toRespondWith('Hello, world!');\n */\nexport type SnapHelpers = {\n /**\n * Send a JSON-RPC request to the snap.\n *\n * @param request - The request. This is similar to a JSON-RPC request, but\n * has an extra `origin` field.\n * @returns The response promise, with extra {@link SnapRequestObject} fields.\n */\n request(request: RequestOptions): SnapRequest;\n\n /**\n * Send a transaction to the snap.\n *\n * @param transaction - The transaction. This is similar to an Ethereum\n * transaction object, but has an extra `origin` field. Any missing fields\n * will be filled in with default values.\n * @returns The response.\n */\n onTransaction(\n transaction?: Partial<TransactionOptions>,\n ): Promise<SnapResponseWithInterface>;\n\n /**\n * Send a transaction to the snap.\n *\n * @param transaction - The transaction. This is similar to an Ethereum\n * transaction object, but has an extra `origin` field. Any missing fields\n * will be filled in with default values.\n * @returns The response.\n * @deprecated Use {@link onTransaction} instead.\n */\n sendTransaction(\n transaction?: Partial<TransactionOptions>,\n ): Promise<SnapResponseWithInterface>;\n\n /**\n * Send a signature request to the snap.\n *\n * @param signature - The signature request object. Contains the params from\n * the various signature methods, but has an extra `origin` and `signatureMethod` field.\n * Any missing fields will be filled in with default values.\n * @returns The response.\n */\n onSignature(\n signature?: Partial<SignatureOptions>,\n ): Promise<SnapResponseWithInterface>;\n\n /**\n * Run a cronjob in the snap. This is similar to {@link request}, but the\n * request will be sent to the `onCronjob` method of the snap.\n *\n * @param cronjob - The cronjob request. This is similar to a JSON-RPC\n * request, and is normally specified in the snap manifest, under the\n * `endowment:cronjob` permission.\n * @returns The response promise, with extra {@link SnapRequestObject} fields.\n */\n onCronjob(cronjob?: Partial<CronjobOptions>): SnapRequest;\n\n /**\n * Run a cronjob in the snap. This is similar to {@link request}, but the\n * request will be sent to the `onCronjob` method of the snap.\n *\n * @param cronjob - The cronjob request. This is similar to a JSON-RPC\n * request, and is normally specified in the snap manifest, under the\n * `endowment:cronjob` permission.\n * @returns The response promise, with extra {@link SnapRequestObject} fields.\n * @deprecated Use {@link onCronjob} instead.\n */\n runCronjob(cronjob: CronjobOptions): SnapRequest;\n\n /**\n * Get the response from the snap's `onHomePage` method.\n *\n * @returns The response.\n */\n onHomePage(): Promise<SnapResponseWithInterface>;\n\n /**\n * Send a keyring request to the Snap.\n *\n * @param keyringRequest - Keyring request.\n * @returns The response.\n */\n onKeyringRequest(\n keyringRequest: KeyringOptions,\n ): Promise<SnapResponseWithoutInterface>;\n\n /**\n * Get the response from the Snap's `onInstall` handler.\n *\n * @returns The response.\n */\n onInstall(request?: Pick<RequestOptions, 'origin'>): SnapRequest;\n\n /**\n * Get the response from the Snap's `onUpdate` handler.\n *\n * @returns The response.\n */\n onUpdate(request?: Pick<RequestOptions, 'origin'>): SnapRequest;\n\n /**\n * Get the response from the Snap's `onNameLookup` handler.\n *\n * @returns The response.\n */\n onNameLookup(\n request: NameLookupOptions,\n ): Promise<SnapResponseWithoutInterface>;\n\n /**\n * Mock a JSON-RPC request. This will cause the snap to respond with the\n * specified response when a request with the specified method is sent.\n *\n * @param mock - The mock options.\n * @param mock.method - The JSON-RPC request method.\n * @param mock.result - The JSON-RPC response, which will be returned when a\n * request with the specified method is sent.\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * // In the test\n * const snap = await installSnap();\n * snap.mockJsonRpc({ method: 'eth_accounts', result: ['0x1234'] });\n *\n * // In the Snap\n * const response =\n * await ethereum.request({ method: 'eth_accounts' }); // ['0x1234']\n */\n mockJsonRpc(mock: JsonRpcMockOptions): {\n /**\n * Remove the mock.\n */\n unmock(): void;\n };\n\n /**\n * Close the page running the snap. This is mainly useful for cleaning up\n * the test environment, and calling it is not strictly necessary.\n *\n * @returns A promise that resolves when the page is closed.\n */\n close(): Promise<void>;\n};\n\n/**\n * Get the helper functions for the Snap.\n *\n * @param snap - The installed Snap.\n * @param snap.snapId - The ID of the Snap.\n * @param snap.store - The Redux store.\n * @param snap.executionService - The execution service.\n * @param snap.runSaga - The `runSaga` function.\n * @param snap.controllerMessenger - The controller messenger.\n * @param snap.options - The simulation options.\n * @returns The Snap helpers.\n */\nexport function getHelpers({\n snapId,\n store,\n executionService,\n runSaga,\n controllerMessenger,\n options,\n}: InstalledSnap & { options: SimulationOptions }): SnapHelpers {\n const onTransaction = async (\n request: TransactionOptions,\n ): Promise<SnapResponseWithInterface> => {\n log('Sending transaction %o.', request);\n\n const {\n origin: transactionOrigin,\n chainId,\n ...transaction\n } = create(request, TransactionOptionsStruct);\n\n const response = await handleRequest({\n snapId,\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 assertIsResponseWithInterface(response);\n\n return response;\n };\n\n const onCronjob = (request: CronjobOptions) => {\n log('Running cronjob %o.', options);\n\n return handleRequest({\n snapId,\n store,\n executionService,\n controllerMessenger,\n runSaga,\n handler: HandlerType.OnCronjob,\n request,\n });\n };\n\n const onKeyringRequest = async (\n request: KeyringOptions,\n ): Promise<SnapResponseWithoutInterface> => {\n log('Sending keyring request %o.', request);\n\n const response = await handleRequest({\n snapId,\n store,\n executionService,\n runSaga,\n controllerMessenger,\n handler: HandlerType.OnKeyringRequest,\n request,\n });\n\n return response;\n };\n\n return {\n request: (request) => {\n log('Sending request %o.', request);\n\n return handleRequest({\n snapId,\n store,\n executionService,\n controllerMessenger,\n runSaga,\n handler: HandlerType.OnRpcRequest,\n request,\n });\n },\n\n onTransaction,\n sendTransaction: onTransaction,\n\n onKeyringRequest,\n\n onInstall: (request?: Pick<RequestOptions, 'origin'>) => {\n log('Running onInstall handler.');\n\n return handleRequest({\n snapId,\n store,\n executionService,\n controllerMessenger,\n runSaga,\n handler: HandlerType.OnInstall,\n request: {\n method: '',\n ...request,\n },\n });\n },\n\n onUpdate: (request?: Pick<RequestOptions, 'origin'>) => {\n log('Running onUpdate handler.');\n\n return handleRequest({\n snapId,\n store,\n executionService,\n controllerMessenger,\n runSaga,\n handler: HandlerType.OnUpdate,\n request: {\n method: '',\n ...request,\n },\n });\n },\n\n onNameLookup: async (\n nameLookupOptions: NameLookupOptions,\n ): Promise<SnapResponseWithoutInterface> => {\n log('Requesting name lookup %o.', nameLookupOptions);\n\n const params = create(nameLookupOptions, NameLookupOptionsStruct);\n\n const response = await handleRequest({\n snapId,\n store,\n executionService,\n controllerMessenger,\n runSaga,\n handler: HandlerType.OnNameLookup,\n request: {\n method: '',\n params,\n },\n });\n\n return response;\n },\n\n onSignature: async (\n request: unknown,\n ): Promise<SnapResponseWithInterface> => {\n log('Requesting signature %o.', request);\n\n const { origin: signatureOrigin, ...signature } = create(\n request,\n SignatureOptionsStruct,\n );\n\n const response = await handleRequest({\n snapId,\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 assertIsResponseWithInterface(response);\n\n return response;\n },\n\n onCronjob,\n runCronjob: onCronjob,\n\n onHomePage: async (): Promise<SnapResponseWithInterface> => {\n log('Rendering home page.');\n\n const response = await handleRequest({\n snapId,\n store,\n executionService,\n controllerMessenger,\n runSaga,\n handler: HandlerType.OnHomePage,\n request: {\n method: '',\n },\n });\n\n assertIsResponseWithInterface(response);\n\n return response;\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 await executionService.terminateAllSnaps();\n },\n };\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import type { SimulationOptions } from "./options.cjs";
2
2
  import type { InstalledSnap } from "./simulation.cjs";
3
- import type { CronjobOptions, JsonRpcMockOptions, RequestOptions, SignatureOptions, SnapRequest, SnapResponseWithInterface, TransactionOptions } from "./types.cjs";
3
+ import type { CronjobOptions, JsonRpcMockOptions, KeyringOptions, NameLookupOptions, RequestOptions, SignatureOptions, SnapRequest, SnapResponseWithInterface, SnapResponseWithoutInterface, TransactionOptions } from "./types.cjs";
4
4
  /**
5
5
  * This is the main entry point to interact with the snap. It is returned by
6
6
  * {@link installSnap}, and has methods to send requests to the snap.
@@ -77,6 +77,31 @@ export type SnapHelpers = {
77
77
  * @returns The response.
78
78
  */
79
79
  onHomePage(): Promise<SnapResponseWithInterface>;
80
+ /**
81
+ * Send a keyring request to the Snap.
82
+ *
83
+ * @param keyringRequest - Keyring request.
84
+ * @returns The response.
85
+ */
86
+ onKeyringRequest(keyringRequest: KeyringOptions): Promise<SnapResponseWithoutInterface>;
87
+ /**
88
+ * Get the response from the Snap's `onInstall` handler.
89
+ *
90
+ * @returns The response.
91
+ */
92
+ onInstall(request?: Pick<RequestOptions, 'origin'>): SnapRequest;
93
+ /**
94
+ * Get the response from the Snap's `onUpdate` handler.
95
+ *
96
+ * @returns The response.
97
+ */
98
+ onUpdate(request?: Pick<RequestOptions, 'origin'>): SnapRequest;
99
+ /**
100
+ * Get the response from the Snap's `onNameLookup` handler.
101
+ *
102
+ * @returns The response.
103
+ */
104
+ onNameLookup(request: NameLookupOptions): Promise<SnapResponseWithoutInterface>;
80
105
  /**
81
106
  * Mock a JSON-RPC request. This will cause the snap to respond with the
82
107
  * specified response when a request with the specified method is sent.
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.cts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAkB;AAEnD,OAAO,KAAK,EAAE,aAAa,EAAE,yBAAqB;AAQlD,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,yBAAyB,EACzB,kBAAkB,EACnB,oBAAgB;AAIjB;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB;;;;;;OAMG;IACH,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,WAAW,CAAC;IAE9C;;;;;;;OAOG;IACH,aAAa,CACX,WAAW,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,GACxC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAEtC;;;;;;;;OAQG;IACH,eAAe,CACb,WAAW,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,GACxC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAEtC;;;;;;;OAOG;IACH,WAAW,CACT,SAAS,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GACpC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAEtC;;;;;;;;OAQG;IACH,SAAS,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,WAAW,CAAC;IAE1D;;;;;;;;;OASG;IACH,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,WAAW,CAAC;IAEjD;;;;OAIG;IACH,UAAU,IAAI,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAEjD;;;;;;;;;;;;;;;;;;OAkBG;IACH,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG;QACrC;;WAEG;QACH,MAAM,IAAI,IAAI,CAAC;KAChB,CAAC;IAEF;;;;;OAKG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,KAAK,EACL,gBAAgB,EAChB,OAAO,EACP,mBAAmB,EACnB,OAAO,GACR,EAAE,aAAa,GAAG;IAAE,OAAO,EAAE,iBAAiB,CAAA;CAAE,GAAG,WAAW,CA4I9D"}
1
+ {"version":3,"file":"helpers.d.cts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAkB;AAEnD,OAAO,KAAK,EAAE,aAAa,EAAE,yBAAqB;AASlD,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,yBAAyB,EACzB,4BAA4B,EAC5B,kBAAkB,EACnB,oBAAgB;AAIjB;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB;;;;;;OAMG;IACH,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,WAAW,CAAC;IAE9C;;;;;;;OAOG;IACH,aAAa,CACX,WAAW,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,GACxC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAEtC;;;;;;;;OAQG;IACH,eAAe,CACb,WAAW,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,GACxC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAEtC;;;;;;;OAOG;IACH,WAAW,CACT,SAAS,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GACpC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAEtC;;;;;;;;OAQG;IACH,SAAS,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,WAAW,CAAC;IAE1D;;;;;;;;;OASG;IACH,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,WAAW,CAAC;IAEjD;;;;OAIG;IACH,UAAU,IAAI,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAEjD;;;;;OAKG;IACH,gBAAgB,CACd,cAAc,EAAE,cAAc,GAC7B,OAAO,CAAC,4BAA4B,CAAC,CAAC;IAEzC;;;;OAIG;IACH,SAAS,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,GAAG,WAAW,CAAC;IAEjE;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,GAAG,WAAW,CAAC;IAEhE;;;;OAIG;IACH,YAAY,CACV,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,4BAA4B,CAAC,CAAC;IAEzC;;;;;;;;;;;;;;;;;;OAkBG;IACH,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG;QACrC;;WAEG;QACH,MAAM,IAAI,IAAI,CAAC;KAChB,CAAC;IAEF;;;;;OAKG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,KAAK,EACL,gBAAgB,EAChB,OAAO,EACP,mBAAmB,EACnB,OAAO,GACR,EAAE,aAAa,GAAG;IAAE,OAAO,EAAE,iBAAiB,CAAA;CAAE,GAAG,WAAW,CAyN9D"}
@@ -1,6 +1,6 @@
1
1
  import type { SimulationOptions } from "./options.mjs";
2
2
  import type { InstalledSnap } from "./simulation.mjs";
3
- import type { CronjobOptions, JsonRpcMockOptions, RequestOptions, SignatureOptions, SnapRequest, SnapResponseWithInterface, TransactionOptions } from "./types.mjs";
3
+ import type { CronjobOptions, JsonRpcMockOptions, KeyringOptions, NameLookupOptions, RequestOptions, SignatureOptions, SnapRequest, SnapResponseWithInterface, SnapResponseWithoutInterface, TransactionOptions } from "./types.mjs";
4
4
  /**
5
5
  * This is the main entry point to interact with the snap. It is returned by
6
6
  * {@link installSnap}, and has methods to send requests to the snap.
@@ -77,6 +77,31 @@ export type SnapHelpers = {
77
77
  * @returns The response.
78
78
  */
79
79
  onHomePage(): Promise<SnapResponseWithInterface>;
80
+ /**
81
+ * Send a keyring request to the Snap.
82
+ *
83
+ * @param keyringRequest - Keyring request.
84
+ * @returns The response.
85
+ */
86
+ onKeyringRequest(keyringRequest: KeyringOptions): Promise<SnapResponseWithoutInterface>;
87
+ /**
88
+ * Get the response from the Snap's `onInstall` handler.
89
+ *
90
+ * @returns The response.
91
+ */
92
+ onInstall(request?: Pick<RequestOptions, 'origin'>): SnapRequest;
93
+ /**
94
+ * Get the response from the Snap's `onUpdate` handler.
95
+ *
96
+ * @returns The response.
97
+ */
98
+ onUpdate(request?: Pick<RequestOptions, 'origin'>): SnapRequest;
99
+ /**
100
+ * Get the response from the Snap's `onNameLookup` handler.
101
+ *
102
+ * @returns The response.
103
+ */
104
+ onNameLookup(request: NameLookupOptions): Promise<SnapResponseWithoutInterface>;
80
105
  /**
81
106
  * Mock a JSON-RPC request. This will cause the snap to respond with the
82
107
  * specified response when a request with the specified method is sent.
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.mts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAkB;AAEnD,OAAO,KAAK,EAAE,aAAa,EAAE,yBAAqB;AAQlD,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,yBAAyB,EACzB,kBAAkB,EACnB,oBAAgB;AAIjB;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB;;;;;;OAMG;IACH,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,WAAW,CAAC;IAE9C;;;;;;;OAOG;IACH,aAAa,CACX,WAAW,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,GACxC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAEtC;;;;;;;;OAQG;IACH,eAAe,CACb,WAAW,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,GACxC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAEtC;;;;;;;OAOG;IACH,WAAW,CACT,SAAS,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GACpC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAEtC;;;;;;;;OAQG;IACH,SAAS,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,WAAW,CAAC;IAE1D;;;;;;;;;OASG;IACH,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,WAAW,CAAC;IAEjD;;;;OAIG;IACH,UAAU,IAAI,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAEjD;;;;;;;;;;;;;;;;;;OAkBG;IACH,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG;QACrC;;WAEG;QACH,MAAM,IAAI,IAAI,CAAC;KAChB,CAAC;IAEF;;;;;OAKG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,KAAK,EACL,gBAAgB,EAChB,OAAO,EACP,mBAAmB,EACnB,OAAO,GACR,EAAE,aAAa,GAAG;IAAE,OAAO,EAAE,iBAAiB,CAAA;CAAE,GAAG,WAAW,CA4I9D"}
1
+ {"version":3,"file":"helpers.d.mts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAkB;AAEnD,OAAO,KAAK,EAAE,aAAa,EAAE,yBAAqB;AASlD,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,yBAAyB,EACzB,4BAA4B,EAC5B,kBAAkB,EACnB,oBAAgB;AAIjB;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB;;;;;;OAMG;IACH,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,WAAW,CAAC;IAE9C;;;;;;;OAOG;IACH,aAAa,CACX,WAAW,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,GACxC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAEtC;;;;;;;;OAQG;IACH,eAAe,CACb,WAAW,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,GACxC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAEtC;;;;;;;OAOG;IACH,WAAW,CACT,SAAS,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GACpC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAEtC;;;;;;;;OAQG;IACH,SAAS,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,WAAW,CAAC;IAE1D;;;;;;;;;OASG;IACH,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,WAAW,CAAC;IAEjD;;;;OAIG;IACH,UAAU,IAAI,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAEjD;;;;;OAKG;IACH,gBAAgB,CACd,cAAc,EAAE,cAAc,GAC7B,OAAO,CAAC,4BAA4B,CAAC,CAAC;IAEzC;;;;OAIG;IACH,SAAS,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,GAAG,WAAW,CAAC;IAEjE;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,GAAG,WAAW,CAAC;IAEhE;;;;OAIG;IACH,YAAY,CACV,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,4BAA4B,CAAC,CAAC;IAEzC;;;;;;;;;;;;;;;;;;OAkBG;IACH,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG;QACrC;;WAEG;QACH,MAAM,IAAI,IAAI,CAAC;KAChB,CAAC;IAEF;;;;;OAKG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,KAAK,EACL,gBAAgB,EAChB,OAAO,EACP,mBAAmB,EACnB,OAAO,GACR,EAAE,aAAa,GAAG;IAAE,OAAO,EAAE,iBAAiB,CAAA;CAAE,GAAG,WAAW,CAyN9D"}
package/dist/helpers.mjs CHANGED
@@ -4,7 +4,7 @@ import { createModuleLogger } from "@metamask/utils";
4
4
  import { rootLogger } from "./logger.mjs";
5
5
  import { handleRequest } from "./request.mjs";
6
6
  import { addJsonRpcMock, removeJsonRpcMock } from "./store/index.mjs";
7
- import { assertIsResponseWithInterface, JsonRpcMockOptionsStruct, SignatureOptionsStruct, TransactionOptionsStruct } from "./structs.mjs";
7
+ import { assertIsResponseWithInterface, JsonRpcMockOptionsStruct, NameLookupOptionsStruct, SignatureOptionsStruct, TransactionOptionsStruct } from "./structs.mjs";
8
8
  const log = createModuleLogger(rootLogger, 'helpers');
9
9
  /**
10
10
  * Get the helper functions for the Snap.
@@ -53,6 +53,19 @@ export function getHelpers({ snapId, store, executionService, runSaga, controlle
53
53
  request,
54
54
  });
55
55
  };
56
+ const onKeyringRequest = async (request) => {
57
+ log('Sending keyring request %o.', request);
58
+ const response = await handleRequest({
59
+ snapId,
60
+ store,
61
+ executionService,
62
+ runSaga,
63
+ controllerMessenger,
64
+ handler: HandlerType.OnKeyringRequest,
65
+ request,
66
+ });
67
+ return response;
68
+ };
56
69
  return {
57
70
  request: (request) => {
58
71
  log('Sending request %o.', request);
@@ -68,6 +81,54 @@ export function getHelpers({ snapId, store, executionService, runSaga, controlle
68
81
  },
69
82
  onTransaction,
70
83
  sendTransaction: onTransaction,
84
+ onKeyringRequest,
85
+ onInstall: (request) => {
86
+ log('Running onInstall handler.');
87
+ return handleRequest({
88
+ snapId,
89
+ store,
90
+ executionService,
91
+ controllerMessenger,
92
+ runSaga,
93
+ handler: HandlerType.OnInstall,
94
+ request: {
95
+ method: '',
96
+ ...request,
97
+ },
98
+ });
99
+ },
100
+ onUpdate: (request) => {
101
+ log('Running onUpdate handler.');
102
+ return handleRequest({
103
+ snapId,
104
+ store,
105
+ executionService,
106
+ controllerMessenger,
107
+ runSaga,
108
+ handler: HandlerType.OnUpdate,
109
+ request: {
110
+ method: '',
111
+ ...request,
112
+ },
113
+ });
114
+ },
115
+ onNameLookup: async (nameLookupOptions) => {
116
+ log('Requesting name lookup %o.', nameLookupOptions);
117
+ const params = create(nameLookupOptions, NameLookupOptionsStruct);
118
+ const response = await handleRequest({
119
+ snapId,
120
+ store,
121
+ executionService,
122
+ controllerMessenger,
123
+ runSaga,
124
+ handler: HandlerType.OnNameLookup,
125
+ request: {
126
+ method: '',
127
+ params,
128
+ },
129
+ });
130
+ return response;
131
+ },
71
132
  onSignature: async (request) => {
72
133
  log('Requesting signature %o.', request);
73
134
  const { origin: signatureOrigin, ...signature } = create(request, SignatureOptionsStruct);
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.mjs","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import { HandlerType } from '@metamask/snaps-utils';\nimport { create } from '@metamask/superstruct';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { rootLogger } from './logger';\nimport type { SimulationOptions } from './options';\nimport { handleRequest } from './request';\nimport type { InstalledSnap } from './simulation';\nimport { addJsonRpcMock, removeJsonRpcMock } from './store';\nimport {\n assertIsResponseWithInterface,\n JsonRpcMockOptionsStruct,\n SignatureOptionsStruct,\n TransactionOptionsStruct,\n} from './structs';\nimport type {\n CronjobOptions,\n JsonRpcMockOptions,\n RequestOptions,\n SignatureOptions,\n SnapRequest,\n SnapResponseWithInterface,\n TransactionOptions,\n} from './types';\n\nconst log = createModuleLogger(rootLogger, 'helpers');\n\n/**\n * This is the main entry point to interact with the snap. It is returned by\n * {@link installSnap}, and has methods to send requests to the snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * const snap = await installSnap();\n * const response = await snap.request({ method: 'hello' });\n *\n * expect(response).toRespondWith('Hello, world!');\n */\nexport type SnapHelpers = {\n /**\n * Send a JSON-RPC request to the snap.\n *\n * @param request - The request. This is similar to a JSON-RPC request, but\n * has an extra `origin` field.\n * @returns The response promise, with extra {@link SnapRequestObject} fields.\n */\n request(request: RequestOptions): SnapRequest;\n\n /**\n * Send a transaction to the snap.\n *\n * @param transaction - The transaction. This is similar to an Ethereum\n * transaction object, but has an extra `origin` field. Any missing fields\n * will be filled in with default values.\n * @returns The response.\n */\n onTransaction(\n transaction?: Partial<TransactionOptions>,\n ): Promise<SnapResponseWithInterface>;\n\n /**\n * Send a transaction to the snap.\n *\n * @param transaction - The transaction. This is similar to an Ethereum\n * transaction object, but has an extra `origin` field. Any missing fields\n * will be filled in with default values.\n * @returns The response.\n * @deprecated Use {@link onTransaction} instead.\n */\n sendTransaction(\n transaction?: Partial<TransactionOptions>,\n ): Promise<SnapResponseWithInterface>;\n\n /**\n * Send a signature request to the snap.\n *\n * @param signature - The signature request object. Contains the params from\n * the various signature methods, but has an extra `origin` and `signatureMethod` field.\n * Any missing fields will be filled in with default values.\n * @returns The response.\n */\n onSignature(\n signature?: Partial<SignatureOptions>,\n ): Promise<SnapResponseWithInterface>;\n\n /**\n * Run a cronjob in the snap. This is similar to {@link request}, but the\n * request will be sent to the `onCronjob` method of the snap.\n *\n * @param cronjob - The cronjob request. This is similar to a JSON-RPC\n * request, and is normally specified in the snap manifest, under the\n * `endowment:cronjob` permission.\n * @returns The response promise, with extra {@link SnapRequestObject} fields.\n */\n onCronjob(cronjob?: Partial<CronjobOptions>): SnapRequest;\n\n /**\n * Run a cronjob in the snap. This is similar to {@link request}, but the\n * request will be sent to the `onCronjob` method of the snap.\n *\n * @param cronjob - The cronjob request. This is similar to a JSON-RPC\n * request, and is normally specified in the snap manifest, under the\n * `endowment:cronjob` permission.\n * @returns The response promise, with extra {@link SnapRequestObject} fields.\n * @deprecated Use {@link onCronjob} instead.\n */\n runCronjob(cronjob: CronjobOptions): SnapRequest;\n\n /**\n * Get the response from the snap's `onHomePage` method.\n *\n * @returns The response.\n */\n onHomePage(): Promise<SnapResponseWithInterface>;\n\n /**\n * Mock a JSON-RPC request. This will cause the snap to respond with the\n * specified response when a request with the specified method is sent.\n *\n * @param mock - The mock options.\n * @param mock.method - The JSON-RPC request method.\n * @param mock.result - The JSON-RPC response, which will be returned when a\n * request with the specified method is sent.\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * // In the test\n * const snap = await installSnap();\n * snap.mockJsonRpc({ method: 'eth_accounts', result: ['0x1234'] });\n *\n * // In the Snap\n * const response =\n * await ethereum.request({ method: 'eth_accounts' }); // ['0x1234']\n */\n mockJsonRpc(mock: JsonRpcMockOptions): {\n /**\n * Remove the mock.\n */\n unmock(): void;\n };\n\n /**\n * Close the page running the snap. This is mainly useful for cleaning up\n * the test environment, and calling it is not strictly necessary.\n *\n * @returns A promise that resolves when the page is closed.\n */\n close(): Promise<void>;\n};\n\n/**\n * Get the helper functions for the Snap.\n *\n * @param snap - The installed Snap.\n * @param snap.snapId - The ID of the Snap.\n * @param snap.store - The Redux store.\n * @param snap.executionService - The execution service.\n * @param snap.runSaga - The `runSaga` function.\n * @param snap.controllerMessenger - The controller messenger.\n * @param snap.options - The simulation options.\n * @returns The Snap helpers.\n */\nexport function getHelpers({\n snapId,\n store,\n executionService,\n runSaga,\n controllerMessenger,\n options,\n}: InstalledSnap & { options: SimulationOptions }): SnapHelpers {\n const onTransaction = async (\n request: TransactionOptions,\n ): Promise<SnapResponseWithInterface> => {\n log('Sending transaction %o.', request);\n\n const {\n origin: transactionOrigin,\n chainId,\n ...transaction\n } = create(request, TransactionOptionsStruct);\n\n const response = await handleRequest({\n snapId,\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 assertIsResponseWithInterface(response);\n\n return response;\n };\n\n const onCronjob = (request: CronjobOptions) => {\n log('Running cronjob %o.', options);\n\n return handleRequest({\n snapId,\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,\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 (\n request: unknown,\n ): Promise<SnapResponseWithInterface> => {\n log('Requesting signature %o.', request);\n\n const { origin: signatureOrigin, ...signature } = create(\n request,\n SignatureOptionsStruct,\n );\n\n const response = await handleRequest({\n snapId,\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 assertIsResponseWithInterface(response);\n\n return response;\n },\n\n onCronjob,\n runCronjob: onCronjob,\n\n onHomePage: async (): Promise<SnapResponseWithInterface> => {\n log('Rendering home page.');\n\n const response = await handleRequest({\n snapId,\n store,\n executionService,\n controllerMessenger,\n runSaga,\n handler: HandlerType.OnHomePage,\n request: {\n method: '',\n },\n });\n\n assertIsResponseWithInterface(response);\n\n return response;\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 await executionService.terminateAllSnaps();\n },\n };\n}\n"]}
1
+ {"version":3,"file":"helpers.mjs","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import { HandlerType } from '@metamask/snaps-utils';\nimport { create } from '@metamask/superstruct';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { rootLogger } from './logger';\nimport type { SimulationOptions } from './options';\nimport { handleRequest } from './request';\nimport type { InstalledSnap } from './simulation';\nimport { addJsonRpcMock, removeJsonRpcMock } from './store';\nimport {\n assertIsResponseWithInterface,\n JsonRpcMockOptionsStruct,\n NameLookupOptionsStruct,\n SignatureOptionsStruct,\n TransactionOptionsStruct,\n} from './structs';\nimport type {\n CronjobOptions,\n JsonRpcMockOptions,\n KeyringOptions,\n NameLookupOptions,\n RequestOptions,\n SignatureOptions,\n SnapRequest,\n SnapResponseWithInterface,\n SnapResponseWithoutInterface,\n TransactionOptions,\n} from './types';\n\nconst log = createModuleLogger(rootLogger, 'helpers');\n\n/**\n * This is the main entry point to interact with the snap. It is returned by\n * {@link installSnap}, and has methods to send requests to the snap.\n *\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * const snap = await installSnap();\n * const response = await snap.request({ method: 'hello' });\n *\n * expect(response).toRespondWith('Hello, world!');\n */\nexport type SnapHelpers = {\n /**\n * Send a JSON-RPC request to the snap.\n *\n * @param request - The request. This is similar to a JSON-RPC request, but\n * has an extra `origin` field.\n * @returns The response promise, with extra {@link SnapRequestObject} fields.\n */\n request(request: RequestOptions): SnapRequest;\n\n /**\n * Send a transaction to the snap.\n *\n * @param transaction - The transaction. This is similar to an Ethereum\n * transaction object, but has an extra `origin` field. Any missing fields\n * will be filled in with default values.\n * @returns The response.\n */\n onTransaction(\n transaction?: Partial<TransactionOptions>,\n ): Promise<SnapResponseWithInterface>;\n\n /**\n * Send a transaction to the snap.\n *\n * @param transaction - The transaction. This is similar to an Ethereum\n * transaction object, but has an extra `origin` field. Any missing fields\n * will be filled in with default values.\n * @returns The response.\n * @deprecated Use {@link onTransaction} instead.\n */\n sendTransaction(\n transaction?: Partial<TransactionOptions>,\n ): Promise<SnapResponseWithInterface>;\n\n /**\n * Send a signature request to the snap.\n *\n * @param signature - The signature request object. Contains the params from\n * the various signature methods, but has an extra `origin` and `signatureMethod` field.\n * Any missing fields will be filled in with default values.\n * @returns The response.\n */\n onSignature(\n signature?: Partial<SignatureOptions>,\n ): Promise<SnapResponseWithInterface>;\n\n /**\n * Run a cronjob in the snap. This is similar to {@link request}, but the\n * request will be sent to the `onCronjob` method of the snap.\n *\n * @param cronjob - The cronjob request. This is similar to a JSON-RPC\n * request, and is normally specified in the snap manifest, under the\n * `endowment:cronjob` permission.\n * @returns The response promise, with extra {@link SnapRequestObject} fields.\n */\n onCronjob(cronjob?: Partial<CronjobOptions>): SnapRequest;\n\n /**\n * Run a cronjob in the snap. This is similar to {@link request}, but the\n * request will be sent to the `onCronjob` method of the snap.\n *\n * @param cronjob - The cronjob request. This is similar to a JSON-RPC\n * request, and is normally specified in the snap manifest, under the\n * `endowment:cronjob` permission.\n * @returns The response promise, with extra {@link SnapRequestObject} fields.\n * @deprecated Use {@link onCronjob} instead.\n */\n runCronjob(cronjob: CronjobOptions): SnapRequest;\n\n /**\n * Get the response from the snap's `onHomePage` method.\n *\n * @returns The response.\n */\n onHomePage(): Promise<SnapResponseWithInterface>;\n\n /**\n * Send a keyring request to the Snap.\n *\n * @param keyringRequest - Keyring request.\n * @returns The response.\n */\n onKeyringRequest(\n keyringRequest: KeyringOptions,\n ): Promise<SnapResponseWithoutInterface>;\n\n /**\n * Get the response from the Snap's `onInstall` handler.\n *\n * @returns The response.\n */\n onInstall(request?: Pick<RequestOptions, 'origin'>): SnapRequest;\n\n /**\n * Get the response from the Snap's `onUpdate` handler.\n *\n * @returns The response.\n */\n onUpdate(request?: Pick<RequestOptions, 'origin'>): SnapRequest;\n\n /**\n * Get the response from the Snap's `onNameLookup` handler.\n *\n * @returns The response.\n */\n onNameLookup(\n request: NameLookupOptions,\n ): Promise<SnapResponseWithoutInterface>;\n\n /**\n * Mock a JSON-RPC request. This will cause the snap to respond with the\n * specified response when a request with the specified method is sent.\n *\n * @param mock - The mock options.\n * @param mock.method - The JSON-RPC request method.\n * @param mock.result - The JSON-RPC response, which will be returned when a\n * request with the specified method is sent.\n * @example\n * import { installSnap } from '@metamask/snaps-jest';\n *\n * // In the test\n * const snap = await installSnap();\n * snap.mockJsonRpc({ method: 'eth_accounts', result: ['0x1234'] });\n *\n * // In the Snap\n * const response =\n * await ethereum.request({ method: 'eth_accounts' }); // ['0x1234']\n */\n mockJsonRpc(mock: JsonRpcMockOptions): {\n /**\n * Remove the mock.\n */\n unmock(): void;\n };\n\n /**\n * Close the page running the snap. This is mainly useful for cleaning up\n * the test environment, and calling it is not strictly necessary.\n *\n * @returns A promise that resolves when the page is closed.\n */\n close(): Promise<void>;\n};\n\n/**\n * Get the helper functions for the Snap.\n *\n * @param snap - The installed Snap.\n * @param snap.snapId - The ID of the Snap.\n * @param snap.store - The Redux store.\n * @param snap.executionService - The execution service.\n * @param snap.runSaga - The `runSaga` function.\n * @param snap.controllerMessenger - The controller messenger.\n * @param snap.options - The simulation options.\n * @returns The Snap helpers.\n */\nexport function getHelpers({\n snapId,\n store,\n executionService,\n runSaga,\n controllerMessenger,\n options,\n}: InstalledSnap & { options: SimulationOptions }): SnapHelpers {\n const onTransaction = async (\n request: TransactionOptions,\n ): Promise<SnapResponseWithInterface> => {\n log('Sending transaction %o.', request);\n\n const {\n origin: transactionOrigin,\n chainId,\n ...transaction\n } = create(request, TransactionOptionsStruct);\n\n const response = await handleRequest({\n snapId,\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 assertIsResponseWithInterface(response);\n\n return response;\n };\n\n const onCronjob = (request: CronjobOptions) => {\n log('Running cronjob %o.', options);\n\n return handleRequest({\n snapId,\n store,\n executionService,\n controllerMessenger,\n runSaga,\n handler: HandlerType.OnCronjob,\n request,\n });\n };\n\n const onKeyringRequest = async (\n request: KeyringOptions,\n ): Promise<SnapResponseWithoutInterface> => {\n log('Sending keyring request %o.', request);\n\n const response = await handleRequest({\n snapId,\n store,\n executionService,\n runSaga,\n controllerMessenger,\n handler: HandlerType.OnKeyringRequest,\n request,\n });\n\n return response;\n };\n\n return {\n request: (request) => {\n log('Sending request %o.', request);\n\n return handleRequest({\n snapId,\n store,\n executionService,\n controllerMessenger,\n runSaga,\n handler: HandlerType.OnRpcRequest,\n request,\n });\n },\n\n onTransaction,\n sendTransaction: onTransaction,\n\n onKeyringRequest,\n\n onInstall: (request?: Pick<RequestOptions, 'origin'>) => {\n log('Running onInstall handler.');\n\n return handleRequest({\n snapId,\n store,\n executionService,\n controllerMessenger,\n runSaga,\n handler: HandlerType.OnInstall,\n request: {\n method: '',\n ...request,\n },\n });\n },\n\n onUpdate: (request?: Pick<RequestOptions, 'origin'>) => {\n log('Running onUpdate handler.');\n\n return handleRequest({\n snapId,\n store,\n executionService,\n controllerMessenger,\n runSaga,\n handler: HandlerType.OnUpdate,\n request: {\n method: '',\n ...request,\n },\n });\n },\n\n onNameLookup: async (\n nameLookupOptions: NameLookupOptions,\n ): Promise<SnapResponseWithoutInterface> => {\n log('Requesting name lookup %o.', nameLookupOptions);\n\n const params = create(nameLookupOptions, NameLookupOptionsStruct);\n\n const response = await handleRequest({\n snapId,\n store,\n executionService,\n controllerMessenger,\n runSaga,\n handler: HandlerType.OnNameLookup,\n request: {\n method: '',\n params,\n },\n });\n\n return response;\n },\n\n onSignature: async (\n request: unknown,\n ): Promise<SnapResponseWithInterface> => {\n log('Requesting signature %o.', request);\n\n const { origin: signatureOrigin, ...signature } = create(\n request,\n SignatureOptionsStruct,\n );\n\n const response = await handleRequest({\n snapId,\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 assertIsResponseWithInterface(response);\n\n return response;\n },\n\n onCronjob,\n runCronjob: onCronjob,\n\n onHomePage: async (): Promise<SnapResponseWithInterface> => {\n log('Rendering home page.');\n\n const response = await handleRequest({\n snapId,\n store,\n executionService,\n controllerMessenger,\n runSaga,\n handler: HandlerType.OnHomePage,\n request: {\n method: '',\n },\n });\n\n assertIsResponseWithInterface(response);\n\n return response;\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 await executionService.terminateAllSnaps();\n },\n };\n}\n"]}
@@ -160,6 +160,19 @@ function getFormElement(form, name) {
160
160
  }
161
161
  return { element, form: form.props.name };
162
162
  }
163
+ /**
164
+ * Get an object containing the element, and optional form that's associated
165
+ * with the element if any.
166
+ *
167
+ * @param element - The JSX element.
168
+ * @returns An object containing the element and optional form.
169
+ */
170
+ function getElementWithOptionalForm(element) {
171
+ if (element.type !== 'Button' || !element.props.form) {
172
+ return { element };
173
+ }
174
+ return { element, form: element.props.form };
175
+ }
163
176
  /**
164
177
  * Get an element from a JSX tree with the given name.
165
178
  *
@@ -170,14 +183,14 @@ function getFormElement(form, name) {
170
183
  */
171
184
  function getElement(content, name) {
172
185
  if (isJSXElementWithName(content, name)) {
173
- return { element: content };
186
+ return getElementWithOptionalForm(content);
174
187
  }
175
188
  return (0, snaps_utils_1.walkJsx)(content, (element) => {
176
189
  if (element.type === 'Form') {
177
190
  return getFormElement(element, name);
178
191
  }
179
192
  if (isJSXElementWithName(element, name)) {
180
- return { element };
193
+ return getElementWithOptionalForm(element);
181
194
  }
182
195
  return undefined;
183
196
  });