@metamask/snaps-jest 4.0.0 → 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.
- package/CHANGELOG.md +21 -1
- package/README.md +66 -179
- package/dist/cjs/environment.js +21 -82
- package/dist/cjs/environment.js.map +1 -1
- package/dist/cjs/helpers.js +118 -43
- package/dist/cjs/helpers.js.map +1 -1
- package/dist/cjs/internals/environment.js +1 -1
- package/dist/cjs/internals/environment.js.map +1 -1
- package/dist/cjs/internals/index.js +1 -4
- package/dist/cjs/internals/index.js.map +1 -1
- package/dist/cjs/internals/request.js +42 -94
- package/dist/cjs/internals/request.js.map +1 -1
- package/dist/cjs/internals/server.js +0 -4
- package/dist/cjs/internals/server.js.map +1 -1
- package/dist/cjs/internals/simulation/constants.js +29 -0
- package/dist/cjs/internals/simulation/constants.js.map +1 -0
- package/dist/cjs/internals/simulation/controllers.js +95 -0
- package/dist/cjs/internals/simulation/controllers.js.map +1 -0
- package/dist/cjs/internals/simulation/files.js +22 -0
- package/dist/cjs/internals/simulation/files.js.map +1 -0
- package/dist/cjs/internals/simulation/index.js +24 -0
- package/dist/cjs/internals/simulation/index.js.map +1 -0
- package/dist/cjs/internals/simulation/interface.js +98 -0
- package/dist/cjs/internals/simulation/interface.js.map +1 -0
- package/dist/cjs/internals/simulation/methods/constants.js +84 -0
- package/dist/cjs/internals/simulation/methods/constants.js.map +1 -0
- package/dist/cjs/internals/simulation/methods/hooks/encryption.js +33 -0
- package/dist/cjs/internals/simulation/methods/hooks/encryption.js.map +1 -0
- package/dist/cjs/internals/simulation/methods/hooks/get-locale.js +17 -0
- package/dist/cjs/internals/simulation/methods/hooks/get-locale.js.map +1 -0
- package/dist/cjs/internals/simulation/methods/hooks/index.js +25 -0
- package/dist/cjs/internals/simulation/methods/hooks/index.js.map +1 -0
- package/dist/cjs/internals/simulation/methods/hooks/interface.js +26 -0
- package/dist/cjs/internals/simulation/methods/hooks/interface.js.map +1 -0
- package/dist/cjs/internals/simulation/methods/hooks/notifications.js +66 -0
- package/dist/cjs/internals/simulation/methods/hooks/notifications.js.map +1 -0
- package/dist/cjs/internals/simulation/methods/hooks/show-dialog.js +43 -0
- package/dist/cjs/internals/simulation/methods/hooks/show-dialog.js.map +1 -0
- package/dist/cjs/internals/simulation/methods/hooks/state.js +80 -0
- package/dist/cjs/internals/simulation/methods/hooks/state.js.map +1 -0
- package/dist/cjs/internals/simulation/methods/index.js +20 -0
- package/dist/cjs/internals/simulation/methods/index.js.map +1 -0
- package/dist/cjs/internals/simulation/methods/specifications.js +81 -0
- package/dist/cjs/internals/simulation/methods/specifications.js.map +1 -0
- package/dist/cjs/internals/simulation/middleware/engine.js +31 -0
- package/dist/cjs/internals/simulation/middleware/engine.js.map +1 -0
- package/dist/cjs/internals/simulation/middleware/index.js +20 -0
- package/dist/cjs/internals/simulation/middleware/index.js.map +1 -0
- package/dist/cjs/internals/simulation/middleware/internal-methods/accounts.js +30 -0
- package/dist/cjs/internals/simulation/middleware/internal-methods/accounts.js.map +1 -0
- package/dist/cjs/internals/simulation/middleware/internal-methods/index.js +20 -0
- package/dist/cjs/internals/simulation/middleware/internal-methods/index.js.map +1 -0
- package/dist/cjs/internals/simulation/middleware/internal-methods/middleware.js +37 -0
- package/dist/cjs/internals/simulation/middleware/internal-methods/middleware.js.map +1 -0
- package/dist/cjs/internals/simulation/middleware/internal-methods/provider-state.js +23 -0
- package/dist/cjs/internals/simulation/middleware/internal-methods/provider-state.js.map +1 -0
- package/dist/cjs/internals/simulation/middleware/mock.js +23 -0
- package/dist/cjs/internals/simulation/middleware/mock.js.map +1 -0
- package/dist/cjs/internals/simulation/options.js +24 -0
- package/dist/cjs/internals/simulation/options.js.map +1 -0
- package/dist/cjs/internals/simulation/simulation.js +124 -0
- package/dist/cjs/internals/simulation/simulation.js.map +1 -0
- package/dist/cjs/internals/simulation/store/index.js +23 -0
- package/dist/cjs/internals/simulation/store/index.js.map +1 -0
- package/dist/cjs/internals/simulation/store/mocks.js +52 -0
- package/dist/cjs/internals/simulation/store/mocks.js.map +1 -0
- package/dist/cjs/internals/simulation/store/notifications.js +52 -0
- package/dist/cjs/internals/simulation/store/notifications.js.map +1 -0
- package/dist/cjs/internals/simulation/store/state.js +64 -0
- package/dist/cjs/internals/simulation/store/state.js.map +1 -0
- package/dist/cjs/internals/simulation/store/store.js +57 -0
- package/dist/cjs/internals/simulation/store/store.js.map +1 -0
- package/dist/cjs/internals/simulation/store/ui.js +48 -0
- package/dist/cjs/internals/simulation/store/ui.js.map +1 -0
- package/dist/cjs/internals/structs.js +47 -5
- package/dist/cjs/internals/structs.js.map +1 -1
- package/dist/cjs/matchers.js +5 -2
- package/dist/cjs/matchers.js.map +1 -1
- package/dist/cjs/options.js +0 -6
- package/dist/cjs/options.js.map +1 -1
- package/dist/esm/environment.js +22 -83
- package/dist/esm/environment.js.map +1 -1
- package/dist/esm/helpers.js +127 -46
- package/dist/esm/helpers.js.map +1 -1
- package/dist/esm/internals/environment.js +1 -1
- package/dist/esm/internals/environment.js.map +1 -1
- package/dist/esm/internals/index.js +1 -5
- package/dist/esm/internals/index.js.map +1 -1
- package/dist/esm/internals/request.js +61 -104
- package/dist/esm/internals/request.js.map +1 -1
- package/dist/esm/internals/server.js +1 -5
- package/dist/esm/internals/server.js.map +1 -1
- package/dist/esm/internals/simulation/constants.js +12 -0
- package/dist/esm/internals/simulation/constants.js.map +1 -0
- package/dist/esm/internals/simulation/controllers.js +90 -0
- package/dist/esm/internals/simulation/controllers.js.map +1 -0
- package/dist/esm/internals/simulation/files.js +19 -0
- package/dist/esm/internals/simulation/files.js.map +1 -0
- package/dist/esm/internals/simulation/index.js +7 -0
- package/dist/esm/internals/simulation/index.js.map +1 -0
- package/dist/esm/internals/simulation/interface.js +95 -0
- package/dist/esm/internals/simulation/interface.js.map +1 -0
- package/dist/esm/internals/simulation/methods/constants.js +69 -0
- package/dist/esm/internals/simulation/methods/constants.js.map +1 -0
- package/dist/esm/internals/simulation/methods/hooks/encryption.js +39 -0
- package/dist/esm/internals/simulation/methods/hooks/encryption.js.map +1 -0
- package/dist/esm/internals/simulation/methods/hooks/get-locale.js +13 -0
- package/dist/esm/internals/simulation/methods/hooks/get-locale.js.map +1 -0
- package/dist/esm/internals/simulation/methods/hooks/index.js +8 -0
- package/dist/esm/internals/simulation/methods/hooks/index.js.map +1 -0
- package/dist/esm/internals/simulation/methods/hooks/interface.js +18 -0
- package/dist/esm/internals/simulation/methods/hooks/interface.js.map +1 -0
- package/dist/esm/internals/simulation/methods/hooks/notifications.js +58 -0
- package/dist/esm/internals/simulation/methods/hooks/notifications.js.map +1 -0
- package/dist/esm/internals/simulation/methods/hooks/show-dialog.js +38 -0
- package/dist/esm/internals/simulation/methods/hooks/show-dialog.js.map +1 -0
- package/dist/esm/internals/simulation/methods/hooks/state.js +74 -0
- package/dist/esm/internals/simulation/methods/hooks/state.js.map +1 -0
- package/dist/esm/internals/simulation/methods/index.js +3 -0
- package/dist/esm/internals/simulation/methods/index.js.map +1 -0
- package/dist/esm/internals/simulation/methods/specifications.js +84 -0
- package/dist/esm/internals/simulation/methods/specifications.js.map +1 -0
- package/dist/esm/internals/simulation/middleware/engine.js +33 -0
- package/dist/esm/internals/simulation/middleware/engine.js.map +1 -0
- package/dist/esm/internals/simulation/middleware/index.js +3 -0
- package/dist/esm/internals/simulation/middleware/index.js.map +1 -0
- package/dist/esm/internals/simulation/middleware/internal-methods/accounts.js +31 -0
- package/dist/esm/internals/simulation/middleware/internal-methods/accounts.js.map +1 -0
- package/dist/esm/internals/simulation/middleware/internal-methods/index.js +3 -0
- package/dist/esm/internals/simulation/middleware/internal-methods/index.js.map +1 -0
- package/dist/esm/internals/simulation/middleware/internal-methods/middleware.js +37 -0
- package/dist/esm/internals/simulation/middleware/internal-methods/middleware.js.map +1 -0
- package/dist/esm/internals/simulation/middleware/internal-methods/provider-state.js +23 -0
- package/dist/esm/internals/simulation/middleware/internal-methods/provider-state.js.map +1 -0
- package/dist/esm/internals/simulation/middleware/mock.js +18 -0
- package/dist/esm/internals/simulation/middleware/mock.js.map +1 -0
- package/dist/esm/internals/simulation/options.js +20 -0
- package/dist/esm/internals/simulation/options.js.map +1 -0
- package/dist/esm/internals/simulation/simulation.js +128 -0
- package/dist/esm/internals/simulation/simulation.js.map +1 -0
- package/dist/esm/internals/simulation/store/index.js +6 -0
- package/dist/esm/internals/simulation/store/index.js.map +1 -0
- package/dist/esm/internals/simulation/store/mocks.js +32 -0
- package/dist/esm/internals/simulation/store/mocks.js.map +1 -0
- package/dist/esm/internals/simulation/store/notifications.js +30 -0
- package/dist/esm/internals/simulation/store/notifications.js.map +1 -0
- package/dist/esm/internals/simulation/store/state.js +47 -0
- package/dist/esm/internals/simulation/store/state.js.map +1 -0
- package/dist/esm/internals/simulation/store/store.js +50 -0
- package/dist/esm/internals/simulation/store/store.js.map +1 -0
- package/dist/esm/internals/simulation/store/ui.js +21 -0
- package/dist/esm/internals/simulation/store/ui.js.map +1 -0
- package/dist/esm/internals/structs.js +41 -5
- package/dist/esm/internals/structs.js.map +1 -1
- package/dist/esm/matchers.js +5 -2
- package/dist/esm/matchers.js.map +1 -1
- package/dist/esm/options.js +1 -7
- package/dist/esm/options.js.map +1 -1
- package/dist/esm/types.js.map +1 -1
- package/dist/types/environment.d.ts +14 -15
- package/dist/types/helpers.d.ts +64 -3
- package/dist/types/internals/index.d.ts +1 -4
- package/dist/types/internals/request.d.ts +38 -56
- package/dist/types/internals/simulation/constants.d.ts +13 -0
- package/dist/types/internals/simulation/controllers.d.ts +40 -0
- package/dist/types/internals/simulation/files.d.ts +11 -0
- package/dist/types/internals/simulation/index.d.ts +5 -0
- package/dist/types/internals/simulation/interface.d.ts +25 -0
- package/dist/types/internals/simulation/methods/constants.d.ts +10 -0
- package/dist/types/internals/simulation/methods/hooks/encryption.d.ts +29 -0
- package/dist/types/internals/simulation/methods/hooks/get-locale.d.ts +9 -0
- package/dist/types/internals/simulation/methods/hooks/index.d.ts +6 -0
- package/dist/types/internals/simulation/methods/hooks/interface.d.ts +16 -0
- package/dist/types/internals/simulation/methods/hooks/notifications.d.ts +16 -0
- package/dist/types/internals/simulation/methods/hooks/show-dialog.d.ts +9 -0
- package/dist/types/internals/simulation/methods/hooks/state.d.ts +22 -0
- package/dist/types/internals/simulation/methods/index.d.ts +1 -0
- package/dist/types/internals/simulation/methods/specifications.d.ts +56 -0
- package/dist/types/internals/simulation/middleware/engine.d.ts +26 -0
- package/dist/types/internals/simulation/middleware/index.d.ts +1 -0
- package/dist/types/internals/simulation/middleware/internal-methods/accounts.d.ts +18 -0
- package/dist/types/internals/simulation/middleware/internal-methods/index.d.ts +1 -0
- package/dist/types/internals/simulation/middleware/internal-methods/middleware.d.ts +22 -0
- package/dist/types/internals/simulation/middleware/internal-methods/provider-state.d.ts +14 -0
- package/dist/types/internals/simulation/middleware/mock.d.ts +10 -0
- package/dist/types/internals/simulation/options.d.ts +37 -0
- package/dist/types/internals/simulation/simulation.d.ts +98 -0
- package/dist/types/internals/simulation/store/index.d.ts +4 -0
- package/dist/types/internals/simulation/store/mocks.d.ts +35 -0
- package/dist/types/internals/simulation/store/notifications.d.ts +44 -0
- package/dist/types/internals/simulation/store/state.d.ts +55 -0
- package/dist/types/internals/simulation/store/store.d.ts +22 -0
- package/dist/types/internals/simulation/store/ui.d.ts +25 -0
- package/dist/types/internals/structs.d.ts +229 -16
- package/dist/types/options.d.ts +3 -35
- package/dist/types/types.d.ts +88 -41
- package/package.json +21 -12
- package/dist/cjs/internals/interface.js +0 -103
- package/dist/cjs/internals/interface.js.map +0 -1
- package/dist/cjs/internals/network.js +0 -148
- package/dist/cjs/internals/network.js.map +0 -1
- package/dist/cjs/internals/types.js +0 -6
- package/dist/cjs/internals/types.js.map +0 -1
- package/dist/cjs/internals/wait-for.js +0 -63
- package/dist/cjs/internals/wait-for.js.map +0 -1
- package/dist/esm/internals/interface.js +0 -100
- package/dist/esm/internals/interface.js.map +0 -1
- package/dist/esm/internals/network.js +0 -143
- package/dist/esm/internals/network.js.map +0 -1
- package/dist/esm/internals/types.js +0 -3
- package/dist/esm/internals/types.js.map +0 -1
- package/dist/esm/internals/wait-for.js +0 -63
- package/dist/esm/internals/wait-for.js.map +0 -1
- package/dist/types/internals/interface.d.ts +0 -25
- package/dist/types/internals/network.d.ts +0 -87
- package/dist/types/internals/types.d.ts +0 -18
- package/dist/types/internals/wait-for.d.ts +0 -38
package/dist/cjs/helpers.js
CHANGED
|
@@ -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
|
|
13
|
+
const _superstruct = require("superstruct");
|
|
13
14
|
const _internals = require("./internals");
|
|
14
|
-
|
|
15
|
-
const { getByTestId } = _pptrtestinglibrary.queries;
|
|
15
|
+
const _mocks = require("./internals/simulation/store/mocks");
|
|
16
16
|
const log = (0, _utils.createModuleLogger)(_internals.rootLogger, 'helpers');
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
}
|
|
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: (
|
|
37
|
-
log('Sending request %o.',
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
57
|
-
log('Mocking %o.',
|
|
58
|
-
|
|
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
|
-
|
|
61
|
-
log('
|
|
62
|
-
|
|
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
|
}
|
package/dist/cjs/helpers.js.map
CHANGED
|
@@ -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,
|
|
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 './
|
|
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
|
-
|
|
13
|
-
return
|
|
12
|
+
handleRequest: function() {
|
|
13
|
+
return handleRequest;
|
|
14
14
|
},
|
|
15
|
-
|
|
16
|
-
return
|
|
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
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
chainId,
|
|
91
|
-
transaction,
|
|
92
|
-
transactionOrigin
|
|
93
|
-
}
|
|
29
|
+
id: 1,
|
|
30
|
+
...options
|
|
94
31
|
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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
|
-
|
|
109
|
-
|
|
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
|
|
118
|
-
|
|
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 {
|
|
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
|
|
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"}
|