@metamask/snaps-execution-environments 0.24.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/LICENSE +20 -0
- package/README.md +3 -0
- package/dist/common/BaseSnapExecutor.d.ts +68 -0
- package/dist/common/BaseSnapExecutor.js +324 -0
- package/dist/common/BaseSnapExecutor.js.map +1 -0
- package/dist/common/commands.d.ts +30 -0
- package/dist/common/commands.js +68 -0
- package/dist/common/commands.js.map +1 -0
- package/dist/common/endowments/crypto.d.ts +8 -0
- package/dist/common/endowments/crypto.js +25 -0
- package/dist/common/endowments/crypto.js.map +1 -0
- package/dist/common/endowments/index.d.ts +25 -0
- package/dist/common/endowments/index.js +122 -0
- package/dist/common/endowments/index.js.map +1 -0
- package/dist/common/endowments/interval.d.ts +9 -0
- package/dist/common/endowments/interval.js +47 -0
- package/dist/common/endowments/interval.js.map +1 -0
- package/dist/common/endowments/math.d.ts +60 -0
- package/dist/common/endowments/math.js +48 -0
- package/dist/common/endowments/math.js.map +1 -0
- package/dist/common/endowments/network.d.ts +48 -0
- package/dist/common/endowments/network.js +362 -0
- package/dist/common/endowments/network.js.map +1 -0
- package/dist/common/endowments/timeout.d.ts +9 -0
- package/dist/common/endowments/timeout.js +50 -0
- package/dist/common/endowments/timeout.js.map +1 -0
- package/dist/common/globalEvents.d.ts +19 -0
- package/dist/common/globalEvents.js +47 -0
- package/dist/common/globalEvents.js.map +1 -0
- package/dist/common/globalObject.d.ts +9 -0
- package/dist/common/globalObject.js +48 -0
- package/dist/common/globalObject.js.map +1 -0
- package/dist/common/keyring.d.ts +12 -0
- package/dist/common/keyring.js +42 -0
- package/dist/common/keyring.js.map +1 -0
- package/dist/common/lockdown/lockdown-more.d.ts +22 -0
- package/dist/common/lockdown/lockdown-more.js +88 -0
- package/dist/common/lockdown/lockdown-more.js.map +1 -0
- package/dist/common/lockdown/lockdown.d.ts +7 -0
- package/dist/common/lockdown/lockdown.js +28 -0
- package/dist/common/lockdown/lockdown.js.map +1 -0
- package/dist/common/sortParams.d.ts +16 -0
- package/dist/common/sortParams.js +32 -0
- package/dist/common/sortParams.js.map +1 -0
- package/dist/common/utils.d.ts +38 -0
- package/dist/common/utils.js +98 -0
- package/dist/common/utils.js.map +1 -0
- package/dist/common/validation.d.ts +100 -0
- package/dist/common/validation.js +110 -0
- package/dist/common/validation.js.map +1 -0
- package/dist/iframe/IFrameSnapExecutor.d.ts +11 -0
- package/dist/iframe/IFrameSnapExecutor.js +41 -0
- package/dist/iframe/IFrameSnapExecutor.js.map +1 -0
- package/dist/iframe/index.d.ts +1 -0
- package/dist/iframe/index.js +9 -0
- package/dist/iframe/index.js.map +1 -0
- package/dist/iframe-test/index.d.ts +1 -0
- package/dist/iframe-test/index.js +8 -0
- package/dist/iframe-test/index.js.map +1 -0
- package/dist/node-process/ChildProcessSnapExecutor.d.ts +4 -0
- package/dist/node-process/ChildProcessSnapExecutor.js +29 -0
- package/dist/node-process/ChildProcessSnapExecutor.js.map +1 -0
- package/dist/node-process/index.d.ts +1 -0
- package/dist/node-process/index.js +9 -0
- package/dist/node-process/index.js.map +1 -0
- package/dist/node-thread/ThreadSnapExecutor.d.ts +4 -0
- package/dist/node-thread/ThreadSnapExecutor.js +29 -0
- package/dist/node-thread/ThreadSnapExecutor.js.map +1 -0
- package/dist/node-thread/index.d.ts +1 -0
- package/dist/node-thread/index.js +9 -0
- package/dist/node-thread/index.js.map +1 -0
- package/dist/openrpc.json +210 -0
- package/dist/webpack/iframe/bundle.js +2 -0
- package/dist/webpack/iframe/bundle.js.LICENSE.txt +21 -0
- package/dist/webpack/iframe/index.html +10 -0
- package/dist/webpack/iframe/lockdown.umd.min.js +1 -0
- package/dist/webpack/node-process/bundle.js +1784 -0
- package/dist/webpack/node-process/bundle.js.LICENSE.txt +3 -0
- package/dist/webpack/node-process/lockdown.umd.min.js +1 -0
- package/dist/webpack/node-thread/bundle.js +1784 -0
- package/dist/webpack/node-thread/bundle.js.LICENSE.txt +3 -0
- package/dist/webpack/node-thread/lockdown.umd.min.js +1 -0
- package/package.json +88 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.isConstructor = exports.createEndowments = void 0;
|
|
18
|
+
const utils_1 = require("@metamask/utils");
|
|
19
|
+
const globalObject_1 = require("../globalObject");
|
|
20
|
+
const interval_1 = __importDefault(require("./interval"));
|
|
21
|
+
const network_1 = __importDefault(require("./network"));
|
|
22
|
+
const timeout_1 = __importDefault(require("./timeout"));
|
|
23
|
+
const crypto_1 = __importDefault(require("./crypto"));
|
|
24
|
+
const math_1 = __importDefault(require("./math"));
|
|
25
|
+
/**
|
|
26
|
+
* A map of endowment names to their factory functions. Some endowments share
|
|
27
|
+
* the same factory function, but we only call each factory once for each snap.
|
|
28
|
+
* See {@link createEndowments} for details.
|
|
29
|
+
*/
|
|
30
|
+
const endowmentFactories = [timeout_1.default, interval_1.default, network_1.default, crypto_1.default, math_1.default].reduce((factories, builder) => {
|
|
31
|
+
builder.names.forEach((name) => {
|
|
32
|
+
factories.set(name, builder.factory);
|
|
33
|
+
});
|
|
34
|
+
return factories;
|
|
35
|
+
}, new Map());
|
|
36
|
+
/**
|
|
37
|
+
* Gets the endowments for a particular Snap. Some endowments, like `setTimeout`
|
|
38
|
+
* and `clearTimeout`, must be attenuated so that they can only affect behavior
|
|
39
|
+
* within the Snap's own realm. Therefore, we use factory functions to create
|
|
40
|
+
* such attenuated / modified endowments. Otherwise, the value that's on the
|
|
41
|
+
* root realm global will be used.
|
|
42
|
+
*
|
|
43
|
+
* @param snap - The Snaps global API object.
|
|
44
|
+
* @param ethereum - The Snap's EIP-1193 provider object.
|
|
45
|
+
* @param endowments - The list of endowments to provide to the snap.
|
|
46
|
+
* @returns An object containing the Snap's endowments.
|
|
47
|
+
*/
|
|
48
|
+
function createEndowments(snap, ethereum, endowments = []) {
|
|
49
|
+
const attenuatedEndowments = {};
|
|
50
|
+
// TODO: All endowments should be hardened to prevent covert communication
|
|
51
|
+
// channels. Hardening the returned objects breaks tests elsewhere in the
|
|
52
|
+
// monorepo, so further research is needed.
|
|
53
|
+
const result = endowments.reduce(({ allEndowments, teardowns }, endowmentName) => {
|
|
54
|
+
// First, check if the endowment has a factory, and default to that.
|
|
55
|
+
if (endowmentFactories.has(endowmentName)) {
|
|
56
|
+
if (!(0, utils_1.hasProperty)(attenuatedEndowments, endowmentName)) {
|
|
57
|
+
// Call the endowment factory for the current endowment. If the factory
|
|
58
|
+
// creates multiple endowments, they will all be assigned to the
|
|
59
|
+
// `attenuatedEndowments` object, but will only be passed on to the snap
|
|
60
|
+
// if explicitly listed among its endowment.
|
|
61
|
+
// This may not have an actual use case, but, safety first.
|
|
62
|
+
// We just confirmed that endowmentFactories has the specified key.
|
|
63
|
+
const _a =
|
|
64
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
65
|
+
endowmentFactories.get(endowmentName)(), { teardownFunction } = _a, endowment = __rest(_a, ["teardownFunction"]);
|
|
66
|
+
Object.assign(attenuatedEndowments, endowment);
|
|
67
|
+
if (teardownFunction) {
|
|
68
|
+
teardowns.push(teardownFunction);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
allEndowments[endowmentName] = attenuatedEndowments[endowmentName];
|
|
72
|
+
}
|
|
73
|
+
else if (endowmentName in globalObject_1.rootRealmGlobal) {
|
|
74
|
+
// If the endowment doesn't have a factory, just use whatever is on the
|
|
75
|
+
// global object.
|
|
76
|
+
const globalValue = globalObject_1.rootRealmGlobal[endowmentName];
|
|
77
|
+
allEndowments[endowmentName] =
|
|
78
|
+
typeof globalValue === 'function' && !isConstructor(globalValue)
|
|
79
|
+
? globalValue.bind(globalObject_1.rootRealmGlobal)
|
|
80
|
+
: globalValue;
|
|
81
|
+
}
|
|
82
|
+
else if (endowmentName === 'ethereum') {
|
|
83
|
+
// Special case for adding the EIP-1193 provider.
|
|
84
|
+
allEndowments[endowmentName] = ethereum;
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
// If we get to this point, we've been passed an endowment that doesn't
|
|
88
|
+
// exist in our current environment.
|
|
89
|
+
throw new Error(`Unknown endowment: "${endowmentName}".`);
|
|
90
|
+
}
|
|
91
|
+
return { allEndowments, teardowns };
|
|
92
|
+
}, {
|
|
93
|
+
allEndowments: { snap },
|
|
94
|
+
teardowns: [],
|
|
95
|
+
});
|
|
96
|
+
const teardown = async () => {
|
|
97
|
+
await Promise.all(result.teardowns.map((teardownFunction) => teardownFunction()));
|
|
98
|
+
};
|
|
99
|
+
return { endowments: result.allEndowments, teardown };
|
|
100
|
+
}
|
|
101
|
+
exports.createEndowments = createEndowments;
|
|
102
|
+
/**
|
|
103
|
+
* Checks whether the specified function is a constructor.
|
|
104
|
+
*
|
|
105
|
+
* @param value - Any function value.
|
|
106
|
+
* @returns Whether the specified function is a constructor.
|
|
107
|
+
*/
|
|
108
|
+
// `Function` is exactly what we want here.
|
|
109
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
110
|
+
function isConstructor(value) {
|
|
111
|
+
var _a, _b;
|
|
112
|
+
// In our current usage, the string `prototype.constructor.name` should never
|
|
113
|
+
// be empty, because you can't create a class with no name, and the
|
|
114
|
+
// `prototype.constructor.name` property is configurable but not writable.
|
|
115
|
+
// Nevertheless, that property was the empty string for `Date` in the iframe
|
|
116
|
+
// execution environment during local testing. We have no idea why, but we
|
|
117
|
+
// have to handle that case.
|
|
118
|
+
// TODO: Does the `prototype` object always have a `constructor` property?
|
|
119
|
+
return Boolean(typeof ((_b = (_a = value.prototype) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.name) === 'string');
|
|
120
|
+
}
|
|
121
|
+
exports.isConstructor = isConstructor;
|
|
122
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/common/endowments/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { SnapsGlobalObject } from '@metamask/snaps-types';\nimport { hasProperty } from '@metamask/utils';\nimport { StreamProvider } from '@metamask/providers';\nimport { rootRealmGlobal } from '../globalObject';\nimport interval from './interval';\nimport network from './network';\nimport timeout from './timeout';\nimport crypto from './crypto';\nimport math from './math';\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 * 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 = [timeout, interval, network, crypto, math].reduce(\n (factories, builder) => {\n builder.names.forEach((name) => {\n factories.set(name, builder.factory);\n });\n return factories;\n },\n new Map<string, () => EndowmentFactoryResult>(),\n);\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 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: SnapsGlobalObject,\n ethereum: StreamProvider,\n endowments: string[] = [],\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, 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 const { teardownFunction, ...endowment } =\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n endowmentFactories.get(endowmentName)!();\n Object.assign(attenuatedEndowments, endowment);\n if (teardownFunction) {\n teardowns.push(teardownFunction);\n }\n }\n\n allEndowments[endowmentName] = attenuatedEndowments[endowmentName];\n } else if (endowmentName in rootRealmGlobal) {\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] =\n typeof globalValue === 'function' && !isConstructor(globalValue)\n ? globalValue.bind(rootRealmGlobal)\n : globalValue;\n } else if (endowmentName === 'ethereum') {\n // Special case for adding the EIP-1193 provider.\n allEndowments[endowmentName] = ethereum;\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 new Error(`Unknown endowment: \"${endowmentName}\".`);\n }\n return { allEndowments, teardowns };\n },\n {\n allEndowments: { snap } as Record<string, unknown>,\n teardowns: [] as (() => void)[],\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\n/**\n * Checks whether the specified function is a constructor.\n *\n * @param value - Any function value.\n * @returns Whether the specified function is a constructor.\n */\n// `Function` is exactly what we want here.\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport function isConstructor<T extends Function>(value: T): boolean {\n // In our current usage, the string `prototype.constructor.name` should never\n // be empty, because you can't create a class with no name, and the\n // `prototype.constructor.name` property is configurable but not writable.\n // Nevertheless, that property was the empty string for `Date` in the iframe\n // execution environment during local testing. We have no idea why, but we\n // have to handle that case.\n // TODO: Does the `prototype` object always have a `constructor` property?\n return Boolean(typeof value.prototype?.constructor?.name === 'string');\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
declare const endowmentModule: {
|
|
2
|
+
names: readonly ["setInterval", "clearInterval"];
|
|
3
|
+
factory: () => {
|
|
4
|
+
readonly setInterval: (handler: TimerHandler, timeout?: number | undefined) => unknown;
|
|
5
|
+
readonly clearInterval: (handle: unknown) => void;
|
|
6
|
+
readonly teardownFunction: () => void;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
export default endowmentModule;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* Creates a pair of `setInterval` and `clearInterval` functions attenuated such
|
|
5
|
+
* that:
|
|
6
|
+
* - `setInterval` throws if its "handler" parameter is not a function.
|
|
7
|
+
* - `clearInterval` only clears timeouts created by its sibling `setInterval`,
|
|
8
|
+
* or else no-ops.
|
|
9
|
+
*
|
|
10
|
+
* @returns An object with the attenuated `setInterval` and `clearInterval`
|
|
11
|
+
* functions.
|
|
12
|
+
*/
|
|
13
|
+
const createInterval = () => {
|
|
14
|
+
const registeredHandles = new Map();
|
|
15
|
+
const _setInterval = (handler, timeout) => {
|
|
16
|
+
if (typeof handler !== 'function') {
|
|
17
|
+
throw new Error(`The interval handler must be a function. Received: ${typeof handler}`);
|
|
18
|
+
}
|
|
19
|
+
const handle = Object.freeze({});
|
|
20
|
+
const platformHandle = setInterval(handler, timeout);
|
|
21
|
+
registeredHandles.set(handle, platformHandle);
|
|
22
|
+
return handle;
|
|
23
|
+
};
|
|
24
|
+
const _clearInterval = (handle) => {
|
|
25
|
+
const platformHandle = registeredHandles.get(handle);
|
|
26
|
+
if (platformHandle !== undefined) {
|
|
27
|
+
clearInterval(platformHandle);
|
|
28
|
+
registeredHandles.delete(handle);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
const teardownFunction = () => {
|
|
32
|
+
for (const handle of registeredHandles.keys()) {
|
|
33
|
+
_clearInterval(handle);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
return {
|
|
37
|
+
setInterval: _setInterval,
|
|
38
|
+
clearInterval: _clearInterval,
|
|
39
|
+
teardownFunction,
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
const endowmentModule = {
|
|
43
|
+
names: ['setInterval', 'clearInterval'],
|
|
44
|
+
factory: createInterval,
|
|
45
|
+
};
|
|
46
|
+
exports.default = endowmentModule;
|
|
47
|
+
//# sourceMappingURL=interval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interval.js","sourceRoot":"","sources":["../../../src/common/endowments/interval.ts"],"names":[],"mappings":";;AAAA;;;;;;;;;GASG;AACH,MAAM,cAAc,GAAG,GAAG,EAAE;IAC1B,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAoB,CAAC;IAEtD,MAAM,YAAY,GAAG,CAAC,OAAqB,EAAE,OAAgB,EAAW,EAAE;QACxE,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE;YACjC,MAAM,IAAI,KAAK,CACb,sDAAsD,OAAO,OAAO,EAAE,CACvE,CAAC;SACH;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACjC,MAAM,cAAc,GAAG,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACrD,iBAAiB,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAC9C,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,CAAC,MAAe,EAAQ,EAAE;QAC/C,MAAM,cAAc,GAAG,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACrD,IAAI,cAAc,KAAK,SAAS,EAAE;YAChC,aAAa,CAAC,cAAqB,CAAC,CAAC;YACrC,iBAAiB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;SAClC;IACH,CAAC,CAAC;IAEF,MAAM,gBAAgB,GAAG,GAAS,EAAE;QAClC,KAAK,MAAM,MAAM,IAAI,iBAAiB,CAAC,IAAI,EAAE,EAAE;YAC7C,cAAc,CAAC,MAAM,CAAC,CAAC;SACxB;IACH,CAAC,CAAC;IAEF,OAAO;QACL,WAAW,EAAE,YAAY;QACzB,aAAa,EAAE,cAAc;QAC7B,gBAAgB;KACR,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG;IACtB,KAAK,EAAE,CAAC,aAAa,EAAE,eAAe,CAAU;IAChD,OAAO,EAAE,cAAc;CACxB,CAAC;AACF,kBAAe,eAAe,CAAC","sourcesContent":["/**\n * Creates a pair of `setInterval` and `clearInterval` functions attenuated such\n * that:\n * - `setInterval` throws if its \"handler\" parameter is not a function.\n * - `clearInterval` only clears timeouts created by its sibling `setInterval`,\n * or else no-ops.\n *\n * @returns An object with the attenuated `setInterval` and `clearInterval`\n * functions.\n */\nconst createInterval = () => {\n const registeredHandles = new Map<unknown, unknown>();\n\n const _setInterval = (handler: TimerHandler, timeout?: number): unknown => {\n if (typeof handler !== 'function') {\n throw new Error(\n `The interval handler must be a function. Received: ${typeof handler}`,\n );\n }\n const handle = Object.freeze({});\n const platformHandle = setInterval(handler, timeout);\n registeredHandles.set(handle, platformHandle);\n return handle;\n };\n\n const _clearInterval = (handle: unknown): void => {\n const platformHandle = registeredHandles.get(handle);\n if (platformHandle !== undefined) {\n clearInterval(platformHandle as any);\n registeredHandles.delete(handle);\n }\n };\n\n const teardownFunction = (): void => {\n for (const handle of registeredHandles.keys()) {\n _clearInterval(handle);\n }\n };\n\n return {\n setInterval: _setInterval,\n clearInterval: _clearInterval,\n teardownFunction,\n } as const;\n};\n\nconst endowmentModule = {\n names: ['setInterval', 'clearInterval'] as const,\n factory: createInterval,\n};\nexport default endowmentModule;\n"]}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create a {@link Math} object, with the same properties as the global
|
|
3
|
+
* {@link Math} object, but with the {@link Math.random} method replaced.
|
|
4
|
+
*
|
|
5
|
+
* @returns The {@link Math} object with the {@link Math.random} method
|
|
6
|
+
* replaced.
|
|
7
|
+
*/
|
|
8
|
+
declare function createMath(): {
|
|
9
|
+
Math: {
|
|
10
|
+
random: () => number;
|
|
11
|
+
E: number;
|
|
12
|
+
LN10: number;
|
|
13
|
+
LN2: number;
|
|
14
|
+
LOG2E: number;
|
|
15
|
+
LOG10E: number;
|
|
16
|
+
PI: number;
|
|
17
|
+
SQRT1_2: number;
|
|
18
|
+
SQRT2: number;
|
|
19
|
+
abs(x: number): number;
|
|
20
|
+
acos(x: number): number;
|
|
21
|
+
asin(x: number): number;
|
|
22
|
+
atan(x: number): number;
|
|
23
|
+
atan2(y: number, x: number): number;
|
|
24
|
+
ceil(x: number): number;
|
|
25
|
+
cos(x: number): number;
|
|
26
|
+
exp(x: number): number;
|
|
27
|
+
floor(x: number): number;
|
|
28
|
+
log(x: number): number;
|
|
29
|
+
max(...values: number[]): number;
|
|
30
|
+
min(...values: number[]): number;
|
|
31
|
+
pow(x: number, y: number): number;
|
|
32
|
+
round(x: number): number;
|
|
33
|
+
sin(x: number): number;
|
|
34
|
+
sqrt(x: number): number;
|
|
35
|
+
tan(x: number): number;
|
|
36
|
+
clz32(x: number): number;
|
|
37
|
+
imul(x: number, y: number): number;
|
|
38
|
+
sign(x: number): number;
|
|
39
|
+
log10(x: number): number;
|
|
40
|
+
log2(x: number): number;
|
|
41
|
+
log1p(x: number): number;
|
|
42
|
+
expm1(x: number): number;
|
|
43
|
+
cosh(x: number): number;
|
|
44
|
+
sinh(x: number): number;
|
|
45
|
+
tanh(x: number): number;
|
|
46
|
+
acosh(x: number): number;
|
|
47
|
+
asinh(x: number): number;
|
|
48
|
+
atanh(x: number): number;
|
|
49
|
+
hypot(...values: number[]): number;
|
|
50
|
+
trunc(x: number): number;
|
|
51
|
+
fround(x: number): number;
|
|
52
|
+
cbrt(x: number): number;
|
|
53
|
+
[Symbol.toStringTag]: string;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
declare const endowmentModule: {
|
|
57
|
+
names: readonly ["Math"];
|
|
58
|
+
factory: typeof createMath;
|
|
59
|
+
};
|
|
60
|
+
export default endowmentModule;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const globalObject_1 = require("../globalObject");
|
|
4
|
+
/**
|
|
5
|
+
* Create a {@link Math} object, with the same properties as the global
|
|
6
|
+
* {@link Math} object, but with the {@link Math.random} method replaced.
|
|
7
|
+
*
|
|
8
|
+
* @returns The {@link Math} object with the {@link Math.random} method
|
|
9
|
+
* replaced.
|
|
10
|
+
*/
|
|
11
|
+
function createMath() {
|
|
12
|
+
// `Math` does not work with `Object.keys`, `Object.entries`, etc., so we
|
|
13
|
+
// need to create a new object with the same properties.
|
|
14
|
+
const keys = Object.getOwnPropertyNames(globalObject_1.rootRealmGlobal.Math);
|
|
15
|
+
const math = keys.reduce((target, key) => {
|
|
16
|
+
if (key === 'random') {
|
|
17
|
+
return target;
|
|
18
|
+
}
|
|
19
|
+
return Object.assign(Object.assign({}, target), { [key]: globalObject_1.rootRealmGlobal.Math[key] });
|
|
20
|
+
}, {});
|
|
21
|
+
return {
|
|
22
|
+
Math: Object.assign(Object.assign({}, math), { random: () => {
|
|
23
|
+
// NOTE: This is not intended to be a secure replacement for the weak
|
|
24
|
+
// random number generator used by `Math.random`. It is only intended to
|
|
25
|
+
// prevent side channel attacks of `Math.random` by replacing it with an
|
|
26
|
+
// alternative implementation that is not vulnerable to the same
|
|
27
|
+
// attacks.
|
|
28
|
+
//
|
|
29
|
+
// This does not mean that this implementation is secure. It is not
|
|
30
|
+
// intended to be used in a security context, and this implementation
|
|
31
|
+
// may change at any time.
|
|
32
|
+
//
|
|
33
|
+
// To securely generate random numbers, use a cryptographically secure
|
|
34
|
+
// random number generator, such as the one provided by the Web Crypto
|
|
35
|
+
// API:
|
|
36
|
+
//
|
|
37
|
+
// - https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/generateKey
|
|
38
|
+
// - https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues
|
|
39
|
+
return crypto.getRandomValues(new Uint32Array(1))[0] / 2 ** 32;
|
|
40
|
+
} }),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const endowmentModule = {
|
|
44
|
+
names: ['Math'],
|
|
45
|
+
factory: createMath,
|
|
46
|
+
};
|
|
47
|
+
exports.default = endowmentModule;
|
|
48
|
+
//# sourceMappingURL=math.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"math.js","sourceRoot":"","sources":["../../../src/common/endowments/math.ts"],"names":[],"mappings":";;AAAA,kDAAkD;AAElD;;;;;;GAMG;AACH,SAAS,UAAU;IACjB,yEAAyE;IACzE,wDAAwD;IACxD,MAAM,IAAI,GAAG,MAAM,CAAC,mBAAmB,CACrC,8BAAe,CAAC,IAAI,CACI,CAAC;IAE3B,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAO,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;QAC7C,IAAI,GAAG,KAAK,QAAQ,EAAE;YACpB,OAAO,MAAM,CAAC;SACf;QAED,uCAAY,MAAM,KAAE,CAAC,GAAG,CAAC,EAAE,8BAAe,CAAC,IAAI,CAAC,GAAG,CAAC,IAAG;IACzD,CAAC,EAAE,EAAU,CAAC,CAAC;IAEf,OAAO;QACL,IAAI,kCACC,IAAI,KACP,MAAM,EAAE,GAAG,EAAE;gBACX,qEAAqE;gBACrE,wEAAwE;gBACxE,wEAAwE;gBACxE,gEAAgE;gBAChE,WAAW;gBACX,EAAE;gBACF,mEAAmE;gBACnE,qEAAqE;gBACrE,0BAA0B;gBAC1B,EAAE;gBACF,sEAAsE;gBACtE,sEAAsE;gBACtE,OAAO;gBACP,EAAE;gBACF,8EAA8E;gBAC9E,4EAA4E;gBAC5E,OAAO,MAAM,CAAC,eAAe,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;YACjE,CAAC,GACF;KACF,CAAC;AACJ,CAAC;AAED,MAAM,eAAe,GAAG;IACtB,KAAK,EAAE,CAAC,MAAM,CAAU;IACxB,OAAO,EAAE,UAAU;CACpB,CAAC;AAEF,kBAAe,eAAe,CAAC","sourcesContent":["import { rootRealmGlobal } from '../globalObject';\n\n/**\n * Create a {@link Math} object, with the same properties as the global\n * {@link Math} object, but with the {@link Math.random} method replaced.\n *\n * @returns The {@link Math} object with the {@link Math.random} method\n * replaced.\n */\nfunction createMath() {\n // `Math` does not work with `Object.keys`, `Object.entries`, etc., so we\n // need to create a new object with the same properties.\n const keys = Object.getOwnPropertyNames(\n rootRealmGlobal.Math,\n ) as (keyof typeof Math)[];\n\n const math = keys.reduce<Math>((target, key) => {\n if (key === 'random') {\n return target;\n }\n\n return { ...target, [key]: rootRealmGlobal.Math[key] };\n }, {} as Math);\n\n return {\n Math: {\n ...math,\n random: () => {\n // NOTE: This is not intended to be a secure replacement for the weak\n // random number generator used by `Math.random`. It is only intended to\n // prevent side channel attacks of `Math.random` by replacing it with an\n // alternative implementation that is not vulnerable to the same\n // attacks.\n //\n // This does not mean that this implementation is secure. It is not\n // intended to be used in a security context, and this implementation\n // may change at any time.\n //\n // To securely generate random numbers, use a cryptographically secure\n // random number generator, such as the one provided by the Web Crypto\n // API:\n //\n // - https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/generateKey\n // - https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues\n return crypto.getRandomValues(new Uint32Array(1))[0] / 2 ** 32;\n },\n },\n };\n}\n\nconst endowmentModule = {\n names: ['Math'] as const,\n factory: createMath,\n};\n\nexport default endowmentModule;\n"]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
declare type WebSocketCallback = (this: WebSocket, ev: any) => any;
|
|
2
|
+
declare const endowmentModule: {
|
|
3
|
+
names: readonly ["fetch", "WebSocket"];
|
|
4
|
+
factory: () => {
|
|
5
|
+
fetch: typeof fetch;
|
|
6
|
+
WebSocket: {
|
|
7
|
+
new (url: string | URL, protocols?: string | string[] | undefined): {
|
|
8
|
+
onclose: WebSocketCallback | null;
|
|
9
|
+
onerror: ((this: WebSocket, ev: Event) => any) | null;
|
|
10
|
+
onmessage: ((this: WebSocket, ev: MessageEvent<any>) => any) | null;
|
|
11
|
+
onopen: ((this: WebSocket, ev: Event) => any) | null;
|
|
12
|
+
close(code?: number | undefined, reason?: string | undefined): void;
|
|
13
|
+
send(data: string | Blob | ArrayBufferView | ArrayBufferLike): void;
|
|
14
|
+
readonly CLOSED: number;
|
|
15
|
+
readonly CLOSING: number;
|
|
16
|
+
readonly CONNECTING: number;
|
|
17
|
+
readonly OPEN: number;
|
|
18
|
+
binaryType: BinaryType;
|
|
19
|
+
readonly bufferedAmount: number;
|
|
20
|
+
readonly extensions: string;
|
|
21
|
+
readonly protocol: string;
|
|
22
|
+
readonly readyState: number;
|
|
23
|
+
readonly url: string;
|
|
24
|
+
addEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined): void;
|
|
25
|
+
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void;
|
|
26
|
+
removeEventListener<K_1 extends keyof WebSocketEventMap>(type: K_1, listener: (this: WebSocket, ev: WebSocketEventMap[K_1]) => any, options?: boolean | EventListenerOptions | undefined): void;
|
|
27
|
+
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions | undefined): void;
|
|
28
|
+
dispatchEvent(event: Event): boolean;
|
|
29
|
+
"__#4@#teardownClose"(): Promise<void>;
|
|
30
|
+
"__#4@#createWrapped"(listener: WebSocketCallback): WebSocketCallback;
|
|
31
|
+
"__#4@#createWrapped"(listener: null): null;
|
|
32
|
+
"__#4@#createWrapped"(listener: WebSocketCallback | null): WebSocketCallback | null;
|
|
33
|
+
"__#4@#socket": WebSocket;
|
|
34
|
+
/**
|
|
35
|
+
* After this is set to true, no new event listeners can be added
|
|
36
|
+
*/
|
|
37
|
+
"__#4@#isTornDown": boolean;
|
|
38
|
+
"__#4@#events": Record<string, Map<WebSocketCallback, WebSocketCallback>>;
|
|
39
|
+
"__#4@#onopenOriginal": WebSocketCallback | null;
|
|
40
|
+
"__#4@#onmessageOriginal": WebSocketCallback | null;
|
|
41
|
+
"__#4@#onerrorOriginal": WebSocketCallback | null;
|
|
42
|
+
"__#4@#oncloseOriginal": WebSocketCallback | null;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
teardownFunction: () => Promise<void>;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
export default endowmentModule;
|