From 1a4345dd78d370bc727790dbe2a20afaec44cfa8 Mon Sep 17 00:00:00 2001 From: Mark Sinclair Date: Wed, 10 Jul 2024 10:10:31 +0100 Subject: [PATCH 1/6] Typescript SDK support for zk-nyms --- .gitignore | 4 +- Cargo.lock | 30 +- Cargo.toml | 3 +- Makefile | 3 +- .../validator-client/src/nyxd/error.rs | 16 +- .../validator-client/src/rpc/reqwest.rs | 3 +- common/network-defaults/Cargo.toml | 6 +- common/wasm/client-core/Cargo.toml | 2 +- common/wasm/utils/Cargo.toml | 4 + package.json | 2 +- .../examples/zk-nyms/browser/README.md | 28 + .../examples/zk-nyms/browser/package.json | 16 + .../examples/zk-nyms/browser/src/index.html | 27 + .../examples/zk-nyms/browser/src/index.ts | 38 + .../examples/zk-nyms/browser/src/utils.ts | 6 + sdk/typescript/packages/sdk/.gitignore | 2 + sdk/typescript/packages/sdk/package.json | 5 +- .../packages/sdk/rollup-esm.config.mjs | 2 +- .../sdk/rollup-worker-full-fat.config.mjs | 8 + .../packages/sdk/rollup-worker.config.mjs | 27 +- ...p-zk-nym-faucet-worker-full-fat.config.mjs | 7 + .../rollup-zk-nym-faucet-worker.config.mjs | 7 + .../rollup-zk-nym-worker-full-fat.config.mjs | 7 + .../sdk/rollup-zk-nym-worker.config.mjs | 7 + sdk/typescript/packages/sdk/rollup/esm.mjs | 2 +- sdk/typescript/packages/sdk/rollup/worker.mjs | 43 + .../packages/sdk/scripts/build-dev-esm.sh | 16 +- sdk/typescript/packages/sdk/scripts/build.sh | 13 + .../packages/sdk/src/coconut/index.ts | 7 - sdk/typescript/packages/sdk/src/index.ts | 2 +- .../packages/sdk/src/zk-nym-faucet/index.ts | 41 + .../packages/sdk/src/zk-nym-faucet/types.ts | 29 + .../packages/sdk/src/zk-nym-faucet/worker.ts | 89 + .../packages/sdk/src/zk-nym/index.ts | 41 + .../packages/sdk/src/zk-nym/types.ts | 29 + .../packages/sdk/src/zk-nym/worker.ts | 50 + tools/internal/sdk-version-bump/src/main.rs | 4 + .../.cargo/config.toml | 0 .../Cargo.toml | 4 +- .../{zknym-lib => zk-nym-faucet-lib}/Makefile | 8 +- .../internal-dev/.gitignore | 0 .../internal-dev/bootstrap.js | 0 .../internal-dev/index.html | 0 .../internal-dev/index.js | 0 .../internal-dev/package.json | 2 +- .../internal-dev/webpack.config.js | 0 .../internal-dev/worker.js | 4 +- .../internal-dev/yarn.lock | 0 .../src/bandwidth_voucher.rs | 0 .../src/error.rs | 4 +- .../src/generic_scheme/coconut/mod.rs | 0 .../src/generic_scheme/coconut/types.rs | 0 .../src/generic_scheme/ecash/mod.rs | 0 .../src/generic_scheme/ecash/types.rs | 0 .../src/generic_scheme/mod.rs | 0 .../src/helpers.rs | 0 .../src/lib.rs | 4 +- .../src/ticketbook.rs | 0 .../src/types.rs | 0 .../src/zk_nym_faucet_client}/client.rs | 28 +- .../src/zk_nym_faucet_client}/mod.rs | 4 +- .../src/zk_nym_faucet_client}/types.rs | 0 wasm/zk-nym-lib/Cargo.toml | 41 + wasm/zk-nym-lib/Makefile | 7 + wasm/zk-nym-lib/internal-dev/.gitignore | 2 + wasm/zk-nym-lib/internal-dev/bootstrap.js | 5 + wasm/zk-nym-lib/internal-dev/index.html | 34 + wasm/zk-nym-lib/internal-dev/index.js | 85 + wasm/zk-nym-lib/internal-dev/package.json | 40 + .../zk-nym-lib/internal-dev/webpack.config.js | 46 + wasm/zk-nym-lib/internal-dev/worker.js | 65 + wasm/zk-nym-lib/internal-dev/yarn.lock | 2183 +++++++++++++++++ wasm/zk-nym-lib/src/credential.rs | 123 + wasm/zk-nym-lib/src/error.rs | 60 + wasm/zk-nym-lib/src/helpers.rs | 39 + wasm/zk-nym-lib/src/lib.rs | 26 + wasm/zk-nym-lib/src/opts.rs | 17 + 77 files changed, 3375 insertions(+), 82 deletions(-) create mode 100644 sdk/typescript/examples/zk-nyms/browser/README.md create mode 100644 sdk/typescript/examples/zk-nyms/browser/package.json create mode 100644 sdk/typescript/examples/zk-nyms/browser/src/index.html create mode 100644 sdk/typescript/examples/zk-nyms/browser/src/index.ts create mode 100644 sdk/typescript/examples/zk-nyms/browser/src/utils.ts create mode 100644 sdk/typescript/packages/sdk/rollup-worker-full-fat.config.mjs create mode 100644 sdk/typescript/packages/sdk/rollup-zk-nym-faucet-worker-full-fat.config.mjs create mode 100644 sdk/typescript/packages/sdk/rollup-zk-nym-faucet-worker.config.mjs create mode 100644 sdk/typescript/packages/sdk/rollup-zk-nym-worker-full-fat.config.mjs create mode 100644 sdk/typescript/packages/sdk/rollup-zk-nym-worker.config.mjs create mode 100644 sdk/typescript/packages/sdk/rollup/worker.mjs delete mode 100644 sdk/typescript/packages/sdk/src/coconut/index.ts create mode 100644 sdk/typescript/packages/sdk/src/zk-nym-faucet/index.ts create mode 100644 sdk/typescript/packages/sdk/src/zk-nym-faucet/types.ts create mode 100644 sdk/typescript/packages/sdk/src/zk-nym-faucet/worker.ts create mode 100644 sdk/typescript/packages/sdk/src/zk-nym/index.ts create mode 100644 sdk/typescript/packages/sdk/src/zk-nym/types.ts create mode 100644 sdk/typescript/packages/sdk/src/zk-nym/worker.ts rename wasm/{zknym-lib => zk-nym-faucet-lib}/.cargo/config.toml (100%) rename wasm/{zknym-lib => zk-nym-faucet-lib}/Cargo.toml (96%) rename wasm/{zknym-lib => zk-nym-faucet-lib}/Makefile (50%) rename wasm/{zknym-lib => zk-nym-faucet-lib}/internal-dev/.gitignore (100%) rename wasm/{zknym-lib => zk-nym-faucet-lib}/internal-dev/bootstrap.js (100%) rename wasm/{zknym-lib => zk-nym-faucet-lib}/internal-dev/index.html (100%) rename wasm/{zknym-lib => zk-nym-faucet-lib}/internal-dev/index.js (100%) rename wasm/{zknym-lib => zk-nym-faucet-lib}/internal-dev/package.json (94%) rename wasm/{zknym-lib => zk-nym-faucet-lib}/internal-dev/webpack.config.js (100%) rename wasm/{zknym-lib => zk-nym-faucet-lib}/internal-dev/worker.js (98%) rename wasm/{zknym-lib => zk-nym-faucet-lib}/internal-dev/yarn.lock (100%) rename wasm/{zknym-lib => zk-nym-faucet-lib}/src/bandwidth_voucher.rs (100%) rename wasm/{zknym-lib => zk-nym-faucet-lib}/src/error.rs (93%) rename wasm/{zknym-lib => zk-nym-faucet-lib}/src/generic_scheme/coconut/mod.rs (100%) rename wasm/{zknym-lib => zk-nym-faucet-lib}/src/generic_scheme/coconut/types.rs (100%) rename wasm/{zknym-lib => zk-nym-faucet-lib}/src/generic_scheme/ecash/mod.rs (100%) rename wasm/{zknym-lib => zk-nym-faucet-lib}/src/generic_scheme/ecash/types.rs (100%) rename wasm/{zknym-lib => zk-nym-faucet-lib}/src/generic_scheme/mod.rs (100%) rename wasm/{zknym-lib => zk-nym-faucet-lib}/src/helpers.rs (100%) rename wasm/{zknym-lib => zk-nym-faucet-lib}/src/lib.rs (90%) rename wasm/{zknym-lib => zk-nym-faucet-lib}/src/ticketbook.rs (100%) rename wasm/{zknym-lib => zk-nym-faucet-lib}/src/types.rs (100%) rename wasm/{zknym-lib/src/vpn_api_client => zk-nym-faucet-lib/src/zk_nym_faucet_client}/client.rs (82%) rename wasm/{zknym-lib/src/vpn_api_client => zk-nym-faucet-lib/src/zk_nym_faucet_client}/mod.rs (61%) rename wasm/{zknym-lib/src/vpn_api_client => zk-nym-faucet-lib/src/zk_nym_faucet_client}/types.rs (100%) create mode 100644 wasm/zk-nym-lib/Cargo.toml create mode 100644 wasm/zk-nym-lib/Makefile create mode 100644 wasm/zk-nym-lib/internal-dev/.gitignore create mode 100644 wasm/zk-nym-lib/internal-dev/bootstrap.js create mode 100644 wasm/zk-nym-lib/internal-dev/index.html create mode 100644 wasm/zk-nym-lib/internal-dev/index.js create mode 100644 wasm/zk-nym-lib/internal-dev/package.json create mode 100644 wasm/zk-nym-lib/internal-dev/webpack.config.js create mode 100644 wasm/zk-nym-lib/internal-dev/worker.js create mode 100644 wasm/zk-nym-lib/internal-dev/yarn.lock create mode 100644 wasm/zk-nym-lib/src/credential.rs create mode 100644 wasm/zk-nym-lib/src/error.rs create mode 100644 wasm/zk-nym-lib/src/helpers.rs create mode 100644 wasm/zk-nym-lib/src/lib.rs create mode 100644 wasm/zk-nym-lib/src/opts.rs diff --git a/.gitignore b/.gitignore index 4dfbe525867..ed4b82f9cf8 100644 --- a/.gitignore +++ b/.gitignore @@ -48,4 +48,6 @@ foxyfox.env .next ppa-private-key.b64 -ppa-private-key.asc \ No newline at end of file +ppa-private-key.asc + +yarn-error.log \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 68792a2ad6b..9ba4d09160d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5407,7 +5407,9 @@ dependencies = [ "log", "schemars", "serde", + "tsify", "url", + "wasm-bindgen", ] [[package]] @@ -10651,8 +10653,8 @@ dependencies = [ ] [[package]] -name = "zknym-lib" -version = "0.1.0" +name = "zk-nym-faucet-lib" +version = "1.3.0-rc.0" dependencies = [ "anyhow", "async-trait", @@ -10677,3 +10679,27 @@ dependencies = [ "wasmtimer", "zeroize", ] + +[[package]] +name = "zk-nym-lib" +version = "1.3.0-rc.0" +dependencies = [ + "bip39", + "js-sys", + "nym-bandwidth-controller", + "nym-bin-common", + "nym-credential-storage", + "nym-credentials", + "nym-credentials-interface", + "nym-network-defaults", + "nym-validator-client", + "serde", + "serde-wasm-bindgen 0.6.5", + "thiserror", + "tsify", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "wasm-utils", + "zeroize", +] diff --git a/Cargo.toml b/Cargo.toml index 237f005d328..75de4c6f23e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -125,7 +125,8 @@ members = [ # "wasm/full-nym-wasm", # If we uncomment this again, remember to also uncomment the profile settings below "wasm/mix-fetch", "wasm/node-tester", - "wasm/zknym-lib", + "wasm/zk-nym-lib", + "wasm/zk-nym-faucet-lib", "tools/internal/testnet-manager", "tools/internal/testnet-manager/dkg-bypass-contract", ] diff --git a/Makefile b/Makefile index f5c323db7f4..123e5caef6c 100644 --- a/Makefile +++ b/Makefile @@ -104,7 +104,8 @@ sdk-wasm-build: $(MAKE) -C wasm/client $(MAKE) -C wasm/node-tester $(MAKE) -C wasm/mix-fetch - $(MAKE) -C wasm/zknym-lib + $(MAKE) -C wasm/zk-nym-lib + $(MAKE) -C wasm/zk-nym-faucet-lib #$(MAKE) -C wasm/full-nym-wasm # run this from npm/yarn to ensure tools are in the path, e.g. yarn build:sdk from root of repo diff --git a/common/client-libs/validator-client/src/nyxd/error.rs b/common/client-libs/validator-client/src/nyxd/error.rs index c71ed596ad4..159d3f6d4c8 100644 --- a/common/client-libs/validator-client/src/nyxd/error.rs +++ b/common/client-libs/validator-client/src/nyxd/error.rs @@ -50,7 +50,7 @@ pub enum NyxdError { #[error("{0} is not a valid tx hash")] InvalidTxHash(String), - #[error("Tendermint RPC request failed - {0}")] + #[error("Tendermint RPC request failed: {0}")] TendermintErrorRpc(#[from] TendermintRpcError), #[error("tendermint library failure: {0}")] @@ -62,22 +62,22 @@ pub enum NyxdError { #[error("Failed when attempting to deserialize data ({0})")] DeserializationError(String), - #[error("Failed when attempting to encode our protobuf data - {0}")] + #[error("Failed when attempting to encode our protobuf data: {0}")] ProtobufEncodingError(#[from] prost::EncodeError), - #[error("Failed to decode our protobuf data - {0}")] + #[error("Failed to decode our protobuf data: {0}")] ProtobufDecodingError(#[from] prost::DecodeError), - #[error("Account {0} does not exist on the chain")] + #[error("Account '{0}' does not exist on the chain")] NonExistentAccountError(AccountId), - #[error("Failed on json serialization/deserialization - {0}")] + #[error("Failed on json serialization/deserialization: {0}")] SerdeJsonError(#[from] serde_json::Error), - #[error("Account {0} is not a valid account address")] + #[error("Account '{0}' is not a valid account address")] MalformedAccountAddress(String), - #[error("Account {0} has an invalid associated public key")] + #[error("Account '{0}' has an invalid associated public key")] InvalidPublicKey(AccountId), #[error("Queried contract (code_id: {0}) did not have any code information attached")] @@ -92,7 +92,7 @@ pub enum NyxdError { #[error("Block has an invalid height (either negative or larger than i64::MAX")] InvalidHeight, - #[error("Failed to compress provided wasm code - {0}")] + #[error("Failed to compress provided wasm code: {0}")] WasmCompressionError(io::Error), #[error("Logs returned from the validator were malformed")] diff --git a/common/client-libs/validator-client/src/rpc/reqwest.rs b/common/client-libs/validator-client/src/rpc/reqwest.rs index 973fb633768..5c708190f7b 100644 --- a/common/client-libs/validator-client/src/rpc/reqwest.rs +++ b/common/client-libs/validator-client/src/rpc/reqwest.rs @@ -109,7 +109,8 @@ trait TendermintRpcErrorMap { impl TendermintRpcErrorMap for reqwest::Error { fn into_rpc_err(self) -> Error { - todo!() + // that's not the best error converion, but it's better than a panic + Error::client_internal(self.to_string()) } } diff --git a/common/network-defaults/Cargo.toml b/common/network-defaults/Cargo.toml index 03d09cf1595..a74943ebf95 100644 --- a/common/network-defaults/Cargo.toml +++ b/common/network-defaults/Cargo.toml @@ -14,10 +14,12 @@ schemars = { workspace = true, features = ["preserve_order"], optional = true } serde = { workspace = true, features = ["derive"], optional = true } url = { workspace = true, optional = true } -# please be extremely careful when adding new dependencies because this crate is imported by the ecash contract, -# so if anything new is added, consider feature-locking it and then just adding it to default feature +# 'wasm-serde-types' feature +tsify = { workspace = true, features = ["js"], optional = true } +wasm-bindgen = { workspace = true, optional = true } [features] +wasm-serde-types = ["tsify", "wasm-bindgen"] default = ["env", "network"] env = ["dotenvy", "log"] network = ["schemars", "serde", "url"] \ No newline at end of file diff --git a/common/wasm/client-core/Cargo.toml b/common/wasm/client-core/Cargo.toml index 015ff09a82d..8456f69e889 100644 --- a/common/wasm/client-core/Cargo.toml +++ b/common/wasm/client-core/Cargo.toml @@ -44,4 +44,4 @@ wasm-storage = { path = "../storage" } console_error_panic_hook = { workspace = true, optional = true } [features] -default = ["console_error_panic_hook"] +default = ["wasm-utils/console_error_panic_hook"] \ No newline at end of file diff --git a/common/wasm/utils/Cargo.toml b/common/wasm/utils/Cargo.toml index 76ebe5f3dd3..c09dafd6f4e 100644 --- a/common/wasm/utils/Cargo.toml +++ b/common/wasm/utils/Cargo.toml @@ -17,6 +17,10 @@ gloo-utils = { workspace = true } gloo-net = { workspace = true, features = ["websocket"], optional = true } #gloo-net = { path = "../../../../gloo/crates/net", features = ["websocket"], optional = true } +# The `console_error_panic_hook` crate provides better debugging of panics by +# logging them with `console.error`. This is great for development, but requires +# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for +# code size when deploying. console_error_panic_hook = { workspace = true, optional = true } # we don't want entire tokio-tungstenite, tungstenite itself is just fine - we just want message and error enums diff --git a/package.json b/package.json index 3ae6557ec9d..a4e738037c6 100644 --- a/package.json +++ b/package.json @@ -54,4 +54,4 @@ "node-gyp": "^9.3.1", "tslog": "3.3.3" } -} +} \ No newline at end of file diff --git a/sdk/typescript/examples/zk-nyms/browser/README.md b/sdk/typescript/examples/zk-nyms/browser/README.md new file mode 100644 index 00000000000..06c7da3edfa --- /dev/null +++ b/sdk/typescript/examples/zk-nyms/browser/README.md @@ -0,0 +1,28 @@ +# Nym credential generation Usage Example + +This is a simple project to show you how to use nym credential generation. + +```ts +import { mixFetch } from '@nymproject/mix-fetch'; + +// HTTP GET +const response = await mixFetch('https://nymtech.net'); +const html = await response.text(); + +// HTTP POST +const apiResponse = await mixFetch('https://api.example.com', { + method: 'POST', + body: JSON.stringify({ foo: 'bar' }), + headers: { [`Content-Type`]: 'application/json', Authorization: `Bearer ${AUTH_TOKEN}` } +}); +``` + +## Running the example + +``` +npm install +npm run start +``` + +Open a browser at http://localhost:1234 and as the example loads, a connection will be made to the Nym Mixnet +and a text file and image will be downloaded and displayed in the browser. diff --git a/sdk/typescript/examples/zk-nyms/browser/package.json b/sdk/typescript/examples/zk-nyms/browser/package.json new file mode 100644 index 00000000000..b627a5080b8 --- /dev/null +++ b/sdk/typescript/examples/zk-nyms/browser/package.json @@ -0,0 +1,16 @@ +{ + "name": "@nymproject/nym-sdk-zk-nyms-example-parcel", + "version": "1.3.0-rc.0", + "license": "Apache-2.0", + "scripts": { + "build": "parcel build --no-cache --no-content-hash", + "serve": "serve dist", + "start": "parcel --no-cache" + }, + "dependencies": { + "@nymproject/sdk": "1.3.0-rc.0", + "parcel": "^2.9.3" + }, + "private": false, + "source": "src/index.html" +} diff --git a/sdk/typescript/examples/zk-nyms/browser/src/index.html b/sdk/typescript/examples/zk-nyms/browser/src/index.html new file mode 100644 index 00000000000..d85245bd72a --- /dev/null +++ b/sdk/typescript/examples/zk-nyms/browser/src/index.html @@ -0,0 +1,27 @@ + + + + + + + Internal Credential Tester + + + + + +
+

Credential

+ + + +
+
+ + + diff --git a/sdk/typescript/examples/zk-nyms/browser/src/index.ts b/sdk/typescript/examples/zk-nyms/browser/src/index.ts new file mode 100644 index 00000000000..73a870fe6b6 --- /dev/null +++ b/sdk/typescript/examples/zk-nyms/browser/src/index.ts @@ -0,0 +1,38 @@ +import { createNymCredentialsClient } from '@nymproject/sdk'; +import { appendOutput } from './utils'; + +async function main() { + const mnemonic = document.getElementById('mnemonic') as HTMLInputElement; + if (process.env.MNEMONIC) { + mnemonic.defaultValue = process.env.MNEMONIC; + } + const coin = document.getElementById('coin') as HTMLInputElement; + const button = document.getElementById('button') as HTMLButtonElement; + + const client = await createNymCredentialsClient(); + + const generateCredential = async () => { + const amount = coin.value; + const mnemonicString = mnemonic.value; + console.log({ amount, mnemonicString }); + try { + appendOutput('About to get a credential... 🥁'); + const credential = await client.comlink.acquireCredential(amount, mnemonicString, { useSandbox: true }); // options: {useSandbox?: boolean; networkDetails?: {}} + appendOutput('Success! 🎉'); + appendOutput(JSON.stringify(credential, null, 2)); + } catch (e) { + console.error('Failed to get credential', e); + appendOutput((e as any).message); + } + }; + + if (button) { + button.addEventListener('click', () => generateCredential()); + } +} + +// wait for the html to load +window.addEventListener('DOMContentLoaded', () => { + // let's do this! + main(); +}); diff --git a/sdk/typescript/examples/zk-nyms/browser/src/utils.ts b/sdk/typescript/examples/zk-nyms/browser/src/utils.ts new file mode 100644 index 00000000000..045ab2c7355 --- /dev/null +++ b/sdk/typescript/examples/zk-nyms/browser/src/utils.ts @@ -0,0 +1,6 @@ +export function appendOutput(value: string) { + const el = document.getElementById('credential') as HTMLPreElement; + const text = document.createTextNode(`${value}\n`); + el.appendChild(text); +} + diff --git a/sdk/typescript/packages/sdk/.gitignore b/sdk/typescript/packages/sdk/.gitignore index fbdf512d0d2..40628ee0d63 100644 --- a/sdk/typescript/packages/sdk/.gitignore +++ b/sdk/typescript/packages/sdk/.gitignore @@ -1,2 +1,4 @@ src/mixnet/wasm/worker.js +src/zk-nym/worker.js +src/zk-nym-faucet/worker.js docs/ diff --git a/sdk/typescript/packages/sdk/package.json b/sdk/typescript/packages/sdk/package.json index 0a416329f4f..f90680a0ce7 100644 --- a/sdk/typescript/packages/sdk/package.json +++ b/sdk/typescript/packages/sdk/package.json @@ -13,7 +13,8 @@ "scripts": { "build": "scripts/build-prod.sh", "build:dev": "scripts/build.sh", - "build:dev:esm": "scripts/build-dev-esm.sh", + "build:dev:esm": "SDK_DEV_MODE=true scripts/build-dev-esm.sh", + "build:dev:esm:no-inline": "scripts/build-dev-esm.sh", "build:worker": "rollup -c rollup-worker.config.mjs", "clean": "rimraf dist", "docs:dev": "run-p docs:watch docs:serve ", @@ -32,6 +33,8 @@ }, "dependencies": { "@nymproject/nym-client-wasm": ">=1.2.4-rc.2 || ^1", + "@nymproject/zk-nym-faucet-lib": ">=1.3.0-rc.0 || ^1", + "@nymproject/zk-nym-lib": ">=1.3.0-rc.0 || ^1", "comlink": "^4.3.1" }, "devDependencies": { diff --git a/sdk/typescript/packages/sdk/rollup-esm.config.mjs b/sdk/typescript/packages/sdk/rollup-esm.config.mjs index fa8d42b2eac..dbe9d64e988 100644 --- a/sdk/typescript/packages/sdk/rollup-esm.config.mjs +++ b/sdk/typescript/packages/sdk/rollup-esm.config.mjs @@ -2,6 +2,6 @@ import { getConfig } from './rollup/esm.mjs'; export default { ...getConfig({ - inline: false, + inline: process.env.SDK_DEV_MODE === 'true', }), }; diff --git a/sdk/typescript/packages/sdk/rollup-worker-full-fat.config.mjs b/sdk/typescript/packages/sdk/rollup-worker-full-fat.config.mjs new file mode 100644 index 00000000000..62a71b1e172 --- /dev/null +++ b/sdk/typescript/packages/sdk/rollup-worker-full-fat.config.mjs @@ -0,0 +1,8 @@ +import { getConfig } from './rollup/worker.mjs'; + +export default { + ...getConfig('src/mixnet/wasm/worker.ts', 'nym_client_wasm_bg.wasm', { + inlineWasm: true, + format: 'cjs', + }), +}; diff --git a/sdk/typescript/packages/sdk/rollup-worker.config.mjs b/sdk/typescript/packages/sdk/rollup-worker.config.mjs index 61aab0b8622..3df1f972789 100644 --- a/sdk/typescript/packages/sdk/rollup-worker.config.mjs +++ b/sdk/typescript/packages/sdk/rollup-worker.config.mjs @@ -1,26 +1,7 @@ -import typescript from '@rollup/plugin-typescript'; -import resolve from '@rollup/plugin-node-resolve'; -import { wasm } from '@rollup/plugin-wasm'; -import replace from '@rollup/plugin-replace'; - -const extensions = ['.js', '.jsx', '.ts', '.tsx']; +import { getConfig } from './rollup/worker.mjs'; export default { - input: 'src/mixnet/wasm/worker.ts', - output: { - dir: 'dist', - format: 'cjs', - }, - plugins: [ - resolve({ extensions }), - // this is some nasty monkey patching that removes the WASM URL (because it is handled by the `wasm` plugin) - replace({ - values: { "input = new URL('nym_client_wasm_bg.wasm', import.meta.url);": 'input = undefined;' }, - delimiters: ['', ''], - preventAssignment: true, - }), - // force the wasm plugin to embed the wasm bundle - this means no downstream bundlers have to worry about handling it - wasm({ maxFileSize: 10000000, targetEnv: 'browser' }), - typescript({ compilerOptions: { declaration: false, target: 'es5' } }), - ], + ...getConfig('src/mixnet/wasm/worker.ts', 'nym_client_wasm_bg.wasm', { + inlineWasm: process.env.SDK_DEV_MODE === 'true', + }), }; diff --git a/sdk/typescript/packages/sdk/rollup-zk-nym-faucet-worker-full-fat.config.mjs b/sdk/typescript/packages/sdk/rollup-zk-nym-faucet-worker-full-fat.config.mjs new file mode 100644 index 00000000000..36153656ab8 --- /dev/null +++ b/sdk/typescript/packages/sdk/rollup-zk-nym-faucet-worker-full-fat.config.mjs @@ -0,0 +1,7 @@ +import { getConfig } from './rollup/worker.mjs'; + +export default { + ...getConfig('src/zk-nym-faucet/worker.ts', 'zk_nym_faucet_lib_bg.wasm'), + inlineWasm: true, + format: 'cjs', +}; diff --git a/sdk/typescript/packages/sdk/rollup-zk-nym-faucet-worker.config.mjs b/sdk/typescript/packages/sdk/rollup-zk-nym-faucet-worker.config.mjs new file mode 100644 index 00000000000..fc5dbefa3bd --- /dev/null +++ b/sdk/typescript/packages/sdk/rollup-zk-nym-faucet-worker.config.mjs @@ -0,0 +1,7 @@ +import { getConfig } from './rollup/worker.mjs'; + +export default { + ...getConfig('src/zk-nym-faucet/worker.ts', 'zk_nym_faucet_lib_bg.wasm', { + inlineWasm: process.env.SDK_DEV_MODE === 'true', + }), +}; diff --git a/sdk/typescript/packages/sdk/rollup-zk-nym-worker-full-fat.config.mjs b/sdk/typescript/packages/sdk/rollup-zk-nym-worker-full-fat.config.mjs new file mode 100644 index 00000000000..749033b6493 --- /dev/null +++ b/sdk/typescript/packages/sdk/rollup-zk-nym-worker-full-fat.config.mjs @@ -0,0 +1,7 @@ +import { getConfig } from './rollup/worker.mjs'; + +export default { + ...getConfig('src/zk-nym/worker.ts', 'nym_credential_client_wasm_bg.wasm'), + inlineWasm: true, + format: 'cjs', +}; diff --git a/sdk/typescript/packages/sdk/rollup-zk-nym-worker.config.mjs b/sdk/typescript/packages/sdk/rollup-zk-nym-worker.config.mjs new file mode 100644 index 00000000000..235a1635a01 --- /dev/null +++ b/sdk/typescript/packages/sdk/rollup-zk-nym-worker.config.mjs @@ -0,0 +1,7 @@ +import { getConfig } from './rollup/worker.mjs'; + +export default { + ...getConfig('src/zk-nym/worker.ts', 'nym_credential_client_wasm_bg.wasm', { + inlineWasm: process.env.SDK_DEV_MODE === 'true', + }), +}; diff --git a/sdk/typescript/packages/sdk/rollup/esm.mjs b/sdk/typescript/packages/sdk/rollup/esm.mjs index 29cd6417934..68ebae2e92a 100644 --- a/sdk/typescript/packages/sdk/rollup/esm.mjs +++ b/sdk/typescript/packages/sdk/rollup/esm.mjs @@ -21,7 +21,7 @@ export const getConfig = (opts) => ({ webWorkerLoader({ targetPlatform: 'browser', inline: opts.inline }), // the inline param is used here resolve({ extensions }), typescript({ - exclude: ['mixnet/wasm/worker.ts'], + exclude: ['mixnet/wasm/worker.ts', 'zk-nym/worker.ts'], compilerOptions: { outDir: opts.outputDir || 'dist/esm' }, }), ], diff --git a/sdk/typescript/packages/sdk/rollup/worker.mjs b/sdk/typescript/packages/sdk/rollup/worker.mjs new file mode 100644 index 00000000000..e5c809e6b46 --- /dev/null +++ b/sdk/typescript/packages/sdk/rollup/worker.mjs @@ -0,0 +1,43 @@ +import typescript from '@rollup/plugin-typescript'; +import resolve from '@rollup/plugin-node-resolve'; +import { wasm } from '@rollup/plugin-wasm'; +import replace from '@rollup/plugin-replace'; + +const extensions = ['.js', '.jsx', '.ts', '.tsx']; + +/** + * Configure worker output + * + * @param opts + * `format`: `es` or `cjs`, + * `inlineWasm`: true or false, + * `tsTarget`: `es5` or `es6` + */ +export const getConfig = (input, wasmFilename, opts) => ({ + input, + output: { + dir: 'dist', + format: opts?.format || 'es', + }, + plugins: [ + resolve({ extensions }), + // this is some nasty monkey patching that removes the WASM URL (because it is handled by the `wasm` plugin) + replace({ + values: { [`input = new URL('${wasmFilename}', import.meta.url);`]: 'input = undefined;' }, + delimiters: ['', ''], + preventAssignment: true, + }), + opts?.inlineWasm === true + ? wasm({ maxFileSize: 10_000_000, targetEnv: 'browser' }) // force the wasm plugin to embed the wasm bundle - this means no downstream bundlers have to worry about handling it + : wasm({ + targetEnv: 'browser', + fileName: '[name].wasm', + }), + typescript({ + compilerOptions: { + declaration: false, + target: opts?.tsTarget || 'es6', + }, + }), + ], +}); diff --git a/sdk/typescript/packages/sdk/scripts/build-dev-esm.sh b/sdk/typescript/packages/sdk/scripts/build-dev-esm.sh index d7ce2b9af63..3b23108f295 100755 --- a/sdk/typescript/packages/sdk/scripts/build-dev-esm.sh +++ b/sdk/typescript/packages/sdk/scripts/build-dev-esm.sh @@ -14,7 +14,21 @@ set -o pipefail rollup -c rollup-worker.config.mjs # move it next to the Typescript `src/index.ts` so it can be inlined by rollup -cp dist/worker.js src/worker/worker.js || true +cp dist/worker.js src/mixnet/wasm/worker.js || true +rm dist/worker.js || true + +#------------------------------------------------------- +# WEB WORKER (zk-nym WASM) +#------------------------------------------------------- +# The web worker needs to be bundled because the WASM bundle needs to be loaded synchronously and all dependencies +# must be included in the worker script (because it is not loaded as an ES Module) + +# build the worker +rollup -c rollup-zk-nym-worker.config.mjs + +# move it next to the Typescript `src/index.ts` so it can be inlined by rollup +mkdir dist/esm || true +cp dist/worker.js src/zk-nym/worker.js || true rm dist/worker.js || true #------------------------------------------------------- diff --git a/sdk/typescript/packages/sdk/scripts/build.sh b/sdk/typescript/packages/sdk/scripts/build.sh index 97e6571bbfa..e715a55da26 100755 --- a/sdk/typescript/packages/sdk/scripts/build.sh +++ b/sdk/typescript/packages/sdk/scripts/build.sh @@ -19,6 +19,19 @@ rollup -c rollup-worker.config.mjs rm -f src/mixnet/wasm/worker.js mv dist/worker.js src/mixnet/wasm/worker.js +#------------------------------------------------------- +# WEB WORKER (zk-nym WASM) +#------------------------------------------------------- +# The web worker needs to be bundled because the WASM bundle needs to be loaded synchronously and all dependencies +# must be included in the worker script (because it is not loaded as an ES Module) + +# build the worker +rollup -c rollup-zk-nym-worker.config.mjs + +# move it next to the Typescript `src/index.ts` so it can be inlined by rollup +cp dist/worker.js src/zk-nym/worker.js || true +rm dist/worker.js || true + #------------------------------------------------------- # ESM #------------------------------------------------------- diff --git a/sdk/typescript/packages/sdk/src/coconut/index.ts b/sdk/typescript/packages/sdk/src/coconut/index.ts deleted file mode 100644 index 3011daa2e06..00000000000 --- a/sdk/typescript/packages/sdk/src/coconut/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -// eslint-disable-next-line no-console - -/** - * @ignore - * @internal - */ -export const notImplementedYet = () => console.log('Not implement, coming soon...'); diff --git a/sdk/typescript/packages/sdk/src/index.ts b/sdk/typescript/packages/sdk/src/index.ts index f89b4834222..74536f6a4da 100644 --- a/sdk/typescript/packages/sdk/src/index.ts +++ b/sdk/typescript/packages/sdk/src/index.ts @@ -1,2 +1,2 @@ -export * from './coconut'; +export * from './zk-nym'; export * from './mixnet'; diff --git a/sdk/typescript/packages/sdk/src/zk-nym-faucet/index.ts b/sdk/typescript/packages/sdk/src/zk-nym-faucet/index.ts new file mode 100644 index 00000000000..e4fef9116a9 --- /dev/null +++ b/sdk/typescript/packages/sdk/src/zk-nym-faucet/index.ts @@ -0,0 +1,41 @@ +import * as Comlink from 'comlink'; +import InlineWasmWebWorker from 'web-worker:./worker'; +import { EventKinds, INymZkNymFaucetClientWebWorker, NymZkNymFaucetClient } from './types'; + +export const createNymCredentialsClient = async (): Promise => { + // eslint-disable-next-line @typescript-eslint/no-use-before-define + const worker = await createWorker(); + + // let comlink handle interop with the web worker + const client = Comlink.wrap(worker); + + return { client }; +}; + +/** + * Async method to create a web worker that runs the Nym credentials client on another thread. It will only return once the worker + * has passed back a `Loaded` event to the calling thread. + * + * @return The instance of the web worker. + */ +const createWorker = async () => + new Promise((resolve, reject) => { + // rollup will inline the built worker script, so that when the SDK is used in + // other projects, they will not need to mess around trying to bundle it + // however, it will make this SDK bundle bigger because of Base64 inline data + const worker = new InlineWasmWebWorker(); + + worker.addEventListener('error', reject); + worker.addEventListener( + 'message', + (msg) => { + worker.removeEventListener('error', reject); + if (msg.data?.kind === EventKinds.Loaded) { + resolve(worker); + } else { + reject(msg); + } + }, + { once: true }, + ); + }); diff --git a/sdk/typescript/packages/sdk/src/zk-nym-faucet/types.ts b/sdk/typescript/packages/sdk/src/zk-nym-faucet/types.ts new file mode 100644 index 00000000000..4aad5508d7b --- /dev/null +++ b/sdk/typescript/packages/sdk/src/zk-nym-faucet/types.ts @@ -0,0 +1,29 @@ +/** + * Enum representing various event kinds. + * @enum + */ +export enum EventKinds { + Loaded = 'Loaded', +} + +export interface LoadedEvent { + kind: EventKinds.Loaded; + args: { + loaded: true; + }; +} + +export type ZkNym = any; // TODO + +export interface ZkNymFaucetClientOpts { + useSandbox?: boolean; + networkDetails?: {}; +} + +export interface INymZkNymFaucetClientWebWorker { + acquireCredential: (faucetApiUrl: string, authToken: string) => Promise; +} + +export interface NymZkNymFaucetClient { + client: INymZkNymFaucetClientWebWorker; +} diff --git a/sdk/typescript/packages/sdk/src/zk-nym-faucet/worker.ts b/sdk/typescript/packages/sdk/src/zk-nym-faucet/worker.ts new file mode 100644 index 00000000000..3803ad40b32 --- /dev/null +++ b/sdk/typescript/packages/sdk/src/zk-nym-faucet/worker.ts @@ -0,0 +1,89 @@ +/* eslint-disable no-restricted-globals */ +import * as Comlink from 'comlink'; +// +// Rollup will replace wasmBytes with a function that loads the WASM bundle from a base64 string embedded in the output. +// +// Doing it this way, saves having to support a large variety of bundlers and their quirks. +// +// @ts-ignore +// eslint-disable-next-line import/no-extraneous-dependencies +import wasmBytes from '@nymproject/nym-credential-client-wasm/zk_nym_faucet_lib_bg.wasm'; +import init, { NymIssuanceBandwidthVoucher } from '@nymproject/zk-nym-faucet-lib/zk_nym_faucet_lib'; +import type { INymZkNymFaucetClientWebWorker, ZkNymFaucetClientOpts, LoadedEvent } from './types'; +import { EventKinds } from './types'; + +/** + * Helper method to send typed messages. + * @param event The strongly typed message to send back to the calling thread. + */ +// eslint-disable-next-line no-restricted-globals +const postMessageWithType = (event: E) => self.postMessage(event); + +console.log('[Nym WASM client for zk-nym faucets] Starting Nym WASM web worker...'); + +// load WASM binary +async function main() { + // rollup with provide a function to get the WASM bytes + const bytes = await wasmBytes(); + + // load rust WASM package + const wasmPackage = await init(bytes); + + console.log('Loaded RUST WASM'); + + wasmPackage.set_panic_hook(); + + const webWorker: INymZkNymFaucetClientWebWorker = { + async acquireCredential(faucetApiUrl: string, authToken: string) { + console.log('getting opts'); + const res = await fetch(`${faucetApiUrl}/api/v1/bandwidth-voucher/prehashed-public-attributes`, { + headers: new Headers({ Authorization: `Bearer ${authToken}` }), + }); + const opts = await res.json(); + + const issuanceVoucher = new NymIssuanceBandwidthVoucher(opts); + const blindSignRequest = issuanceVoucher.getBlindSignRequest(); + + console.log('getting partial vks'); + const partialVksRes = await fetch(`${faucetApiUrl}/api/v1/bandwidth-voucher/partial-verification-keys`, { + headers: new Headers({ Authorization: `Bearer ${authToken}` }), + }); + const partialVks = await partialVksRes.json(); + + console.log('getting master vk'); + const masterVkRes = await fetch(`${faucetApiUrl}/api/v1/bandwidth-voucher/master-verification-key`, { + headers: new Headers({ Authorization: `Bearer ${authToken}` }), + }); + const masterVk = await masterVkRes.json(); + + console.log('getting blinded shares'); + const sharesRes = await fetch(`${faucetApiUrl}/api/v1/bandwidth-voucher/obtain`, { + method: 'POST', + headers: new Headers({ + Authorization: `Bearer ${authToken}`, + 'Content-Type': 'application/json', + }), + body: JSON.stringify({ + blindSignRequest, + }), + }); + + const credentialShares = await sharesRes.json(); + + console.log('unblinding shares'); + const bandwidthVoucher = issuanceVoucher.unblindShares(credentialShares, partialVks); + console.log('is valid: ', bandwidthVoucher.ensureIsValid(masterVk.bs58EncodedKey)); + + const serialised = bandwidthVoucher.serialise(); + console.log('serialised:\n', serialised); + }, + }; + + // start comlink listening for messages and handle them above + Comlink.expose(webWorker); + + // notify any listeners that the web worker has loaded and is ready for testing + postMessageWithType({ kind: EventKinds.Loaded, args: { loaded: true } }); +} + +main().catch((e: any) => console.error('Unhandled exception in zk-nym faucet worker', e)); diff --git a/sdk/typescript/packages/sdk/src/zk-nym/index.ts b/sdk/typescript/packages/sdk/src/zk-nym/index.ts new file mode 100644 index 00000000000..5eb2b31017b --- /dev/null +++ b/sdk/typescript/packages/sdk/src/zk-nym/index.ts @@ -0,0 +1,41 @@ +import * as Comlink from 'comlink'; +import InlineWasmWebWorker from 'web-worker:./worker'; +import { EventKinds, INymZkNymClientWebWorker, NymZkNymClient } from './types'; + +export const createNymCredentialsClient = async (): Promise => { + // eslint-disable-next-line @typescript-eslint/no-use-before-define + const worker = await createWorker(); + + // let comlink handle interop with the web worker + const client = Comlink.wrap(worker); + + return { client }; +}; + +/** + * Async method to create a web worker that runs the Nym credentials client on another thread. It will only return once the worker + * has passed back a `Loaded` event to the calling thread. + * + * @return The instance of the web worker. + */ +const createWorker = async () => + new Promise((resolve, reject) => { + // rollup will inline the built worker script, so that when the SDK is used in + // other projects, they will not need to mess around trying to bundle it + // however, it will make this SDK bundle bigger because of Base64 inline data + const worker = new InlineWasmWebWorker(); + + worker.addEventListener('error', reject); + worker.addEventListener( + 'message', + (msg) => { + worker.removeEventListener('error', reject); + if (msg.data?.kind === EventKinds.Loaded) { + resolve(worker); + } else { + reject(msg); + } + }, + { once: true }, + ); + }); diff --git a/sdk/typescript/packages/sdk/src/zk-nym/types.ts b/sdk/typescript/packages/sdk/src/zk-nym/types.ts new file mode 100644 index 00000000000..660c0d7d18c --- /dev/null +++ b/sdk/typescript/packages/sdk/src/zk-nym/types.ts @@ -0,0 +1,29 @@ +/** + * Enum representing various event kinds. + * @enum + */ +export enum EventKinds { + Loaded = 'Loaded', +} + +export interface LoadedEvent { + kind: EventKinds.Loaded; + args: { + loaded: true; + }; +} + +export type ZkNym = any; // TODO + +export interface ZkNymClientOpts { + useSandbox?: boolean; + networkDetails?: {}; +} + +export interface INymZkNymClientWebWorker { + acquireCredential: (coin: string, mnemonic: string, opts: ZkNymClientOpts) => Promise; +} + +export interface NymZkNymClient { + client: INymZkNymClientWebWorker; +} diff --git a/sdk/typescript/packages/sdk/src/zk-nym/worker.ts b/sdk/typescript/packages/sdk/src/zk-nym/worker.ts new file mode 100644 index 00000000000..aee431dd9e2 --- /dev/null +++ b/sdk/typescript/packages/sdk/src/zk-nym/worker.ts @@ -0,0 +1,50 @@ +/* eslint-disable no-restricted-globals */ +import * as Comlink from 'comlink'; +// +// Rollup will replace wasmBytes with a function that loads the WASM bundle from a base64 string embedded in the output. +// +// Doing it this way, saves having to support a large variety of bundlers and their quirks. +// +// @ts-ignore +// eslint-disable-next-line import/no-extraneous-dependencies +import wasmBytes from '@nymproject/zk-nym-lib/zk_nym_lib_bg.wasm'; +import init, { acquireCredential } from '@nymproject/zk-nym-lib/zk_nym_lib'; +import type { INymZkNymClientWebWorker, ZkNymClientOpts, LoadedEvent } from './types'; +import { EventKinds } from './types'; + +/** + * Helper method to send typed messages. + * @param event The strongly typed message to send back to the calling thread. + */ +// eslint-disable-next-line no-restricted-globals +const postMessageWithType = (event: E) => self.postMessage(event); + +console.log('[Nym WASM client for zk-nyms] Starting Nym WASM web worker...'); + +// load WASM binary +async function main() { + // rollup with provide a function to get the WASM bytes + const bytes = await wasmBytes(); + + // load rust WASM package + const wasmPackage = await init(bytes); + + console.log('Loaded RUST WASM'); + + wasmPackage.set_panic_hook(); + + const webWorker: INymZkNymClientWebWorker = { + async acquireCredential(coin: string, mnemonic: string, opts: ZkNymClientOpts) { + console.log('[Worker] --- acquireCredential ---', { coin, mnemonic, opts }); + return acquireCredential(mnemonic, coin, opts); + }, + }; + + // start comlink listening for messages and handle them above + Comlink.expose(webWorker); + + // notify any listeners that the web worker has loaded and is ready for testing + postMessageWithType({ kind: EventKinds.Loaded, args: { loaded: true } }); +} + +main().catch((e: any) => console.error('Unhandled exception in zk-nym worker', e)); diff --git a/tools/internal/sdk-version-bump/src/main.rs b/tools/internal/sdk-version-bump/src/main.rs index cf77ba6be0b..7ad969f6a0f 100644 --- a/tools/internal/sdk-version-bump/src/main.rs +++ b/tools/internal/sdk-version-bump/src/main.rs @@ -229,6 +229,7 @@ fn initialise_internal_packages>(root: P) -> InternalPackages { packages.register_cargo("wasm/node-tester"); // packages.register_cargo("wasm/full-nym-wasm"); packages.register_cargo("nym-browser-extension/storage"); + packages.register_cargo("wasm/zknym-lib"); // js packages that will have their package.json modified packages.register_json("nym-wallet"); @@ -242,6 +243,7 @@ fn initialise_internal_packages>(root: P) -> InternalPackages { packages.register_json("sdk/typescript/examples/node-tester/parcel"); packages.register_json("sdk/typescript/examples/node-tester/plain-html"); packages.register_json("sdk/typescript/examples/node-tester/react"); + packages.register_json("sdk/typescript/examples/zk-nyms/browser"); packages.register_json("sdk/typescript/packages/mix-fetch"); packages.register_json("sdk/typescript/packages/mix-fetch-node"); packages.register_json("sdk/typescript/packages/mix-fetch/internal-dev"); @@ -276,6 +278,8 @@ fn initialise_internal_packages>(root: P) -> InternalPackages { packages.register_known_js_dependency("@nymproject/ts-sdk-docs"); packages.register_known_js_dependency("@nymproject/contract-clients"); + packages.register_known_js_dependency("@nymproject/zknym-lib"); + packages } diff --git a/wasm/zknym-lib/.cargo/config.toml b/wasm/zk-nym-faucet-lib/.cargo/config.toml similarity index 100% rename from wasm/zknym-lib/.cargo/config.toml rename to wasm/zk-nym-faucet-lib/.cargo/config.toml diff --git a/wasm/zknym-lib/Cargo.toml b/wasm/zk-nym-faucet-lib/Cargo.toml similarity index 96% rename from wasm/zknym-lib/Cargo.toml rename to wasm/zk-nym-faucet-lib/Cargo.toml index 5ef55b03146..bf6e33d76da 100644 --- a/wasm/zknym-lib/Cargo.toml +++ b/wasm/zk-nym-faucet-lib/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "zknym-lib" -version = "0.1.0" +name = "zk-nym-faucet-lib" +version = "1.3.0-rc.0" authors.workspace = true repository.workspace = true homepage.workspace = true diff --git a/wasm/zknym-lib/Makefile b/wasm/zk-nym-faucet-lib/Makefile similarity index 50% rename from wasm/zknym-lib/Makefile rename to wasm/zk-nym-faucet-lib/Makefile index d4b7d1b02ed..3d7d83f621f 100644 --- a/wasm/zknym-lib/Makefile +++ b/wasm/zk-nym-faucet-lib/Makefile @@ -2,15 +2,15 @@ all: build build-node build: - wasm-pack build --scope nymproject --target web --out-dir ../../dist/wasm/zknym-lib - wasm-opt -Oz -o ../../dist/wasm/zknym-lib/zknym_lib_bg.wasm ../../dist/wasm/zknym-lib/zknym_lib_bg.wasm + wasm-pack build --scope nymproject --target web --out-dir ../../dist/wasm/zk-nym-faucet-lib + wasm-opt -Oz -o ../../dist/wasm/zk-nym-faucet-lib/zk_nym_faucet_lib_bg.wasm ../../dist/wasm/zk-nym-faucet-lib/zk_nym_faucet_lib_bg.wasm build-debug-dev: wasm-pack build --scope nymproject --target no-modules build-rust-node: - wasm-pack build --scope nymproject --target nodejs --out-dir ../../dist/node/wasm/zknym-lib - wasm-opt -Oz -o ../../dist/node/wasm/zknym-lib/zknym_lib_bg.wasm ../../dist/node/wasm/zknym-lib/zknym_lib_bg.wasm + wasm-pack build --scope nymproject --target nodejs --out-dir ../../dist/node/wasm/zk-nym-faucet-lib + wasm-opt -Oz -o ../../dist/node/wasm/zk-nym-faucet-lib/zk_nym_faucet_lib_bg.wasm ../../dist/node/wasm/zk-nym-faucet-lib/zk_nym_faucet_lib_bg.wasm #build-package-json-node: # node build-node.mjs diff --git a/wasm/zknym-lib/internal-dev/.gitignore b/wasm/zk-nym-faucet-lib/internal-dev/.gitignore similarity index 100% rename from wasm/zknym-lib/internal-dev/.gitignore rename to wasm/zk-nym-faucet-lib/internal-dev/.gitignore diff --git a/wasm/zknym-lib/internal-dev/bootstrap.js b/wasm/zk-nym-faucet-lib/internal-dev/bootstrap.js similarity index 100% rename from wasm/zknym-lib/internal-dev/bootstrap.js rename to wasm/zk-nym-faucet-lib/internal-dev/bootstrap.js diff --git a/wasm/zknym-lib/internal-dev/index.html b/wasm/zk-nym-faucet-lib/internal-dev/index.html similarity index 100% rename from wasm/zknym-lib/internal-dev/index.html rename to wasm/zk-nym-faucet-lib/internal-dev/index.html diff --git a/wasm/zknym-lib/internal-dev/index.js b/wasm/zk-nym-faucet-lib/internal-dev/index.js similarity index 100% rename from wasm/zknym-lib/internal-dev/index.js rename to wasm/zk-nym-faucet-lib/internal-dev/index.js diff --git a/wasm/zknym-lib/internal-dev/package.json b/wasm/zk-nym-faucet-lib/internal-dev/package.json similarity index 94% rename from wasm/zknym-lib/internal-dev/package.json rename to wasm/zk-nym-faucet-lib/internal-dev/package.json index 0735d70ea19..54f018596d0 100644 --- a/wasm/zknym-lib/internal-dev/package.json +++ b/wasm/zk-nym-faucet-lib/internal-dev/package.json @@ -35,6 +35,6 @@ "webpack-dev-server": "^4.7.4" }, "dependencies": { - "@nymproject/nym-zknym-lib": "file:../pkg" + "@nymproject/nym-zknym-faucet-lib": "file:../pkg" } } diff --git a/wasm/zknym-lib/internal-dev/webpack.config.js b/wasm/zk-nym-faucet-lib/internal-dev/webpack.config.js similarity index 100% rename from wasm/zknym-lib/internal-dev/webpack.config.js rename to wasm/zk-nym-faucet-lib/internal-dev/webpack.config.js diff --git a/wasm/zknym-lib/internal-dev/worker.js b/wasm/zk-nym-faucet-lib/internal-dev/worker.js similarity index 98% rename from wasm/zknym-lib/internal-dev/worker.js rename to wasm/zk-nym-faucet-lib/internal-dev/worker.js index b58a4720fb3..6ecffa2959d 100644 --- a/wasm/zknym-lib/internal-dev/worker.js +++ b/wasm/zk-nym-faucet-lib/internal-dev/worker.js @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -const RUST_WASM_URL = "zknym_lib_bg.wasm" +const RUST_WASM_URL = "zk_nym_faucet_lib_bg.wasm" -importScripts('zknym_lib.js'); +importScripts('zk_nym_faucet_lib.js'); console.log('Initializing worker'); diff --git a/wasm/zknym-lib/internal-dev/yarn.lock b/wasm/zk-nym-faucet-lib/internal-dev/yarn.lock similarity index 100% rename from wasm/zknym-lib/internal-dev/yarn.lock rename to wasm/zk-nym-faucet-lib/internal-dev/yarn.lock diff --git a/wasm/zknym-lib/src/bandwidth_voucher.rs b/wasm/zk-nym-faucet-lib/src/bandwidth_voucher.rs similarity index 100% rename from wasm/zknym-lib/src/bandwidth_voucher.rs rename to wasm/zk-nym-faucet-lib/src/bandwidth_voucher.rs diff --git a/wasm/zknym-lib/src/error.rs b/wasm/zk-nym-faucet-lib/src/error.rs similarity index 93% rename from wasm/zknym-lib/src/error.rs rename to wasm/zk-nym-faucet-lib/src/error.rs index 37c49aa6720..c9f5c33777c 100644 --- a/wasm/zknym-lib/src/error.rs +++ b/wasm/zk-nym-faucet-lib/src/error.rs @@ -1,7 +1,7 @@ // Copyright 2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::vpn_api_client::NymVpnApiClientError; +use crate::zk_nym_faucet_client::NymZkNymFaucetClientError; use thiserror::Error; use wasm_utils::wasm_error; @@ -22,7 +22,7 @@ pub enum ZkNymError { #[error("failed to contact the vpn api")] HttpClientFailure { #[from] - source: NymVpnApiClientError, + source: NymZkNymFaucetClientError, }, #[error("the provided shares and issuers are not from the same epoch! {shares} and {issuers}")] InconsistentEpochId { shares: u64, issuers: u64 }, diff --git a/wasm/zknym-lib/src/generic_scheme/coconut/mod.rs b/wasm/zk-nym-faucet-lib/src/generic_scheme/coconut/mod.rs similarity index 100% rename from wasm/zknym-lib/src/generic_scheme/coconut/mod.rs rename to wasm/zk-nym-faucet-lib/src/generic_scheme/coconut/mod.rs diff --git a/wasm/zknym-lib/src/generic_scheme/coconut/types.rs b/wasm/zk-nym-faucet-lib/src/generic_scheme/coconut/types.rs similarity index 100% rename from wasm/zknym-lib/src/generic_scheme/coconut/types.rs rename to wasm/zk-nym-faucet-lib/src/generic_scheme/coconut/types.rs diff --git a/wasm/zknym-lib/src/generic_scheme/ecash/mod.rs b/wasm/zk-nym-faucet-lib/src/generic_scheme/ecash/mod.rs similarity index 100% rename from wasm/zknym-lib/src/generic_scheme/ecash/mod.rs rename to wasm/zk-nym-faucet-lib/src/generic_scheme/ecash/mod.rs diff --git a/wasm/zknym-lib/src/generic_scheme/ecash/types.rs b/wasm/zk-nym-faucet-lib/src/generic_scheme/ecash/types.rs similarity index 100% rename from wasm/zknym-lib/src/generic_scheme/ecash/types.rs rename to wasm/zk-nym-faucet-lib/src/generic_scheme/ecash/types.rs diff --git a/wasm/zknym-lib/src/generic_scheme/mod.rs b/wasm/zk-nym-faucet-lib/src/generic_scheme/mod.rs similarity index 100% rename from wasm/zknym-lib/src/generic_scheme/mod.rs rename to wasm/zk-nym-faucet-lib/src/generic_scheme/mod.rs diff --git a/wasm/zknym-lib/src/helpers.rs b/wasm/zk-nym-faucet-lib/src/helpers.rs similarity index 100% rename from wasm/zknym-lib/src/helpers.rs rename to wasm/zk-nym-faucet-lib/src/helpers.rs diff --git a/wasm/zknym-lib/src/lib.rs b/wasm/zk-nym-faucet-lib/src/lib.rs similarity index 90% rename from wasm/zknym-lib/src/lib.rs rename to wasm/zk-nym-faucet-lib/src/lib.rs index 540a386ee82..22e41b73bd7 100644 --- a/wasm/zknym-lib/src/lib.rs +++ b/wasm/zk-nym-faucet-lib/src/lib.rs @@ -20,7 +20,7 @@ pub mod types; // keep in internal to the crate since I'm not sure how temporary this thing is going to be // I mostly got it, so I could test the whole thing end to end -pub(crate) mod vpn_api_client; +pub(crate) mod zk_nym_faucet_client; pub(crate) static GLOBAL_COCONUT_PARAMS: OnceLock = OnceLock::new(); @@ -29,7 +29,7 @@ pub(crate) static GLOBAL_COCONUT_PARAMS: OnceLock = OnceLock::new(); pub fn main() { wasm_utils::console_log!("[rust main]: rust module loaded"); wasm_utils::console_log!( - "wasm zk-nym version used: {}", + "wasm zk-nym faucet client version used: {}", nym_bin_common::bin_info_owned!() ); } diff --git a/wasm/zknym-lib/src/ticketbook.rs b/wasm/zk-nym-faucet-lib/src/ticketbook.rs similarity index 100% rename from wasm/zknym-lib/src/ticketbook.rs rename to wasm/zk-nym-faucet-lib/src/ticketbook.rs diff --git a/wasm/zknym-lib/src/types.rs b/wasm/zk-nym-faucet-lib/src/types.rs similarity index 100% rename from wasm/zknym-lib/src/types.rs rename to wasm/zk-nym-faucet-lib/src/types.rs diff --git a/wasm/zknym-lib/src/vpn_api_client/client.rs b/wasm/zk-nym-faucet-lib/src/zk_nym_faucet_client/client.rs similarity index 82% rename from wasm/zknym-lib/src/vpn_api_client/client.rs rename to wasm/zk-nym-faucet-lib/src/zk_nym_faucet_client/client.rs index 38627d78389..7bed32113fb 100644 --- a/wasm/zknym-lib/src/vpn_api_client/client.rs +++ b/wasm/zk-nym-faucet-lib/src/zk_nym_faucet_client/client.rs @@ -1,9 +1,9 @@ // Copyright 2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use super::NymVpnApiClientError; +use super::NymZkNymFaucetClientError; use crate::error::ZkNymError; -use crate::vpn_api_client::types::{ +use crate::zk_nym_faucet_client::types::{ AttributesResponse, BandwidthVoucherRequest, BandwidthVoucherResponse, MasterVerificationKeyResponse, PartialVerificationKeysResponse, }; @@ -15,7 +15,7 @@ use reqwest::IntoUrl; use serde::de::DeserializeOwned; #[allow(dead_code)] -pub struct VpnApiClient { +pub struct NymZkNymFaucetClientErrorApiClient { inner: Client, bearer_token: String, } @@ -24,8 +24,8 @@ pub struct VpnApiClient { pub fn new_client( base_url: impl IntoUrl, bearer_token: impl Into, -) -> Result { - Ok(VpnApiClient { +) -> Result { + Ok(NymZkNymFaucetClientErrorApiClient { inner: Client::builder(base_url)? .with_user_agent(format!("nym-wasm-znym-lib/{}", env!("CARGO_PKG_VERSION"))) .build()?, @@ -36,14 +36,14 @@ pub fn new_client( // TODO: do it properly by implementing auth headers on `ApiClient` trait #[allow(dead_code)] #[async_trait(?Send)] -pub trait NymVpnApiClient { - async fn simple_get(&self, path: PathSegments<'_>) -> Result +pub trait NymNymZkNymFaucetClientErrorApiClient { + async fn simple_get(&self, path: PathSegments<'_>) -> Result where T: DeserializeOwned; async fn get_prehashed_public_attributes( &self, - ) -> Result { + ) -> Result { self.simple_get(&[ "/api", "/v1", @@ -55,7 +55,7 @@ pub trait NymVpnApiClient { async fn get_partial_verification_keys( &self, - ) -> Result { + ) -> Result { self.simple_get(&[ "/api", "/v1", @@ -67,7 +67,7 @@ pub trait NymVpnApiClient { async fn get_master_verification_key( &self, - ) -> Result { + ) -> Result { self.simple_get(&[ "/api", "/v1", @@ -80,12 +80,12 @@ pub trait NymVpnApiClient { async fn get_bandwidth_voucher_blinded_shares( &self, blind_sign_request: BlindSignRequest, - ) -> Result; + ) -> Result; } #[async_trait(?Send)] -impl NymVpnApiClient for VpnApiClient { - async fn simple_get(&self, path: PathSegments<'_>) -> Result +impl NymNymZkNymFaucetClientErrorApiClient for NymZkNymFaucetClientErrorApiClient { + async fn simple_get(&self, path: PathSegments<'_>) -> Result where T: DeserializeOwned, { @@ -112,7 +112,7 @@ impl NymVpnApiClient for VpnApiClient { async fn get_bandwidth_voucher_blinded_shares( &self, blind_sign_request: BlindSignRequest, - ) -> Result { + ) -> Result { let req = self.inner.create_post_request( &["/api", "/v1", "/bandwidth-voucher", "/obtain"], NO_PARAMS, diff --git a/wasm/zknym-lib/src/vpn_api_client/mod.rs b/wasm/zk-nym-faucet-lib/src/zk_nym_faucet_client/mod.rs similarity index 61% rename from wasm/zknym-lib/src/vpn_api_client/mod.rs rename to wasm/zk-nym-faucet-lib/src/zk_nym_faucet_client/mod.rs index 041e9f0bc1c..e4a1a30d07d 100644 --- a/wasm/zknym-lib/src/vpn_api_client/mod.rs +++ b/wasm/zk-nym-faucet-lib/src/zk_nym_faucet_client/mod.rs @@ -1,7 +1,7 @@ // Copyright 2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::vpn_api_client::types::ErrorResponse; +use crate::zk_nym_faucet_client::types::ErrorResponse; use nym_http_api_client::HttpClientError; #[cfg(test)] @@ -9,4 +9,4 @@ pub(crate) mod client; pub mod types; -pub type NymVpnApiClientError = HttpClientError; +pub type NymZkNymFaucetClientError = HttpClientError; diff --git a/wasm/zknym-lib/src/vpn_api_client/types.rs b/wasm/zk-nym-faucet-lib/src/zk_nym_faucet_client/types.rs similarity index 100% rename from wasm/zknym-lib/src/vpn_api_client/types.rs rename to wasm/zk-nym-faucet-lib/src/zk_nym_faucet_client/types.rs diff --git a/wasm/zk-nym-lib/Cargo.toml b/wasm/zk-nym-lib/Cargo.toml new file mode 100644 index 00000000000..64fae0ee178 --- /dev/null +++ b/wasm/zk-nym-lib/Cargo.toml @@ -0,0 +1,41 @@ +[package] +name = "zk-nym-lib" +version = "1.3.0-rc.0" +authors.workspace = true +repository.workspace = true +homepage.workspace = true +documentation.workspace = true +edition.workspace = true +license.workspace = true + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +bip39 = { workspace = true } +#futures = { workspace = true } +js-sys = { workspace = true } +serde = { workspace = true, features = ["derive"] } +#serde_json = { workspace = true } +serde-wasm-bindgen = { workspace = true } +wasm-bindgen = { workspace = true } +wasm-bindgen-futures = { workspace = true } +thiserror = { workspace = true } +tsify = { workspace = true, features = ["js"] } +zeroize = { workspace = true } + +wasm-utils = { path = "../../common/wasm/utils" } + +nym-bin-common = { path = "../../common/bin-common" } +nym-credentials = { path = "../../common/credentials" } +nym-credential-storage = { path = "../../common/credential-storage" } +nym-bandwidth-controller = { path = "../../common/bandwidth-controller" } +nym-validator-client = { path = "../../common/client-libs/validator-client", default-features = false } +nym-credentials-interface = { path = "../../common/credentials-interface" } +nym-network-defaults = { path = "../../common/network-defaults" } + +[dev-dependencies] +wasm-bindgen-test = "0.3.36" + +[package.metadata.wasm-pack.profile.release] +wasm-opt = false diff --git a/wasm/zk-nym-lib/Makefile b/wasm/zk-nym-lib/Makefile new file mode 100644 index 00000000000..4b0306cd8ee --- /dev/null +++ b/wasm/zk-nym-lib/Makefile @@ -0,0 +1,7 @@ +build: + wasm-pack build --scope nymproject --target web --out-dir ../../dist/wasm/zk-nym-lib + wasm-opt -Oz -o ../../dist/wasm/zk-nym-lib/zk_nym_lib_bg.wasm ../../dist/wasm/zk-nym-lib/zk_nym_lib_bg.wasm + +# make my life easier so I wouldn't need to deal with any bundlers. sorry @MS : ) +build-debug-dev: + wasm-pack build --scope nymproject --target no-modules \ No newline at end of file diff --git a/wasm/zk-nym-lib/internal-dev/.gitignore b/wasm/zk-nym-lib/internal-dev/.gitignore new file mode 100644 index 00000000000..f06235c460c --- /dev/null +++ b/wasm/zk-nym-lib/internal-dev/.gitignore @@ -0,0 +1,2 @@ +node_modules +dist diff --git a/wasm/zk-nym-lib/internal-dev/bootstrap.js b/wasm/zk-nym-lib/internal-dev/bootstrap.js new file mode 100644 index 00000000000..a017926b28c --- /dev/null +++ b/wasm/zk-nym-lib/internal-dev/bootstrap.js @@ -0,0 +1,5 @@ +// A dependency graph that contains any wasm must all be imported +// asynchronously. This `bootstrap.js` file does the single async import, so +// that no one else needs to worry about it again. +import('./index.js') + .catch(e => console.error('Error importing `index.js`:', e)); diff --git a/wasm/zk-nym-lib/internal-dev/index.html b/wasm/zk-nym-lib/internal-dev/index.html new file mode 100644 index 00000000000..bf70d2046dd --- /dev/null +++ b/wasm/zk-nym-lib/internal-dev/index.html @@ -0,0 +1,34 @@ + + + + + + + Nym Credentials WebAssembly Demo + + + + + +

Yet another coconut demo

+
+ + + +
+
+ + + + + +
+ +
+

+ +

+ + + + \ No newline at end of file diff --git a/wasm/zk-nym-lib/internal-dev/index.js b/wasm/zk-nym-lib/internal-dev/index.js new file mode 100644 index 00000000000..1d0200d9e41 --- /dev/null +++ b/wasm/zk-nym-lib/internal-dev/index.js @@ -0,0 +1,85 @@ +// Copyright 2020-2023 Nym Technologies SA +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +class WebWorkerClient { + worker = null; + + constructor() { + this.worker = new Worker('./worker.js'); + + this.worker.onmessage = (ev) => { + if (ev.data && ev.data.kind) { + switch (ev.data.kind) { + case 'ReceivedCredential': + const { credential } = ev.data.args; + displayCredential(credential) + break; + } + } + }; + } + + getCredential = (amount, mnemonic) => { + if (!this.worker) { + console.error('Could not get credential because worker does not exist'); + return; + } + + this.worker.postMessage({ + kind: 'GetCredential', + args: { + amount, + mnemonic + }, + }); + }; +} + +let client = null; + +async function main() { + client = new WebWorkerClient(); + + const coconutButton = document.querySelector('#coconut-button'); + coconutButton.onclick = function () { + getCredential(); + }; +} + +async function getCredential() { + const amount = document.getElementById('credential-amount').value; + const mnemonic = document.getElementById('mnemonic').value; + + await client.getCredential(amount, mnemonic); +} + + + +function displayCredential(credential) { + console.log("got credential", credential) + + let timestamp = new Date().toISOString().substr(11, 12); + + let credentialDiv = document.createElement('div'); + let paragraph = document.createElement('p'); + paragraph.setAttribute('style', 'color: blue'); + let paragraphContent = document.createTextNode(timestamp + ' 🥥🥥🥥 >>> ' + JSON.stringify(credential)); + paragraph.appendChild(paragraphContent); + + credentialDiv.appendChild(paragraph); + document.getElementById('output').appendChild(credentialDiv); +} + + +main(); diff --git a/wasm/zk-nym-lib/internal-dev/package.json b/wasm/zk-nym-lib/internal-dev/package.json new file mode 100644 index 00000000000..14ac792dbb3 --- /dev/null +++ b/wasm/zk-nym-lib/internal-dev/package.json @@ -0,0 +1,40 @@ +{ + "name": "create-wasm-app", + "version": "0.1.0", + "description": "create an app to consume rust-generated wasm packages", + "main": "index.js", + "bin": { + "create-wasm-app": ".bin/create-wasm-app.js" + }, + "scripts": { + "build": "webpack --config webpack.config.js", + "build:wasm": "cd ../ && make wasm-build", + "start": "webpack-dev-server --port 8001" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/rustwasm/create-wasm-app.git" + }, + "keywords": [ + "webassembly", + "wasm", + "rust", + "webpack" + ], + "author": "Gala Calero ", + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/nymtech/nym/issues" + }, + "homepage": "https://nymtech.net/docs", + "devDependencies": { + "copy-webpack-plugin": "^11.0.0", + "hello-wasm-pack": "^0.1.0", + "webpack": "^5.70.0", + "webpack-cli": "^4.9.2", + "webpack-dev-server": "^4.7.4" + }, + "dependencies": { + "@nymproject/zk-nym-lib": "file:../pkg" + } +} diff --git a/wasm/zk-nym-lib/internal-dev/webpack.config.js b/wasm/zk-nym-lib/internal-dev/webpack.config.js new file mode 100644 index 00000000000..b8cd5c3a47c --- /dev/null +++ b/wasm/zk-nym-lib/internal-dev/webpack.config.js @@ -0,0 +1,46 @@ +const CopyWebpackPlugin = require("copy-webpack-plugin"); +const path = require("path"); + +module.exports = { + performance: { + hints: false, + maxEntrypointSize: 512000, + maxAssetSize: 512000, + }, + entry: { + bootstrap: "./bootstrap.js", + worker: "./worker.js", + }, + output: { + path: path.resolve(__dirname, "dist"), + filename: "[name].js", + }, + mode: "development", + // mode: 'production', + plugins: [ + new CopyWebpackPlugin({ + patterns: [ + "index.html", + { + from: "../pkg/*.(js|wasm)", + to: "[name][ext]", + }, + ], + }), + ], + devServer: { + proxy: { + '/api': { + target: 'https://sandbox-nym-api1.nymtech.net/', + secure: false, + }, + }, + headers: { + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS", + "Access-Control-Allow-Headers": + "X-Requested-With, content-type, Authorization", + }, + }, + experiments: { syncWebAssembly: true }, +}; \ No newline at end of file diff --git a/wasm/zk-nym-lib/internal-dev/worker.js b/wasm/zk-nym-lib/internal-dev/worker.js new file mode 100644 index 00000000000..d94fe16e298 --- /dev/null +++ b/wasm/zk-nym-lib/internal-dev/worker.js @@ -0,0 +1,65 @@ +// Copyright 2020-2023 Nym Technologies SA +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +const RUST_WASM_URL = "nym_zk_nym_lib_bg.wasm" + +importScripts('nym_zk_nym_lib.js'); + +console.log('Initializing worker'); + +// wasm_bindgen creates a global variable (with the exports attached) that is in scope after `importScripts` +const { + acquireCredential, +} = wasm_bindgen; + +async function testGetCredential() { + self.onmessage = async event => { + if (event.data && event.data.kind) { + switch (event.data.kind) { + case 'GetCredential': { + const { amount, mnemonic } = event.data.args; + + // TODO: this should just use cosmjs' coin + let coin = `${amount}unym` + console.log(`getting credential for ${coin}`); + + let credential = await acquireCredential(mnemonic, coin, { useSandbox: true }) + + self.postMessage({ + kind : 'ReceivedCredential', + args: { + credential + } + }) + } + } + } + }; +} + +async function main() { + console.log(">>>>>>>>>>>>>>>>>>>>> JS WORKER MAIN START"); + + // load rust WASM package + await wasm_bindgen(RUST_WASM_URL); + console.log('Loaded RUST WASM'); + + // run test on simplified and dedicated tester: + await testGetCredential(); + // + console.log(">>>>>>>>>>>>>>>>>>>>> JS WORKER MAIN END") +} + +// Let's get started! +main(); \ No newline at end of file diff --git a/wasm/zk-nym-lib/internal-dev/yarn.lock b/wasm/zk-nym-lib/internal-dev/yarn.lock new file mode 100644 index 00000000000..cd7cdf3aa8c --- /dev/null +++ b/wasm/zk-nym-lib/internal-dev/yarn.lock @@ -0,0 +1,2183 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@discoveryjs/json-ext@^0.5.0": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" + integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== + +"@jridgewell/gen-mapping@^0.3.0": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/source-map@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" + integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.17" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" + integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== + dependencies: + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" + +"@leichtgewicht/ip-codec@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" + integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@nymproject/nym-credential-client-wasm@file:../pkg": + version "1.2.0-rc.9" + +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/bonjour@^3.5.9": + version "3.5.10" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.10.tgz#0f6aadfe00ea414edc86f5d106357cda9701e275" + integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== + dependencies: + "@types/node" "*" + +"@types/connect-history-api-fallback@^1.3.5": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" + integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== + dependencies: + "@types/express-serve-static-core" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/eslint-scope@^3.7.3": + version "3.7.4" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" + integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "8.37.0" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.37.0.tgz#29cebc6c2a3ac7fea7113207bf5a828fdf4d7ef1" + integrity sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" + integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== + +"@types/estree@^0.0.51": + version "0.0.51" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" + integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== + +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": + version "4.17.33" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz#de35d30a9d637dc1450ad18dd583d75d5733d543" + integrity sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@*", "@types/express@^4.17.13": + version "4.17.17" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.17.tgz#01d5437f6ef9cfa8668e616e13c2f2ac9a491ae4" + integrity sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.33" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/http-proxy@^1.17.8": + version "1.17.10" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.10.tgz#e576c8e4a0cc5c6a138819025a88e167ebb38d6c" + integrity sha512-Qs5aULi+zV1bwKAg5z1PWnDXWmsn+LxIvUGv6E2+OOMYhclZMO+OXd9pYVf2gLykf2I7IV2u7oTHwChPNsvJ7g== + dependencies: + "@types/node" "*" + +"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": + version "7.0.11" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" + integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== + +"@types/mime@*": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" + integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== + +"@types/node@*": + version "18.15.11" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.11.tgz#b3b790f09cb1696cffcec605de025b088fa4225f" + integrity sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q== + +"@types/qs@*": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + +"@types/retry@0.12.0": + version "0.12.0" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" + integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== + +"@types/serve-index@^1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" + integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== + dependencies: + "@types/express" "*" + +"@types/serve-static@*", "@types/serve-static@^1.13.10": + version "1.15.1" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.1.tgz#86b1753f0be4f9a1bee68d459fcda5be4ea52b5d" + integrity sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ== + dependencies: + "@types/mime" "*" + "@types/node" "*" + +"@types/sockjs@^0.3.33": + version "0.3.33" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" + integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== + dependencies: + "@types/node" "*" + +"@types/ws@^8.5.1": + version "8.5.4" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.4.tgz#bb10e36116d6e570dd943735f86c933c1587b8a5" + integrity sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg== + dependencies: + "@types/node" "*" + +"@webassemblyjs/ast@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" + integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + +"@webassemblyjs/floating-point-hex-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" + integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== + +"@webassemblyjs/helper-api-error@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" + integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== + +"@webassemblyjs/helper-buffer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" + integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== + +"@webassemblyjs/helper-numbers@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" + integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" + integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== + +"@webassemblyjs/helper-wasm-section@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" + integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + +"@webassemblyjs/ieee754@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" + integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" + integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" + integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== + +"@webassemblyjs/wasm-edit@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" + integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-wasm-section" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-opt" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + "@webassemblyjs/wast-printer" "1.11.1" + +"@webassemblyjs/wasm-gen@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" + integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wasm-opt@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" + integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + +"@webassemblyjs/wasm-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" + integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wast-printer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" + integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@xtuc/long" "4.2.2" + +"@webpack-cli/configtest@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.2.0.tgz#7b20ce1c12533912c3b217ea68262365fa29a6f5" + integrity sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg== + +"@webpack-cli/info@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.5.0.tgz#6c78c13c5874852d6e2dd17f08a41f3fe4c261b1" + integrity sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ== + dependencies: + envinfo "^7.7.3" + +"@webpack-cli/serve@^1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.7.0.tgz#e1993689ac42d2b16e9194376cfb6753f6254db1" + integrity sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q== + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-import-assertions@^1.7.6: + version "1.8.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" + integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== + +acorn@^8.5.0, acorn@^8.7.1: + version "8.8.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" + integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== + +ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv-keywords@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + +ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.0, ajv@^8.8.0: + version "8.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ansi-html-community@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" + integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +array-flatten@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +body-parser@1.20.1: + version "1.20.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +bonjour-service@^1.0.11: + version "1.1.1" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.1.1.tgz#960948fa0e0153f5d26743ab15baf8e33752c135" + integrity sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg== + dependencies: + array-flatten "^2.1.2" + dns-equal "^1.0.0" + fast-deep-equal "^3.1.3" + multicast-dns "^7.2.5" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browserslist@^4.14.5: + version "4.21.5" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" + integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== + dependencies: + caniuse-lite "^1.0.30001449" + electron-to-chromium "^1.4.284" + node-releases "^2.0.8" + update-browserslist-db "^1.0.10" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +caniuse-lite@^1.0.30001449: + version "1.0.30001474" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001474.tgz#13b6fe301a831fe666cce8ca4ef89352334133d5" + integrity sha512-iaIZ8gVrWfemh5DG3T9/YqarVZoYf0r188IjaGwx68j4Pf0SGY6CQkmJUIE+NZHkkecQGohzXmBGEwWDr9aM3Q== + +chokidar@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +colorette@^2.0.10, colorette@^2.0.14: + version "2.0.19" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" + integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^7.0.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +connect-history-api-fallback@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" + integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + +copy-webpack-plugin@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz#96d4dbdb5f73d02dd72d0528d1958721ab72e04a" + integrity sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ== + dependencies: + fast-glob "^3.2.11" + glob-parent "^6.0.1" + globby "^13.1.1" + normalize-path "^3.0.0" + schema-utils "^4.0.0" + serialize-javascript "^6.0.0" + +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== + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^4.1.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +default-gateway@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" + integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== + dependencies: + execa "^5.0.0" + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-node@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== + +dns-packet@^5.2.2: + version "5.5.0" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.5.0.tgz#f59cbf3396c130957c56a6ad5fd3959ccdc30065" + integrity sha512-USawdAUzRkV6xrqTjiAEp6M9YagZEzWcSUaZTcIFAiyQWW1SoI6KyId8y2+/71wbgHKQAKd+iupLv4YvEwYWvA== + dependencies: + "@leichtgewicht/ip-codec" "^2.0.1" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +electron-to-chromium@^1.4.284: + version "1.4.352" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.352.tgz#be96bd7c2f4b980deebc9338a49a67430a33ed73" + integrity sha512-ikFUEyu5/q+wJpMOxWxTaEVk2M1qKqTGKKyfJmod1CPZxKfYnxVS41/GCBQg21ItBpZybyN8sNpRqCUGm+Zc4Q== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +enhanced-resolve@^5.10.0: + version "5.12.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz#300e1c90228f5b570c4d35babf263f6da7155634" + integrity sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +envinfo@^7.7.3: + version "7.8.1" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" + integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== + +es-module-lexer@^0.9.0: + version "0.9.3" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" + integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +express@^4.17.3: + version "4.18.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" + integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.2.11, fast-glob@^3.3.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" + integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fastest-levenshtein@^1.0.12: + version "1.0.16" + resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" + integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== + +fastq@^1.6.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + dependencies: + reusify "^1.0.4" + +faye-websocket@^0.11.3: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +find-up@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +follow-redirects@^1.0.0: + version "1.15.2" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fs-monkey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" + integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +get-intrinsic@^1.0.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" + integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob@^7.1.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globby@^13.1.1: + version "13.2.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-13.2.2.tgz#63b90b1bf68619c2135475cbd4e71e66aa090592" + integrity sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w== + dependencies: + dir-glob "^3.0.1" + fast-glob "^3.3.0" + ignore "^5.2.4" + merge2 "^1.4.1" + slash "^4.0.0" + +graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hello-wasm-pack@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/hello-wasm-pack/-/hello-wasm-pack-0.1.0.tgz#482a2e3371828056ac35f5b5fec76c0b99dcd530" + integrity sha512-3hx0GDkDLf/a9ThCMV2qG4mwza8N/MCtm8aeFFc/cdBCL2zMJ1kW1wjNl7xPqD1lz8Yl5+uhnc/cpui4dLwz/w== + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-entities@^2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46" + integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-parser-js@>=0.5.1: + version "0.5.8" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" + integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== + +http-proxy-middleware@^2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" + integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== + dependencies: + "@types/http-proxy" "^1.17.8" + http-proxy "^1.18.1" + is-glob "^4.0.1" + is-plain-obj "^3.0.0" + micromatch "^4.0.2" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ignore@^5.2.4: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== + +interpret@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" + integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +ipaddr.js@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" + integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-core-module@^2.9.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" + integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== + dependencies: + has "^1.0.3" + +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" + integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== + +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +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.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + +jest-worker@^27.4.5: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +json-parse-even-better-errors@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +launch-editor@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.6.0.tgz#4c0c1a6ac126c572bd9ff9a30da1d2cae66defd7" + integrity sha512-JpDCcQnyAAzZZaZ7vEiSqL690w7dAEyLao+KC96zBplnYbJS7TYNjvM3M7y3dGz+v7aIsJk3hllWuc0kWAjyRQ== + dependencies: + picocolors "^1.0.0" + shell-quote "^1.7.3" + +loader-runner@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +memfs@^3.4.3: + version "3.4.13" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.13.tgz#248a8bd239b3c240175cd5ec548de5227fc4f345" + integrity sha512-omTM41g3Skpvx5dSYeZIbXKcXoAVc/AoMNwn9TKx++L/gaen/+4TTttmu8ZSch5vfVJ8uJvGbroTsIlslRg6lg== + dependencies: + fs-monkey "^1.0.3" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micromatch@^4.0.2, micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimalistic-assert@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multicast-dns@^7.2.5: + version "7.2.5" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" + integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== + dependencies: + dns-packet "^5.2.2" + thunky "^1.0.2" + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +node-forge@^1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + +node-releases@^2.0.8: + version "2.0.10" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" + integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +object-inspect@^1.9.0: + version "1.12.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" + integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +open@^8.0.9: + version "8.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" + integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-retry@^4.5.0: + version "4.6.2" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" + integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== + dependencies: + "@types/retry" "0.12.0" + retry "^0.13.1" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +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== + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +punycode@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + +qs@6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +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" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +readable-stream@^2.0.1: + 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.0.6: + 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.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +rechoir@^0.7.0: + version "0.7.1" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" + integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg== + dependencies: + resolve "^1.9.0" + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve@^1.9.0: + version "1.22.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +retry@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +safe-buffer@5.1.2, 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== + +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, 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== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +schema-utils@^3.1.0, schema-utils@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" + integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" + integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.8.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.0.0" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== + +selfsigned@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.1.1.tgz#18a7613d714c0cd3385c48af0075abf3f266af61" + integrity sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ== + dependencies: + node-forge "^1" + +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz#b206efb27c3da0b0ab6b52f48d170b7996458e5c" + integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== + dependencies: + randombytes "^2.1.0" + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +shell-quote@^1.7.3: + version "1.8.0" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.0.tgz#20d078d0eaf71d54f43bd2ba14a1b5b9bfa5c8ba" + integrity sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +signal-exit@^3.0.3: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +slash@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" + integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== + +sockjs@^0.3.24: + version "0.3.24" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" + integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== + dependencies: + faye-websocket "^0.11.3" + uuid "^8.3.2" + websocket-driver "^0.7.4" + +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +"statuses@>= 1.4.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + +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-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +terser-webpack-plugin@^5.1.3: + version "5.3.7" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.7.tgz#ef760632d24991760f339fe9290deb936ad1ffc7" + integrity sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw== + dependencies: + "@jridgewell/trace-mapping" "^0.3.17" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.1" + terser "^5.16.5" + +terser@^5.16.5: + version "5.16.8" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.8.tgz#ccde583dabe71df3f4ed02b65eb6532e0fae15d5" + integrity sha512-QI5g1E/ef7d+PsDifb+a6nnVgC4F22Bg6T0xrBrz6iloVB4PUkkunp6V8nzoOOZJIzjWVdAGqCdlKlhLq/TbIA== + dependencies: + "@jridgewell/source-map" "^0.3.2" + acorn "^8.5.0" + commander "^2.20.0" + source-map-support "~0.5.20" + +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +update-browserslist-db@^1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" + integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +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== + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +watchpack@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" + integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +webpack-cli@^4.9.2: + version "4.10.0" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.10.0.tgz#37c1d69c8d85214c5a65e589378f53aec64dab31" + integrity sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w== + dependencies: + "@discoveryjs/json-ext" "^0.5.0" + "@webpack-cli/configtest" "^1.2.0" + "@webpack-cli/info" "^1.5.0" + "@webpack-cli/serve" "^1.7.0" + colorette "^2.0.14" + commander "^7.0.0" + cross-spawn "^7.0.3" + fastest-levenshtein "^1.0.12" + import-local "^3.0.2" + interpret "^2.2.0" + rechoir "^0.7.0" + webpack-merge "^5.7.3" + +webpack-dev-middleware@^5.3.1: + version "5.3.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f" + integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== + dependencies: + colorette "^2.0.10" + memfs "^3.4.3" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + +webpack-dev-server@^4.7.4: + version "4.13.2" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.13.2.tgz#d97445481d78691efe6d9a3b230833d802fc31f9" + integrity sha512-5i6TrGBRxG4vnfDpB6qSQGfnB6skGBXNL5/542w2uRGLimX6qeE5BQMLrzIC3JYV/xlGOv+s+hTleI9AZKUQNw== + dependencies: + "@types/bonjour" "^3.5.9" + "@types/connect-history-api-fallback" "^1.3.5" + "@types/express" "^4.17.13" + "@types/serve-index" "^1.9.1" + "@types/serve-static" "^1.13.10" + "@types/sockjs" "^0.3.33" + "@types/ws" "^8.5.1" + ansi-html-community "^0.0.8" + bonjour-service "^1.0.11" + chokidar "^3.5.3" + colorette "^2.0.10" + compression "^1.7.4" + connect-history-api-fallback "^2.0.0" + default-gateway "^6.0.3" + express "^4.17.3" + graceful-fs "^4.2.6" + html-entities "^2.3.2" + http-proxy-middleware "^2.0.3" + ipaddr.js "^2.0.1" + launch-editor "^2.6.0" + open "^8.0.9" + p-retry "^4.5.0" + rimraf "^3.0.2" + schema-utils "^4.0.0" + selfsigned "^2.1.1" + serve-index "^1.9.1" + sockjs "^0.3.24" + spdy "^4.0.2" + webpack-dev-middleware "^5.3.1" + ws "^8.13.0" + +webpack-merge@^5.7.3: + version "5.8.0" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" + integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== + dependencies: + clone-deep "^4.0.1" + wildcard "^2.0.0" + +webpack-sources@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + +webpack@^5.70.0: + version "5.77.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.77.0.tgz#dea3ad16d7ea6b84aa55fa42f4eac9f30e7eb9b4" + integrity sha512-sbGNjBr5Ya5ss91yzjeJTLKyfiwo5C628AFjEa6WSXcZa4E+F57om3Cc8xLb1Jh0b243AWuSYRf3dn7HVeFQ9Q== + dependencies: + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^0.0.51" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/wasm-edit" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + acorn "^8.7.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.10.0" + es-module-lexer "^0.9.0" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.9" + json-parse-even-better-errors "^2.3.1" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.4.0" + webpack-sources "^3.2.3" + +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wildcard@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" + integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@^8.13.0: + version "8.13.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" + integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== diff --git a/wasm/zk-nym-lib/src/credential.rs b/wasm/zk-nym-lib/src/credential.rs new file mode 100644 index 00000000000..1a87960d207 --- /dev/null +++ b/wasm/zk-nym-lib/src/credential.rs @@ -0,0 +1,123 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::error::WasmCredentialClientError; +use crate::opts::CredentialClientOpts; +use js_sys::Promise; +use nym_credential_storage::ephemeral_storage::EphemeralCredentialStorage; +use nym_credential_storage::models::StoredIssuedCredential; +use nym_network_defaults::NymNetworkDetails; +use nym_validator_client::nyxd::{Config, CosmWasmCoin}; +use nym_validator_client::DirectSigningReqwestRpcNyxdClient; +use serde::{Deserialize, Serialize}; +use tsify::Tsify; +use wasm_bindgen::prelude::*; +use wasm_bindgen_futures::future_to_promise; +use wasm_utils::console_log; +use wasm_utils::error::PromisableResult; +use zeroize::{Zeroize, ZeroizeOnDrop}; + +#[wasm_bindgen(js_name = acquireCredential)] +pub fn acquire_credential(mnemonic: String, amount: String, opts: CredentialClientOpts) -> Promise { + future_to_promise(async move { + acquire_credential_async(mnemonic, amount, opts) + .await + .map(|credential| { + serde_wasm_bindgen::to_value(&credential).expect("this serialization can't fail") + }) + .into_promise_result() + }) +} + +async fn acquire_credential_async( + mnemonic: String, + amount: String, + opts: CredentialClientOpts, +) -> Result { + // start by parsing mnemonic so that we could immediately move it into a Zeroizing wrapper + let mnemonic = crate::helpers::parse_mnemonic(mnemonic)?; + + // why are we parsing into CosmWasmCoin and not "our" Coin? + // simple. because it has the nicest 'FromStr' impl + let amount: CosmWasmCoin = + amount + .parse() + .map_err(|source| WasmCredentialClientError::MalformedCoin { + source: Box::new(source), + })?; + + if amount.amount.is_zero() { + return Err(WasmCredentialClientError::ZeroCoinValue); + } + + let network = match opts.network_details { + Some(specified) => specified, + None => { + if let Some(true) = opts.use_sandbox { + crate::helpers::minimal_coconut_sandbox() + } else { + NymNetworkDetails::new_mainnet() + } + } + }; + + let config = Config::try_from_nym_network_details(&network)?; + + // just get the first nyxd endpoint + let nyxd_endpoint = network + .endpoints + .get(0) + .ok_or(WasmCredentialClientError::NoNyxdEndpoints)? + .try_nyxd_url()?; + + let client = DirectSigningReqwestRpcNyxdClient::connect_reqwest_with_mnemonic( + config, + nyxd_endpoint, + mnemonic, + ); + + console_log!("starting the deposit..."); + let deposit_state = nym_bandwidth_controller::acquire::deposit(&client, amount).await?; + let blinded_serial = deposit_state.voucher.blinded_serial_number_bs58(); + console_log!( + "obtained bandwidth voucher with the following blinded serial number: {blinded_serial}" + ); + + // TODO: use proper persistent storage here. probably indexeddb like we have for our 'normal' wasm client + let ephemeral_storage = EphemeralCredentialStorage::default(); + + // store credential in the ephemeral storage... + nym_bandwidth_controller::acquire::get_bandwidth_voucher( + &deposit_state, + &client, + &ephemeral_storage, + ) + .await?; + + // and immediately get it out! + let mut credentials = ephemeral_storage.take_credentials().await; + let cred = credentials.pop().expect("we just got a credential issued"); + + Ok(cred.into()) +} + +#[derive(Tsify, Debug, Clone, Serialize, Deserialize, Zeroize, ZeroizeOnDrop)] +#[tsify(into_wasm_abi, from_wasm_abi)] +#[serde(rename_all = "camelCase")] +pub struct WasmIssuedCredential { + pub serialization_revision: u8, + pub credential_data: Vec, + pub credential_type: String, + pub epoch_id: u32, +} + +impl From for WasmIssuedCredential { + fn from(value: StoredIssuedCredential) -> Self { + WasmIssuedCredential { + serialization_revision: value.serialization_revision, + credential_data: value.credential_data.clone(), + credential_type: value.credential_type.clone(), + epoch_id: value.epoch_id, + } + } +} diff --git a/wasm/zk-nym-lib/src/error.rs b/wasm/zk-nym-lib/src/error.rs new file mode 100644 index 00000000000..d3e3666ca56 --- /dev/null +++ b/wasm/zk-nym-lib/src/error.rs @@ -0,0 +1,60 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use nym_bandwidth_controller::error::BandwidthControllerError; +use nym_network_defaults::UrlParseError; +use nym_validator_client::nyxd::error::NyxdError; +use thiserror::Error; +use wasm_utils::wasm_error; + +#[derive(Debug, Error)] +pub enum WasmCredentialClientError { + #[error(transparent)] + BandwidthControllerError { + #[from] + source: BandwidthControllerError, + }, + + #[error("the passed credential value had a value of zero")] + ZeroCoinValue, + + #[error("failed to use credential storage: {source}")] + StorageError { + #[from] + source: nym_credential_storage::error::StorageError, + }, + + #[error(transparent)] + NyxdFailure { + #[from] + source: NyxdError, + }, + + #[error("no nyxd endpoints have been provided - we can't interact with the chain")] + NoNyxdEndpoints, + + #[error("the provided nyxd endpoint is malformed: {source}")] + MalformedNyxdEndpoint { + #[from] + source: UrlParseError, + }, + + // #[error("The provided deposit value was malformed: {source}")] + // MalformedCoin { source: serde_wasm_bindgen::Error }, + #[error("The provided deposit value was malformed: {source}")] + // annoyingly cosmwasm hasn't exposed CoinFromStrError directly + // so we have to rely on the dynamic dispatch here + MalformedCoin { source: Box }, + + // #[error("Coin parse error")] + // CoinParseError, + // #[error("State error")] + // StateError, + #[error("The provided mnemonic was malformed: {source}")] + MalformedMnemonic { + #[from] + source: bip39::Error, + }, +} + +wasm_error!(WasmCredentialClientError); diff --git a/wasm/zk-nym-lib/src/helpers.rs b/wasm/zk-nym-lib/src/helpers.rs new file mode 100644 index 00000000000..0bed6d91d37 --- /dev/null +++ b/wasm/zk-nym-lib/src/helpers.rs @@ -0,0 +1,39 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::error::WasmCredentialClientError; +use nym_network_defaults::{NymContracts, NymNetworkDetails, ValidatorDetails}; +use zeroize::Zeroizing; + +pub(crate) fn parse_mnemonic(raw: String) -> Result { + // make sure that whatever happens, the raw value gets zeroized + let wrapped = Zeroizing::new(raw); + Ok(bip39::Mnemonic::parse(&*wrapped)?) +} + +pub(crate) fn minimal_coconut_sandbox() -> NymNetworkDetails { + // we can piggyback on mainnet defaults for certain things, + // since sandbox uses the same network name, denoms, etc. + let default_mainnet = NymNetworkDetails::new_mainnet(); + + NymNetworkDetails { + network_name: default_mainnet.network_name, + chain_details: default_mainnet.chain_details, + endpoints: vec![ValidatorDetails::new( + "https://sandbox-validator1.nymtech.net", + None, + None, + )], + contracts: NymContracts { + coconut_bandwidth_contract_address: Some( + "n16a32stm6kknhq5cc8rx77elr66pygf2hfszw7wvpq746x3uffylqkjar4l".into(), + ), + coconut_dkg_contract_address: Some( + "n1ahg0erc2fs6xx3j5m8sfx3ryuzdjh6kf6qm9plsf865fltekyrfsesac6a".into(), + ), + // we don't need other contracts for getting credential + ..Default::default() + }, + explorer_api: None, + } +} diff --git a/wasm/zk-nym-lib/src/lib.rs b/wasm/zk-nym-lib/src/lib.rs new file mode 100644 index 00000000000..2484312cf94 --- /dev/null +++ b/wasm/zk-nym-lib/src/lib.rs @@ -0,0 +1,26 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +#[cfg(target_arch = "wasm32")] +mod credential; +#[cfg(target_arch = "wasm32")] +mod error; +#[cfg(target_arch = "wasm32")] +mod helpers; +#[cfg(target_arch = "wasm32")] +mod opts; + +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; + +#[wasm_bindgen(start)] +#[cfg(target_arch = "wasm32")] +pub fn main() { + wasm_utils::console_log!("[rust main]: rust module loaded"); + wasm_utils::console_log!( + "credential client version used: {:#?}", + nym_bin_common::bin_info!() + ); + wasm_utils::console_log!("[rust main]: setting panic hook"); + wasm_utils::set_panic_hook(); +} diff --git a/wasm/zk-nym-lib/src/opts.rs b/wasm/zk-nym-lib/src/opts.rs new file mode 100644 index 00000000000..599b15b6345 --- /dev/null +++ b/wasm/zk-nym-lib/src/opts.rs @@ -0,0 +1,17 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use nym_network_defaults::NymNetworkDetails; +use serde::{Deserialize, Serialize}; +use tsify::Tsify; + +#[derive(Tsify, Debug, Clone, Serialize, Deserialize)] +#[tsify(into_wasm_abi, from_wasm_abi)] +#[serde(rename_all = "camelCase")] +pub struct CredentialClientOpts { + #[tsify(optional)] + pub network_details: Option, + + #[tsify(optional)] + pub use_sandbox: Option, +} From d04307d074c22927baddcf53ba96d1097510371f Mon Sep 17 00:00:00 2001 From: Mark Sinclair Date: Mon, 12 Aug 2024 16:24:27 +0100 Subject: [PATCH 2/6] wip --- .../src/client/packet_statistics_control.rs | 6 + common/credential-utils/Cargo.toml | 2 +- common/credentials-interface/Cargo.toml | 9 + common/credentials-interface/src/lib.rs | 8 + sdk/rust/nym-sdk/src/bandwidth/client.rs | 6 +- wasm/zk-nym-lib/Cargo.toml | 3 +- wasm/zk-nym-lib/Makefile | 5 +- wasm/zk-nym-lib/src/bandwidth.rs | 62 +++++++ wasm/zk-nym-lib/src/credential.rs | 155 +++++++++++------- wasm/zk-nym-lib/src/error.rs | 4 +- wasm/zk-nym-lib/src/helpers.rs | 1 + wasm/zk-nym-lib/src/lib.rs | 2 + 12 files changed, 196 insertions(+), 67 deletions(-) create mode 100644 wasm/zk-nym-lib/src/bandwidth.rs diff --git a/common/client-core/src/client/packet_statistics_control.rs b/common/client-core/src/client/packet_statistics_control.rs index 499d5de0928..309648dbd82 100644 --- a/common/client-core/src/client/packet_statistics_control.rs +++ b/common/client-core/src/client/packet_statistics_control.rs @@ -3,6 +3,7 @@ use std::{ time::{Duration, Instant}, }; +#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use nym_metrics::{inc, inc_by}; use si_scale::helpers::bibytes2; @@ -72,6 +73,11 @@ struct PacketStatistics { } impl PacketStatistics { + #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] + fn handle_event(&mut self, event: crate::client::packet_statistics_control::PacketStatisticsEvent) { + } + + #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] fn handle_event(&mut self, event: PacketStatisticsEvent) { match event { PacketStatisticsEvent::RealPacketSent(packet_size) => { diff --git a/common/credential-utils/Cargo.toml b/common/credential-utils/Cargo.toml index 81ba19a85be..42550b72a97 100644 --- a/common/credential-utils/Cargo.toml +++ b/common/credential-utils/Cargo.toml @@ -9,7 +9,7 @@ license.workspace = true [dependencies] log = { workspace = true } thiserror = { workspace = true } -tokio = { workspace = true } +tokio = { workspace = true, features = ["sync", "time"] } time.workspace = true nym-bandwidth-controller = { path = "../../common/bandwidth-controller" } diff --git a/common/credentials-interface/Cargo.toml b/common/credentials-interface/Cargo.toml index 2142acf14a9..17895daf669 100644 --- a/common/credentials-interface/Cargo.toml +++ b/common/credentials-interface/Cargo.toml @@ -18,6 +18,15 @@ strum = { workspace = true, features = ["derive"] } time = { workspace = true, features = ["serde"] } rand = { workspace = true } +# 'wasm-serde-types' feature +wasm-utils = { path = "../wasm/utils", default-features = false, optional = true } +tsify = { workspace = true, features = ["js"], optional = true } +wasm-bindgen = { workspace = true, optional = true } + nym-compact-ecash = { path = "../nym_offline_compact_ecash" } nym-ecash-time = { path = "../ecash-time" } nym-network-defaults = { path = "../network-defaults" } + +[features] +default = [] +wasm-serde-types = ["tsify", "wasm-bindgen", "wasm-utils"] diff --git a/common/credentials-interface/src/lib.rs b/common/credentials-interface/src/lib.rs index 85938c3c61a..57cc80f4599 100644 --- a/common/credentials-interface/src/lib.rs +++ b/common/credentials-interface/src/lib.rs @@ -30,6 +30,12 @@ pub use nym_compact_ecash::{ }; use nym_ecash_time::{ecash_today, EcashTime}; +#[cfg(feature = "wasm-serde-types")] +use tsify::Tsify; + +#[cfg(feature = "wasm-serde-types")] +use wasm_bindgen::{prelude::wasm_bindgen}; + #[derive(Debug, Clone)] pub struct CredentialSigningData { pub withdrawal_request: WithdrawalRequest, @@ -233,6 +239,8 @@ impl From for NymPayInfo { )] #[serde(rename_all = "kebab-case")] #[strum(serialize_all = "kebab-case")] +#[cfg_attr(feature = "wasm-serde-types", derive(Tsify))] +#[cfg_attr(feature = "wasm-serde-types", tsify(into_wasm_abi, from_wasm_abi))] pub enum TicketType { #[default] V1MixnetEntry, diff --git a/sdk/rust/nym-sdk/src/bandwidth/client.rs b/sdk/rust/nym-sdk/src/bandwidth/client.rs index 19da50eccbf..ee37538699b 100644 --- a/sdk/rust/nym-sdk/src/bandwidth/client.rs +++ b/sdk/rust/nym-sdk/src/bandwidth/client.rs @@ -26,11 +26,11 @@ where St: Storage, ::StorageError: Send + Sync + 'static, { - pub(crate) fn new( + pub fn new( network_details: NymNetworkDetails, mnemonic: String, storage: &'a St, - client_id: String, + client_id_private_key_base58: String, ticketbook_type: TicketType, ) -> Result { let nyxd_url = network_details.endpoints[0].nyxd_url.as_str(); @@ -44,7 +44,7 @@ where Ok(Self { client, storage, - client_id: client_id.into(), + client_id: client_id_private_key_base58.into(), ticketbook_type, }) } diff --git a/wasm/zk-nym-lib/Cargo.toml b/wasm/zk-nym-lib/Cargo.toml index 64fae0ee178..17c22012fb3 100644 --- a/wasm/zk-nym-lib/Cargo.toml +++ b/wasm/zk-nym-lib/Cargo.toml @@ -28,10 +28,11 @@ wasm-utils = { path = "../../common/wasm/utils" } nym-bin-common = { path = "../../common/bin-common" } nym-credentials = { path = "../../common/credentials" } +nym-credential-utils = { path = "../../common/credential-utils" } nym-credential-storage = { path = "../../common/credential-storage" } nym-bandwidth-controller = { path = "../../common/bandwidth-controller" } nym-validator-client = { path = "../../common/client-libs/validator-client", default-features = false } -nym-credentials-interface = { path = "../../common/credentials-interface" } +nym-credentials-interface = { path = "../../common/credentials-interface", features = ["wasm-serde-types"]} nym-network-defaults = { path = "../../common/network-defaults" } [dev-dependencies] diff --git a/wasm/zk-nym-lib/Makefile b/wasm/zk-nym-lib/Makefile index 4b0306cd8ee..6da64ad2810 100644 --- a/wasm/zk-nym-lib/Makefile +++ b/wasm/zk-nym-lib/Makefile @@ -4,4 +4,7 @@ build: # make my life easier so I wouldn't need to deal with any bundlers. sorry @MS : ) build-debug-dev: - wasm-pack build --scope nymproject --target no-modules \ No newline at end of file + wasm-pack build --scope nymproject --target no-modules + +clippy: + cargo clippy --target wasm32-unknown-unknown -- -Dwarnings diff --git a/wasm/zk-nym-lib/src/bandwidth.rs b/wasm/zk-nym-lib/src/bandwidth.rs new file mode 100644 index 00000000000..f5342b34941 --- /dev/null +++ b/wasm/zk-nym-lib/src/bandwidth.rs @@ -0,0 +1,62 @@ +// Copyright 2022-2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::error::WasmCredentialClientError; +use nym_credential_storage::storage::Storage; +use nym_credential_utils::utils::issue_credential; +use nym_credentials_interface::TicketType; +use nym_network_defaults::NymNetworkDetails; +use nym_validator_client::{nyxd, DirectSigningReqwestRpcValidatorClient}; +use zeroize::Zeroizing; + +/// Represents a client that can be used to acquire bandwidth. You typically create one when you +/// want to connect to the mixnet using paid coconut bandwidth credentials. +/// The way to create this client is by calling +/// [`crate::mixnet::DisconnectedMixnetClient::create_bandwidth_client`] on the associated mixnet +/// client. +pub struct BandwidthAcquireClient<'a, St: Storage> { + client: DirectSigningReqwestRpcValidatorClient, + storage: &'a St, + client_id: Zeroizing, + ticketbook_type: TicketType, +} + +impl<'a, St> BandwidthAcquireClient<'a, St> +where + St: Storage, + ::StorageError: Send + Sync + 'static, +{ + pub fn new( + network_details: NymNetworkDetails, + mnemonic: String, + storage: &'a St, + client_id_private_key_base58: String, + ticketbook_type: TicketType, + ) -> Result { + let nyxd_url = network_details.endpoints[0].nyxd_url.as_str(); + let config = nyxd::Config::try_from_nym_network_details(&network_details)?; + + let client = DirectSigningReqwestRpcValidatorClient::connect_with_mnemonic( + config, + nyxd_url, + mnemonic.parse()?, + )?; + Ok(Self { + client, + storage, + client_id: client_id_private_key_base58.into(), + ticketbook_type, + }) + } + + pub async fn acquire(&self) -> Result<(), WasmCredentialClientError> { + issue_credential( + &self.client, + self.storage, + self.client_id.as_bytes(), + self.ticketbook_type, + ) + .await?; + Ok(()) + } +} diff --git a/wasm/zk-nym-lib/src/credential.rs b/wasm/zk-nym-lib/src/credential.rs index 1a87960d207..9c7f1613b22 100644 --- a/wasm/zk-nym-lib/src/credential.rs +++ b/wasm/zk-nym-lib/src/credential.rs @@ -5,37 +5,52 @@ use crate::error::WasmCredentialClientError; use crate::opts::CredentialClientOpts; use js_sys::Promise; use nym_credential_storage::ephemeral_storage::EphemeralCredentialStorage; -use nym_credential_storage::models::StoredIssuedCredential; +use nym_credential_storage::storage::Storage; +use nym_credentials_interface::TicketType; use nym_network_defaults::NymNetworkDetails; -use nym_validator_client::nyxd::{Config, CosmWasmCoin}; -use nym_validator_client::DirectSigningReqwestRpcNyxdClient; +use crate::bandwidth::BandwidthAcquireClient; +use nym_validator_client::nyxd::CosmWasmCoin; use serde::{Deserialize, Serialize}; use tsify::Tsify; use wasm_bindgen::prelude::*; use wasm_bindgen_futures::future_to_promise; -use wasm_utils::console_log; use wasm_utils::error::PromisableResult; use zeroize::{Zeroize, ZeroizeOnDrop}; +use nym_credentials::ecash::bandwidth::serialiser::VersionedSerialise; #[wasm_bindgen(js_name = acquireCredential)] -pub fn acquire_credential(mnemonic: String, amount: String, opts: CredentialClientOpts) -> Promise { +pub fn acquire_credential( + mnemonic: String, + amount: String, + client_id_private_key_base58: String, + ticketbook_type: TicketType, + opts: CredentialClientOpts, +) -> Promise { future_to_promise(async move { - acquire_credential_async(mnemonic, amount, opts) - .await - .map(|credential| { - serde_wasm_bindgen::to_value(&credential).expect("this serialization can't fail") - }) - .into_promise_result() + acquire_credential_async( + mnemonic, + amount, + client_id_private_key_base58, + ticketbook_type, + opts, + ) + .await + .map(|credential| { + serde_wasm_bindgen::to_value(&credential).expect("this serialization can't fail") + }) + .into_promise_result() }) } async fn acquire_credential_async( mnemonic: String, amount: String, + client_id_private_key_base58: String, + ticketbook_type: TicketType, opts: CredentialClientOpts, ) -> Result { - // start by parsing mnemonic so that we could immediately move it into a Zeroizing wrapper - let mnemonic = crate::helpers::parse_mnemonic(mnemonic)?; + // // start by parsing mnemonic so that we could immediately move it into a Zeroizing wrapper + // let mnemonic = crate::helpers::parse_mnemonic(mnemonic)?; // why are we parsing into CosmWasmCoin and not "our" Coin? // simple. because it has the nicest 'FromStr' impl @@ -61,44 +76,64 @@ async fn acquire_credential_async( } }; - let config = Config::try_from_nym_network_details(&network)?; - - // just get the first nyxd endpoint - let nyxd_endpoint = network - .endpoints - .get(0) - .ok_or(WasmCredentialClientError::NoNyxdEndpoints)? - .try_nyxd_url()?; - - let client = DirectSigningReqwestRpcNyxdClient::connect_reqwest_with_mnemonic( - config, - nyxd_endpoint, - mnemonic, - ); - - console_log!("starting the deposit..."); - let deposit_state = nym_bandwidth_controller::acquire::deposit(&client, amount).await?; - let blinded_serial = deposit_state.voucher.blinded_serial_number_bs58(); - console_log!( - "obtained bandwidth voucher with the following blinded serial number: {blinded_serial}" - ); - - // TODO: use proper persistent storage here. probably indexeddb like we have for our 'normal' wasm client let ephemeral_storage = EphemeralCredentialStorage::default(); - // store credential in the ephemeral storage... - nym_bandwidth_controller::acquire::get_bandwidth_voucher( - &deposit_state, - &client, + let client = BandwidthAcquireClient::new( + network, + mnemonic, &ephemeral_storage, - ) - .await?; - - // and immediately get it out! - let mut credentials = ephemeral_storage.take_credentials().await; - let cred = credentials.pop().expect("we just got a credential issued"); - - Ok(cred.into()) + client_id_private_key_base58, + ticketbook_type, + )?; + + client.acquire().await?; + + // let config = Config::try_from_nym_network_details(&network)?; + // + // // just get the first nyxd endpoint + // let nyxd_endpoint = network + // .endpoints + // .get(0) + // .ok_or(WasmCredentialClientError::NoNyxdEndpoints)? + // .try_nyxd_url()?; + // + // let client = DirectSigningReqwestRpcNyxdClient::connect_reqwest_with_mnemonic( + // config, + // nyxd_endpoint, + // mnemonic, + // ); + // + // console_log!("starting the deposit..."); + // let deposit_state = nym_bandwidth_controller::acquire::deposit(&client, amount).await?; + // let blinded_serial = deposit_state.voucher.blinded_serial_number_bs58(); + // console_log!( + // "obtained bandwidth voucher with the following blinded serial number: {blinded_serial}" + // ); + // + // // TODO: use proper persistent storage here. probably indexeddb like we have for our 'normal' wasm client + // let ephemeral_storage = EphemeralCredentialStorage::default(); + // + // // store credential in the ephemeral storage... + // nym_bandwidth_controller::acquire::get_bandwidth_voucher( + // &deposit_state, + // &client, + // &ephemeral_storage, + // ) + // .await?; + // + + match ephemeral_storage.get_next_unspent_usable_ticketbook(1u32).await? { + Some(ticket_book) => { + let serialized = ticket_book.ticketbook.pack(); + + Ok(WasmIssuedCredential { + serialization_revision: serialized.revision, + credential_data: serialized.data, + ticketbook_type: format!("{}", ticketbook_type), + }) + }, + None => Err(WasmCredentialClientError::TicketbookCredentialStoreIsNone), + } } #[derive(Tsify, Debug, Clone, Serialize, Deserialize, Zeroize, ZeroizeOnDrop)] @@ -107,17 +142,17 @@ async fn acquire_credential_async( pub struct WasmIssuedCredential { pub serialization_revision: u8, pub credential_data: Vec, - pub credential_type: String, - pub epoch_id: u32, + pub ticketbook_type: String, + // pub epoch_id: u32, } -impl From for WasmIssuedCredential { - fn from(value: StoredIssuedCredential) -> Self { - WasmIssuedCredential { - serialization_revision: value.serialization_revision, - credential_data: value.credential_data.clone(), - credential_type: value.credential_type.clone(), - epoch_id: value.epoch_id, - } - } -} +// impl From for WasmIssuedCredential { +// fn from(value: StoredIssuedCredential) -> Self { +// WasmIssuedCredential { +// serialization_revision: value.serialization_revision, +// credential_data: value.credential_data.clone(), +// ticketbook_type: value.ticketbook_type.clone(), +// // epoch_id: value.epoch_id, +// } +// } +// } diff --git a/wasm/zk-nym-lib/src/error.rs b/wasm/zk-nym-lib/src/error.rs index d3e3666ca56..99e1a5d03d3 100644 --- a/wasm/zk-nym-lib/src/error.rs +++ b/wasm/zk-nym-lib/src/error.rs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 use nym_bandwidth_controller::error::BandwidthControllerError; -use nym_network_defaults::UrlParseError; use nym_validator_client::nyxd::error::NyxdError; use thiserror::Error; use wasm_utils::wasm_error; @@ -55,6 +54,9 @@ pub enum WasmCredentialClientError { #[from] source: bip39::Error, }, + + #[error("The ticket book cannot be retrieved from the credential store")] + TicketbookCredentialStoreIsNone, } wasm_error!(WasmCredentialClientError); diff --git a/wasm/zk-nym-lib/src/helpers.rs b/wasm/zk-nym-lib/src/helpers.rs index 0bed6d91d37..a74e53f245a 100644 --- a/wasm/zk-nym-lib/src/helpers.rs +++ b/wasm/zk-nym-lib/src/helpers.rs @@ -35,5 +35,6 @@ pub(crate) fn minimal_coconut_sandbox() -> NymNetworkDetails { ..Default::default() }, explorer_api: None, + nym_vpn_api_url: None, } } diff --git a/wasm/zk-nym-lib/src/lib.rs b/wasm/zk-nym-lib/src/lib.rs index 2484312cf94..a7f29509526 100644 --- a/wasm/zk-nym-lib/src/lib.rs +++ b/wasm/zk-nym-lib/src/lib.rs @@ -9,6 +9,8 @@ mod error; mod helpers; #[cfg(target_arch = "wasm32")] mod opts; +#[cfg(target_arch = "wasm32")] +mod bandwidth; #[cfg(target_arch = "wasm32")] use wasm_bindgen::prelude::*; From d9f09e3b919c7284821db8c09162c6e4e6f8116a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Fri, 16 Aug 2024 11:10:12 +0200 Subject: [PATCH 3/6] Disable some stuff for wasm32 --- common/credential-utils/Cargo.toml | 6 +++--- common/credential-utils/src/utils.rs | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/common/credential-utils/Cargo.toml b/common/credential-utils/Cargo.toml index 42550b72a97..732cea9f894 100644 --- a/common/credential-utils/Cargo.toml +++ b/common/credential-utils/Cargo.toml @@ -16,7 +16,7 @@ nym-bandwidth-controller = { path = "../../common/bandwidth-controller" } nym-credentials = { path = "../../common/credentials" } nym-credentials-interface = { path = "../../common/credentials-interface" } nym-credential-storage = { path = "../../common/credential-storage", features = ["persistent-storage"] } -nym-validator-client = { path = "../../common/client-libs/validator-client" } +nym-validator-client = { path = "../../common/client-libs/validator-client", default-features = false } nym-config = { path = "../../common/config" } -nym-client-core = { path = "../../common/client-core" } -nym-ecash-time = { path = "../../common/ecash-time" } \ No newline at end of file +nym-client-core = { path = "../../common/client-core", features = ["wasm"] } +nym-ecash-time = { path = "../../common/ecash-time" } diff --git a/common/credential-utils/src/utils.rs b/common/credential-utils/src/utils.rs index 41381d53f99..5dd257e0cf6 100644 --- a/common/credential-utils/src/utils.rs +++ b/common/credential-utils/src/utils.rs @@ -8,6 +8,7 @@ use nym_bandwidth_controller::acquire::{ }; use nym_client_core::config::disk_persistence::CommonClientPaths; use nym_config::DEFAULT_DATA_DIR; +#[cfg(not(target_arch = "wasm32"))] use nym_credential_storage::persistent_storage::PersistentStorage; use nym_credential_storage::storage::Storage; use nym_credentials_interface::TicketType; @@ -80,6 +81,7 @@ where Ok(()) } +#[cfg(not(target_arch = "wasm32"))] pub async fn setup_persistent_storage(client_home_directory: PathBuf) -> PersistentStorage { let data_dir = client_home_directory.join(DEFAULT_DATA_DIR); let paths = CommonClientPaths::new_base(data_dir); From 0a1f861448b10ced8424440fc87b5e6e7b38b4aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Fri, 16 Aug 2024 11:19:14 +0200 Subject: [PATCH 4/6] Fix compilation --- wasm/zk-nym-lib/src/error.rs | 10 +++++----- wasm/zk-nym-lib/src/helpers.rs | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/wasm/zk-nym-lib/src/error.rs b/wasm/zk-nym-lib/src/error.rs index 99e1a5d03d3..2b11d1e5c37 100644 --- a/wasm/zk-nym-lib/src/error.rs +++ b/wasm/zk-nym-lib/src/error.rs @@ -32,11 +32,11 @@ pub enum WasmCredentialClientError { #[error("no nyxd endpoints have been provided - we can't interact with the chain")] NoNyxdEndpoints, - #[error("the provided nyxd endpoint is malformed: {source}")] - MalformedNyxdEndpoint { - #[from] - source: UrlParseError, - }, + // #[error("the provided nyxd endpoint is malformed: {source}")] + // MalformedNyxdEndpoint { + // #[from] + // source: UrlParseError, + // }, // #[error("The provided deposit value was malformed: {source}")] // MalformedCoin { source: serde_wasm_bindgen::Error }, diff --git a/wasm/zk-nym-lib/src/helpers.rs b/wasm/zk-nym-lib/src/helpers.rs index a74e53f245a..f562d589ca6 100644 --- a/wasm/zk-nym-lib/src/helpers.rs +++ b/wasm/zk-nym-lib/src/helpers.rs @@ -25,9 +25,9 @@ pub(crate) fn minimal_coconut_sandbox() -> NymNetworkDetails { None, )], contracts: NymContracts { - coconut_bandwidth_contract_address: Some( - "n16a32stm6kknhq5cc8rx77elr66pygf2hfszw7wvpq746x3uffylqkjar4l".into(), - ), + // coconut_bandwidth_contract_address: Some( + // "n16a32stm6kknhq5cc8rx77elr66pygf2hfszw7wvpq746x3uffylqkjar4l".into(), + // ), coconut_dkg_contract_address: Some( "n1ahg0erc2fs6xx3j5m8sfx3ryuzdjh6kf6qm9plsf865fltekyrfsesac6a".into(), ), From 6ee8b655e411f8e4a52e07162bca51b078e20b3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 16 Aug 2024 12:09:30 +0100 Subject: [PATCH 5/6] fix: make sure to construct correct client instance --- wasm/zk-nym-lib/src/bandwidth.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/wasm/zk-nym-lib/src/bandwidth.rs b/wasm/zk-nym-lib/src/bandwidth.rs index f5342b34941..9675a946d4f 100644 --- a/wasm/zk-nym-lib/src/bandwidth.rs +++ b/wasm/zk-nym-lib/src/bandwidth.rs @@ -6,7 +6,7 @@ use nym_credential_storage::storage::Storage; use nym_credential_utils::utils::issue_credential; use nym_credentials_interface::TicketType; use nym_network_defaults::NymNetworkDetails; -use nym_validator_client::{nyxd, DirectSigningReqwestRpcValidatorClient}; +use nym_validator_client::{nyxd, DirectSigningReqwestRpcNyxdClient}; use zeroize::Zeroizing; /// Represents a client that can be used to acquire bandwidth. You typically create one when you @@ -15,7 +15,7 @@ use zeroize::Zeroizing; /// [`crate::mixnet::DisconnectedMixnetClient::create_bandwidth_client`] on the associated mixnet /// client. pub struct BandwidthAcquireClient<'a, St: Storage> { - client: DirectSigningReqwestRpcValidatorClient, + client: DirectSigningReqwestRpcNyxdClient, storage: &'a St, client_id: Zeroizing, ticketbook_type: TicketType, @@ -36,11 +36,11 @@ where let nyxd_url = network_details.endpoints[0].nyxd_url.as_str(); let config = nyxd::Config::try_from_nym_network_details(&network_details)?; - let client = DirectSigningReqwestRpcValidatorClient::connect_with_mnemonic( + let client = DirectSigningReqwestRpcNyxdClient::connect_reqwest_with_mnemonic( config, - nyxd_url, + nyxd_url.parse().expect("TODO: MAKE SURE YOU HANDLE IT"), mnemonic.parse()?, - )?; + ); Ok(Self { client, storage, @@ -50,13 +50,16 @@ where } pub async fn acquire(&self) -> Result<(), WasmCredentialClientError> { - issue_credential( + if let Err(err) = issue_credential( &self.client, self.storage, self.client_id.as_bytes(), self.ticketbook_type, ) - .await?; + .await + { + panic!("unhandled error: {err}") + } Ok(()) } } From 954d2e71768b99d5ed1b9859aa7288480b9236b9 Mon Sep 17 00:00:00 2001 From: Mark Sinclair Date: Tue, 20 Aug 2024 15:47:00 +0100 Subject: [PATCH 6/6] make clippy happy --- Cargo.lock | 4 ++++ Makefile | 2 +- .../src/client/packet_statistics_control.rs | 6 +++++- common/credential-utils/src/utils.rs | 3 +++ common/credentials-interface/src/lib.rs | 2 +- wasm/zk-nym-lib/src/credential.rs | 11 +++++++---- wasm/zk-nym-lib/src/helpers.rs | 8 -------- wasm/zk-nym-lib/src/lib.rs | 4 ++-- 8 files changed, 23 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9ba4d09160d..15f7bc9988e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4856,6 +4856,9 @@ dependencies = [ "strum 0.25.0", "thiserror", "time", + "tsify", + "wasm-bindgen", + "wasm-utils", ] [[package]] @@ -10689,6 +10692,7 @@ dependencies = [ "nym-bandwidth-controller", "nym-bin-common", "nym-credential-storage", + "nym-credential-utils", "nym-credentials", "nym-credentials-interface", "nym-network-defaults", diff --git a/Makefile b/Makefile index 123e5caef6c..1e21128fbc3 100644 --- a/Makefile +++ b/Makefile @@ -116,7 +116,7 @@ sdk-typescript-build: yarn --cwd sdk/typescript/codegen/contract-clients build # NOTE: These targets are part of the main workspace (but not as wasm32-unknown-unknown) -WASM_CRATES = extension-storage nym-client-wasm nym-node-tester-wasm zknym-lib +WASM_CRATES = extension-storage nym-client-wasm nym-node-tester-wasm zk-nym-lib sdk-wasm-test: #cargo test $(addprefix -p , $(WASM_CRATES)) --target wasm32-unknown-unknown -- -Dwarnings diff --git a/common/client-core/src/client/packet_statistics_control.rs b/common/client-core/src/client/packet_statistics_control.rs index 309648dbd82..65273e5c2ad 100644 --- a/common/client-core/src/client/packet_statistics_control.rs +++ b/common/client-core/src/client/packet_statistics_control.rs @@ -74,7 +74,10 @@ struct PacketStatistics { impl PacketStatistics { #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] - fn handle_event(&mut self, event: crate::client::packet_statistics_control::PacketStatisticsEvent) { + fn handle_event( + &mut self, + _event: crate::client::packet_statistics_control::PacketStatisticsEvent, + ) { } #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] @@ -336,6 +339,7 @@ impl PacketRates { } } +#[allow(unused_variables, dead_code)] #[derive(Debug)] pub(crate) enum PacketStatisticsEvent { // The real packets sent. Recall that acks are sent by the gateway, so it's not included here. diff --git a/common/credential-utils/src/utils.rs b/common/credential-utils/src/utils.rs index 5dd257e0cf6..f28d3eb15b5 100644 --- a/common/credential-utils/src/utils.rs +++ b/common/credential-utils/src/utils.rs @@ -6,7 +6,9 @@ use log::*; use nym_bandwidth_controller::acquire::{ get_ticket_book, query_and_persist_required_global_signatures, }; +#[cfg(not(target_arch = "wasm32"))] use nym_client_core::config::disk_persistence::CommonClientPaths; +#[cfg(not(target_arch = "wasm32"))] use nym_config::DEFAULT_DATA_DIR; #[cfg(not(target_arch = "wasm32"))] use nym_credential_storage::persistent_storage::PersistentStorage; @@ -17,6 +19,7 @@ use nym_validator_client::coconut::all_ecash_api_clients; use nym_validator_client::nyxd::contract_traits::{ dkg_query_client::EpochState, DkgQueryClient, EcashQueryClient, EcashSigningClient, }; +#[cfg(not(target_arch = "wasm32"))] use std::path::PathBuf; use std::time::Duration; use time::OffsetDateTime; diff --git a/common/credentials-interface/src/lib.rs b/common/credentials-interface/src/lib.rs index 57cc80f4599..401e92900fc 100644 --- a/common/credentials-interface/src/lib.rs +++ b/common/credentials-interface/src/lib.rs @@ -34,7 +34,7 @@ use nym_ecash_time::{ecash_today, EcashTime}; use tsify::Tsify; #[cfg(feature = "wasm-serde-types")] -use wasm_bindgen::{prelude::wasm_bindgen}; +use wasm_bindgen::prelude::wasm_bindgen; #[derive(Debug, Clone)] pub struct CredentialSigningData { diff --git a/wasm/zk-nym-lib/src/credential.rs b/wasm/zk-nym-lib/src/credential.rs index 9c7f1613b22..566bb968a68 100644 --- a/wasm/zk-nym-lib/src/credential.rs +++ b/wasm/zk-nym-lib/src/credential.rs @@ -1,14 +1,15 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::bandwidth::BandwidthAcquireClient; use crate::error::WasmCredentialClientError; use crate::opts::CredentialClientOpts; use js_sys::Promise; use nym_credential_storage::ephemeral_storage::EphemeralCredentialStorage; use nym_credential_storage::storage::Storage; +use nym_credentials::ecash::bandwidth::serialiser::VersionedSerialise; use nym_credentials_interface::TicketType; use nym_network_defaults::NymNetworkDetails; -use crate::bandwidth::BandwidthAcquireClient; use nym_validator_client::nyxd::CosmWasmCoin; use serde::{Deserialize, Serialize}; use tsify::Tsify; @@ -16,7 +17,6 @@ use wasm_bindgen::prelude::*; use wasm_bindgen_futures::future_to_promise; use wasm_utils::error::PromisableResult; use zeroize::{Zeroize, ZeroizeOnDrop}; -use nym_credentials::ecash::bandwidth::serialiser::VersionedSerialise; #[wasm_bindgen(js_name = acquireCredential)] pub fn acquire_credential( @@ -122,7 +122,10 @@ async fn acquire_credential_async( // .await?; // - match ephemeral_storage.get_next_unspent_usable_ticketbook(1u32).await? { + match ephemeral_storage + .get_next_unspent_usable_ticketbook(1u32) + .await? + { Some(ticket_book) => { let serialized = ticket_book.ticketbook.pack(); @@ -131,7 +134,7 @@ async fn acquire_credential_async( credential_data: serialized.data, ticketbook_type: format!("{}", ticketbook_type), }) - }, + } None => Err(WasmCredentialClientError::TicketbookCredentialStoreIsNone), } } diff --git a/wasm/zk-nym-lib/src/helpers.rs b/wasm/zk-nym-lib/src/helpers.rs index f562d589ca6..7f8b2a077de 100644 --- a/wasm/zk-nym-lib/src/helpers.rs +++ b/wasm/zk-nym-lib/src/helpers.rs @@ -1,15 +1,7 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::error::WasmCredentialClientError; use nym_network_defaults::{NymContracts, NymNetworkDetails, ValidatorDetails}; -use zeroize::Zeroizing; - -pub(crate) fn parse_mnemonic(raw: String) -> Result { - // make sure that whatever happens, the raw value gets zeroized - let wrapped = Zeroizing::new(raw); - Ok(bip39::Mnemonic::parse(&*wrapped)?) -} pub(crate) fn minimal_coconut_sandbox() -> NymNetworkDetails { // we can piggyback on mainnet defaults for certain things, diff --git a/wasm/zk-nym-lib/src/lib.rs b/wasm/zk-nym-lib/src/lib.rs index a7f29509526..8ffb70b0d97 100644 --- a/wasm/zk-nym-lib/src/lib.rs +++ b/wasm/zk-nym-lib/src/lib.rs @@ -1,6 +1,8 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +#[cfg(target_arch = "wasm32")] +mod bandwidth; #[cfg(target_arch = "wasm32")] mod credential; #[cfg(target_arch = "wasm32")] @@ -9,8 +11,6 @@ mod error; mod helpers; #[cfg(target_arch = "wasm32")] mod opts; -#[cfg(target_arch = "wasm32")] -mod bandwidth; #[cfg(target_arch = "wasm32")] use wasm_bindgen::prelude::*;