@metamask/snaps-execution-environments 3.3.0 → 3.4.1
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 +15 -1
- package/dist/browserify/iframe/bundle.js +6 -11
- package/dist/browserify/node-process/bundle.js +5 -10
- package/dist/browserify/node-thread/bundle.js +5 -10
- package/dist/browserify/offscreen/bundle.js +6 -4
- package/dist/browserify/worker-executor/bundle.js +6 -11
- package/dist/browserify/worker-pool/bundle.js +6 -4
- package/dist/cjs/common/BaseSnapExecutor.js +35 -9
- package/dist/cjs/common/BaseSnapExecutor.js.map +1 -1
- package/dist/cjs/common/endowments/commonEndowmentFactory.js.map +1 -1
- package/dist/cjs/common/endowments/index.js +3 -2
- package/dist/cjs/common/endowments/index.js.map +1 -1
- package/dist/cjs/common/endowments/network.js +130 -43
- package/dist/cjs/common/endowments/network.js.map +1 -1
- package/dist/cjs/common/utils.js +1 -0
- package/dist/cjs/common/utils.js.map +1 -1
- package/dist/cjs/common/validation.js +11 -8
- package/dist/cjs/common/validation.js.map +1 -1
- package/dist/cjs/iframe/IFrameSnapExecutor.js +2 -2
- package/dist/cjs/iframe/IFrameSnapExecutor.js.map +1 -1
- package/dist/cjs/node-process/ChildProcessSnapExecutor.js +2 -2
- package/dist/cjs/node-process/ChildProcessSnapExecutor.js.map +1 -1
- package/dist/cjs/node-thread/ThreadSnapExecutor.js +2 -2
- package/dist/cjs/node-thread/ThreadSnapExecutor.js.map +1 -1
- package/dist/cjs/webworker/executor/WebWorkerSnapExecutor.js +2 -2
- package/dist/cjs/webworker/executor/WebWorkerSnapExecutor.js.map +1 -1
- package/dist/esm/common/BaseSnapExecutor.js +38 -12
- package/dist/esm/common/BaseSnapExecutor.js.map +1 -1
- package/dist/esm/common/endowments/commonEndowmentFactory.js.map +1 -1
- package/dist/esm/common/endowments/index.js +9 -6
- package/dist/esm/common/endowments/index.js.map +1 -1
- package/dist/esm/common/endowments/network.js +129 -42
- package/dist/esm/common/endowments/network.js.map +1 -1
- package/dist/esm/common/utils.js +1 -0
- package/dist/esm/common/utils.js.map +1 -1
- package/dist/esm/common/validation.js +13 -10
- package/dist/esm/common/validation.js.map +1 -1
- package/dist/esm/iframe/IFrameSnapExecutor.js +1 -1
- package/dist/esm/iframe/IFrameSnapExecutor.js.map +1 -1
- package/dist/esm/node-process/ChildProcessSnapExecutor.js +1 -1
- package/dist/esm/node-process/ChildProcessSnapExecutor.js.map +1 -1
- package/dist/esm/node-thread/ThreadSnapExecutor.js +1 -1
- package/dist/esm/node-thread/ThreadSnapExecutor.js.map +1 -1
- package/dist/esm/webworker/executor/WebWorkerSnapExecutor.js +1 -1
- package/dist/esm/webworker/executor/WebWorkerSnapExecutor.js.map +1 -1
- package/dist/types/common/BaseSnapExecutor.d.ts +4 -3
- package/dist/types/common/endowments/commonEndowmentFactory.d.ts +2 -0
- package/dist/types/common/endowments/index.d.ts +14 -5
- package/dist/types/common/endowments/network.d.ts +2 -1
- package/dist/types/common/validation.d.ts +10 -14
- package/package.json +8 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/common/endowments/index.ts"],"sourcesContent":["import type { StreamProvider } from '@metamask/providers';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport type { SnapsProvider } from '@metamask/snaps-sdk';\nimport { logWarning } from '@metamask/snaps-utils';\nimport { hasProperty } from '@metamask/utils';\n\nimport { rootRealmGlobal } from '../globalObject';\nimport type { EndowmentFactoryOptions } from './commonEndowmentFactory';\nimport buildCommonEndowments from './commonEndowmentFactory';\n\ntype EndowmentFactoryResult = {\n /**\n * A function that performs any necessary teardown when the snap becomes idle.\n *\n * NOTE:** The endowments are not reconstructed if the snap is re-invoked\n * before being terminated, so the teardown operation must not render the\n * endowments unusable; it should simply restore the endowments to their\n * original state.\n */\n teardownFunction?: () => Promise<void> | void;\n [key: string]: unknown;\n};\n\n/**\n * Retrieve consolidated endowment factories for common endowments.\n */\nconst registeredEndowments = buildCommonEndowments();\n\n/**\n * A map of endowment names to their factory functions. Some endowments share\n * the same factory function, but we only call each factory once for each snap.\n * See {@link createEndowments} for details.\n */\nconst endowmentFactories = registeredEndowments.reduce((factories, builder) => {\n builder.names.forEach((name) => {\n factories.set(name, builder.factory);\n });\n return factories;\n}, new Map<string, (options?: EndowmentFactoryOptions) => EndowmentFactoryResult>());\n\n/**\n * Gets the endowments for a particular Snap. Some endowments, like `setTimeout`\n * and `clearTimeout`, must be attenuated so that they can only affect behavior\n * within the Snap's own realm. Therefore, we use factory functions to create\n * such attenuated / modified endowments. Otherwise, the value that's on the\n * root realm global will be used.\n *\n * @param snap - The Snaps global API object.\n * @param ethereum - The Snap's EIP-1193 provider object.\n * @param snapId - The id of the snap that will use the created endowments.\n * @param endowments - The list of endowments to provide to the snap.\n * @returns An object containing the Snap's endowments.\n */\nexport function createEndowments(\n snap: SnapsProvider
|
|
1
|
+
{"version":3,"sources":["../../../../src/common/endowments/index.ts"],"sourcesContent":["import type { StreamProvider } from '@metamask/providers';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport type { SnapsProvider } from '@metamask/snaps-sdk';\nimport { logWarning } from '@metamask/snaps-utils';\nimport { hasProperty } from '@metamask/utils';\n\nimport type { NotifyFunction } from '../BaseSnapExecutor';\nimport { rootRealmGlobal } from '../globalObject';\nimport type { EndowmentFactoryOptions } from './commonEndowmentFactory';\nimport buildCommonEndowments from './commonEndowmentFactory';\n\ntype EndowmentFactoryResult = {\n /**\n * A function that performs any necessary teardown when the snap becomes idle.\n *\n * NOTE:** The endowments are not reconstructed if the snap is re-invoked\n * before being terminated, so the teardown operation must not render the\n * endowments unusable; it should simply restore the endowments to their\n * original state.\n */\n teardownFunction?: () => Promise<void> | void;\n [key: string]: unknown;\n};\n\n/**\n * Retrieve consolidated endowment factories for common endowments.\n */\nconst registeredEndowments = buildCommonEndowments();\n\n/**\n * A map of endowment names to their factory functions. Some endowments share\n * the same factory function, but we only call each factory once for each snap.\n * See {@link createEndowments} for details.\n */\nconst endowmentFactories = registeredEndowments.reduce((factories, builder) => {\n builder.names.forEach((name) => {\n factories.set(name, builder.factory);\n });\n return factories;\n}, new Map<string, (options?: EndowmentFactoryOptions) => EndowmentFactoryResult>());\n\n/**\n * Gets the endowments for a particular Snap. Some endowments, like `setTimeout`\n * and `clearTimeout`, must be attenuated so that they can only affect behavior\n * within the Snap's own realm. Therefore, we use factory functions to create\n * such attenuated / modified endowments. Otherwise, the value that's on the\n * root realm global will be used.\n *\n * @param options - An options bag.\n * @param options.snap - The Snaps global API object.\n * @param options.ethereum - The Snap's EIP-1193 provider object.\n * @param options.snapId - The id of the snap that will use the created endowments.\n * @param options.endowments - The list of endowments to provide to the snap.\n * @param options.notify - A reference to the notify function of the snap executor.\n * @returns An object containing the Snap's endowments.\n */\nexport function createEndowments({\n snap,\n ethereum,\n snapId,\n endowments,\n notify,\n}: {\n snap: SnapsProvider;\n ethereum: StreamProvider;\n snapId: string;\n endowments: string[];\n notify: NotifyFunction;\n}): { endowments: Record<string, unknown>; teardown: () => Promise<void> } {\n const attenuatedEndowments: Record<string, unknown> = {};\n\n // TODO: All endowments should be hardened to prevent covert communication\n // channels. Hardening the returned objects breaks tests elsewhere in the\n // monorepo, so further research is needed.\n const result = endowments.reduce<{\n allEndowments: Record<string, unknown>;\n teardowns: (() => Promise<void> | void)[];\n }>(\n ({ allEndowments, teardowns }, endowmentName) => {\n // First, check if the endowment has a factory, and default to that.\n if (endowmentFactories.has(endowmentName)) {\n if (!hasProperty(attenuatedEndowments, endowmentName)) {\n // Call the endowment factory for the current endowment. If the factory\n // creates multiple endowments, they will all be assigned to the\n // `attenuatedEndowments` object, but will only be passed on to the snap\n // if explicitly listed among its endowment.\n // This may not have an actual use case, but, safety first.\n\n // We just confirmed that endowmentFactories has the specified key.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const { teardownFunction, ...endowment } = endowmentFactories.get(\n endowmentName,\n )!({ snapId, notify });\n Object.assign(attenuatedEndowments, endowment);\n if (teardownFunction) {\n teardowns.push(teardownFunction);\n }\n }\n allEndowments[endowmentName] = attenuatedEndowments[endowmentName];\n } else if (endowmentName === 'ethereum') {\n // Special case for adding the EIP-1193 provider.\n allEndowments[endowmentName] = ethereum;\n } else if (endowmentName in rootRealmGlobal) {\n logWarning(`Access to unhardened global ${endowmentName}.`);\n // If the endowment doesn't have a factory, just use whatever is on the\n // global object.\n const globalValue = (rootRealmGlobal as Record<string, unknown>)[\n endowmentName\n ];\n allEndowments[endowmentName] = globalValue;\n } else {\n // If we get to this point, we've been passed an endowment that doesn't\n // exist in our current environment.\n throw rpcErrors.internal(`Unknown endowment: \"${endowmentName}\".`);\n }\n return { allEndowments, teardowns };\n },\n {\n allEndowments: { snap },\n teardowns: [],\n },\n );\n\n const teardown = async () => {\n await Promise.all(\n result.teardowns.map((teardownFunction) => teardownFunction()),\n );\n };\n return { endowments: result.allEndowments, teardown };\n}\n"],"names":["rpcErrors","logWarning","hasProperty","rootRealmGlobal","buildCommonEndowments","registeredEndowments","endowmentFactories","reduce","factories","builder","names","forEach","name","set","factory","Map","createEndowments","snap","ethereum","snapId","endowments","notify","attenuatedEndowments","result","allEndowments","teardowns","endowmentName","has","teardownFunction","endowment","get","Object","assign","push","globalValue","internal","teardown","Promise","all","map"],"mappings":"AACA,SAASA,SAAS,QAAQ,uBAAuB;AAEjD,SAASC,UAAU,QAAQ,wBAAwB;AACnD,SAASC,WAAW,QAAQ,kBAAkB;AAG9C,SAASC,eAAe,QAAQ,kBAAkB;AAElD,OAAOC,2BAA2B,2BAA2B;AAe7D;;CAEC,GACD,MAAMC,uBAAuBD;AAE7B;;;;CAIC,GACD,MAAME,qBAAqBD,qBAAqBE,MAAM,CAAC,CAACC,WAAWC;IACjEA,QAAQC,KAAK,CAACC,OAAO,CAAC,CAACC;QACrBJ,UAAUK,GAAG,CAACD,MAAMH,QAAQK,OAAO;IACrC;IACA,OAAON;AACT,GAAG,IAAIO;AAEP;;;;;;;;;;;;;;CAcC,GACD,OAAO,SAASC,iBAAiB,EAC/BC,IAAI,EACJC,QAAQ,EACRC,MAAM,EACNC,UAAU,EACVC,MAAM,EAOP;IACC,MAAMC,uBAAgD,CAAC;IAEvD,0EAA0E;IAC1E,yEAAyE;IACzE,2CAA2C;IAC3C,MAAMC,SAASH,WAAWb,MAAM,CAI9B,CAAC,EAAEiB,aAAa,EAAEC,SAAS,EAAE,EAAEC;QAC7B,oEAAoE;QACpE,IAAIpB,mBAAmBqB,GAAG,CAACD,gBAAgB;YACzC,IAAI,CAACxB,YAAYoB,sBAAsBI,gBAAgB;gBACrD,uEAAuE;gBACvE,gEAAgE;gBAChE,wEAAwE;gBACxE,4CAA4C;gBAC5C,2DAA2D;gBAE3D,mEAAmE;gBACnE,oEAAoE;gBACpE,MAAM,EAAEE,gBAAgB,EAAE,GAAGC,WAAW,GAAGvB,mBAAmBwB,GAAG,CAC/DJ,eACC;oBAAEP;oBAAQE;gBAAO;gBACpBU,OAAOC,MAAM,CAACV,sBAAsBO;gBACpC,IAAID,kBAAkB;oBACpBH,UAAUQ,IAAI,CAACL;gBACjB;YACF;YACAJ,aAAa,CAACE,cAAc,GAAGJ,oBAAoB,CAACI,cAAc;QACpE,OAAO,IAAIA,kBAAkB,YAAY;YACvC,iDAAiD;YACjDF,aAAa,CAACE,cAAc,GAAGR;QACjC,OAAO,IAAIQ,iBAAiBvB,iBAAiB;YAC3CF,WAAW,CAAC,4BAA4B,EAAEyB,cAAc,CAAC,CAAC;YAC1D,uEAAuE;YACvE,iBAAiB;YACjB,MAAMQ,cAAc,AAAC/B,eAA2C,CAC9DuB,cACD;YACDF,aAAa,CAACE,cAAc,GAAGQ;QACjC,OAAO;YACL,uEAAuE;YACvE,oCAAoC;YACpC,MAAMlC,UAAUmC,QAAQ,CAAC,CAAC,oBAAoB,EAAET,cAAc,EAAE,CAAC;QACnE;QACA,OAAO;YAAEF;YAAeC;QAAU;IACpC,GACA;QACED,eAAe;YAAEP;QAAK;QACtBQ,WAAW,EAAE;IACf;IAGF,MAAMW,WAAW;QACf,MAAMC,QAAQC,GAAG,CACff,OAAOE,SAAS,CAACc,GAAG,CAAC,CAACX,mBAAqBA;IAE/C;IACA,OAAO;QAAER,YAAYG,OAAOC,aAAa;QAAEY;IAAS;AACtD"}
|
|
@@ -38,8 +38,9 @@ function _class_private_field_set(receiver, privateMap, value) {
|
|
|
38
38
|
_class_apply_descriptor_set(receiver, descriptor, value);
|
|
39
39
|
return value;
|
|
40
40
|
}
|
|
41
|
+
import { assert } from '@metamask/utils';
|
|
41
42
|
import { withTeardown } from '../utils';
|
|
42
|
-
var _teardownRef = /*#__PURE__*/ new WeakMap(), _ogResponse = /*#__PURE__*/ new WeakMap();
|
|
43
|
+
var _teardownRef = /*#__PURE__*/ new WeakMap(), _ogResponse = /*#__PURE__*/ new WeakMap(), _onStart = /*#__PURE__*/ new WeakMap(), _onFinish = /*#__PURE__*/ new WeakMap();
|
|
43
44
|
/**
|
|
44
45
|
* This class wraps a Response object.
|
|
45
46
|
* That way, a teardown process can stop any processes left.
|
|
@@ -72,25 +73,60 @@ var _teardownRef = /*#__PURE__*/ new WeakMap(), _ogResponse = /*#__PURE__*/ new
|
|
|
72
73
|
return _class_private_field_get(this, _ogResponse).url;
|
|
73
74
|
}
|
|
74
75
|
async text() {
|
|
75
|
-
return withTeardown(
|
|
76
|
+
return await withTeardown((async ()=>{
|
|
77
|
+
await _class_private_field_get(this, _onStart).call(this);
|
|
78
|
+
try {
|
|
79
|
+
return await _class_private_field_get(this, _ogResponse).text();
|
|
80
|
+
} finally{
|
|
81
|
+
await _class_private_field_get(this, _onFinish).call(this);
|
|
82
|
+
}
|
|
83
|
+
})(), _class_private_field_get(this, _teardownRef));
|
|
76
84
|
}
|
|
77
85
|
async arrayBuffer() {
|
|
78
|
-
return withTeardown(
|
|
86
|
+
return await withTeardown((async ()=>{
|
|
87
|
+
await _class_private_field_get(this, _onStart).call(this);
|
|
88
|
+
try {
|
|
89
|
+
return await _class_private_field_get(this, _ogResponse).arrayBuffer();
|
|
90
|
+
} finally{
|
|
91
|
+
await _class_private_field_get(this, _onFinish).call(this);
|
|
92
|
+
}
|
|
93
|
+
})(), _class_private_field_get(this, _teardownRef));
|
|
79
94
|
}
|
|
80
95
|
async blob() {
|
|
81
|
-
return withTeardown(
|
|
96
|
+
return await withTeardown((async ()=>{
|
|
97
|
+
await _class_private_field_get(this, _onStart).call(this);
|
|
98
|
+
try {
|
|
99
|
+
return await _class_private_field_get(this, _ogResponse).blob();
|
|
100
|
+
} finally{
|
|
101
|
+
await _class_private_field_get(this, _onFinish).call(this);
|
|
102
|
+
}
|
|
103
|
+
})(), _class_private_field_get(this, _teardownRef));
|
|
82
104
|
}
|
|
83
105
|
clone() {
|
|
84
106
|
const newResponse = _class_private_field_get(this, _ogResponse).clone();
|
|
85
|
-
return new ResponseWrapper(newResponse, _class_private_field_get(this, _teardownRef));
|
|
107
|
+
return new ResponseWrapper(newResponse, _class_private_field_get(this, _teardownRef), _class_private_field_get(this, _onStart), _class_private_field_get(this, _onFinish));
|
|
86
108
|
}
|
|
87
109
|
async formData() {
|
|
88
|
-
return withTeardown(
|
|
110
|
+
return await withTeardown((async ()=>{
|
|
111
|
+
await _class_private_field_get(this, _onStart).call(this);
|
|
112
|
+
try {
|
|
113
|
+
return await _class_private_field_get(this, _ogResponse).formData();
|
|
114
|
+
} finally{
|
|
115
|
+
await _class_private_field_get(this, _onFinish).call(this);
|
|
116
|
+
}
|
|
117
|
+
})(), _class_private_field_get(this, _teardownRef));
|
|
89
118
|
}
|
|
90
119
|
async json() {
|
|
91
|
-
return withTeardown(
|
|
120
|
+
return await withTeardown((async ()=>{
|
|
121
|
+
await _class_private_field_get(this, _onStart).call(this);
|
|
122
|
+
try {
|
|
123
|
+
return await _class_private_field_get(this, _ogResponse).json();
|
|
124
|
+
} finally{
|
|
125
|
+
await _class_private_field_get(this, _onFinish).call(this);
|
|
126
|
+
}
|
|
127
|
+
})(), _class_private_field_get(this, _teardownRef));
|
|
92
128
|
}
|
|
93
|
-
constructor(ogResponse, teardownRef){
|
|
129
|
+
constructor(ogResponse, teardownRef, onStart, onFinish){
|
|
94
130
|
_class_private_field_init(this, _teardownRef, {
|
|
95
131
|
writable: true,
|
|
96
132
|
value: void 0
|
|
@@ -99,8 +135,18 @@ var _teardownRef = /*#__PURE__*/ new WeakMap(), _ogResponse = /*#__PURE__*/ new
|
|
|
99
135
|
writable: true,
|
|
100
136
|
value: void 0
|
|
101
137
|
});
|
|
138
|
+
_class_private_field_init(this, _onStart, {
|
|
139
|
+
writable: true,
|
|
140
|
+
value: void 0
|
|
141
|
+
});
|
|
142
|
+
_class_private_field_init(this, _onFinish, {
|
|
143
|
+
writable: true,
|
|
144
|
+
value: void 0
|
|
145
|
+
});
|
|
102
146
|
_class_private_field_set(this, _ogResponse, ogResponse);
|
|
103
147
|
_class_private_field_set(this, _teardownRef, teardownRef);
|
|
148
|
+
_class_private_field_set(this, _onStart, onStart);
|
|
149
|
+
_class_private_field_set(this, _onFinish, onFinish);
|
|
104
150
|
}
|
|
105
151
|
}
|
|
106
152
|
/**
|
|
@@ -113,9 +159,12 @@ var _teardownRef = /*#__PURE__*/ new WeakMap(), _ogResponse = /*#__PURE__*/ new
|
|
|
113
159
|
* to ensure that a bad actor cannot get access to the original function, thus
|
|
114
160
|
* potentially preventing the network requests from being torn down.
|
|
115
161
|
*
|
|
162
|
+
* @param options - An options bag.
|
|
163
|
+
* @param options.notify - A reference to the notify function of the snap executor.
|
|
116
164
|
* @returns An object containing a wrapped `fetch`
|
|
117
165
|
* function, as well as a teardown function.
|
|
118
|
-
*/ const createNetwork = ()=>{
|
|
166
|
+
*/ const createNetwork = ({ notify } = {})=>{
|
|
167
|
+
assert(notify, 'Notify must be passed to network endowment factory');
|
|
119
168
|
// Open fetch calls or open body streams
|
|
120
169
|
const openConnections = new Set();
|
|
121
170
|
// Track last teardown count
|
|
@@ -135,43 +184,81 @@ var _teardownRef = /*#__PURE__*/ new WeakMap(), _ogResponse = /*#__PURE__*/ new
|
|
|
135
184
|
once: true
|
|
136
185
|
});
|
|
137
186
|
}
|
|
187
|
+
let started = false;
|
|
188
|
+
const onStart = async ()=>{
|
|
189
|
+
if (!started) {
|
|
190
|
+
started = true;
|
|
191
|
+
await notify({
|
|
192
|
+
method: 'OutboundRequest',
|
|
193
|
+
params: {
|
|
194
|
+
source: 'fetch'
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
let finished = false;
|
|
200
|
+
const onFinish = async ()=>{
|
|
201
|
+
if (!finished) {
|
|
202
|
+
finished = true;
|
|
203
|
+
await notify({
|
|
204
|
+
method: 'OutboundResponse',
|
|
205
|
+
params: {
|
|
206
|
+
source: 'fetch'
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
};
|
|
138
211
|
let res;
|
|
139
212
|
let openFetchConnection;
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
213
|
+
return await withTeardown((async ()=>{
|
|
214
|
+
try {
|
|
215
|
+
await notify({
|
|
216
|
+
method: 'OutboundRequest',
|
|
217
|
+
params: {
|
|
218
|
+
source: 'fetch'
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
const fetchPromise = fetch(input, {
|
|
222
|
+
...init,
|
|
223
|
+
signal: abortController.signal
|
|
224
|
+
});
|
|
225
|
+
openFetchConnection = {
|
|
226
|
+
cancel: async ()=>{
|
|
227
|
+
abortController.abort();
|
|
228
|
+
try {
|
|
229
|
+
await fetchPromise;
|
|
230
|
+
} catch {
|
|
231
|
+
/* do nothing */ }
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
openConnections.add(openFetchConnection);
|
|
235
|
+
res = new ResponseWrapper(await fetchPromise, teardownRef, onStart, onFinish);
|
|
236
|
+
} finally{
|
|
237
|
+
if (openFetchConnection !== undefined) {
|
|
238
|
+
openConnections.delete(openFetchConnection);
|
|
152
239
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
240
|
+
await notify({
|
|
241
|
+
method: 'OutboundResponse',
|
|
242
|
+
params: {
|
|
243
|
+
source: 'fetch'
|
|
244
|
+
}
|
|
245
|
+
});
|
|
159
246
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
247
|
+
if (res.body !== null) {
|
|
248
|
+
const body = new WeakRef(res.body);
|
|
249
|
+
const openBodyConnection = {
|
|
250
|
+
cancel: /* istanbul ignore next: see it.todo('can be torn down during body read') test */ async ()=>{
|
|
251
|
+
try {
|
|
252
|
+
await body.deref()?.cancel();
|
|
253
|
+
} catch {
|
|
254
|
+
/* do nothing */ }
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
openConnections.add(openBodyConnection);
|
|
258
|
+
cleanup.register(res.body, /* istanbul ignore next: can't test garbage collection without modifying node parameters */ ()=>openConnections.delete(openBodyConnection));
|
|
259
|
+
}
|
|
260
|
+
return harden(res);
|
|
261
|
+
})(), teardownRef);
|
|
175
262
|
};
|
|
176
263
|
const teardownFunction = async ()=>{
|
|
177
264
|
teardownRef.lastTeardown += 1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/common/endowments/network.ts"],"sourcesContent":["import { withTeardown } from '../utils';\n\n/**\n * This class wraps a Response object.\n * That way, a teardown process can stop any processes left.\n */\nclass ResponseWrapper implements Response {\n readonly #teardownRef: { lastTeardown: number };\n\n #ogResponse: Response;\n\n constructor(ogResponse: Response, teardownRef: { lastTeardown: number }) {\n this.#ogResponse = ogResponse;\n this.#teardownRef = teardownRef;\n }\n\n get body(): ReadableStream<Uint8Array> | null {\n return this.#ogResponse.body;\n }\n\n get bodyUsed() {\n return this.#ogResponse.bodyUsed;\n }\n\n get headers() {\n return this.#ogResponse.headers;\n }\n\n get ok() {\n return this.#ogResponse.ok;\n }\n\n get redirected() {\n return this.#ogResponse.redirected;\n }\n\n get status() {\n return this.#ogResponse.status;\n }\n\n get statusText() {\n return this.#ogResponse.statusText;\n }\n\n get type() {\n return this.#ogResponse.type;\n }\n\n get url() {\n return this.#ogResponse.url;\n }\n\n async text() {\n return withTeardown<string>(this.#ogResponse.text(), this as any);\n }\n\n async arrayBuffer(): Promise<ArrayBuffer> {\n return withTeardown<ArrayBuffer>(\n this.#ogResponse.arrayBuffer(),\n this as any,\n );\n }\n\n async blob(): Promise<Blob> {\n return withTeardown<Blob>(this.#ogResponse.blob(), this as any);\n }\n\n clone(): Response {\n const newResponse = this.#ogResponse.clone();\n return new ResponseWrapper(newResponse, this.#teardownRef);\n }\n\n async formData(): Promise<FormData> {\n return withTeardown<FormData>(this.#ogResponse.formData(), this as any);\n }\n\n async json(): Promise<any> {\n return withTeardown(this.#ogResponse.json(), this as any);\n }\n}\n\n/**\n * Create a network endowment, consisting of a `fetch` function.\n * This allows us to provide a teardown function, so that we can cancel\n * any pending requests, connections, streams, etc. that may be open when a snap\n * is terminated.\n *\n * This wraps the original implementation of `fetch`,\n * to ensure that a bad actor cannot get access to the original function, thus\n * potentially preventing the network requests from being torn down.\n *\n * @returns An object containing a wrapped `fetch`\n * function, as well as a teardown function.\n */\nconst createNetwork = () => {\n // Open fetch calls or open body streams\n const openConnections = new Set<{ cancel: () => Promise<void> }>();\n // Track last teardown count\n const teardownRef = { lastTeardown: 0 };\n\n // Remove items from openConnections after they were garbage collected\n const cleanup = new FinalizationRegistry<() => void>(\n /* istanbul ignore next: can't test garbage collection without modifying node parameters */\n (callback) => callback(),\n );\n\n const _fetch: typeof fetch = async (\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> => {\n const abortController = new AbortController();\n if (init?.signal !== null && init?.signal !== undefined) {\n const originalSignal = init.signal;\n // Merge abort controllers\n originalSignal.addEventListener(\n 'abort',\n () => {\n abortController.abort((originalSignal as any).reason);\n },\n { once: true },\n );\n }\n\n let res: Response;\n let openFetchConnection: { cancel: () => Promise<void> } | undefined;\n try {\n const fetchPromise = fetch(input, {\n ...init,\n signal: abortController.signal,\n });\n\n openFetchConnection = {\n cancel: async () => {\n abortController.abort();\n try {\n await fetchPromise;\n } catch {\n /* do nothing */\n }\n },\n };\n openConnections.add(openFetchConnection);\n\n res = new ResponseWrapper(\n await withTeardown(fetchPromise, teardownRef),\n teardownRef,\n );\n } finally {\n if (openFetchConnection !== undefined) {\n openConnections.delete(openFetchConnection);\n }\n }\n\n if (res.body !== null) {\n const body = new WeakRef<ReadableStream>(res.body);\n\n const openBodyConnection = {\n cancel:\n /* istanbul ignore next: see it.todo('can be torn down during body read') test */\n async () => {\n try {\n await body.deref()?.cancel();\n } catch {\n /* do nothing */\n }\n },\n };\n openConnections.add(openBodyConnection);\n cleanup.register(\n res.body,\n /* istanbul ignore next: can't test garbage collection without modifying node parameters */\n () => openConnections.delete(openBodyConnection),\n );\n }\n return harden(res);\n };\n\n const teardownFunction = async () => {\n teardownRef.lastTeardown += 1;\n const promises: Promise<void>[] = [];\n openConnections.forEach(({ cancel }) => promises.push(cancel()));\n openConnections.clear();\n await Promise.all(promises);\n };\n\n return {\n fetch: harden(_fetch),\n // Request, Headers and Response are the endowments injected alongside fetch\n // only when 'endowment:network-access' permission is requested,\n // therefore these are hardened as part of fetch dependency injection within its factory.\n // These endowments are not (and should never be) available by default.\n Request: harden(Request),\n Headers: harden(Headers),\n Response: harden(Response),\n teardownFunction,\n };\n};\n\nconst endowmentModule = {\n names: ['fetch', 'Request', 'Headers', 'Response'] as const,\n factory: createNetwork,\n};\nexport default endowmentModule;\n"],"names":["withTeardown","ResponseWrapper","body","ogResponse","bodyUsed","headers","ok","redirected","status","statusText","type","url","text","arrayBuffer","blob","clone","newResponse","teardownRef","formData","json","constructor","createNetwork","openConnections","Set","lastTeardown","cleanup","FinalizationRegistry","callback","_fetch","input","init","abortController","AbortController","signal","undefined","originalSignal","addEventListener","abort","reason","once","res","openFetchConnection","fetchPromise","fetch","cancel","add","delete","WeakRef","openBodyConnection","deref","register","harden","teardownFunction","promises","forEach","push","clear","Promise","all","Request","Headers","Response","endowmentModule","names","factory"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/common/endowments/network.ts"],"sourcesContent":["import { assert } from '@metamask/utils';\n\nimport { withTeardown } from '../utils';\nimport type { EndowmentFactoryOptions } from './commonEndowmentFactory';\n\n/**\n * This class wraps a Response object.\n * That way, a teardown process can stop any processes left.\n */\nclass ResponseWrapper implements Response {\n readonly #teardownRef: { lastTeardown: number };\n\n #ogResponse: Response;\n\n #onStart: () => Promise<void>;\n\n #onFinish: () => Promise<void>;\n\n constructor(\n ogResponse: Response,\n teardownRef: { lastTeardown: number },\n onStart: () => Promise<void>,\n onFinish: () => Promise<void>,\n ) {\n this.#ogResponse = ogResponse;\n this.#teardownRef = teardownRef;\n this.#onStart = onStart;\n this.#onFinish = onFinish;\n }\n\n get body(): ReadableStream<Uint8Array> | null {\n return this.#ogResponse.body;\n }\n\n get bodyUsed() {\n return this.#ogResponse.bodyUsed;\n }\n\n get headers() {\n return this.#ogResponse.headers;\n }\n\n get ok() {\n return this.#ogResponse.ok;\n }\n\n get redirected() {\n return this.#ogResponse.redirected;\n }\n\n get status() {\n return this.#ogResponse.status;\n }\n\n get statusText() {\n return this.#ogResponse.statusText;\n }\n\n get type() {\n return this.#ogResponse.type;\n }\n\n get url() {\n return this.#ogResponse.url;\n }\n\n async text() {\n return await withTeardown<string>(\n (async () => {\n await this.#onStart();\n try {\n return await this.#ogResponse.text();\n } finally {\n await this.#onFinish();\n }\n })(),\n this.#teardownRef,\n );\n }\n\n async arrayBuffer(): Promise<ArrayBuffer> {\n return await withTeardown<ArrayBuffer>(\n (async () => {\n await this.#onStart();\n try {\n return await this.#ogResponse.arrayBuffer();\n } finally {\n await this.#onFinish();\n }\n })(),\n this.#teardownRef,\n );\n }\n\n async blob(): Promise<Blob> {\n return await withTeardown<Blob>(\n (async () => {\n await this.#onStart();\n try {\n return await this.#ogResponse.blob();\n } finally {\n await this.#onFinish();\n }\n })(),\n this.#teardownRef,\n );\n }\n\n clone(): Response {\n const newResponse = this.#ogResponse.clone();\n return new ResponseWrapper(\n newResponse,\n this.#teardownRef,\n this.#onStart,\n this.#onFinish,\n );\n }\n\n async formData(): Promise<FormData> {\n return await withTeardown<FormData>(\n (async () => {\n await this.#onStart();\n try {\n return await this.#ogResponse.formData();\n } finally {\n await this.#onFinish();\n }\n })(),\n this.#teardownRef,\n );\n }\n\n async json(): Promise<any> {\n return await withTeardown(\n (async () => {\n await this.#onStart();\n try {\n return await this.#ogResponse.json();\n } finally {\n await this.#onFinish();\n }\n })(),\n this.#teardownRef,\n );\n }\n}\n\n/**\n * Create a network endowment, consisting of a `fetch` function.\n * This allows us to provide a teardown function, so that we can cancel\n * any pending requests, connections, streams, etc. that may be open when a snap\n * is terminated.\n *\n * This wraps the original implementation of `fetch`,\n * to ensure that a bad actor cannot get access to the original function, thus\n * potentially preventing the network requests from being torn down.\n *\n * @param options - An options bag.\n * @param options.notify - A reference to the notify function of the snap executor.\n * @returns An object containing a wrapped `fetch`\n * function, as well as a teardown function.\n */\nconst createNetwork = ({ notify }: EndowmentFactoryOptions = {}) => {\n assert(notify, 'Notify must be passed to network endowment factory');\n // Open fetch calls or open body streams\n const openConnections = new Set<{ cancel: () => Promise<void> }>();\n // Track last teardown count\n const teardownRef = { lastTeardown: 0 };\n\n // Remove items from openConnections after they were garbage collected\n const cleanup = new FinalizationRegistry<() => void>(\n /* istanbul ignore next: can't test garbage collection without modifying node parameters */\n (callback) => callback(),\n );\n\n const _fetch: typeof fetch = async (\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> => {\n const abortController = new AbortController();\n if (init?.signal !== null && init?.signal !== undefined) {\n const originalSignal = init.signal;\n // Merge abort controllers\n originalSignal.addEventListener(\n 'abort',\n () => {\n abortController.abort((originalSignal as any).reason);\n },\n { once: true },\n );\n }\n\n let started = false;\n const onStart = async () => {\n if (!started) {\n started = true;\n await notify({\n method: 'OutboundRequest',\n params: { source: 'fetch' },\n });\n }\n };\n\n let finished = false;\n const onFinish = async () => {\n if (!finished) {\n finished = true;\n await notify({\n method: 'OutboundResponse',\n params: { source: 'fetch' },\n });\n }\n };\n\n let res: Response;\n let openFetchConnection: { cancel: () => Promise<void> } | undefined;\n return await withTeardown(\n (async () => {\n try {\n await notify({\n method: 'OutboundRequest',\n params: { source: 'fetch' },\n });\n const fetchPromise = fetch(input, {\n ...init,\n signal: abortController.signal,\n });\n\n openFetchConnection = {\n cancel: async () => {\n abortController.abort();\n try {\n await fetchPromise;\n } catch {\n /* do nothing */\n }\n },\n };\n openConnections.add(openFetchConnection);\n\n res = new ResponseWrapper(\n await fetchPromise,\n teardownRef,\n onStart,\n onFinish,\n );\n } finally {\n if (openFetchConnection !== undefined) {\n openConnections.delete(openFetchConnection);\n }\n await notify({\n method: 'OutboundResponse',\n params: { source: 'fetch' },\n });\n }\n\n if (res.body !== null) {\n const body = new WeakRef<ReadableStream>(res.body);\n\n const openBodyConnection = {\n cancel:\n /* istanbul ignore next: see it.todo('can be torn down during body read') test */\n async () => {\n try {\n await body.deref()?.cancel();\n } catch {\n /* do nothing */\n }\n },\n };\n openConnections.add(openBodyConnection);\n cleanup.register(\n res.body,\n /* istanbul ignore next: can't test garbage collection without modifying node parameters */\n () => openConnections.delete(openBodyConnection),\n );\n }\n return harden(res);\n })(),\n teardownRef,\n );\n };\n\n const teardownFunction = async () => {\n teardownRef.lastTeardown += 1;\n const promises: Promise<void>[] = [];\n openConnections.forEach(({ cancel }) => promises.push(cancel()));\n openConnections.clear();\n await Promise.all(promises);\n };\n\n return {\n fetch: harden(_fetch),\n // Request, Headers and Response are the endowments injected alongside fetch\n // only when 'endowment:network-access' permission is requested,\n // therefore these are hardened as part of fetch dependency injection within its factory.\n // These endowments are not (and should never be) available by default.\n Request: harden(Request),\n Headers: harden(Headers),\n Response: harden(Response),\n teardownFunction,\n };\n};\n\nconst endowmentModule = {\n names: ['fetch', 'Request', 'Headers', 'Response'] as const,\n factory: createNetwork,\n};\nexport default endowmentModule;\n"],"names":["assert","withTeardown","ResponseWrapper","body","ogResponse","bodyUsed","headers","ok","redirected","status","statusText","type","url","text","onStart","onFinish","teardownRef","arrayBuffer","blob","clone","newResponse","formData","json","constructor","createNetwork","notify","openConnections","Set","lastTeardown","cleanup","FinalizationRegistry","callback","_fetch","input","init","abortController","AbortController","signal","undefined","originalSignal","addEventListener","abort","reason","once","started","method","params","source","finished","res","openFetchConnection","fetchPromise","fetch","cancel","add","delete","WeakRef","openBodyConnection","deref","register","harden","teardownFunction","promises","forEach","push","clear","Promise","all","Request","Headers","Response","endowmentModule","names","factory"],"mappings":"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"}
|
package/dist/esm/common/utils.js
CHANGED
|
@@ -64,6 +64,7 @@ import { log } from '../logging';
|
|
|
64
64
|
export const BLOCKED_RPC_METHODS = Object.freeze([
|
|
65
65
|
'wallet_requestSnaps',
|
|
66
66
|
'wallet_requestPermissions',
|
|
67
|
+
'wallet_revokePermissions',
|
|
67
68
|
// We disallow all of these confirmations for now, since the screens are not ready for Snaps.
|
|
68
69
|
'eth_sendRawTransaction',
|
|
69
70
|
'eth_sendTransaction',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/common/utils.ts"],"sourcesContent":["import type { StreamProvider } from '@metamask/providers';\nimport type { RequestArguments } from '@metamask/providers/dist/BaseProvider';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { assert, assertStruct, getSafeJson, JsonStruct } from '@metamask/utils';\n\nimport { log } from '../logging';\n/**\n * Make proxy for Promise and handle the teardown process properly.\n * If the teardown is called in the meanwhile, Promise result will not be\n * exposed to the snap anymore and warning will be logged to the console.\n *\n * @param originalPromise - Original promise.\n * @param teardownRef - Reference containing teardown count.\n * @param teardownRef.lastTeardown - Number of the last teardown.\n * @returns New proxy promise.\n */\nexport async function withTeardown<Type>(\n originalPromise: Promise<Type>,\n teardownRef: { lastTeardown: number },\n): Promise<Type> {\n const myTeardown = teardownRef.lastTeardown;\n return new Promise<Type>((resolve, reject) => {\n originalPromise\n .then((value) => {\n if (teardownRef.lastTeardown === myTeardown) {\n resolve(value);\n } else {\n log(\n 'Late promise received after Snap finished execution. Promise will be dropped.',\n );\n }\n })\n .catch((reason) => {\n if (teardownRef.lastTeardown === myTeardown) {\n reject(reason);\n } else {\n log(\n 'Late promise received after Snap finished execution. Promise will be dropped.',\n );\n }\n });\n });\n}\n\n/**\n * Returns a Proxy that narrows down (attenuates) the fields available on\n * the StreamProvider and replaces the request implementation.\n *\n * @param provider - Instance of a StreamProvider to be limited.\n * @param request - Custom attenuated request object.\n * @returns Proxy to the StreamProvider instance.\n */\nexport function proxyStreamProvider(\n provider: StreamProvider,\n request: unknown,\n): StreamProvider {\n // Proxy target is intentionally set to be an empty object, to ensure\n // that access to the prototype chain is not possible.\n const proxy = new Proxy(\n {},\n {\n has(_target: object, prop: string | symbol) {\n return (\n typeof prop === 'string' &&\n ['request', 'on', 'removeListener'].includes(prop)\n );\n },\n get(_target, prop: keyof StreamProvider) {\n if (prop === 'request') {\n return request;\n } else if (['on', 'removeListener'].includes(prop)) {\n return provider[prop];\n }\n\n return undefined;\n },\n },\n );\n\n return proxy as StreamProvider;\n}\n\n// We're blocking these RPC methods for v1, will revisit later.\nexport const BLOCKED_RPC_METHODS = Object.freeze([\n 'wallet_requestSnaps',\n 'wallet_requestPermissions',\n // We disallow all of these confirmations for now, since the screens are not ready for Snaps.\n 'eth_sendRawTransaction',\n 'eth_sendTransaction',\n 'eth_sign',\n 'eth_signTypedData',\n 'eth_signTypedData_v1',\n 'eth_signTypedData_v3',\n 'eth_signTypedData_v4',\n 'eth_decrypt',\n 'eth_getEncryptionPublicKey',\n 'wallet_addEthereumChain',\n 'wallet_switchEthereumChain',\n 'wallet_watchAsset',\n 'wallet_registerOnboarding',\n 'wallet_scanQRCode',\n]);\n\n/**\n * Asserts the validity of request arguments for a snap outbound request using the `snap.request` API.\n *\n * @param args - The arguments to validate.\n */\nexport function assertSnapOutboundRequest(args: RequestArguments) {\n // Disallow any non `wallet_` or `snap_` methods for separation of concerns.\n assert(\n String.prototype.startsWith.call(args.method, 'wallet_') ||\n String.prototype.startsWith.call(args.method, 'snap_'),\n 'The global Snap API only allows RPC methods starting with `wallet_*` and `snap_*`.',\n rpcErrors.methodNotSupported,\n );\n assert(\n !BLOCKED_RPC_METHODS.includes(args.method),\n rpcErrors.methodNotFound({\n data: {\n method: args.method,\n },\n }),\n );\n assertStruct(\n args,\n JsonStruct,\n 'Provided value is not JSON-RPC compatible',\n rpcErrors.invalidParams,\n );\n}\n\n/**\n * Asserts the validity of request arguments for an ethereum outbound request using the `ethereum.request` API.\n *\n * @param args - The arguments to validate.\n */\nexport function assertEthereumOutboundRequest(args: RequestArguments) {\n // Disallow snaps methods for separation of concerns.\n assert(\n !String.prototype.startsWith.call(args.method, 'snap_'),\n rpcErrors.methodNotFound({\n data: {\n method: args.method,\n },\n }),\n );\n assert(\n !BLOCKED_RPC_METHODS.includes(args.method),\n rpcErrors.methodNotFound({\n data: {\n method: args.method,\n },\n }),\n );\n assertStruct(\n args,\n JsonStruct,\n 'Provided value is not JSON-RPC compatible',\n rpcErrors.invalidParams,\n );\n}\n\n/**\n * Gets a sanitized value to be used for passing to the underlying MetaMask provider.\n *\n * @param value - An unsanitized value from a snap.\n * @returns A sanitized value ready to be passed to a MetaMask provider.\n */\nexport function sanitizeRequestArguments(value: unknown): RequestArguments {\n // Before passing to getSafeJson we run the value through JSON serialization.\n // This lets request arguments contain undefined which is normally disallowed.\n const json = JSON.parse(JSON.stringify(value));\n return getSafeJson(json) as RequestArguments;\n}\n"],"names":["rpcErrors","assert","assertStruct","getSafeJson","JsonStruct","log","withTeardown","originalPromise","teardownRef","myTeardown","lastTeardown","Promise","resolve","reject","then","value","catch","reason","proxyStreamProvider","provider","request","proxy","Proxy","has","_target","prop","includes","get","undefined","BLOCKED_RPC_METHODS","Object","freeze","assertSnapOutboundRequest","args","String","prototype","startsWith","call","method","methodNotSupported","methodNotFound","data","invalidParams","assertEthereumOutboundRequest","sanitizeRequestArguments","json","JSON","parse","stringify"],"mappings":"AAEA,SAASA,SAAS,QAAQ,uBAAuB;AACjD,SAASC,MAAM,EAAEC,YAAY,EAAEC,WAAW,EAAEC,UAAU,QAAQ,kBAAkB;AAEhF,SAASC,GAAG,QAAQ,aAAa;AACjC;;;;;;;;;CASC,GACD,OAAO,eAAeC,aACpBC,eAA8B,EAC9BC,WAAqC;IAErC,MAAMC,aAAaD,YAAYE,YAAY;IAC3C,OAAO,IAAIC,QAAc,CAACC,SAASC;QACjCN,gBACGO,IAAI,CAAC,CAACC;YACL,IAAIP,YAAYE,YAAY,KAAKD,YAAY;gBAC3CG,QAAQG;YACV,OAAO;gBACLV,IACE;YAEJ;QACF,GACCW,KAAK,CAAC,CAACC;YACN,IAAIT,YAAYE,YAAY,KAAKD,YAAY;gBAC3CI,OAAOI;YACT,OAAO;gBACLZ,IACE;YAEJ;QACF;IACJ;AACF;AAEA;;;;;;;CAOC,GACD,OAAO,SAASa,oBACdC,QAAwB,EACxBC,OAAgB;IAEhB,qEAAqE;IACrE,sDAAsD;IACtD,MAAMC,QAAQ,IAAIC,MAChB,CAAC,GACD;QACEC,KAAIC,OAAe,EAAEC,IAAqB;YACxC,OACE,OAAOA,SAAS,YAChB;gBAAC;gBAAW;gBAAM;aAAiB,CAACC,QAAQ,CAACD;QAEjD;QACAE,KAAIH,OAAO,EAAEC,IAA0B;YACrC,IAAIA,SAAS,WAAW;gBACtB,OAAOL;YACT,OAAO,IAAI;gBAAC;gBAAM;aAAiB,CAACM,QAAQ,CAACD,OAAO;gBAClD,OAAON,QAAQ,CAACM,KAAK;YACvB;YAEA,OAAOG;QACT;IACF;IAGF,OAAOP;AACT;AAEA,+DAA+D;AAC/D,OAAO,MAAMQ,sBAAsBC,OAAOC,MAAM,CAAC;IAC/C;IACA;IACA,6FAA6F;IAC7F;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD,EAAE;AAEH;;;;CAIC,GACD,OAAO,SAASC,0BAA0BC,IAAsB;IAC9D,4EAA4E;IAC5EhC,OACEiC,OAAOC,SAAS,CAACC,UAAU,CAACC,IAAI,CAACJ,KAAKK,MAAM,EAAE,cAC5CJ,OAAOC,SAAS,CAACC,UAAU,CAACC,IAAI,CAACJ,KAAKK,MAAM,EAAE,UAChD,sFACAtC,UAAUuC,kBAAkB;IAE9BtC,OACE,CAAC4B,oBAAoBH,QAAQ,CAACO,KAAKK,MAAM,GACzCtC,UAAUwC,cAAc,CAAC;QACvBC,MAAM;YACJH,QAAQL,KAAKK,MAAM;QACrB;IACF;IAEFpC,aACE+B,MACA7B,YACA,6CACAJ,UAAU0C,aAAa;AAE3B;AAEA;;;;CAIC,GACD,OAAO,SAASC,8BAA8BV,IAAsB;IAClE,qDAAqD;IACrDhC,OACE,CAACiC,OAAOC,SAAS,CAACC,UAAU,CAACC,IAAI,CAACJ,KAAKK,MAAM,EAAE,UAC/CtC,UAAUwC,cAAc,CAAC;QACvBC,MAAM;YACJH,QAAQL,KAAKK,MAAM;QACrB;IACF;IAEFrC,OACE,CAAC4B,oBAAoBH,QAAQ,CAACO,KAAKK,MAAM,GACzCtC,UAAUwC,cAAc,CAAC;QACvBC,MAAM;YACJH,QAAQL,KAAKK,MAAM;QACrB;IACF;IAEFpC,aACE+B,MACA7B,YACA,6CACAJ,UAAU0C,aAAa;AAE3B;AAEA;;;;;CAKC,GACD,OAAO,SAASE,yBAAyB7B,KAAc;IACrD,6EAA6E;IAC7E,8EAA8E;IAC9E,MAAM8B,OAAOC,KAAKC,KAAK,CAACD,KAAKE,SAAS,CAACjC;IACvC,OAAOZ,YAAY0C;AACrB"}
|
|
1
|
+
{"version":3,"sources":["../../../src/common/utils.ts"],"sourcesContent":["import type { StreamProvider } from '@metamask/providers';\nimport type { RequestArguments } from '@metamask/providers/dist/BaseProvider';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { assert, assertStruct, getSafeJson, JsonStruct } from '@metamask/utils';\n\nimport { log } from '../logging';\n/**\n * Make proxy for Promise and handle the teardown process properly.\n * If the teardown is called in the meanwhile, Promise result will not be\n * exposed to the snap anymore and warning will be logged to the console.\n *\n * @param originalPromise - Original promise.\n * @param teardownRef - Reference containing teardown count.\n * @param teardownRef.lastTeardown - Number of the last teardown.\n * @returns New proxy promise.\n */\nexport async function withTeardown<Type>(\n originalPromise: Promise<Type>,\n teardownRef: { lastTeardown: number },\n): Promise<Type> {\n const myTeardown = teardownRef.lastTeardown;\n return new Promise<Type>((resolve, reject) => {\n originalPromise\n .then((value) => {\n if (teardownRef.lastTeardown === myTeardown) {\n resolve(value);\n } else {\n log(\n 'Late promise received after Snap finished execution. Promise will be dropped.',\n );\n }\n })\n .catch((reason) => {\n if (teardownRef.lastTeardown === myTeardown) {\n reject(reason);\n } else {\n log(\n 'Late promise received after Snap finished execution. Promise will be dropped.',\n );\n }\n });\n });\n}\n\n/**\n * Returns a Proxy that narrows down (attenuates) the fields available on\n * the StreamProvider and replaces the request implementation.\n *\n * @param provider - Instance of a StreamProvider to be limited.\n * @param request - Custom attenuated request object.\n * @returns Proxy to the StreamProvider instance.\n */\nexport function proxyStreamProvider(\n provider: StreamProvider,\n request: unknown,\n): StreamProvider {\n // Proxy target is intentionally set to be an empty object, to ensure\n // that access to the prototype chain is not possible.\n const proxy = new Proxy(\n {},\n {\n has(_target: object, prop: string | symbol) {\n return (\n typeof prop === 'string' &&\n ['request', 'on', 'removeListener'].includes(prop)\n );\n },\n get(_target, prop: keyof StreamProvider) {\n if (prop === 'request') {\n return request;\n } else if (['on', 'removeListener'].includes(prop)) {\n return provider[prop];\n }\n\n return undefined;\n },\n },\n );\n\n return proxy as StreamProvider;\n}\n\n// We're blocking these RPC methods for v1, will revisit later.\nexport const BLOCKED_RPC_METHODS = Object.freeze([\n 'wallet_requestSnaps',\n 'wallet_requestPermissions',\n 'wallet_revokePermissions',\n // We disallow all of these confirmations for now, since the screens are not ready for Snaps.\n 'eth_sendRawTransaction',\n 'eth_sendTransaction',\n 'eth_sign',\n 'eth_signTypedData',\n 'eth_signTypedData_v1',\n 'eth_signTypedData_v3',\n 'eth_signTypedData_v4',\n 'eth_decrypt',\n 'eth_getEncryptionPublicKey',\n 'wallet_addEthereumChain',\n 'wallet_switchEthereumChain',\n 'wallet_watchAsset',\n 'wallet_registerOnboarding',\n 'wallet_scanQRCode',\n]);\n\n/**\n * Asserts the validity of request arguments for a snap outbound request using the `snap.request` API.\n *\n * @param args - The arguments to validate.\n */\nexport function assertSnapOutboundRequest(args: RequestArguments) {\n // Disallow any non `wallet_` or `snap_` methods for separation of concerns.\n assert(\n String.prototype.startsWith.call(args.method, 'wallet_') ||\n String.prototype.startsWith.call(args.method, 'snap_'),\n 'The global Snap API only allows RPC methods starting with `wallet_*` and `snap_*`.',\n rpcErrors.methodNotSupported,\n );\n assert(\n !BLOCKED_RPC_METHODS.includes(args.method),\n rpcErrors.methodNotFound({\n data: {\n method: args.method,\n },\n }),\n );\n assertStruct(\n args,\n JsonStruct,\n 'Provided value is not JSON-RPC compatible',\n rpcErrors.invalidParams,\n );\n}\n\n/**\n * Asserts the validity of request arguments for an ethereum outbound request using the `ethereum.request` API.\n *\n * @param args - The arguments to validate.\n */\nexport function assertEthereumOutboundRequest(args: RequestArguments) {\n // Disallow snaps methods for separation of concerns.\n assert(\n !String.prototype.startsWith.call(args.method, 'snap_'),\n rpcErrors.methodNotFound({\n data: {\n method: args.method,\n },\n }),\n );\n assert(\n !BLOCKED_RPC_METHODS.includes(args.method),\n rpcErrors.methodNotFound({\n data: {\n method: args.method,\n },\n }),\n );\n assertStruct(\n args,\n JsonStruct,\n 'Provided value is not JSON-RPC compatible',\n rpcErrors.invalidParams,\n );\n}\n\n/**\n * Gets a sanitized value to be used for passing to the underlying MetaMask provider.\n *\n * @param value - An unsanitized value from a snap.\n * @returns A sanitized value ready to be passed to a MetaMask provider.\n */\nexport function sanitizeRequestArguments(value: unknown): RequestArguments {\n // Before passing to getSafeJson we run the value through JSON serialization.\n // This lets request arguments contain undefined which is normally disallowed.\n const json = JSON.parse(JSON.stringify(value));\n return getSafeJson(json) as RequestArguments;\n}\n"],"names":["rpcErrors","assert","assertStruct","getSafeJson","JsonStruct","log","withTeardown","originalPromise","teardownRef","myTeardown","lastTeardown","Promise","resolve","reject","then","value","catch","reason","proxyStreamProvider","provider","request","proxy","Proxy","has","_target","prop","includes","get","undefined","BLOCKED_RPC_METHODS","Object","freeze","assertSnapOutboundRequest","args","String","prototype","startsWith","call","method","methodNotSupported","methodNotFound","data","invalidParams","assertEthereumOutboundRequest","sanitizeRequestArguments","json","JSON","parse","stringify"],"mappings":"AAEA,SAASA,SAAS,QAAQ,uBAAuB;AACjD,SAASC,MAAM,EAAEC,YAAY,EAAEC,WAAW,EAAEC,UAAU,QAAQ,kBAAkB;AAEhF,SAASC,GAAG,QAAQ,aAAa;AACjC;;;;;;;;;CASC,GACD,OAAO,eAAeC,aACpBC,eAA8B,EAC9BC,WAAqC;IAErC,MAAMC,aAAaD,YAAYE,YAAY;IAC3C,OAAO,IAAIC,QAAc,CAACC,SAASC;QACjCN,gBACGO,IAAI,CAAC,CAACC;YACL,IAAIP,YAAYE,YAAY,KAAKD,YAAY;gBAC3CG,QAAQG;YACV,OAAO;gBACLV,IACE;YAEJ;QACF,GACCW,KAAK,CAAC,CAACC;YACN,IAAIT,YAAYE,YAAY,KAAKD,YAAY;gBAC3CI,OAAOI;YACT,OAAO;gBACLZ,IACE;YAEJ;QACF;IACJ;AACF;AAEA;;;;;;;CAOC,GACD,OAAO,SAASa,oBACdC,QAAwB,EACxBC,OAAgB;IAEhB,qEAAqE;IACrE,sDAAsD;IACtD,MAAMC,QAAQ,IAAIC,MAChB,CAAC,GACD;QACEC,KAAIC,OAAe,EAAEC,IAAqB;YACxC,OACE,OAAOA,SAAS,YAChB;gBAAC;gBAAW;gBAAM;aAAiB,CAACC,QAAQ,CAACD;QAEjD;QACAE,KAAIH,OAAO,EAAEC,IAA0B;YACrC,IAAIA,SAAS,WAAW;gBACtB,OAAOL;YACT,OAAO,IAAI;gBAAC;gBAAM;aAAiB,CAACM,QAAQ,CAACD,OAAO;gBAClD,OAAON,QAAQ,CAACM,KAAK;YACvB;YAEA,OAAOG;QACT;IACF;IAGF,OAAOP;AACT;AAEA,+DAA+D;AAC/D,OAAO,MAAMQ,sBAAsBC,OAAOC,MAAM,CAAC;IAC/C;IACA;IACA;IACA,6FAA6F;IAC7F;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD,EAAE;AAEH;;;;CAIC,GACD,OAAO,SAASC,0BAA0BC,IAAsB;IAC9D,4EAA4E;IAC5EhC,OACEiC,OAAOC,SAAS,CAACC,UAAU,CAACC,IAAI,CAACJ,KAAKK,MAAM,EAAE,cAC5CJ,OAAOC,SAAS,CAACC,UAAU,CAACC,IAAI,CAACJ,KAAKK,MAAM,EAAE,UAChD,sFACAtC,UAAUuC,kBAAkB;IAE9BtC,OACE,CAAC4B,oBAAoBH,QAAQ,CAACO,KAAKK,MAAM,GACzCtC,UAAUwC,cAAc,CAAC;QACvBC,MAAM;YACJH,QAAQL,KAAKK,MAAM;QACrB;IACF;IAEFpC,aACE+B,MACA7B,YACA,6CACAJ,UAAU0C,aAAa;AAE3B;AAEA;;;;CAIC,GACD,OAAO,SAASC,8BAA8BV,IAAsB;IAClE,qDAAqD;IACrDhC,OACE,CAACiC,OAAOC,SAAS,CAACC,UAAU,CAACC,IAAI,CAACJ,KAAKK,MAAM,EAAE,UAC/CtC,UAAUwC,cAAc,CAAC;QACvBC,MAAM;YACJH,QAAQL,KAAKK,MAAM;QACrB;IACF;IAEFrC,OACE,CAAC4B,oBAAoBH,QAAQ,CAACO,KAAKK,MAAM,GACzCtC,UAAUwC,cAAc,CAAC;QACvBC,MAAM;YACJH,QAAQL,KAAKK,MAAM;QACrB;IACF;IAEFpC,aACE+B,MACA7B,YACA,6CACAJ,UAAU0C,aAAa;AAE3B;AAEA;;;;;CAKC,GACD,OAAO,SAASE,yBAAyB7B,KAAc;IACrD,6EAA6E;IAC7E,8EAA8E;IAC9E,MAAM8B,OAAOC,KAAKC,KAAK,CAACD,KAAKE,SAAS,CAACjC;IACvC,OAAOZ,YAAY0C;AACrB"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { rpcErrors } from '@metamask/rpc-errors';
|
|
2
2
|
import { ChainIdStruct, HandlerType } from '@metamask/snaps-utils';
|
|
3
|
-
import { assertStruct, JsonRpcIdStruct,
|
|
4
|
-
import { array, assign, enums, is, literal, nullable, object,
|
|
5
|
-
export const JsonRpcRequestWithoutIdStruct =
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
import { assertStruct, JsonRpcIdStruct, JsonRpcParamsStruct, JsonRpcSuccessStruct, JsonRpcVersionStruct, JsonStruct } from '@metamask/utils';
|
|
4
|
+
import { array, assign, enums, is, literal, nullable, object, optional, record, string, tuple, union } from 'superstruct';
|
|
5
|
+
export const JsonRpcRequestWithoutIdStruct = object({
|
|
6
|
+
jsonrpc: optional(JsonRpcVersionStruct),
|
|
7
|
+
id: optional(JsonRpcIdStruct),
|
|
8
|
+
method: string(),
|
|
9
|
+
params: optional(JsonRpcParamsStruct)
|
|
10
|
+
});
|
|
10
11
|
export const EndowmentStruct = string();
|
|
11
12
|
/**
|
|
12
13
|
* Check if the given value is an endowment.
|
|
@@ -36,7 +37,7 @@ export const TerminateRequestArgumentsStruct = union([
|
|
|
36
37
|
export const ExecuteSnapRequestArgumentsStruct = tuple([
|
|
37
38
|
string(),
|
|
38
39
|
string(),
|
|
39
|
-
|
|
40
|
+
array(EndowmentStruct)
|
|
40
41
|
]);
|
|
41
42
|
export const SnapRpcRequestArgumentsStruct = tuple([
|
|
42
43
|
string(),
|
|
@@ -87,9 +88,11 @@ export const OnNameLookupRequestArgumentsStruct = union([
|
|
|
87
88
|
*/ export function assertIsOnNameLookupRequestArguments(value) {
|
|
88
89
|
assertStruct(value, OnNameLookupRequestArgumentsStruct, 'Invalid request params', rpcErrors.invalidParams);
|
|
89
90
|
}
|
|
90
|
-
const OkResponseStruct =
|
|
91
|
+
const OkResponseStruct = object({
|
|
92
|
+
id: JsonRpcIdStruct,
|
|
93
|
+
jsonrpc: JsonRpcVersionStruct,
|
|
91
94
|
result: OkStruct
|
|
92
|
-
})
|
|
95
|
+
});
|
|
93
96
|
const SnapRpcResponse = JsonRpcSuccessStruct;
|
|
94
97
|
|
|
95
98
|
//# sourceMappingURL=validation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/common/validation.ts"],"sourcesContent":["import { rpcErrors } from '@metamask/rpc-errors';\nimport { ChainIdStruct, HandlerType } from '@metamask/snaps-utils';\nimport type { Json, JsonRpcSuccess } from '@metamask/utils';\nimport {\n assertStruct,\n JsonRpcIdStruct,\n
|
|
1
|
+
{"version":3,"sources":["../../../src/common/validation.ts"],"sourcesContent":["import { rpcErrors } from '@metamask/rpc-errors';\nimport { ChainIdStruct, HandlerType } from '@metamask/snaps-utils';\nimport type { Json, JsonRpcSuccess } from '@metamask/utils';\nimport {\n assertStruct,\n JsonRpcIdStruct,\n JsonRpcParamsStruct,\n JsonRpcSuccessStruct,\n JsonRpcVersionStruct,\n JsonStruct,\n} from '@metamask/utils';\nimport type { Infer } from 'superstruct';\nimport {\n array,\n assign,\n enums,\n is,\n literal,\n nullable,\n object,\n optional,\n record,\n string,\n tuple,\n union,\n} from 'superstruct';\n\nexport const JsonRpcRequestWithoutIdStruct = object({\n jsonrpc: optional(JsonRpcVersionStruct),\n id: optional(JsonRpcIdStruct),\n method: string(),\n params: optional(JsonRpcParamsStruct),\n});\n\nexport type JsonRpcRequestWithoutId = Infer<\n typeof JsonRpcRequestWithoutIdStruct\n>;\n\nexport const EndowmentStruct = string();\nexport type Endowment = Infer<typeof EndowmentStruct>;\n\n/**\n * Check if the given value is an endowment.\n *\n * @param value - The value to check.\n * @returns Whether the value is an endowment.\n */\nexport function isEndowment(value: unknown): value is Endowment {\n return is(value, EndowmentStruct);\n}\n\n/**\n * Check if the given value is an array of endowments.\n *\n * @param value - The value to check.\n * @returns Whether the value is an array of endowments.\n */\nexport function isEndowmentsArray(value: unknown): value is Endowment[] {\n return Array.isArray(value) && value.every(isEndowment);\n}\n\nconst OkStruct = literal('OK');\n\nexport const PingRequestArgumentsStruct = optional(\n union([literal(undefined), array()]),\n);\n\nexport const TerminateRequestArgumentsStruct = union([\n literal(undefined),\n array(),\n]);\n\nexport const ExecuteSnapRequestArgumentsStruct = tuple([\n string(),\n string(),\n array(EndowmentStruct),\n]);\n\nexport const SnapRpcRequestArgumentsStruct = tuple([\n string(),\n enums(Object.values(HandlerType)),\n string(),\n assign(\n JsonRpcRequestWithoutIdStruct,\n object({\n params: optional(record(string(), JsonStruct)),\n }),\n ),\n]);\n\nexport type PingRequestArguments = Infer<typeof PingRequestArgumentsStruct>;\nexport type TerminateRequestArguments = Infer<\n typeof TerminateRequestArgumentsStruct\n>;\n\nexport type ExecuteSnapRequestArguments = Infer<\n typeof ExecuteSnapRequestArgumentsStruct\n>;\n\nexport type SnapRpcRequestArguments = Infer<\n typeof SnapRpcRequestArgumentsStruct\n>;\n\nexport type RequestArguments =\n | PingRequestArguments\n | TerminateRequestArguments\n | ExecuteSnapRequestArguments\n | SnapRpcRequestArguments;\n\nexport const OnTransactionRequestArgumentsStruct = object({\n // TODO: Improve `transaction` type.\n transaction: record(string(), JsonStruct),\n chainId: ChainIdStruct,\n transactionOrigin: nullable(string()),\n});\n\nexport type OnTransactionRequestArguments = Infer<\n typeof OnTransactionRequestArgumentsStruct\n>;\n\n/**\n * Asserts that the given value is a valid {@link OnTransactionRequestArguments}\n * object.\n *\n * @param value - The value to validate.\n * @throws If the value is not a valid {@link OnTransactionRequestArguments}\n * object.\n */\nexport function assertIsOnTransactionRequestArguments(\n value: unknown,\n): asserts value is OnTransactionRequestArguments {\n assertStruct(\n value,\n OnTransactionRequestArgumentsStruct,\n 'Invalid request params',\n rpcErrors.invalidParams,\n );\n}\n\nconst baseNameLookupArgs = { chainId: ChainIdStruct };\nconst domainRequestStruct = object({\n ...baseNameLookupArgs,\n address: string(),\n});\nconst addressRequestStruct = object({\n ...baseNameLookupArgs,\n domain: string(),\n});\n\nexport const OnNameLookupRequestArgumentsStruct = union([\n domainRequestStruct,\n addressRequestStruct,\n]);\n\nexport type OnNameLookupRequestArguments = Infer<\n typeof OnNameLookupRequestArgumentsStruct\n>;\n\nexport type PossibleLookupRequestArgs = typeof baseNameLookupArgs & {\n address?: string;\n domain?: string;\n};\n\n/**\n * Asserts that the given value is a valid {@link OnNameLookupRequestArguments}\n * object.\n *\n * @param value - The value to validate.\n * @throws If the value is not a valid {@link OnNameLookupRequestArguments}\n * object.\n */\nexport function assertIsOnNameLookupRequestArguments(\n value: unknown,\n): asserts value is OnNameLookupRequestArguments {\n assertStruct(\n value,\n OnNameLookupRequestArgumentsStruct,\n 'Invalid request params',\n rpcErrors.invalidParams,\n );\n}\n\nconst OkResponseStruct = object({\n id: JsonRpcIdStruct,\n jsonrpc: JsonRpcVersionStruct,\n result: OkStruct,\n});\n\nconst SnapRpcResponse = JsonRpcSuccessStruct;\n\nexport type OkResponse = Infer<typeof OkResponseStruct>;\nexport type SnapRpcResponse = Infer<typeof SnapRpcResponse>;\n\nexport type Response = OkResponse | SnapRpcResponse;\n\ntype RequestParams<Params extends unknown[] | undefined> =\n Params extends undefined ? [] : Params;\n\ntype RequestFunction<\n Args extends RequestArguments,\n ResponseType extends JsonRpcSuccess<Json>,\n> = (...args: RequestParams<Args>) => Promise<ResponseType['result']>;\n\nexport type Ping = RequestFunction<PingRequestArguments, OkResponse>;\nexport type Terminate = RequestFunction<TerminateRequestArguments, OkResponse>;\nexport type ExecuteSnap = RequestFunction<\n ExecuteSnapRequestArguments,\n OkResponse\n>;\nexport type SnapRpc = RequestFunction<SnapRpcRequestArguments, SnapRpcResponse>;\n"],"names":["rpcErrors","ChainIdStruct","HandlerType","assertStruct","JsonRpcIdStruct","JsonRpcParamsStruct","JsonRpcSuccessStruct","JsonRpcVersionStruct","JsonStruct","array","assign","enums","is","literal","nullable","object","optional","record","string","tuple","union","JsonRpcRequestWithoutIdStruct","jsonrpc","id","method","params","EndowmentStruct","isEndowment","value","isEndowmentsArray","Array","isArray","every","OkStruct","PingRequestArgumentsStruct","undefined","TerminateRequestArgumentsStruct","ExecuteSnapRequestArgumentsStruct","SnapRpcRequestArgumentsStruct","Object","values","OnTransactionRequestArgumentsStruct","transaction","chainId","transactionOrigin","assertIsOnTransactionRequestArguments","invalidParams","baseNameLookupArgs","domainRequestStruct","address","addressRequestStruct","domain","OnNameLookupRequestArgumentsStruct","assertIsOnNameLookupRequestArguments","OkResponseStruct","result","SnapRpcResponse"],"mappings":"AAAA,SAASA,SAAS,QAAQ,uBAAuB;AACjD,SAASC,aAAa,EAAEC,WAAW,QAAQ,wBAAwB;AAEnE,SACEC,YAAY,EACZC,eAAe,EACfC,mBAAmB,EACnBC,oBAAoB,EACpBC,oBAAoB,EACpBC,UAAU,QACL,kBAAkB;AAEzB,SACEC,KAAK,EACLC,MAAM,EACNC,KAAK,EACLC,EAAE,EACFC,OAAO,EACPC,QAAQ,EACRC,MAAM,EACNC,QAAQ,EACRC,MAAM,EACNC,MAAM,EACNC,KAAK,EACLC,KAAK,QACA,cAAc;AAErB,OAAO,MAAMC,gCAAgCN,OAAO;IAClDO,SAASN,SAAST;IAClBgB,IAAIP,SAASZ;IACboB,QAAQN;IACRO,QAAQT,SAASX;AACnB,GAAG;AAMH,OAAO,MAAMqB,kBAAkBR,SAAS;AAGxC;;;;;CAKC,GACD,OAAO,SAASS,YAAYC,KAAc;IACxC,OAAOhB,GAAGgB,OAAOF;AACnB;AAEA;;;;;CAKC,GACD,OAAO,SAASG,kBAAkBD,KAAc;IAC9C,OAAOE,MAAMC,OAAO,CAACH,UAAUA,MAAMI,KAAK,CAACL;AAC7C;AAEA,MAAMM,WAAWpB,QAAQ;AAEzB,OAAO,MAAMqB,6BAA6BlB,SACxCI,MAAM;IAACP,QAAQsB;IAAY1B;CAAQ,GACnC;AAEF,OAAO,MAAM2B,kCAAkChB,MAAM;IACnDP,QAAQsB;IACR1B;CACD,EAAE;AAEH,OAAO,MAAM4B,oCAAoClB,MAAM;IACrDD;IACAA;IACAT,MAAMiB;CACP,EAAE;AAEH,OAAO,MAAMY,gCAAgCnB,MAAM;IACjDD;IACAP,MAAM4B,OAAOC,MAAM,CAACtC;IACpBgB;IACAR,OACEW,+BACAN,OAAO;QACLU,QAAQT,SAASC,OAAOC,UAAUV;IACpC;CAEH,EAAE;AAqBH,OAAO,MAAMiC,sCAAsC1B,OAAO;IACxD,oCAAoC;IACpC2B,aAAazB,OAAOC,UAAUV;IAC9BmC,SAAS1C;IACT2C,mBAAmB9B,SAASI;AAC9B,GAAG;AAMH;;;;;;;CAOC,GACD,OAAO,SAAS2B,sCACdjB,KAAc;IAEdzB,aACEyB,OACAa,qCACA,0BACAzC,UAAU8C,aAAa;AAE3B;AAEA,MAAMC,qBAAqB;IAAEJ,SAAS1C;AAAc;AACpD,MAAM+C,sBAAsBjC,OAAO;IACjC,GAAGgC,kBAAkB;IACrBE,SAAS/B;AACX;AACA,MAAMgC,uBAAuBnC,OAAO;IAClC,GAAGgC,kBAAkB;IACrBI,QAAQjC;AACV;AAEA,OAAO,MAAMkC,qCAAqChC,MAAM;IACtD4B;IACAE;CACD,EAAE;AAWH;;;;;;;CAOC,GACD,OAAO,SAASG,qCACdzB,KAAc;IAEdzB,aACEyB,OACAwB,oCACA,0BACApD,UAAU8C,aAAa;AAE3B;AAEA,MAAMQ,mBAAmBvC,OAAO;IAC9BQ,IAAInB;IACJkB,SAASf;IACTgD,QAAQtB;AACV;AAEA,MAAMuB,kBAAkBlD"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import ObjectMultiplex from '@metamask/object-multiplex';
|
|
2
2
|
import { WindowPostMessageStream } from '@metamask/post-message-stream';
|
|
3
3
|
import { logError, SNAP_STREAM_NAMES } from '@metamask/snaps-utils';
|
|
4
|
-
import { pipeline } from 'stream';
|
|
4
|
+
import { pipeline } from 'readable-stream';
|
|
5
5
|
import { BaseSnapExecutor } from '../common/BaseSnapExecutor';
|
|
6
6
|
import { log } from '../logging';
|
|
7
7
|
export class IFrameSnapExecutor extends BaseSnapExecutor {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/iframe/IFrameSnapExecutor.ts"],"sourcesContent":["import ObjectMultiplex from '@metamask/object-multiplex';\nimport type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { WindowPostMessageStream } from '@metamask/post-message-stream';\nimport { logError, SNAP_STREAM_NAMES } from '@metamask/snaps-utils';\nimport { pipeline } from 'stream';\n\nimport { BaseSnapExecutor } from '../common/BaseSnapExecutor';\nimport { log } from '../logging';\n\nexport class IFrameSnapExecutor extends BaseSnapExecutor {\n /**\n * Initialize the IFrameSnapExecutor. This creates a post message stream from\n * and to the parent window, for two-way communication with the iframe.\n *\n * @param stream - The stream to use for communication.\n * @returns An instance of `IFrameSnapExecutor`, with the initialized post\n * message streams.\n */\n static initialize(\n stream: BasePostMessageStream = new WindowPostMessageStream({\n name: 'child',\n target: 'parent',\n targetWindow: self.parent,\n targetOrigin: '*',\n }),\n ) {\n log('Worker: Connecting to parent.');\n\n const mux = new ObjectMultiplex();\n pipeline(stream, mux, stream, (error) => {\n if (error) {\n logError(`Parent stream failure, closing worker.`, error);\n }\n self.close();\n });\n\n const commandStream = mux.createStream(SNAP_STREAM_NAMES.COMMAND);\n const rpcStream = mux.createStream(SNAP_STREAM_NAMES.JSON_RPC);\n\n return new IFrameSnapExecutor(commandStream, rpcStream);\n }\n}\n"],"names":["ObjectMultiplex","WindowPostMessageStream","logError","SNAP_STREAM_NAMES","pipeline","BaseSnapExecutor","log","IFrameSnapExecutor","initialize","stream","name","target","targetWindow","self","parent","targetOrigin","mux","error","close","commandStream","createStream","COMMAND","rpcStream","JSON_RPC"],"mappings":"AAAA,OAAOA,qBAAqB,6BAA6B;AAEzD,SAASC,uBAAuB,QAAQ,gCAAgC;AACxE,SAASC,QAAQ,EAAEC,iBAAiB,QAAQ,wBAAwB;AACpE,SAASC,QAAQ,QAAQ,
|
|
1
|
+
{"version":3,"sources":["../../../src/iframe/IFrameSnapExecutor.ts"],"sourcesContent":["import ObjectMultiplex from '@metamask/object-multiplex';\nimport type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { WindowPostMessageStream } from '@metamask/post-message-stream';\nimport { logError, SNAP_STREAM_NAMES } from '@metamask/snaps-utils';\nimport { pipeline } from 'readable-stream';\n\nimport { BaseSnapExecutor } from '../common/BaseSnapExecutor';\nimport { log } from '../logging';\n\nexport class IFrameSnapExecutor extends BaseSnapExecutor {\n /**\n * Initialize the IFrameSnapExecutor. This creates a post message stream from\n * and to the parent window, for two-way communication with the iframe.\n *\n * @param stream - The stream to use for communication.\n * @returns An instance of `IFrameSnapExecutor`, with the initialized post\n * message streams.\n */\n static initialize(\n stream: BasePostMessageStream = new WindowPostMessageStream({\n name: 'child',\n target: 'parent',\n targetWindow: self.parent,\n targetOrigin: '*',\n }),\n ) {\n log('Worker: Connecting to parent.');\n\n const mux = new ObjectMultiplex();\n pipeline(stream, mux, stream, (error) => {\n if (error) {\n logError(`Parent stream failure, closing worker.`, error);\n }\n self.close();\n });\n\n const commandStream = mux.createStream(SNAP_STREAM_NAMES.COMMAND);\n const rpcStream = mux.createStream(SNAP_STREAM_NAMES.JSON_RPC);\n\n return new IFrameSnapExecutor(commandStream, rpcStream);\n }\n}\n"],"names":["ObjectMultiplex","WindowPostMessageStream","logError","SNAP_STREAM_NAMES","pipeline","BaseSnapExecutor","log","IFrameSnapExecutor","initialize","stream","name","target","targetWindow","self","parent","targetOrigin","mux","error","close","commandStream","createStream","COMMAND","rpcStream","JSON_RPC"],"mappings":"AAAA,OAAOA,qBAAqB,6BAA6B;AAEzD,SAASC,uBAAuB,QAAQ,gCAAgC;AACxE,SAASC,QAAQ,EAAEC,iBAAiB,QAAQ,wBAAwB;AACpE,SAASC,QAAQ,QAAQ,kBAAkB;AAE3C,SAASC,gBAAgB,QAAQ,6BAA6B;AAC9D,SAASC,GAAG,QAAQ,aAAa;AAEjC,OAAO,MAAMC,2BAA2BF;IACtC;;;;;;;GAOC,GACD,OAAOG,WACLC,SAAgC,IAAIR,wBAAwB;QAC1DS,MAAM;QACNC,QAAQ;QACRC,cAAcC,KAAKC,MAAM;QACzBC,cAAc;IAChB,EAAE,EACF;QACAT,IAAI;QAEJ,MAAMU,MAAM,IAAIhB;QAChBI,SAASK,QAAQO,KAAKP,QAAQ,CAACQ;YAC7B,IAAIA,OAAO;gBACTf,SAAS,CAAC,sCAAsC,CAAC,EAAEe;YACrD;YACAJ,KAAKK,KAAK;QACZ;QAEA,MAAMC,gBAAgBH,IAAII,YAAY,CAACjB,kBAAkBkB,OAAO;QAChE,MAAMC,YAAYN,IAAII,YAAY,CAACjB,kBAAkBoB,QAAQ;QAE7D,OAAO,IAAIhB,mBAAmBY,eAAeG;IAC/C;AACF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import ObjectMultiplex from '@metamask/object-multiplex';
|
|
2
2
|
import { ProcessMessageStream } from '@metamask/post-message-stream';
|
|
3
3
|
import { logError, SNAP_STREAM_NAMES } from '@metamask/snaps-utils';
|
|
4
|
-
import { pipeline } from 'stream';
|
|
4
|
+
import { pipeline } from 'readable-stream';
|
|
5
5
|
import { BaseSnapExecutor } from '../common/BaseSnapExecutor';
|
|
6
6
|
import { log } from '../logging';
|
|
7
7
|
export class ChildProcessSnapExecutor extends BaseSnapExecutor {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/node-process/ChildProcessSnapExecutor.ts"],"sourcesContent":["import ObjectMultiplex from '@metamask/object-multiplex';\nimport { ProcessMessageStream } from '@metamask/post-message-stream';\nimport { logError, SNAP_STREAM_NAMES } from '@metamask/snaps-utils';\nimport { pipeline } from 'stream';\n\nimport { BaseSnapExecutor } from '../common/BaseSnapExecutor';\nimport { log } from '../logging';\n\nexport class ChildProcessSnapExecutor extends BaseSnapExecutor {\n static initialize() {\n log('Worker: Connecting to parent.');\n\n const parentStream = new ProcessMessageStream();\n const mux = new ObjectMultiplex();\n pipeline(parentStream, mux as any, parentStream, (error) => {\n if (error) {\n logError(`Parent stream failure, closing worker.`, error);\n }\n self.close();\n });\n\n const commandStream = mux.createStream(SNAP_STREAM_NAMES.COMMAND);\n const rpcStream = mux.createStream(SNAP_STREAM_NAMES.JSON_RPC) as any;\n return new ChildProcessSnapExecutor(commandStream, rpcStream);\n }\n}\n"],"names":["ObjectMultiplex","ProcessMessageStream","logError","SNAP_STREAM_NAMES","pipeline","BaseSnapExecutor","log","ChildProcessSnapExecutor","initialize","parentStream","mux","error","self","close","commandStream","createStream","COMMAND","rpcStream","JSON_RPC"],"mappings":"AAAA,OAAOA,qBAAqB,6BAA6B;AACzD,SAASC,oBAAoB,QAAQ,gCAAgC;AACrE,SAASC,QAAQ,EAAEC,iBAAiB,QAAQ,wBAAwB;AACpE,SAASC,QAAQ,QAAQ,
|
|
1
|
+
{"version":3,"sources":["../../../src/node-process/ChildProcessSnapExecutor.ts"],"sourcesContent":["import ObjectMultiplex from '@metamask/object-multiplex';\nimport { ProcessMessageStream } from '@metamask/post-message-stream';\nimport { logError, SNAP_STREAM_NAMES } from '@metamask/snaps-utils';\nimport { pipeline } from 'readable-stream';\n\nimport { BaseSnapExecutor } from '../common/BaseSnapExecutor';\nimport { log } from '../logging';\n\nexport class ChildProcessSnapExecutor extends BaseSnapExecutor {\n static initialize() {\n log('Worker: Connecting to parent.');\n\n const parentStream = new ProcessMessageStream();\n const mux = new ObjectMultiplex();\n pipeline(parentStream, mux as any, parentStream, (error) => {\n if (error) {\n logError(`Parent stream failure, closing worker.`, error);\n }\n self.close();\n });\n\n const commandStream = mux.createStream(SNAP_STREAM_NAMES.COMMAND);\n const rpcStream = mux.createStream(SNAP_STREAM_NAMES.JSON_RPC) as any;\n return new ChildProcessSnapExecutor(commandStream, rpcStream);\n }\n}\n"],"names":["ObjectMultiplex","ProcessMessageStream","logError","SNAP_STREAM_NAMES","pipeline","BaseSnapExecutor","log","ChildProcessSnapExecutor","initialize","parentStream","mux","error","self","close","commandStream","createStream","COMMAND","rpcStream","JSON_RPC"],"mappings":"AAAA,OAAOA,qBAAqB,6BAA6B;AACzD,SAASC,oBAAoB,QAAQ,gCAAgC;AACrE,SAASC,QAAQ,EAAEC,iBAAiB,QAAQ,wBAAwB;AACpE,SAASC,QAAQ,QAAQ,kBAAkB;AAE3C,SAASC,gBAAgB,QAAQ,6BAA6B;AAC9D,SAASC,GAAG,QAAQ,aAAa;AAEjC,OAAO,MAAMC,iCAAiCF;IAC5C,OAAOG,aAAa;QAClBF,IAAI;QAEJ,MAAMG,eAAe,IAAIR;QACzB,MAAMS,MAAM,IAAIV;QAChBI,SAASK,cAAcC,KAAYD,cAAc,CAACE;YAChD,IAAIA,OAAO;gBACTT,SAAS,CAAC,sCAAsC,CAAC,EAAES;YACrD;YACAC,KAAKC,KAAK;QACZ;QAEA,MAAMC,gBAAgBJ,IAAIK,YAAY,CAACZ,kBAAkBa,OAAO;QAChE,MAAMC,YAAYP,IAAIK,YAAY,CAACZ,kBAAkBe,QAAQ;QAC7D,OAAO,IAAIX,yBAAyBO,eAAeG;IACrD;AACF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import ObjectMultiplex from '@metamask/object-multiplex';
|
|
2
2
|
import { ThreadMessageStream } from '@metamask/post-message-stream';
|
|
3
3
|
import { logError, SNAP_STREAM_NAMES } from '@metamask/snaps-utils';
|
|
4
|
-
import { pipeline } from 'stream';
|
|
4
|
+
import { pipeline } from 'readable-stream';
|
|
5
5
|
import { BaseSnapExecutor } from '../common/BaseSnapExecutor';
|
|
6
6
|
import { log } from '../logging';
|
|
7
7
|
export class ThreadSnapExecutor extends BaseSnapExecutor {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/node-thread/ThreadSnapExecutor.ts"],"sourcesContent":["import ObjectMultiplex from '@metamask/object-multiplex';\nimport { ThreadMessageStream } from '@metamask/post-message-stream';\nimport { logError, SNAP_STREAM_NAMES } from '@metamask/snaps-utils';\nimport { pipeline } from 'stream';\n\nimport { BaseSnapExecutor } from '../common/BaseSnapExecutor';\nimport { log } from '../logging';\n\nexport class ThreadSnapExecutor extends BaseSnapExecutor {\n static initialize() {\n log('Worker: Connecting to parent.');\n\n const parentStream = new ThreadMessageStream();\n const mux = new ObjectMultiplex();\n pipeline(parentStream, mux as any, parentStream, (error) => {\n if (error) {\n logError(`Parent stream failure, closing worker.`, error);\n }\n self.close();\n });\n\n const commandStream = mux.createStream(SNAP_STREAM_NAMES.COMMAND);\n const rpcStream = mux.createStream(SNAP_STREAM_NAMES.JSON_RPC) as any;\n return new ThreadSnapExecutor(commandStream, rpcStream);\n }\n}\n"],"names":["ObjectMultiplex","ThreadMessageStream","logError","SNAP_STREAM_NAMES","pipeline","BaseSnapExecutor","log","ThreadSnapExecutor","initialize","parentStream","mux","error","self","close","commandStream","createStream","COMMAND","rpcStream","JSON_RPC"],"mappings":"AAAA,OAAOA,qBAAqB,6BAA6B;AACzD,SAASC,mBAAmB,QAAQ,gCAAgC;AACpE,SAASC,QAAQ,EAAEC,iBAAiB,QAAQ,wBAAwB;AACpE,SAASC,QAAQ,QAAQ,
|
|
1
|
+
{"version":3,"sources":["../../../src/node-thread/ThreadSnapExecutor.ts"],"sourcesContent":["import ObjectMultiplex from '@metamask/object-multiplex';\nimport { ThreadMessageStream } from '@metamask/post-message-stream';\nimport { logError, SNAP_STREAM_NAMES } from '@metamask/snaps-utils';\nimport { pipeline } from 'readable-stream';\n\nimport { BaseSnapExecutor } from '../common/BaseSnapExecutor';\nimport { log } from '../logging';\n\nexport class ThreadSnapExecutor extends BaseSnapExecutor {\n static initialize() {\n log('Worker: Connecting to parent.');\n\n const parentStream = new ThreadMessageStream();\n const mux = new ObjectMultiplex();\n pipeline(parentStream, mux as any, parentStream, (error) => {\n if (error) {\n logError(`Parent stream failure, closing worker.`, error);\n }\n self.close();\n });\n\n const commandStream = mux.createStream(SNAP_STREAM_NAMES.COMMAND);\n const rpcStream = mux.createStream(SNAP_STREAM_NAMES.JSON_RPC) as any;\n return new ThreadSnapExecutor(commandStream, rpcStream);\n }\n}\n"],"names":["ObjectMultiplex","ThreadMessageStream","logError","SNAP_STREAM_NAMES","pipeline","BaseSnapExecutor","log","ThreadSnapExecutor","initialize","parentStream","mux","error","self","close","commandStream","createStream","COMMAND","rpcStream","JSON_RPC"],"mappings":"AAAA,OAAOA,qBAAqB,6BAA6B;AACzD,SAASC,mBAAmB,QAAQ,gCAAgC;AACpE,SAASC,QAAQ,EAAEC,iBAAiB,QAAQ,wBAAwB;AACpE,SAASC,QAAQ,QAAQ,kBAAkB;AAE3C,SAASC,gBAAgB,QAAQ,6BAA6B;AAC9D,SAASC,GAAG,QAAQ,aAAa;AAEjC,OAAO,MAAMC,2BAA2BF;IACtC,OAAOG,aAAa;QAClBF,IAAI;QAEJ,MAAMG,eAAe,IAAIR;QACzB,MAAMS,MAAM,IAAIV;QAChBI,SAASK,cAAcC,KAAYD,cAAc,CAACE;YAChD,IAAIA,OAAO;gBACTT,SAAS,CAAC,sCAAsC,CAAC,EAAES;YACrD;YACAC,KAAKC,KAAK;QACZ;QAEA,MAAMC,gBAAgBJ,IAAIK,YAAY,CAACZ,kBAAkBa,OAAO;QAChE,MAAMC,YAAYP,IAAIK,YAAY,CAACZ,kBAAkBe,QAAQ;QAC7D,OAAO,IAAIX,mBAAmBO,eAAeG;IAC/C;AACF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import ObjectMultiplex from '@metamask/object-multiplex';
|
|
2
2
|
import { WebWorkerPostMessageStream } from '@metamask/post-message-stream';
|
|
3
3
|
import { logError, SNAP_STREAM_NAMES } from '@metamask/snaps-utils';
|
|
4
|
-
import { pipeline } from 'stream';
|
|
4
|
+
import { pipeline } from 'readable-stream';
|
|
5
5
|
import { BaseSnapExecutor } from '../../common/BaseSnapExecutor';
|
|
6
6
|
import { log } from '../../logging';
|
|
7
7
|
export class WebWorkerSnapExecutor extends BaseSnapExecutor {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/webworker/executor/WebWorkerSnapExecutor.ts"],"sourcesContent":["import ObjectMultiplex from '@metamask/object-multiplex';\nimport type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { WebWorkerPostMessageStream } from '@metamask/post-message-stream';\nimport { logError, SNAP_STREAM_NAMES } from '@metamask/snaps-utils';\nimport { pipeline } from 'stream';\n\nimport { BaseSnapExecutor } from '../../common/BaseSnapExecutor';\nimport { log } from '../../logging';\n\nexport class WebWorkerSnapExecutor extends BaseSnapExecutor {\n /**\n * Initialize the WebWorkerSnapExecutor. This creates a post message stream\n * from and to the parent window, for two-way communication with the iframe.\n *\n * @param stream - The stream to use for communication.\n * @returns An instance of `WebWorkerSnapExecutor`, with the initialized post\n * message streams.\n */\n static initialize(\n stream: BasePostMessageStream = new WebWorkerPostMessageStream(),\n ) {\n log('Worker: Connecting to parent.');\n\n const mux = new ObjectMultiplex();\n pipeline(stream, mux, stream, (error) => {\n if (error) {\n logError(`Parent stream failure, closing worker.`, error);\n }\n self.close();\n });\n\n const commandStream = mux.createStream(SNAP_STREAM_NAMES.COMMAND);\n const rpcStream = mux.createStream(SNAP_STREAM_NAMES.JSON_RPC);\n\n return new WebWorkerSnapExecutor(commandStream, rpcStream);\n }\n}\n"],"names":["ObjectMultiplex","WebWorkerPostMessageStream","logError","SNAP_STREAM_NAMES","pipeline","BaseSnapExecutor","log","WebWorkerSnapExecutor","initialize","stream","mux","error","self","close","commandStream","createStream","COMMAND","rpcStream","JSON_RPC"],"mappings":"AAAA,OAAOA,qBAAqB,6BAA6B;AAEzD,SAASC,0BAA0B,QAAQ,gCAAgC;AAC3E,SAASC,QAAQ,EAAEC,iBAAiB,QAAQ,wBAAwB;AACpE,SAASC,QAAQ,QAAQ,
|
|
1
|
+
{"version":3,"sources":["../../../../src/webworker/executor/WebWorkerSnapExecutor.ts"],"sourcesContent":["import ObjectMultiplex from '@metamask/object-multiplex';\nimport type { BasePostMessageStream } from '@metamask/post-message-stream';\nimport { WebWorkerPostMessageStream } from '@metamask/post-message-stream';\nimport { logError, SNAP_STREAM_NAMES } from '@metamask/snaps-utils';\nimport { pipeline } from 'readable-stream';\n\nimport { BaseSnapExecutor } from '../../common/BaseSnapExecutor';\nimport { log } from '../../logging';\n\nexport class WebWorkerSnapExecutor extends BaseSnapExecutor {\n /**\n * Initialize the WebWorkerSnapExecutor. This creates a post message stream\n * from and to the parent window, for two-way communication with the iframe.\n *\n * @param stream - The stream to use for communication.\n * @returns An instance of `WebWorkerSnapExecutor`, with the initialized post\n * message streams.\n */\n static initialize(\n stream: BasePostMessageStream = new WebWorkerPostMessageStream(),\n ) {\n log('Worker: Connecting to parent.');\n\n const mux = new ObjectMultiplex();\n pipeline(stream, mux, stream, (error) => {\n if (error) {\n logError(`Parent stream failure, closing worker.`, error);\n }\n self.close();\n });\n\n const commandStream = mux.createStream(SNAP_STREAM_NAMES.COMMAND);\n const rpcStream = mux.createStream(SNAP_STREAM_NAMES.JSON_RPC);\n\n return new WebWorkerSnapExecutor(commandStream, rpcStream);\n }\n}\n"],"names":["ObjectMultiplex","WebWorkerPostMessageStream","logError","SNAP_STREAM_NAMES","pipeline","BaseSnapExecutor","log","WebWorkerSnapExecutor","initialize","stream","mux","error","self","close","commandStream","createStream","COMMAND","rpcStream","JSON_RPC"],"mappings":"AAAA,OAAOA,qBAAqB,6BAA6B;AAEzD,SAASC,0BAA0B,QAAQ,gCAAgC;AAC3E,SAASC,QAAQ,EAAEC,iBAAiB,QAAQ,wBAAwB;AACpE,SAASC,QAAQ,QAAQ,kBAAkB;AAE3C,SAASC,gBAAgB,QAAQ,gCAAgC;AACjE,SAASC,GAAG,QAAQ,gBAAgB;AAEpC,OAAO,MAAMC,8BAA8BF;IACzC;;;;;;;GAOC,GACD,OAAOG,WACLC,SAAgC,IAAIR,4BAA4B,EAChE;QACAK,IAAI;QAEJ,MAAMI,MAAM,IAAIV;QAChBI,SAASK,QAAQC,KAAKD,QAAQ,CAACE;YAC7B,IAAIA,OAAO;gBACTT,SAAS,CAAC,sCAAsC,CAAC,EAAES;YACrD;YACAC,KAAKC,KAAK;QACZ;QAEA,MAAMC,gBAAgBJ,IAAIK,YAAY,CAACZ,kBAAkBa,OAAO;QAChE,MAAMC,YAAYP,IAAIK,YAAY,CAACZ,kBAAkBe,QAAQ;QAE7D,OAAO,IAAIX,sBAAsBO,eAAeG;IAClD;AACF"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="ses" />
|
|
3
3
|
import type { HandlerType, SnapExportsParameters } from '@metamask/snaps-utils';
|
|
4
|
-
import type { Json } from '@metamask/utils';
|
|
5
|
-
import type { Duplex } from 'stream';
|
|
4
|
+
import type { JsonRpcNotification, Json } from '@metamask/utils';
|
|
5
|
+
import type { Duplex } from 'readable-stream';
|
|
6
6
|
export declare type InvokeSnapArgs = Omit<SnapExportsParameters[0], 'chainId'>;
|
|
7
7
|
export declare type InvokeSnap = (target: string, handler: HandlerType, args: InvokeSnapArgs | undefined) => Promise<Json>;
|
|
8
|
+
export declare type NotifyFunction = (notification: Omit<JsonRpcNotification, 'jsonrpc'>) => Promise<void>;
|
|
8
9
|
export declare class BaseSnapExecutor {
|
|
9
10
|
#private;
|
|
10
11
|
private readonly snapData;
|
|
@@ -25,7 +26,7 @@ export declare class BaseSnapExecutor {
|
|
|
25
26
|
* @param sourceCode - The source code of the snap, in IIFE format.
|
|
26
27
|
* @param _endowments - An array of the names of the endowments.
|
|
27
28
|
*/
|
|
28
|
-
protected startSnap(snapId: string, sourceCode: string, _endowments
|
|
29
|
+
protected startSnap(snapId: string, sourceCode: string, _endowments: string[]): Promise<void>;
|
|
29
30
|
/**
|
|
30
31
|
* Cancels all running evaluations of all snaps and clears all snap data.
|
|
31
32
|
* NOTE:** Should only be called in response to the `terminate` RPC command.
|