diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4dc371d..c59e2ab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,6 +34,16 @@ jobs: - name: Build run: yarn run build + # The browser bundle resolves node builtins through its own fallback map, + # so nothing else in this workflow would notice it breaking. + - name: Build web + run: yarn run build-web + + # A compiling bundle is not a working one. This drives the RSA host + # function in a context with none of the node globals the bundle maps away. + - name: Browser bundle + run: node scripts/browser-bundle.test.js + # The examples compile contracts with blanc++, which is not available here, # so CI runs the VM suite only. - name: Test diff --git a/package.json b/package.json index 8055e41..f5229de 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,12 @@ "bigint-conversion": "^2.4.3", "buffer": "^6.0.3", "clean-webpack-plugin": "^4.0.0", + "constants-browserify": "^1.0.0", + "create-hash": "^1.2.0", "mocha": "^10.4.0", + "process": "^0.11.10", + "randombytes": "^2.1.0", + "stream-browserify": "^3.0.0", "ts-loader": "^9.2.6", "ts-node": "^10.5.0", "tslib": "^2.3.1", @@ -79,9 +84,9 @@ "lodash": "^4.17.21", "loglevel": "^1.8.0", "loglevel-plugin-prefix": "^0.8.4", + "node-rsa": "^1.1.1", "rustbn.js": "^0.2.0", - "sorted-btree": "^1.6.0", - "node-rsa": "^1.1.1" + "sorted-btree": "^1.6.0" }, "resolutions": { "serialize-javascript": "^7.1.0" diff --git a/scripts/browser-bundle.test.js b/scripts/browser-bundle.test.js new file mode 100644 index 0000000..769eb84 --- /dev/null +++ b/scripts/browser-bundle.test.js @@ -0,0 +1,185 @@ +// Check that the browser bundle works where a browser runs it. The webpack +// build proves only that every import resolved; it cannot show whether the +// node builtins the bundle maps away still behave once they are gone. So this +// loads the emitted chunks into a context that holds no Buffer, no process, no +// global and no require, then drives the RSA host function end to end: node-rsa +// reaches the crypto shim, the shim reaches create-hash, and the buffer package +// stands in for the node one. +// +// Usage: node scripts/browser-bundle.test.js +// +// Run yarn run build-web first. This script builds nothing. +// +// It reports in the same shape as the bash tests beside it, since CI and a +// reader both want one format, but the work is a node sandbox rather than shell. +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const vm = require('vm'); +const crypto = require('crypto'); + +const ROOT = path.join(__dirname, '..'); +const DIST = path.join(ROOT, 'dist-web'); +const NodeRSA = require(path.join(ROOT, 'node_modules', 'node-rsa')); + +let cases = 0; +let passed = 0; + +function ok(name) { + cases += 1; + passed += 1; + console.log(`ok ${cases} ${name}`); +} + +function no(name, detail) { + cases += 1; + console.log(`not ok ${cases} ${name}\n ${detail}`); +} + +function browserContext() { + const sandbox = { + console, + WebAssembly, + TextEncoder, + TextDecoder, + URL, + URLSearchParams, + ArrayBuffer, + DataView, + Uint8Array, + Uint16Array, + Uint32Array, + Int8Array, + Int16Array, + Int32Array, + Float32Array, + Float64Array, + BigInt64Array, + BigUint64Array, + setTimeout, + clearTimeout, + setInterval, + clearInterval, + }; + sandbox.window = sandbox; + sandbox.self = sandbox; + return vm.createContext(sandbox); +} + +// Drives verify_rsa_sha256_sig inside the sandbox. VM.from accepts an empty +// module and the memory is assigned directly, which is how the node suite +// reaches the host functions without a compiled contract. +const DRIVER = ` + const { Blockchain, VM, Memory } = vertLib; + function verify(signatureHex) { + const chain = new Blockchain({ chain: 'wax' }); + const memory = Memory.create(256); + const machine = VM.from(new Uint8Array(), chain); + machine._memory = memory; + + const bytes = new Uint8Array(memory.buffer); + const encoder = new TextEncoder(); + let offset = 0; + const write = (value) => { + bytes.set(value, offset); + const at = offset; + offset += value.length + 1; + return [at, value.length]; + }; + const fromHex = (hex) => { + const out = new Uint8Array(hex.length / 2); + for (let i = 0; i < out.length; i += 1) out[i] = parseInt(hex.substr(i * 2, 2), 16); + return out; + }; + + const [digestAt, digestLen] = write(fromHex(input.digest)); + const [signatureAt, signatureLen] = write(encoder.encode(signatureHex)); + const [exponentAt, exponentLen] = write(encoder.encode(input.exponent)); + const [modulusAt, modulusLen] = write(encoder.encode(input.modulus)); + + return machine.imports.env.verify_rsa_sha256_sig( + digestAt, digestLen, + signatureAt, signatureLen, + exponentAt, exponentLen, + modulusAt, modulusLen, + ); + } + result = { valid: verify(input.signature), tampered: verify(input.tampered) }; +`; + +function main() { + for (const chunk of ['externals.min.js', 'vert.min.js']) { + if (!fs.existsSync(path.join(DIST, chunk))) { + no('the browser bundle is present', `${path.join('dist-web', chunk)} is missing; run yarn run build-web`); + report(); + return; + } + } + + const context = browserContext(); + let library; + try { + for (const chunk of ['externals.min.js', 'vert.min.js']) { + vm.runInContext(fs.readFileSync(path.join(DIST, chunk), 'utf8'), context, { filename: chunk }); + } + library = context.vert; + } catch (error) { + no('the bundle loads without node globals', String(error)); + report(); + return; + } + + if (library && typeof library.Blockchain === 'function') { + ok('the bundle loads in a context with no Buffer, process, global or require'); + } else { + no('the bundle loads in a context with no Buffer, process, global or require', 'the UMD export is missing Blockchain'); + report(); + return; + } + + // Sign outside the sandbox with the real node crypto, which is where a + // signature comes from in practice. + const key = new NodeRSA({ b: 1024 }); + const digest = crypto.createHash('sha256').update('Hello, RSA!').digest('hex'); + const signature = key.sign(Buffer.from(digest, 'hex'), 'hex'); + const publicKey = key.exportKey('components-public'); + + context.vertLib = library; + context.input = { + digest, + signature, + tampered: (signature.slice(0, 2) === 'ff' ? '00' : 'ff') + signature.slice(2), + exponent: publicKey.e.toString(16), + modulus: publicKey.n.toString('hex'), + }; + + try { + vm.runInContext(DRIVER, context, { filename: 'verify-rsa-sha256-sig' }); + } catch (error) { + no('the RSA host function runs in the bundle', String(error)); + report(); + return; + } + + const { valid, tampered } = context.result; + if (valid === 1) { + ok('the bundle accepts a valid RSA signature'); + } else { + no('the bundle accepts a valid RSA signature', `verify_rsa_sha256_sig returned ${valid}, wanted 1`); + } + if (tampered === 0) { + ok('the bundle rejects a tampered RSA signature'); + } else { + no('the bundle rejects a tampered RSA signature', `verify_rsa_sha256_sig returned ${tampered}, wanted 0`); + } + + report(); +} + +function report() { + console.log(`passed ${passed}/${cases}`); + process.exit(passed === cases ? 0 : 1); +} + +main(); diff --git a/src/antelope/vm.ts b/src/antelope/vm.ts index 01f53dc..ba6bb86 100644 --- a/src/antelope/vm.ts +++ b/src/antelope/vm.ts @@ -1,5 +1,9 @@ import assert from "../assert"; import Buffer, { bufferToBigInt, readBufferFromBigInt } from "../buffer"; +// node-rsa works on node buffers, and the Buffer above is this package's own +// Uint8Array subclass. Node resolves this import to its built-in module, and a +// bundler resolves it to the buffer package, so both get a real one. +import { Buffer as NodeBuffer } from "buffer"; import { log, Vert } from "../vert"; import { IndexObject, KeyValueObject, SecondaryKeyStore, Table } from "./table"; import { IteratorCache } from "./iterator-cache"; @@ -541,14 +545,14 @@ class VM extends Vert { exponentHex (${exponent_len}): ${exponentHex} modulusHex (${modulus_len}): ${modulusHex.substring(0, 100)}...`); - // Convert hex strings to Node.js buffers (using global Buffer, not custom Buffer) - const dataBuffer = global.Buffer.from(dataHex, 'hex'); - const signatureBuffer = global.Buffer.from(signatureHex, 'hex'); + // Convert hex strings to node buffers, not this package's Buffer. + const dataBuffer = NodeBuffer.from(dataHex, 'hex'); + const signatureBuffer = NodeBuffer.from(signatureHex, 'hex'); // Create RSA public key from components const key = new NodeRSA(); key.importKey({ - n: global.Buffer.from(modulusHex, 'hex'), + n: NodeBuffer.from(modulusHex, 'hex'), e: parseInt(exponentHex, 16) }, 'components-public'); diff --git a/webpack.config.js b/webpack.config.js index 0ac889b..219efaf 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -25,12 +25,23 @@ module.exports = { new CleanWebpackPlugin({ cleanOnceBeforeBuildPatterns: ['**/*'] }), new webpack.ProvidePlugin({ Buffer: ["buffer", "Buffer"], + // node-rsa reads process.title to tell a browser from node, and webpack + // no longer supplies a process object of its own. + process: "process/browser", }), ], resolve: { extensions: ['.tsx', '.ts', '.js'], fallback: { assert: false, + constants: require.resolve('constants-browserify'), + crypto: require.resolve('./webpack/crypto-shim.js'), + stream: require.resolve('stream-browserify'), + // rustbn.js and colors reach for these only on their node branches, which + // a browser build never takes. + fs: false, + os: false, + path: false, } }, output: { diff --git a/webpack/crypto-shim.js b/webpack/crypto-shim.js new file mode 100644 index 0000000..ba42aba --- /dev/null +++ b/webpack/crypto-shim.js @@ -0,0 +1,12 @@ +// node-rsa requires the node crypto module at load time in every scheme file, +// but the branches it takes when its environment is 'browser' call only +// createHash and randomBytes: the RSA arithmetic itself runs on its own +// BigInteger. Mapping crypto to this module therefore keeps the browser bundle +// to those two functions rather than pulling a whole crypto implementation in +// behind them. The engine selector reads publicEncrypt and friends off this +// object, finds them absent, and settles on the pure JavaScript engine, which +// is the one a browser has to use anyway. +module.exports = { + createHash: require('create-hash'), + randomBytes: require('randombytes'), +}; diff --git a/yarn.lock b/yarn.lock index aa60947..bd1d958 100644 --- a/yarn.lock +++ b/yarn.lock @@ -547,6 +547,14 @@ buffer@^6.0.3: base64-js "^1.3.1" ieee754 "^1.2.1" +call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" + integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + call-bind@^1.0.2, call-bind@^1.0.7: version "1.0.7" resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz" @@ -558,6 +566,24 @@ call-bind@^1.0.2, call-bind@^1.0.7: get-intrinsic "^1.2.4" set-function-length "^1.2.1" +call-bind@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.9.tgz#39a644700c80bc7d0ca9102fc6d1d43b2fd7eee7" + integrity sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ== + dependencies: + call-bind-apply-helpers "^1.0.2" + es-define-property "^1.0.1" + get-intrinsic "^1.3.0" + set-function-length "^1.2.2" + +call-bound@^1.0.3, call-bound@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a" + integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== + dependencies: + call-bind-apply-helpers "^1.0.2" + get-intrinsic "^1.3.0" + camelcase@^6.0.0: version "6.3.0" resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" @@ -616,6 +642,15 @@ chrome-trace-event@^1.0.2: resolved "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz" integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== +cipher-base@^1.0.1: + version "1.0.7" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.7.tgz#bd094bfef42634ccfd9e13b9fc73274997111e39" + integrity sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA== + dependencies: + inherits "^2.0.4" + safe-buffer "^5.2.1" + to-buffer "^1.2.2" + clean-webpack-plugin@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-4.0.0.tgz" @@ -689,6 +724,27 @@ concat-map@0.0.1: resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + create-require@^1.1.0: version "1.1.1" resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz" @@ -783,6 +839,15 @@ dreamopt@~0.8.0: dependencies: wordwrap ">=0.0.2" +dunder-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" + integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== + dependencies: + call-bind-apply-helpers "^1.0.1" + es-errors "^1.3.0" + gopd "^1.2.0" + electron-to-chromium@^1.5.402: version "1.5.411" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.411.tgz#d56c7e43f91e2b3abb53b4eecd646e20d0b18b34" @@ -834,6 +899,11 @@ es-define-property@^1.0.0: dependencies: get-intrinsic "^1.2.4" +es-define-property@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" + integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== + es-errors@^1.3.0: version "1.3.0" resolved "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz" @@ -844,6 +914,13 @@ es-module-lexer@^2.1.0: resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-2.3.2.tgz#311fa4f40168c1975c505477c51b23234d41ad55" integrity sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw== +es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.2.tgz#a2d0b373205724dfa525d23b0c3e1b1ca582c99b" + integrity sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw== + dependencies: + es-errors "^1.3.0" + es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.53, es5-ext@^0.10.62, es5-ext@^0.10.64, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: version "0.10.64" resolved "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz" @@ -1011,6 +1088,13 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" +for-each@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.5.tgz#d650688027826920feeb0af747ee7b9421a41d47" + integrity sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg== + dependencies: + is-callable "^1.2.7" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" @@ -1047,6 +1131,30 @@ get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: has-symbols "^1.0.3" hasown "^2.0.0" +get-intrinsic@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" + integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== + dependencies: + call-bind-apply-helpers "^1.0.2" + es-define-property "^1.0.1" + es-errors "^1.3.0" + es-object-atoms "^1.1.1" + function-bind "^1.1.2" + get-proto "^1.0.1" + gopd "^1.2.0" + has-symbols "^1.1.0" + hasown "^2.0.2" + math-intrinsics "^1.1.0" + +get-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" + integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== + dependencies: + dunder-proto "^1.0.1" + es-object-atoms "^1.0.0" + glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" @@ -1095,6 +1203,11 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" +gopd@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" + integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== + graceful-fs@^4.1.2, graceful-fs@^4.2.11, graceful-fs@^4.2.4: version "4.2.11" resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" @@ -1122,6 +1235,11 @@ has-symbols@^1.0.3: resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== +has-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" + integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== + has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz" @@ -1129,6 +1247,16 @@ has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: dependencies: has-symbols "^1.0.3" +hash-base@^3.0.0, hash-base@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.2.tgz#79d72def7611c3f6e3c3b5730652638001b10a74" + integrity sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg== + dependencies: + inherits "^2.0.4" + readable-stream "^2.3.8" + safe-buffer "^5.2.1" + to-buffer "^1.2.1" + hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: version "1.1.7" resolved "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz" @@ -1144,6 +1272,13 @@ hasown@^2.0.0: dependencies: function-bind "^1.1.2" +hasown@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.4.tgz#8c62d8cb90beb2aad5d0a5b67581ad9854c3f003" + integrity sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A== + dependencies: + function-bind "^1.1.2" + he@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" @@ -1184,7 +1319,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.3, inherits@^2.0.4: +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@~2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -1209,7 +1344,7 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-callable@^1.1.3: +is-callable@^1.1.3, is-callable@^1.2.7: version "1.2.7" resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== @@ -1286,6 +1421,13 @@ is-promise@^2.2.2: resolved "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz" integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== +is-typed-array@^1.1.14: + version "1.1.15" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.15.tgz#4bfb4a45b61cee83a5a46fba778e4e8d59c0ce0b" + integrity sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ== + dependencies: + which-typed-array "^1.1.16" + is-typed-array@^1.1.3: version "1.1.13" resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz" @@ -1298,6 +1440,16 @@ is-unicode-supported@^0.1.0: resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" @@ -1418,6 +1570,20 @@ make-error@^1.1.1: resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== +math-intrinsics@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" + integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + memoizee@^0.4.15: version "0.4.15" resolved "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz" @@ -1683,6 +1849,45 @@ possible-typed-array-names@^1.0.0: resolved "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz" integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +readable-stream@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.5.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readdirp@~3.6.0: version "3.6.0" resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" @@ -1735,11 +1940,29 @@ rimraf@^2.6.3: dependencies: glob "^7.1.3" +ripemd160@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.3.tgz#9be54e4ba5e3559c8eee06a25cd7648bbccdf5a8" + integrity sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA== + dependencies: + hash-base "^3.1.2" + inherits "^2.0.4" + rustbn.js@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz" integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== +safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@^5.2.1, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" @@ -1767,7 +1990,7 @@ serialize-javascript@^6.0.2, serialize-javascript@^7.1.0: resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-7.1.0.tgz#9e462c5c6dec5dbc8b55d90c52a4ad6aff985b9f" integrity sha512-RNEqWOyhhUQYN9V1GfHwu9AR/g+NTciH6Z5u3/no6X3/w+04J2lVDL+svFQVXgXrEGBMG2puMVN3gq2SNGuTGw== -set-function-length@^1.2.1: +set-function-length@^1.2.1, set-function-length@^1.2.2: version "1.2.2" resolved "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz" integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== @@ -1779,6 +2002,15 @@ set-function-length@^1.2.1: gopd "^1.0.1" has-property-descriptors "^1.0.2" +sha.js@^2.4.0: + version "2.4.12" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.12.tgz#eb8b568bf383dfd1867a32c3f2b74eb52bdbf23f" + integrity sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w== + dependencies: + inherits "^2.0.4" + safe-buffer "^5.2.1" + to-buffer "^1.2.0" + shallow-clone@^3.0.0: version "3.0.1" resolved "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz" @@ -1821,6 +2053,14 @@ source-map@^0.7.4: resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz" integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== +stream-browserify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f" + integrity sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA== + dependencies: + inherits "~2.0.4" + readable-stream "^3.5.0" + string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" @@ -1830,6 +2070,20 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" @@ -1889,6 +2143,15 @@ timers-ext@^0.1.7: es5-ext "~0.10.46" next-tick "1" +to-buffer@^1.2.0, to-buffer@^1.2.1, to-buffer@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.2.2.tgz#ffe59ef7522ada0a2d1cb5dfe03bb8abc3cdc133" + integrity sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw== + dependencies: + isarray "^2.0.5" + safe-buffer "^5.2.1" + typed-array-buffer "^1.0.3" + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" @@ -1946,6 +2209,15 @@ type@^2.7.2: resolved "https://registry.npmjs.org/type/-/type-2.7.2.tgz" integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== +typed-array-buffer@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz#a72395450a4869ec033fd549371b47af3a2ee536" + integrity sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw== + dependencies: + call-bound "^1.0.3" + es-errors "^1.3.0" + is-typed-array "^1.1.14" + typescript@^4.5.5: version "4.9.5" resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz" @@ -1964,6 +2236,11 @@ update-browserslist-db@^1.3.0: escalade "^3.2.0" picocolors "^1.1.1" +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + util@^0.12.4: version "0.12.5" resolved "https://registry.npmjs.org/util/-/util-0.12.5.tgz" @@ -2069,6 +2346,19 @@ which-typed-array@^1.1.14, which-typed-array@^1.1.2: gopd "^1.0.1" has-tostringtag "^1.0.2" +which-typed-array@^1.1.16: + version "1.1.22" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.22.tgz#8f3cc78aefb40b437346dd40a1dbfa5d1da43fe9" + integrity sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw== + dependencies: + available-typed-arrays "^1.0.7" + call-bind "^1.0.9" + call-bound "^1.0.4" + for-each "^0.3.5" + get-proto "^1.0.1" + gopd "^1.2.0" + has-tostringtag "^1.0.2" + which@^2.0.1: version "2.0.2" resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz"