From bd1d88e9e847108edc6efa8f3da86f20eb6cea48 Mon Sep 17 00:00:00 2001 From: fmtabbara Date: Wed, 7 Dec 2022 10:40:43 +0000 Subject: [PATCH 01/39] fix display mnemonic bug --- nym-wallet/src/components/textfields.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/nym-wallet/src/components/textfields.tsx b/nym-wallet/src/components/textfields.tsx index 085ede1ab3..1b0224c134 100644 --- a/nym-wallet/src/components/textfields.tsx +++ b/nym-wallet/src/components/textfields.tsx @@ -10,17 +10,17 @@ export const MnemonicInput: React.FC<{ error?: string; onUpdateMnemonic: (mnemonic: string) => void; }> = ({ mnemonic, error, onUpdateMnemonic }) => { - const [showPassword, setShowPassword] = useState(false); + const [showMnemonic, setShowMnemonic] = useState(false); return ( onUpdateMnemonic(e.target.value)} - multiline autoFocus fullWidth + multiline={showMnemonic} inputProps={{ style: { height: '160px', @@ -34,7 +34,7 @@ export const MnemonicInput: React.FC<{ }} /> setShowPassword((show) => !show)} />} + control={ setShowMnemonic((show) => !show)} />} label="Reveal my mnemonic" /> {error && } From ec60966a850043bd8a454ad4751667c616bb2198 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Thu, 8 Dec 2022 19:39:11 +0100 Subject: [PATCH 02/39] Clients: save init results to JSON (#1865) * clients: output results of init to json * Remove leftover dbg * Tidy * Fix nym-connect --- Cargo.lock | 5 ++- clients/client-core/src/init.rs | 45 +++++++++++++++++++-- clients/native/Cargo.toml | 3 +- clients/native/src/commands/init.rs | 52 +++++++++++++++++++++++- clients/socks5/Cargo.toml | 3 +- clients/socks5/src/commands/init.rs | 54 +++++++++++++++++++++++-- nym-connect/Cargo.lock | 5 ++- nym-connect/src-tauri/src/config/mod.rs | 3 +- 8 files changed, 154 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9d687961cb..9a7618ad3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3372,6 +3372,7 @@ dependencies = [ "proxy-helpers", "rand 0.7.3", "serde", + "serde_json", "snafu 0.6.10", "socks5-requests", "tap", @@ -5005,9 +5006,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.83" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7" +checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" dependencies = [ "itoa 1.0.1", "ryu", diff --git a/clients/client-core/src/init.rs b/clients/client-core/src/init.rs index 44c20a7597..5cbd4bfcc6 100644 --- a/clients/client-core/src/init.rs +++ b/clients/client-core/src/init.rs @@ -3,7 +3,7 @@ //! Collection of initialization steps used by client implementations -use std::{sync::Arc, time::Duration}; +use std::{fmt::Display, sync::Arc, time::Duration}; use config::NymConfig; use crypto::asymmetric::{encryption, identity}; @@ -14,6 +14,7 @@ use nymsphinx::addressing::nodes::NodeIdentity; use rand::rngs::OsRng; use rand::seq::SliceRandom; use rand::thread_rng; +use serde::Serialize; use tap::TapFallible; use topology::{filter::VersionFilterable, gateway}; use url::Url; @@ -24,6 +25,43 @@ use crate::{ error::ClientCoreError, }; +#[derive(Debug, Serialize)] +pub struct InitResults { + version: String, + id: String, + identity_key: String, + encryption_key: String, + gateway_id: String, + gateway_listener: String, +} + +impl InitResults { + pub fn new(config: &Config, address: &Recipient) -> Self + where + T: NymConfig, + { + Self { + version: config.get_version().to_string(), + id: config.get_id(), + identity_key: address.identity().to_base58_string(), + encryption_key: address.encryption_key().to_base58_string(), + gateway_id: config.get_gateway_id(), + gateway_listener: config.get_gateway_listener(), + } + } +} + +impl Display for InitResults { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + writeln!(f, "Version: {}", self.version)?; + writeln!(f, "ID: {}", self.id)?; + writeln!(f, "Identity key: {}", self.identity_key)?; + writeln!(f, "Encryption: {}", self.encryption_key)?; + writeln!(f, "Gateway ID: {}", self.gateway_id)?; + write!(f, "Gateway: {}", self.gateway_listener) + } +} + pub async fn query_gateway_details( validator_servers: Vec, chosen_gateway_id: Option<&str>, @@ -102,7 +140,7 @@ async fn register_with_gateway( Ok(shared_keys) } -pub fn show_address(config: &Config) -> Result<(), ClientCoreError> +pub fn get_client_address(config: &Config) -> Result where T: config::NymConfig, { @@ -142,6 +180,5 @@ where NodeIdentity::from_base58_string(config.get_gateway_id())?, ); - println!("\nThe address of this client is: {}", client_recipient); - Ok(()) + Ok(client_recipient) } diff --git a/clients/native/Cargo.toml b/clients/native/Cargo.toml index 0a8ad9f29f..1b19bf32ad 100644 --- a/clients/native/Cargo.toml +++ b/clients/native/Cargo.toml @@ -26,7 +26,9 @@ log = "0.4" # self explanatory pretty_env_logger = "0.4" # for formatting log messages rand = { version = "0.7.3", features = ["wasm-bindgen"] } # rng-related traits + some rng implementation to use serde = { version = "1.0.104", features = ["derive"] } # for config serialization/deserialization +serde_json = "1.0" sled = "0.34" # for storage of replySURB decryption keys +tap = "1.0.1" thiserror = "1.0.34" tokio = { version = "1.21.2", features = ["rt-multi-thread", "net", "signal"] } # async runtime tokio-tungstenite = "0.14" # websocket @@ -51,7 +53,6 @@ topology = { path = "../../common/topology" } validator-client = { path = "../../common/client-libs/validator-client", features = ["nymd-client"] } version-checker = { path = "../../common/version-checker" } websocket-requests = { path = "websocket-requests" } -tap = "1.0.1" [features] coconut = ["coconut-interface", "credentials", "credentials/coconut", "gateway-requests/coconut", "gateway-client/coconut", "client-core/coconut"] diff --git a/clients/native/src/commands/init.rs b/clients/native/src/commands/init.rs index dfcd98bab2..f30c5c1fe3 100644 --- a/clients/native/src/commands/init.rs +++ b/clients/native/src/commands/init.rs @@ -1,9 +1,13 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use std::fmt::Display; + use clap::Args; use client_core::{config::GatewayEndpointConfig, error::ClientCoreError}; use config::NymConfig; +use nymsphinx::addressing::clients::Recipient; +use serde::Serialize; use crate::{ client::config::Config, @@ -55,6 +59,10 @@ pub(crate) struct Init { #[cfg(feature = "coconut")] #[clap(long)] enabled_credentials_mode: bool, + + /// Save a summary of the initialization to a json file + #[clap(long)] + output_json: bool, } impl From for OverrideConfig { @@ -73,6 +81,29 @@ impl From for OverrideConfig { } } +#[derive(Debug, Serialize)] +pub struct InitResults { + #[serde(flatten)] + client_core: client_core::init::InitResults, + client_listening_port: String, +} + +impl InitResults { + pub fn new(config: &Config, address: &Recipient) -> Self { + Self { + client_core: client_core::init::InitResults::new(config.get_base(), address), + client_listening_port: config.get_listening_port().to_string(), + } + } +} + +impl Display for InitResults { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + writeln!(f, "{}", self.client_core)?; + write!(f, "Client listening port: {}", self.client_listening_port) + } +} + pub(crate) async fn execute(args: &Init) { println!("Initialising client..."); @@ -126,10 +157,27 @@ pub(crate) async fn execute(args: &Init) { ); println!("Client configuration completed."); - client_core::init::show_address(config.get_base()).unwrap_or_else(|err| { - eprintln!("Failed to show address\nError: {err}"); + let address = client_core::init::get_client_address(config.get_base()).unwrap_or_else(|err| { + eprintln!("Failed to get address\nError: {err}"); std::process::exit(1) }); + + println!("\nThe address of this client is: {}\n", address); + + let init_results = InitResults::new(&config, &address); + println!("{}", init_results); + + // Output summary to a json file, if specified + if args.output_json { + let output_file = "client_init_results.json"; + match std::fs::File::create(output_file) { + Ok(file) => match serde_json::to_writer_pretty(file, &init_results) { + Ok(_) => println!("Saved: {}", output_file), + Err(err) => eprintln!("Could not save {}: {}", output_file, err), + }, + Err(err) => eprintln!("Could not save {}: {}", output_file, err), + } + } } async fn setup_gateway( diff --git a/clients/socks5/Cargo.toml b/clients/socks5/Cargo.toml index cd00e23262..de5ecf33ee 100644 --- a/clients/socks5/Cargo.toml +++ b/clients/socks5/Cargo.toml @@ -19,7 +19,9 @@ pin-project = "1.0" pretty_env_logger = "0.4" rand = { version = "0.7.3", features = ["wasm-bindgen"] } serde = { version = "1.0", features = ["derive"] } # for config serialization/deserialization +serde_json = "1.0.89" snafu = "0.6" +tap = "1.0.1" thiserror = "1.0.34" tokio = { version = "1.21.2", features = ["rt-multi-thread", "net", "signal"] } url = "2.2" @@ -46,7 +48,6 @@ task = { path = "../../common/task" } topology = { path = "../../common/topology" } validator-client = { path = "../../common/client-libs/validator-client", features = ["nymd-client"] } version-checker = { path = "../../common/version-checker" } -tap = "1.0.1" [features] coconut = ["coconut-interface", "credentials", "gateway-requests/coconut", "gateway-client/coconut", "credentials/coconut", "client-core/coconut"] diff --git a/clients/socks5/src/commands/init.rs b/clients/socks5/src/commands/init.rs index a727d0d8e9..c0d46480f3 100644 --- a/clients/socks5/src/commands/init.rs +++ b/clients/socks5/src/commands/init.rs @@ -1,9 +1,13 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use std::fmt::Display; + use clap::Args; use client_core::{config::GatewayEndpointConfig, error::ClientCoreError}; use config::NymConfig; +use nymsphinx::addressing::clients::Recipient; +use serde::Serialize; use crate::{ client::config::Config, @@ -55,6 +59,10 @@ pub(crate) struct Init { #[cfg(feature = "coconut")] #[clap(long)] enabled_credentials_mode: bool, + + /// Save a summary of the initialization to a json file + #[clap(long)] + output_json: bool, } impl From for OverrideConfig { @@ -71,6 +79,29 @@ impl From for OverrideConfig { } } +#[derive(Debug, Serialize)] +pub struct InitResults { + #[serde(flatten)] + client_core: client_core::init::InitResults, + socks5_listening_port: String, +} + +impl InitResults { + pub fn new(config: &Config, address: &Recipient) -> Self { + Self { + client_core: client_core::init::InitResults::new(config.get_base(), address), + socks5_listening_port: config.get_listening_port().to_string(), + } + } +} + +impl Display for InitResults { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + writeln!(f, "{}", self.client_core)?; + write!(f, "SOCKS5 listening port: {}", self.socks5_listening_port) + } +} + pub(crate) async fn execute(args: &Init) { println!("Initialising client..."); @@ -123,12 +154,29 @@ pub(crate) async fn execute(args: &Init) { "Gateway listener: {}", config.get_base().get_gateway_listener() ); - println!("Client configuration completed."); + println!("Client configuration completed.\n"); - client_core::init::show_address(config.get_base()).unwrap_or_else(|err| { - eprintln!("Failed to show address\nError: {err}"); + let address = client_core::init::get_client_address(config.get_base()).unwrap_or_else(|err| { + eprintln!("Failed to get address\nError: {err}"); std::process::exit(1) }); + + let init_results = InitResults::new(&config, &address); + println!("{}", init_results); + + // Output summary to a json file, if specified + if args.output_json { + let output_file = "socks5_client_init_results.json"; + match std::fs::File::create(output_file) { + Ok(file) => match serde_json::to_writer_pretty(file, &init_results) { + Ok(_) => println!("Saved: {}", output_file), + Err(err) => eprintln!("Could not save {}: {}", output_file, err), + }, + Err(err) => eprintln!("Could not save {}: {}", output_file, err), + } + } + + println!("\nThe address of this client is: {}\n", address); } async fn setup_gateway( diff --git a/nym-connect/Cargo.lock b/nym-connect/Cargo.lock index ae06ce7609..dea013dc0c 100644 --- a/nym-connect/Cargo.lock +++ b/nym-connect/Cargo.lock @@ -3376,6 +3376,7 @@ dependencies = [ "proxy-helpers", "rand 0.7.3", "serde", + "serde_json", "snafu", "socks5-requests", "tap", @@ -4818,9 +4819,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.85" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" +checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" dependencies = [ "itoa 1.0.3", "ryu", diff --git a/nym-connect/src-tauri/src/config/mod.rs b/nym-connect/src-tauri/src/config/mod.rs index e9a46b26a1..91adefbc53 100644 --- a/nym-connect/src-tauri/src/config/mod.rs +++ b/nym-connect/src-tauri/src/config/mod.rs @@ -159,7 +159,8 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str ); log::info!("Client configuration completed."); - client_core::init::show_address(config.get_base())?; + let address = client_core::init::get_client_address(config.get_base())?; + println!("\nThe address of this client is: {}\n", address); Ok(()) } From 85515fe16eb81eeb739023bcd586ab259c08344d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Thu, 8 Dec 2022 22:59:11 +0100 Subject: [PATCH 03/39] Client: dedup setup gateway during init (#1871) * clients: dedup gateway setup logic * nym-connect: extract out print_save_config --- clients/client-core/src/error.rs | 2 + clients/client-core/src/init.rs | 37 +++++++++++- clients/native/src/commands/init.rs | 67 ++++++--------------- clients/socks5/src/commands/init.rs | 66 ++++++--------------- nym-connect/src-tauri/src/config/mod.rs | 78 +++++-------------------- 5 files changed, 91 insertions(+), 159 deletions(-) diff --git a/clients/client-core/src/error.rs b/clients/client-core/src/error.rs index e173a987fc..f81a7536e8 100644 --- a/clients/client-core/src/error.rs +++ b/clients/client-core/src/error.rs @@ -26,6 +26,8 @@ pub enum ClientCoreError { NoGatewayWithId(String), #[error("No gateways on network")] NoGatewaysOnNetwork, + #[error("Failed to setup gateway")] + FailedToSetupGateway, #[error("List of validator apis is empty")] ListOfValidatorApisIsEmpty, #[error("Could not load existing gateway configuration: {0}")] diff --git a/clients/client-core/src/init.rs b/clients/client-core/src/init.rs index 5cbd4bfcc6..9964b6f60a 100644 --- a/clients/client-core/src/init.rs +++ b/clients/client-core/src/init.rs @@ -21,7 +21,7 @@ use url::Url; use crate::{ client::key_manager::KeyManager, - config::{persistence::key_pathfinder::ClientKeyPathfinder, Config}, + config::{persistence::key_pathfinder::ClientKeyPathfinder, Config, GatewayEndpointConfig}, error::ClientCoreError, }; @@ -140,6 +140,41 @@ async fn register_with_gateway( Ok(shared_keys) } +pub async fn setup_gateway( + register: bool, + user_chosen_gateway_id: Option<&str>, + config: &Config, +) -> Result { + if register { + // Get the gateway details by querying the validator-api. Either pick one at random or use + // the chosen one if it's among the available ones. + println!("Configuring gateway"); + let gateway = + query_gateway_details(config.get_validator_api_endpoints(), user_chosen_gateway_id) + .await?; + log::debug!("Querying gateway gives: {}", gateway); + + // Registering with gateway by setting up and writing shared keys to disk + log::trace!("Registering gateway"); + register_with_gateway_and_store_keys(gateway.clone(), config).await?; + println!("Saved all generated keys"); + + Ok(gateway.into()) + } else if user_chosen_gateway_id.is_some() { + // Just set the config, don't register or create any keys + // This assumes that the user knows what they are doing, and that the existing keys are + // valid for the gateway being used + println!("Using gateway provided by user, keeping existing keys"); + let gateway = + query_gateway_details(config.get_validator_api_endpoints(), user_chosen_gateway_id) + .await?; + log::debug!("Querying gateway gives: {}", gateway); + Ok(gateway.into()) + } else { + Err(ClientCoreError::FailedToSetupGateway) + } +} + pub fn get_client_address(config: &Config) -> Result where T: config::NymConfig, diff --git a/clients/native/src/commands/init.rs b/clients/native/src/commands/init.rs index f30c5c1fe3..56a9cc1da1 100644 --- a/clients/native/src/commands/init.rs +++ b/clients/native/src/commands/init.rs @@ -134,12 +134,20 @@ pub(crate) async fn execute(args: &Init) { let override_config_fields = OverrideConfig::from(args.clone()); config = override_config(config, override_config_fields); - let gateway = setup_gateway(id, register_gateway, user_chosen_gateway_id, &config) + let gateway = if !register_gateway && user_chosen_gateway_id.is_none() { + reuse_gateway_config(id) + } else { + client_core::init::setup_gateway( + register_gateway, + user_chosen_gateway_id, + config.get_base(), + ) .await - .unwrap_or_else(|err| { - eprintln!("Failed to setup gateway\nError: {err}"); - std::process::exit(1) - }); + } + .unwrap_or_else(|err| { + eprintln!("Failed to setup gateway\nError: {err}"); + std::process::exit(1) + }); config.get_base_mut().with_gateway_endpoint(gateway); let config_save_location = config.get_config_file_save_location(); @@ -180,45 +188,11 @@ pub(crate) async fn execute(args: &Init) { } } -async fn setup_gateway( - id: &str, - register: bool, - user_chosen_gateway_id: Option<&str>, - config: &Config, -) -> Result { - if register { - // Get the gateway details by querying the validator-api. Either pick one at random or use - // the chosen one if it's among the available ones. - println!("Configuring gateway"); - let gateway = client_core::init::query_gateway_details( - config.get_base().get_validator_api_endpoints(), - user_chosen_gateway_id, - ) - .await?; - log::debug!("Querying gateway gives: {}", gateway); - - // Registering with gateway by setting up and writing shared keys to disk - log::trace!("Registering gateway"); - client_core::init::register_with_gateway_and_store_keys(gateway.clone(), config.get_base()) - .await?; - println!("Saved all generated keys"); - - Ok(gateway.into()) - } else if user_chosen_gateway_id.is_some() { - // Just set the config, don't register or create any keys - // This assumes that the user knows what they are doing, and that the existing keys are - // valid for the gateway being used - println!("Using gateway provided by user, keeping existing keys"); - let gateway = client_core::init::query_gateway_details( - config.get_base().get_validator_api_endpoints(), - user_chosen_gateway_id, - ) - .await?; - log::debug!("Querying gateway gives: {}", gateway); - Ok(gateway.into()) - } else { - println!("Not registering gateway, will reuse existing config and keys"); - let existing_config = Config::load_from_file(Some(id)).map_err(|err| { +fn reuse_gateway_config(id: &str) -> Result { + println!("Not registering gateway, will reuse existing config and keys"); + Config::load_from_file(Some(id)) + .map(|existing_config| existing_config.get_base().get_gateway_endpoint().clone()) + .map_err(|err| { log::error!( "Unable to configure gateway: {err}. \n Seems like the client was already initialized but it was not possible to read \ @@ -227,8 +201,5 @@ async fn setup_gateway( removing the existing configuration and starting over." ); ClientCoreError::CouldNotLoadExistingGatewayConfiguration(err) - })?; - - Ok(existing_config.get_base().get_gateway_endpoint().clone()) - } + }) } diff --git a/clients/socks5/src/commands/init.rs b/clients/socks5/src/commands/init.rs index c0d46480f3..a71852913d 100644 --- a/clients/socks5/src/commands/init.rs +++ b/clients/socks5/src/commands/init.rs @@ -133,12 +133,20 @@ pub(crate) async fn execute(args: &Init) { let override_config_fields = OverrideConfig::from(args.clone()); config = override_config(config, override_config_fields); - let gateway = setup_gateway(id, register_gateway, user_chosen_gateway_id, &config) + let gateway = if !register_gateway && user_chosen_gateway_id.is_none() { + reuse_gateway_config(id) + } else { + client_core::init::setup_gateway( + register_gateway, + user_chosen_gateway_id, + config.get_base(), + ) .await - .unwrap_or_else(|err| { - eprintln!("Failed to setup gateway\nError: {err}"); - std::process::exit(1) - }); + } + .unwrap_or_else(|err| { + eprintln!("Failed to setup gateway\nError: {err}"); + std::process::exit(1) + }); config.get_base_mut().with_gateway_endpoint(gateway); let config_save_location = config.get_config_file_save_location(); @@ -179,45 +187,11 @@ pub(crate) async fn execute(args: &Init) { println!("\nThe address of this client is: {}\n", address); } -async fn setup_gateway( - id: &str, - register: bool, - user_chosen_gateway_id: Option<&str>, - config: &Config, -) -> Result { - if register { - // Get the gateway details by querying the validator-api. Either pick one at random or use - // the chosen one if it's among the available ones. - println!("Configuring gateway"); - let gateway = client_core::init::query_gateway_details( - config.get_base().get_validator_api_endpoints(), - user_chosen_gateway_id, - ) - .await?; - log::debug!("Querying gateway gives: {}", gateway); - - // Registering with gateway by setting up and writing shared keys to disk - log::trace!("Registering gateway"); - client_core::init::register_with_gateway_and_store_keys(gateway.clone(), config.get_base()) - .await?; - println!("Saved all generated keys"); - - Ok(gateway.into()) - } else if user_chosen_gateway_id.is_some() { - // Just set the config, don't register or create any keys - // This assumes that the user knows what they are doing, and that the existing keys are - // valid for the gateway being used - println!("Using gateway provided by user, keeping existing keys"); - let gateway = client_core::init::query_gateway_details( - config.get_base().get_validator_api_endpoints(), - user_chosen_gateway_id, - ) - .await?; - log::debug!("Querying gateway gives: {}", gateway); - Ok(gateway.into()) - } else { - println!("Not registering gateway, will reuse existing config and keys"); - let existing_config = Config::load_from_file(Some(id)).map_err(|err| { +fn reuse_gateway_config(id: &str) -> Result { + println!("Not registering gateway, will reuse existing config and keys"); + Config::load_from_file(Some(id)) + .map(|existing_config| existing_config.get_base().get_gateway_endpoint().clone()) + .map_err(|err| { log::error!( "Unable to configure gateway: {err}. \n Seems like the client was already initialized but it was not possible to read \ @@ -226,7 +200,5 @@ async fn setup_gateway( removing the existing configuration and starting over." ); ClientCoreError::CouldNotLoadExistingGatewayConfiguration(err) - })?; - Ok(existing_config.get_base().get_gateway_endpoint().clone()) - } + }) } diff --git a/nym-connect/src-tauri/src/config/mod.rs b/nym-connect/src-tauri/src/config/mod.rs index 91adefbc53..3a851cdba5 100644 --- a/nym-connect/src-tauri/src/config/mod.rs +++ b/nym-connect/src-tauri/src/config/mod.rs @@ -1,6 +1,5 @@ use std::path::PathBuf; -use client_core::config::GatewayEndpointConfig; use std::sync::Arc; use tap::TapFallible; use tokio::sync::RwLock; @@ -127,21 +126,31 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str .set_custom_validator_apis(config_common::parse_validators(&raw_validators)); } - let gateway = setup_gateway( - &id, + let gateway = client_core::init::setup_gateway( register_gateway, Some(&chosen_gateway_id), - config.get_socks5(), + config.get_base(), ) .await?; + config.get_base_mut().with_gateway_endpoint(gateway); - let config_save_location = config.get_socks5().get_config_file_save_location(); config.get_socks5().save_to_file(None).tap_err(|_| { log::error!("Failed to save the config file"); })?; - log::info!("Saved configuration file to {:?}", config_save_location); + print_save_config(&config); + + let address = client_core::init::get_client_address(config.get_base())?; + log::info!("The address of this client is: {}", address); + Ok(()) +} + +fn print_save_config(config: &Config) { + log::info!( + "Saved configuration file to {:?}", + config.get_socks5().get_config_file_save_location() + ); log::info!("Gateway id: {}", config.get_base().get_gateway_id()); log::info!("Gateway owner: {}", config.get_base().get_gateway_owner()); log::info!( @@ -158,61 +167,4 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str config.get_socks5().get_listening_port() ); log::info!("Client configuration completed."); - - let address = client_core::init::get_client_address(config.get_base())?; - println!("\nThe address of this client is: {}\n", address); - Ok(()) -} - -// TODO: deduplicate with same functions in other client -async fn setup_gateway( - id: &str, - register: bool, - user_chosen_gateway_id: Option<&str>, - config: &Socks5Config, -) -> Result { - if register { - // Get the gateway details by querying the validator-api. Either pick one at random or use - // the chosen one if it's among the available ones. - println!("Configuring gateway"); - let gateway = client_core::init::query_gateway_details( - config.get_base().get_validator_api_endpoints(), - user_chosen_gateway_id, - ) - .await?; - log::debug!("Querying gateway gives: {}", gateway); - - // Registering with gateway by setting up and writing shared keys to disk - log::trace!("Registering gateway"); - client_core::init::register_with_gateway_and_store_keys(gateway.clone(), config.get_base()) - .await?; - println!("Saved all generated keys"); - - Ok(gateway.into()) - } else if user_chosen_gateway_id.is_some() { - // Just set the config, don't register or create any keys - // This assumes that the user knows what they are doing, and that the existing keys are - // valid for the gateway being used - println!("Using gateway provided by user, keeping existing keys"); - let gateway = client_core::init::query_gateway_details( - config.get_base().get_validator_api_endpoints(), - user_chosen_gateway_id, - ) - .await?; - log::debug!("Querying gateway gives: {}", gateway); - Ok(gateway.into()) - } else { - println!("Not registering gateway, will reuse existing config and keys"); - let existing_config = Socks5Config::load_from_file(Some(id)).map_err(|err| { - log::error!( - "Unable to configure gateway: {err}. \n - Seems like the client was already initialized but it was not possible to read \ - the existing configuration file. \n - CAUTION: Consider backing up your gateway keys and try force gateway registration, or \ - removing the existing configuration and starting over." - ); - BackendError::CouldNotLoadExistingGatewayConfiguration(err) - })?; - Ok(existing_config.get_base().get_gateway_endpoint().clone()) - } } From c534c4b91db260b002a7a77cc0c18b55dc622063 Mon Sep 17 00:00:00 2001 From: fmtabbara Date: Fri, 9 Dec 2022 10:28:49 +0000 Subject: [PATCH 04/39] remove fixed height for mnemonic input --- nym-wallet/src/components/textfields.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/nym-wallet/src/components/textfields.tsx b/nym-wallet/src/components/textfields.tsx index 1b0224c134..afcbcfedb7 100644 --- a/nym-wallet/src/components/textfields.tsx +++ b/nym-wallet/src/components/textfields.tsx @@ -21,11 +21,6 @@ export const MnemonicInput: React.FC<{ autoFocus fullWidth multiline={showMnemonic} - inputProps={{ - style: { - height: '160px', - }, - }} InputLabelProps={{ shrink: true }} sx={{ 'input::-webkit-textfield-decoration-container': { From ebaf99fadb07d863a5d4cdf2e26dcee07d715a87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C5=9Fu?= Date: Fri, 9 Dec 2022 13:00:27 +0200 Subject: [PATCH 05/39] Feature/dkg state to disk (#1872) * Add PersistentState * Save and load state to/from disk * If in progress, don't continually write the same state * Fix tests and add serde one * Update changelog * Fix clippy --- CHANGELOG.md | 8 ++ common/crypto/dkg/src/bte/keys.rs | 2 +- .../crypto/dkg/src/bte/proof_discrete_log.rs | 2 +- common/crypto/dkg/src/dealing.rs | 73 +++++++++- validator-api/src/coconut/dkg/complaints.rs | 4 +- validator-api/src/coconut/dkg/controller.rs | 19 ++- validator-api/src/coconut/dkg/dealing.rs | 6 + validator-api/src/coconut/dkg/public_key.rs | 4 + validator-api/src/coconut/dkg/state.rs | 135 +++++++++++++++--- .../src/coconut/dkg/verification_key.rs | 4 + validator-api/src/coconut/error.rs | 3 + validator-api/src/config/mod.rs | 16 +++ 12 files changed, 247 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a2888c43c..c2926410d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Changed + +- validator-api: can recover from shutdown during DKG process ([#1872]) + +[#1872]: https://github.com/nymtech/nym/pull/1872 + ## [v1.1.2] ### Changed diff --git a/common/crypto/dkg/src/bte/keys.rs b/common/crypto/dkg/src/bte/keys.rs index 9412790db8..098e9638c7 100644 --- a/common/crypto/dkg/src/bte/keys.rs +++ b/common/crypto/dkg/src/bte/keys.rs @@ -53,7 +53,7 @@ impl PublicKey { } } -#[derive(Debug)] +#[derive(Clone, Debug)] #[cfg_attr(test, derive(PartialEq, Eq))] pub struct PublicKeyWithProof { pub(crate) key: PublicKey, diff --git a/common/crypto/dkg/src/bte/proof_discrete_log.rs b/common/crypto/dkg/src/bte/proof_discrete_log.rs index 5dbdbba702..489eb13244 100644 --- a/common/crypto/dkg/src/bte/proof_discrete_log.rs +++ b/common/crypto/dkg/src/bte/proof_discrete_log.rs @@ -13,7 +13,7 @@ use zeroize::Zeroize; const DISCRETE_LOG_DOMAIN: &[u8] = b"NYM_COCONUT_NIDKG_V01_CS01_WITH_BLS12381_XMD:SHA-256_SSWU_RO_PROOF_DISCRETE_LOG"; -#[derive(Debug)] +#[derive(Clone, Debug)] #[cfg_attr(test, derive(PartialEq, Eq))] pub struct ProofOfDiscreteLog { pub(crate) rand_commitment: G1Projective, diff --git a/common/crypto/dkg/src/dealing.rs b/common/crypto/dkg/src/dealing.rs index 817bffdf12..b3633ec82d 100644 --- a/common/crypto/dkg/src/dealing.rs +++ b/common/crypto/dkg/src/dealing.rs @@ -9,19 +9,79 @@ use crate::interpolation::polynomial::{Polynomial, PublicCoefficients}; use crate::interpolation::{ perform_lagrangian_interpolation_at_origin, perform_lagrangian_interpolation_at_x, }; +use crate::utils::deserialize_g2; use crate::{NodeIndex, Share, Threshold}; use bls12_381::{G2Projective, Scalar}; +use group::GroupEncoding; use rand_core::RngCore; use std::collections::BTreeMap; use zeroize::Zeroize; -#[derive(Debug)] +#[derive(Clone, Debug)] #[cfg_attr(test, derive(PartialEq, Eq))] pub struct RecoveredVerificationKeys { pub recovered_master: G2Projective, pub recovered_partials: Vec, } +impl RecoveredVerificationKeys { + pub fn to_bytes(&self) -> Vec { + let partials = self.recovered_partials.len(); + let mut bytes = Vec::with_capacity(96 + 4 + 96 * partials); + bytes.extend_from_slice(self.recovered_master.to_bytes().as_ref()); + bytes.extend_from_slice(&((partials as u32).to_be_bytes())); + for partial in &self.recovered_partials { + bytes.extend_from_slice(partial.to_bytes().as_ref()); + } + + bytes + } + + pub fn try_from_bytes(b: &[u8]) -> Result { + if b.len() < 96 + 4 { + return Err(DkgError::new_deserialization_failure( + "RecoveredVerificationKeys", + "insufficient number of bytes provided", + )); + } + + let recovered_master = deserialize_g2(&b[..96]).ok_or_else(|| { + DkgError::new_deserialization_failure( + "RecoveredVerificationKeys.recovered_master", + "invalid curve point", + ) + })?; + + let partials = u32::from_be_bytes([b[96], b[97], b[98], b[99]]) as usize; + let mut recovered_partials = Vec::with_capacity(partials); + + if b.len() != 96 + 4 + 96 * partials { + return Err(DkgError::new_deserialization_failure( + "RecoveredVerificationKeys", + "insufficient number of bytes provided", + )); + } + + let mut i = 96 + 4; + for _ in 0..partials { + let partial = deserialize_g2(&b[i..i + 96]).ok_or_else(|| { + DkgError::new_deserialization_failure( + "RecoveredVerificationKeys.recovered_partials", + "invalid curve point", + ) + })?; + + recovered_partials.push(partial); + i += 96; + } + + Ok(RecoveredVerificationKeys { + recovered_master, + recovered_partials, + }) + } +} + #[derive(Debug)] #[cfg_attr(test, derive(PartialEq, Eq))] pub struct Dealing { @@ -355,6 +415,17 @@ mod tests { use crate::combine_shares; use rand_core::SeedableRng; + #[test] + fn recovered_verification_keys_serde() { + let keys = RecoveredVerificationKeys { + recovered_master: Default::default(), + recovered_partials: vec![Default::default(), Default::default()], + }; + let bytes = keys.to_bytes(); + let recovered_keys = RecoveredVerificationKeys::try_from_bytes(&bytes).unwrap(); + assert_eq!(keys, recovered_keys); + } + #[test] #[ignore] // expensive test fn recovering_partial_verification_keys() { diff --git a/validator-api/src/coconut/dkg/complaints.rs b/validator-api/src/coconut/dkg/complaints.rs index 0001e4f76d..4ef0d32ce0 100644 --- a/validator-api/src/coconut/dkg/complaints.rs +++ b/validator-api/src/coconut/dkg/complaints.rs @@ -1,7 +1,9 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -#[derive(Debug, Eq, PartialEq)] +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] pub(crate) enum ComplaintReason { MalformedBTEPublicKey, InvalidBTEPublicKey, diff --git a/validator-api/src/coconut/dkg/controller.rs b/validator-api/src/coconut/dkg/controller.rs index 0cd538793b..6a7268af47 100644 --- a/validator-api/src/coconut/dkg/controller.rs +++ b/validator-api/src/coconut/dkg/controller.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::coconut::dkg::client::DkgClient; -use crate::coconut::dkg::state::{ConsistentState, State}; +use crate::coconut::dkg::state::{ConsistentState, PersistentState, State}; use crate::coconut::dkg::verification_key::{ verification_key_finalization, verification_key_validation, }; @@ -63,12 +63,20 @@ impl DkgController { )) { coconut_keypair.set(coconut_keypair_value).await; } + let persistent_state = + PersistentState::load_from_file(config.persistent_state_path()).unwrap_or_default(); Ok(DkgController { dkg_client: DkgClient::new(nymd_client), secret_key_path: config.secret_key_path(), verification_key_path: config.verification_key_path(), - state: State::new(config.get_announce_address(), dkg_keypair, coconut_keypair), + state: State::new( + config.persistent_state_path(), + persistent_state, + config.get_announce_address(), + dkg_keypair, + coconut_keypair, + ), rng, polling_rate: config.get_dkg_contract_polling_rate(), }) @@ -114,6 +122,13 @@ impl DkgController { }; if let Err(e) = ret { warn!("Could not handle this iteration for the epoch state: {}", e); + } else if epoch_state != EpochState::InProgress { + let persistent_state = PersistentState::from(&self.state); + if let Err(e) = + persistent_state.save_to_file(self.state.persistent_state_path()) + { + warn!("Could not backup the state for this iteration: {}", e); + } } } } diff --git a/validator-api/src/coconut/dkg/dealing.rs b/validator-api/src/coconut/dkg/dealing.rs index b6ebed9853..7e53202dac 100644 --- a/validator-api/src/coconut/dkg/dealing.rs +++ b/validator-api/src/coconut/dkg/dealing.rs @@ -55,6 +55,7 @@ pub(crate) async fn dealing_exchange( pub(crate) mod tests { use super::*; use crate::coconut::dkg::complaints::ComplaintReason; + use crate::coconut::dkg::state::PersistentState; use crate::coconut::tests::DummyClient; use crate::coconut::KeyPair; use coconut_dkg_common::dealer::DealerDetails; @@ -63,6 +64,7 @@ pub(crate) mod tests { use dkg::bte::Params; use rand::rngs::OsRng; use std::collections::HashMap; + use std::path::PathBuf; use std::str::FromStr; use std::sync::{Arc, RwLock}; use url::Url; @@ -110,6 +112,8 @@ pub(crate) mod tests { ); let params = setup(); let mut state = State::new( + PathBuf::default(), + PersistentState::default(), Url::parse("localhost:8000").unwrap(), DkgKeyPair::new(¶ms, OsRng), KeyPair::new(), @@ -163,6 +167,8 @@ pub(crate) mod tests { ); let params = setup(); let mut state = State::new( + PathBuf::default(), + PersistentState::default(), Url::parse("localhost:8000").unwrap(), DkgKeyPair::new(¶ms, OsRng), KeyPair::new(), diff --git a/validator-api/src/coconut/dkg/public_key.rs b/validator-api/src/coconut/dkg/public_key.rs index 29a3e732f1..0ce3bd45b3 100644 --- a/validator-api/src/coconut/dkg/public_key.rs +++ b/validator-api/src/coconut/dkg/public_key.rs @@ -34,10 +34,12 @@ pub(crate) async fn public_key_submission( #[cfg(test)] pub(crate) mod tests { use super::*; + use crate::coconut::dkg::state::PersistentState; use crate::coconut::tests::DummyClient; use crate::coconut::KeyPair; use dkg::bte::keys::KeyPair as DkgKeyPair; use rand::rngs::OsRng; + use std::path::PathBuf; use std::str::FromStr; use url::Url; use validator_client::nymd::AccountId; @@ -51,6 +53,8 @@ pub(crate) mod tests { AccountId::from_str(TEST_VALIDATOR_ADDRESS).unwrap(), )); let mut state = State::new( + PathBuf::default(), + PersistentState::default(), Url::parse("localhost:8000").unwrap(), DkgKeyPair::new(&dkg::bte::setup(), OsRng), KeyPair::new(), diff --git a/validator-api/src/coconut/dkg/state.rs b/validator-api/src/coconut/dkg/state.rs index aebcdea495..b7d7796ca0 100644 --- a/validator-api/src/coconut/dkg/state.rs +++ b/validator-api/src/coconut/dkg/state.rs @@ -9,13 +9,33 @@ use coconut_dkg_common::types::EpochState; use cosmwasm_std::Addr; use dkg::bte::{keys::KeyPair as DkgKeyPair, PublicKey, PublicKeyWithProof}; use dkg::{NodeIndex, RecoveredVerificationKeys, Threshold}; +use serde::de::Error; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::collections::BTreeMap; +use std::path::PathBuf; use url::Url; +fn bte_pk_serialize( + val: &PublicKeyWithProof, + serializer: S, +) -> Result { + val.to_bytes().serialize(serializer) +} + +fn bte_pk_deserialize<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + let vec: Vec = Deserialize::deserialize(deserializer)?; + PublicKeyWithProof::try_from_bytes(&vec).map_err(|err| Error::custom(format_args!("{:?}", err))) +} + // note: each dealer is also a receiver which simplifies some logic significantly -#[derive(Debug)] +#[derive(Clone, Deserialize, Debug, Serialize)] pub(crate) struct DkgParticipant { pub(crate) _address: Addr, + #[serde(serialize_with = "bte_pk_serialize")] + #[serde(deserialize_with = "bte_pk_deserialize")] pub(crate) bte_public_key_with_proof: PublicKeyWithProof, pub(crate) assigned_index: NodeIndex, } @@ -71,20 +91,6 @@ pub(crate) trait ConsistentState { } } -pub(crate) struct State { - announce_address: Url, - dkg_keypair: DkgKeyPair, - coconut_keypair: CoconutKeyPair, - node_index: Option, - dealers: BTreeMap>, - receiver_index: Option, - threshold: Option, - recovered_vks: Vec, - proposal_id: Option, - voted_vks: bool, - executed_proposal: bool, -} - #[async_trait] impl ConsistentState for State { fn node_index_value(&self) -> Result { @@ -131,27 +137,110 @@ impl ConsistentState for State { } } +fn vks_serialize( + val: &[RecoveredVerificationKeys], + serializer: S, +) -> Result { + let vec: Vec> = val.iter().map(|vk| vk.to_bytes()).collect(); + vec.serialize(serializer) +} + +fn vks_deserialize<'de, D>(deserializer: D) -> Result, D::Error> +where + D: Deserializer<'de>, +{ + let vec: Vec> = Deserialize::deserialize(deserializer)?; + vec.into_iter() + .map(|b| { + RecoveredVerificationKeys::try_from_bytes(&b) + .map_err(|err| D::Error::custom(format_args!("{:?}", err))) + }) + .collect() +} + +#[derive(Default, Deserialize, Serialize)] +pub(crate) struct PersistentState { + node_index: Option, + dealers: BTreeMap>, + receiver_index: Option, + threshold: Option, + #[serde(serialize_with = "vks_serialize")] + #[serde(deserialize_with = "vks_deserialize")] + recovered_vks: Vec, + proposal_id: Option, + voted_vks: bool, + executed_proposal: bool, +} + +impl From<&State> for PersistentState { + fn from(s: &State) -> Self { + PersistentState { + node_index: s.node_index, + dealers: s.dealers.clone(), + receiver_index: s.receiver_index, + threshold: s.threshold, + recovered_vks: s.recovered_vks.clone(), + proposal_id: s.proposal_id, + voted_vks: s.voted_vks, + executed_proposal: s.executed_proposal, + } + } +} + +impl PersistentState { + pub fn save_to_file(&self, path: PathBuf) -> Result<(), CoconutError> { + std::fs::write(path, serde_json::to_string(self)?)?; + Ok(()) + } + + pub fn load_from_file(path: PathBuf) -> Result { + Ok(serde_json::from_str(&std::fs::read_to_string(path)?)?) + } +} + +pub(crate) struct State { + persistent_state_path: PathBuf, + announce_address: Url, + dkg_keypair: DkgKeyPair, + coconut_keypair: CoconutKeyPair, + node_index: Option, + dealers: BTreeMap>, + receiver_index: Option, + threshold: Option, + recovered_vks: Vec, + proposal_id: Option, + voted_vks: bool, + executed_proposal: bool, +} + impl State { pub fn new( + persistent_state_path: PathBuf, + persistent_state: PersistentState, announce_address: Url, dkg_keypair: DkgKeyPair, coconut_keypair: CoconutKeyPair, ) -> Self { State { + persistent_state_path, announce_address, dkg_keypair, coconut_keypair, - node_index: None, - dealers: BTreeMap::new(), - receiver_index: None, - threshold: None, - recovered_vks: vec![], - proposal_id: None, - voted_vks: false, - executed_proposal: false, + node_index: persistent_state.node_index, + dealers: persistent_state.dealers, + receiver_index: persistent_state.receiver_index, + threshold: persistent_state.threshold, + recovered_vks: persistent_state.recovered_vks, + proposal_id: persistent_state.proposal_id, + voted_vks: persistent_state.voted_vks, + executed_proposal: persistent_state.executed_proposal, } } + pub fn persistent_state_path(&self) -> PathBuf { + self.persistent_state_path.clone() + } + pub fn announce_address(&self) -> &Url { &self.announce_address } diff --git a/validator-api/src/coconut/dkg/verification_key.rs b/validator-api/src/coconut/dkg/verification_key.rs index 38ce4dd13c..cecd825154 100644 --- a/validator-api/src/coconut/dkg/verification_key.rs +++ b/validator-api/src/coconut/dkg/verification_key.rs @@ -249,6 +249,7 @@ pub(crate) mod tests { use super::*; use crate::coconut::dkg::dealing::dealing_exchange; use crate::coconut::dkg::public_key::public_key_submission; + use crate::coconut::dkg::state::PersistentState; use crate::coconut::tests::DummyClient; use crate::coconut::KeyPair; use coconut_dkg_common::dealer::DealerDetails; @@ -259,6 +260,7 @@ pub(crate) mod tests { use rand::Rng; use std::collections::HashMap; use std::env::temp_dir; + use std::path::PathBuf; use std::str::FromStr; use std::sync::{Arc, RwLock}; use url::Url; @@ -289,6 +291,8 @@ pub(crate) mod tests { ); let keypair = DkgKeyPair::new(¶ms, OsRng); let state = State::new( + PathBuf::default(), + PersistentState::default(), Url::parse("localhost:8000").unwrap(), keypair, KeyPair::new(), diff --git a/validator-api/src/coconut/error.rs b/validator-api/src/coconut/error.rs index 9b6fadf957..234d1cb96c 100644 --- a/validator-api/src/coconut/error.rs +++ b/validator-api/src/coconut/error.rs @@ -23,6 +23,9 @@ pub enum CoconutError { #[error("{0}")] IOError(#[from] std::io::Error), + #[error("{0}")] + SerdeJsonError(#[from] serde_json::Error), + #[error("Could not parse Ed25519 data")] Ed25519ParseError(#[from] Ed25519RecoveryError), diff --git a/validator-api/src/config/mod.rs b/validator-api/src/config/mod.rs index e08b3bb20a..715ed19311 100644 --- a/validator-api/src/config/mod.rs +++ b/validator-api/src/config/mod.rs @@ -282,6 +282,9 @@ pub struct CoconutSigner { /// Specifies whether rewarding service is enabled in this process. enabled: bool, + /// Path to a JSON file where state is persisted between different stages of DKG. + dkg_persistent_state_path: PathBuf, + /// Path to the coconut verification key. verification_key_path: PathBuf, @@ -299,6 +302,7 @@ pub struct CoconutSigner { } impl CoconutSigner { + pub const DKG_PERSISTENT_STATE_FILE: &'static str = "dkg_persistent_state.json"; pub const DKG_DECRYPTION_KEY_FILE: &'static str = "dkg_decryption_key.pem"; pub const DKG_PUBLIC_KEY_WITH_PROOF_FILE: &'static str = "dkg_public_key_with_proof.pem"; pub const COCONUT_VERIFICATION_KEY_FILE: &'static str = "coconut_verification_key.pem"; @@ -312,6 +316,10 @@ impl CoconutSigner { Config::default_data_directory(None).join(Self::COCONUT_SECRET_KEY_FILE) } + fn default_dkg_persistent_state_path() -> PathBuf { + Config::default_data_directory(None).join(Self::DKG_PERSISTENT_STATE_FILE) + } + fn default_dkg_decryption_key_path() -> PathBuf { Config::default_data_directory(None).join(Self::DKG_DECRYPTION_KEY_FILE) } @@ -325,6 +333,7 @@ impl Default for CoconutSigner { fn default() -> Self { Self { enabled: Default::default(), + dkg_persistent_state_path: CoconutSigner::default_dkg_persistent_state_path(), verification_key_path: CoconutSigner::default_coconut_verification_key_path(), secret_key_path: CoconutSigner::default_coconut_secret_key_path(), decryption_key_path: CoconutSigner::default_dkg_decryption_key_path(), @@ -345,6 +354,8 @@ impl Config { Config::default_data_directory(Some(id)).join(NodeStatusAPI::DB_FILE); self.network_monitor.credentials_database_path = Config::default_data_directory(Some(id)).join(NetworkMonitor::DB_FILE); + self.coconut_signer.dkg_persistent_state_path = + Config::default_data_directory(Some(id)).join(CoconutSigner::DKG_PERSISTENT_STATE_FILE); self.coconut_signer.verification_key_path = Config::default_data_directory(Some(id)) .join(CoconutSigner::COCONUT_VERIFICATION_KEY_FILE); self.coconut_signer.secret_key_path = @@ -509,6 +520,11 @@ impl Config { self.node_status_api.database_path.clone() } + #[cfg(feature = "coconut")] + pub fn persistent_state_path(&self) -> PathBuf { + self.coconut_signer.dkg_persistent_state_path.clone() + } + #[cfg(feature = "coconut")] pub fn verification_key_path(&self) -> PathBuf { self.coconut_signer.verification_key_path.clone() From 2ec56164537e5b6747702d579389f961ddf6071a Mon Sep 17 00:00:00 2001 From: fmtabbara Date: Fri, 9 Dec 2022 13:07:59 +0000 Subject: [PATCH 06/39] text update --- .../bonding/node-settings/settings-pages/NodeUnbondPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx b/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx index f576afccd9..535b68f6e5 100644 --- a/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx +++ b/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx @@ -26,7 +26,7 @@ export const NodeUnbondPage = ({ bondedNode, onConfirm, onError }: Props) => { {isMixnode(bondedNode) && ( theme.palette.nym.text.muted }}> - If you unbond you will loose all delegations! + If you unbond you will lose all delegations! )} From 7a52124d53c85c9484f557303e79c9329f112ff4 Mon Sep 17 00:00:00 2001 From: fmtabbara Date: Fri, 9 Dec 2022 13:29:06 +0000 Subject: [PATCH 07/39] content updates --- .../settings-pages/NodeUnbondPage.tsx | 51 ++++++++----------- 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx b/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx index 535b68f6e5..a1fb0ea3fe 100644 --- a/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx +++ b/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { Box, Button, Typography, Grid, TextField } from '@mui/material'; +import { Box, Button, Typography, Grid, TextField, Stack } from '@mui/material'; import { TBondedMixnode, TBondedGateway } from 'src/context/bonding'; import { Error } from 'src/components/Error'; import { UnbondModal } from 'src/components/Bonding/modals/UnbondModal'; @@ -15,38 +15,31 @@ export const NodeUnbondPage = ({ bondedNode, onConfirm, onError }: Props) => { const [isConfirmed, setIsConfirmed] = useState(false); //TODO: Check what happens with a gateway return ( - - - - + + + + Unbond - - {isMixnode(bondedNode) && ( - - theme.palette.nym.text.muted }}> - If you unbond you will lose all delegations! - - - )} + + {isMixnode(bondedNode) && ( + + theme.palette.nym.text.muted }}> + Remember you should only unbond if you want to remove your node from the network for good. + + + )} + - - - - - + + - - + To unbond, type{' '} t.palette.nym.highlight }}> @@ -54,16 +47,14 @@ export const NodeUnbondPage = ({ bondedNode, onConfirm, onError }: Props) => { {' '} in the field below and click continue - - + setConfirmField(e.target.value)} InputLabelProps={{ shrink: true }} /> - - + - + {isConfirmed && ( From 39cb6f6ec09ee6a2f6dd9d29b006dd9240fe30ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Fri, 9 Dec 2022 15:04:47 +0100 Subject: [PATCH 08/39] network-requester: return error on socket close (#1876) * network-requester: return error when the socket closes * changelog: add note --- CHANGELOG.md | 5 +++++ service-providers/network-requester/src/core.rs | 2 +- service-providers/network-requester/src/error.rs | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c2926410d9..306b94c729 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,13 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// - validator-api: can recover from shutdown during DKG process ([#1872]) +### Fixed + +- network-requester: fix bug where websocket connection disconnect resulted in success error code + [#1872]: https://github.com/nymtech/nym/pull/1872 + ## [v1.1.2] ### Changed diff --git a/service-providers/network-requester/src/core.rs b/service-providers/network-requester/src/core.rs index e58bffaef0..70e0518e27 100644 --- a/service-providers/network-requester/src/core.rs +++ b/service-providers/network-requester/src/core.rs @@ -447,7 +447,7 @@ impl ServiceProvider { .await else { log::error!("The websocket stream has finished!"); - return Ok(()); + return Err(NetworkRequesterError::ConnectionClosed); }; let raw_message = received.message; diff --git a/service-providers/network-requester/src/error.rs b/service-providers/network-requester/src/error.rs index ab5390b19d..6e033305d0 100644 --- a/service-providers/network-requester/src/error.rs +++ b/service-providers/network-requester/src/error.rs @@ -7,4 +7,7 @@ pub enum NetworkRequesterError { #[error("Websocket error")] WebsocketConnectionError(#[from] WebsocketConnectionError), + + #[error("Websocket connection closed")] + ConnectionClosed, } From b694e675e6f1bb53562a5b26144113369ca6c5bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Fri, 9 Dec 2022 16:12:30 +0100 Subject: [PATCH 09/39] clients: further deduplicate init code (#1873) * client-core: move init helpers to module * WIP * socks5: return error instead of terminate in init * Extract out reuse_existing_gateway_config * rustfmt * Remove comment out code * nym-connect: use setup_gateway * Linebreak * changelog: update * Tweak log * rustfmt --- CHANGELOG.md | 1 + Cargo.lock | 27 +-- clients/client-core/Cargo.toml | 3 +- .../client-core/src/client/base_client/mod.rs | 6 +- clients/client-core/src/config/mod.rs | 14 +- clients/client-core/src/init.rs | 219 ------------------ clients/client-core/src/init/helpers.rs | 95 ++++++++ clients/client-core/src/init/mod.rs | 191 +++++++++++++++ clients/native/src/client/config/mod.rs | 10 +- clients/native/src/commands/init.rs | 102 +++----- clients/native/src/commands/mod.rs | 2 +- clients/native/src/error.rs | 2 + clients/socks5/Cargo.toml | 1 - clients/socks5/src/client/config/mod.rs | 10 +- clients/socks5/src/client/mod.rs | 14 +- clients/socks5/src/commands/init.rs | 103 ++++---- clients/socks5/src/commands/mod.rs | 4 +- clients/socks5/src/commands/run.rs | 2 +- clients/socks5/src/main.rs | 2 +- clients/socks5/src/socks/types.rs | 22 +- common/task/src/shutdown.rs | 2 +- common/task/src/spawn.rs | 2 +- nym-connect/Cargo.lock | 29 +-- nym-connect/src-tauri/src/config/mod.rs | 15 +- nym-connect/src-tauri/src/tasks.rs | 2 +- 25 files changed, 435 insertions(+), 445 deletions(-) delete mode 100644 clients/client-core/src/init.rs create mode 100644 clients/client-core/src/init/helpers.rs create mode 100644 clients/client-core/src/init/mod.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 306b94c729..77afb36529 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// ### Changed - validator-api: can recover from shutdown during DKG process ([#1872]) +- client-core: deduplicate gateway inititialization, part of work towards a rust-sdk ### Fixed diff --git a/Cargo.lock b/Cargo.lock index 9a7618ad3a..e755f118fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -603,6 +603,7 @@ dependencies = [ "pemstore", "rand 0.7.3", "serde", + "serde_json", "sled", "tap", "task", @@ -2668,7 +2669,7 @@ checksum = "fe435806c197dfeaa5efcded5e623c4b8230fd28fdf1e91e7a86e40ef2acbf90" dependencies = [ "arrayref", "no-std-compat", - "snafu 0.7.1", + "snafu", ] [[package]] @@ -3373,7 +3374,6 @@ dependencies = [ "rand 0.7.3", "serde", "serde_json", - "snafu 0.6.10", "socks5-requests", "tap", "task", @@ -5196,16 +5196,6 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" -[[package]] -name = "snafu" -version = "0.6.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eab12d3c261b2308b0d80c26fffb58d17eba81a4be97890101f416b478c79ca7" -dependencies = [ - "doc-comment", - "snafu-derive 0.6.10", -] - [[package]] name = "snafu" version = "0.7.1" @@ -5213,18 +5203,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5177903bf45656592d9eb5c0e22f408fc023aae51dbe2088889b71633ba451f2" dependencies = [ "doc-comment", - "snafu-derive 0.7.1", -] - -[[package]] -name = "snafu-derive" -version = "0.6.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1508efa03c362e23817f96cde18abed596a25219a8b2c66e8db33c03543d315b" -dependencies = [ - "proc-macro2", - "quote", - "syn", + "snafu-derive", ] [[package]] diff --git a/clients/client-core/Cargo.toml b/clients/client-core/Cargo.toml index 7b0ecc9c97..56edca335b 100644 --- a/clients/client-core/Cargo.toml +++ b/clients/client-core/Cargo.toml @@ -13,11 +13,12 @@ humantime-serde = "1.0" log = "0.4" rand = { version = "0.7.3", features = ["wasm-bindgen"] } serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0.89" sled = { version = "0.34", optional = true } tap = "1.0.1" thiserror = "1.0.34" -url = { version ="2.2", features = ["serde"] } tokio = { version = "1.21.2", features = ["time", "macros"]} +url = { version ="2.2", features = ["serde"] } # internal config = { path = "../../common/config" } diff --git a/clients/client-core/src/client/base_client/mod.rs b/clients/client-core/src/client/base_client/mod.rs index 5295b08e55..21e5616458 100644 --- a/clients/client-core/src/client/base_client/mod.rs +++ b/clients/client-core/src/client/base_client/mod.rs @@ -23,7 +23,7 @@ use gateway_client::{ AcknowledgementReceiver, AcknowledgementSender, GatewayClient, MixnetMessageReceiver, MixnetMessageSender, }; -use log::info; +use log::{debug, info}; use nymsphinx::addressing::clients::Recipient; use nymsphinx::addressing::nodes::NodeIdentity; #[cfg(feature = "reply-surb")] @@ -412,8 +412,8 @@ impl<'a> BaseClientBuilder<'a> { ); } - info!("Client startup finished!"); - info!("The address of this client is: {}", self.as_mix_recipient()); + debug!("Core client startup finished!"); + debug!("The address of this client is: {}", self.as_mix_recipient()); Ok(BaseClient { client_input: ClientInputStatus::AwaitingProducer { diff --git a/clients/client-core/src/config/mod.rs b/clients/client-core/src/config/mod.rs index 09a1f5cfcd..8236fff213 100644 --- a/clients/client-core/src/config/mod.rs +++ b/clients/client-core/src/config/mod.rs @@ -34,6 +34,10 @@ pub fn missing_string_value() -> String { MISSING_VALUE.to_string() } +pub trait ClientCoreConfigTrait { + fn get_gateway_endpoint(&self) -> &GatewayEndpointConfig; +} + #[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] #[serde(deny_unknown_fields)] pub struct Config { @@ -45,6 +49,12 @@ pub struct Config { debug: DebugConfig, } +impl ClientCoreConfigTrait for Config { + fn get_gateway_endpoint(&self) -> &GatewayEndpointConfig { + &self.client.gateway_endpoint + } +} + impl Config { pub fn new>(id: S) -> Self where @@ -220,10 +230,6 @@ impl Config { &self.client.gateway_endpoint } - pub fn get_gateway_endpoint(&self) -> &GatewayEndpointConfig { - &self.client.gateway_endpoint - } - pub fn get_database_path(&self) -> PathBuf { self.client.database_path.clone() } diff --git a/clients/client-core/src/init.rs b/clients/client-core/src/init.rs deleted file mode 100644 index 9964b6f60a..0000000000 --- a/clients/client-core/src/init.rs +++ /dev/null @@ -1,219 +0,0 @@ -// Copyright 2022 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -//! Collection of initialization steps used by client implementations - -use std::{fmt::Display, sync::Arc, time::Duration}; - -use config::NymConfig; -use crypto::asymmetric::{encryption, identity}; -use gateway_client::GatewayClient; -use gateway_requests::registration::handshake::SharedKeys; -use nymsphinx::addressing::clients::Recipient; -use nymsphinx::addressing::nodes::NodeIdentity; -use rand::rngs::OsRng; -use rand::seq::SliceRandom; -use rand::thread_rng; -use serde::Serialize; -use tap::TapFallible; -use topology::{filter::VersionFilterable, gateway}; -use url::Url; - -use crate::{ - client::key_manager::KeyManager, - config::{persistence::key_pathfinder::ClientKeyPathfinder, Config, GatewayEndpointConfig}, - error::ClientCoreError, -}; - -#[derive(Debug, Serialize)] -pub struct InitResults { - version: String, - id: String, - identity_key: String, - encryption_key: String, - gateway_id: String, - gateway_listener: String, -} - -impl InitResults { - pub fn new(config: &Config, address: &Recipient) -> Self - where - T: NymConfig, - { - Self { - version: config.get_version().to_string(), - id: config.get_id(), - identity_key: address.identity().to_base58_string(), - encryption_key: address.encryption_key().to_base58_string(), - gateway_id: config.get_gateway_id(), - gateway_listener: config.get_gateway_listener(), - } - } -} - -impl Display for InitResults { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - writeln!(f, "Version: {}", self.version)?; - writeln!(f, "ID: {}", self.id)?; - writeln!(f, "Identity key: {}", self.identity_key)?; - writeln!(f, "Encryption: {}", self.encryption_key)?; - writeln!(f, "Gateway ID: {}", self.gateway_id)?; - write!(f, "Gateway: {}", self.gateway_listener) - } -} - -pub async fn query_gateway_details( - validator_servers: Vec, - chosen_gateway_id: Option<&str>, -) -> Result { - let validator_api = validator_servers - .choose(&mut thread_rng()) - .ok_or(ClientCoreError::ListOfValidatorApisIsEmpty)?; - let validator_client = validator_client::client::ApiClient::new(validator_api.clone()); - - log::trace!("Fetching list of gateways from: {}", validator_api); - let gateways = validator_client.get_cached_gateways().await?; - let valid_gateways = gateways - .into_iter() - .filter_map(|gateway| gateway.try_into().ok()) - .collect::>(); - - let filtered_gateways = valid_gateways.filter_by_version(env!("CARGO_PKG_VERSION")); - - // if we have chosen particular gateway - use it, otherwise choose a random one. - // (remember that in active topology all gateways have at least 100 reputation so should - // be working correctly) - if let Some(gateway_id) = chosen_gateway_id { - filtered_gateways - .iter() - .find(|gateway| gateway.identity_key.to_base58_string() == gateway_id) - .ok_or_else(|| ClientCoreError::NoGatewayWithId(gateway_id.to_string())) - .cloned() - } else { - filtered_gateways - .choose(&mut rand::thread_rng()) - .ok_or(ClientCoreError::NoGatewaysOnNetwork) - .cloned() - } -} - -pub async fn register_with_gateway_and_store_keys( - gateway_details: gateway::Node, - config: &Config, -) -> Result<(), ClientCoreError> -where - T: NymConfig, -{ - let mut rng = OsRng; - let mut key_manager = KeyManager::new(&mut rng); - - let shared_keys = - register_with_gateway(&gateway_details, key_manager.identity_keypair()).await?; - key_manager.insert_gateway_shared_key(shared_keys); - - let pathfinder = ClientKeyPathfinder::new_from_config(config); - Ok(key_manager - .store_keys(&pathfinder) - .tap_err(|err| log::error!("Failed to generate keys: {err}"))?) -} - -async fn register_with_gateway( - gateway: &gateway::Node, - our_identity: Arc, -) -> Result, ClientCoreError> { - let timeout = Duration::from_millis(1500); - let mut gateway_client = GatewayClient::new_init( - gateway.clients_address(), - gateway.identity_key, - gateway.owner.clone(), - our_identity.clone(), - timeout, - ); - gateway_client - .establish_connection() - .await - .tap_err(|_| log::warn!("Failed to establish connection with gateway!"))?; - let shared_keys = gateway_client - .perform_initial_authentication() - .await - .tap_err(|_| log::warn!("Failed to register with the gateway!"))?; - Ok(shared_keys) -} - -pub async fn setup_gateway( - register: bool, - user_chosen_gateway_id: Option<&str>, - config: &Config, -) -> Result { - if register { - // Get the gateway details by querying the validator-api. Either pick one at random or use - // the chosen one if it's among the available ones. - println!("Configuring gateway"); - let gateway = - query_gateway_details(config.get_validator_api_endpoints(), user_chosen_gateway_id) - .await?; - log::debug!("Querying gateway gives: {}", gateway); - - // Registering with gateway by setting up and writing shared keys to disk - log::trace!("Registering gateway"); - register_with_gateway_and_store_keys(gateway.clone(), config).await?; - println!("Saved all generated keys"); - - Ok(gateway.into()) - } else if user_chosen_gateway_id.is_some() { - // Just set the config, don't register or create any keys - // This assumes that the user knows what they are doing, and that the existing keys are - // valid for the gateway being used - println!("Using gateway provided by user, keeping existing keys"); - let gateway = - query_gateway_details(config.get_validator_api_endpoints(), user_chosen_gateway_id) - .await?; - log::debug!("Querying gateway gives: {}", gateway); - Ok(gateway.into()) - } else { - Err(ClientCoreError::FailedToSetupGateway) - } -} - -pub fn get_client_address(config: &Config) -> Result -where - T: config::NymConfig, -{ - fn load_identity_keys( - pathfinder: &ClientKeyPathfinder, - ) -> Result { - let identity_keypair: identity::KeyPair = - pemstore::load_keypair(&pemstore::KeyPairPath::new( - pathfinder.private_identity_key().to_owned(), - pathfinder.public_identity_key().to_owned(), - )) - .tap_err(|_| log::error!("Failed to read stored identity key files"))?; - Ok(identity_keypair) - } - - fn load_sphinx_keys( - pathfinder: &ClientKeyPathfinder, - ) -> Result { - let sphinx_keypair: encryption::KeyPair = - pemstore::load_keypair(&pemstore::KeyPairPath::new( - pathfinder.private_encryption_key().to_owned(), - pathfinder.public_encryption_key().to_owned(), - )) - .tap_err(|_| log::error!("Failed to read stored sphinx key files"))?; - Ok(sphinx_keypair) - } - - let pathfinder = ClientKeyPathfinder::new_from_config(config); - let identity_keypair = load_identity_keys(&pathfinder)?; - let sphinx_keypair = load_sphinx_keys(&pathfinder)?; - - let client_recipient = Recipient::new( - *identity_keypair.public_key(), - *sphinx_keypair.public_key(), - // TODO: below only works under assumption that gateway address == gateway id - // (which currently is true) - NodeIdentity::from_base58_string(config.get_gateway_id())?, - ); - - Ok(client_recipient) -} diff --git a/clients/client-core/src/init/helpers.rs b/clients/client-core/src/init/helpers.rs new file mode 100644 index 0000000000..c838f8c6db --- /dev/null +++ b/clients/client-core/src/init/helpers.rs @@ -0,0 +1,95 @@ +use std::{sync::Arc, time::Duration}; + +use rand::{rngs::OsRng, seq::SliceRandom, thread_rng}; +use tap::TapFallible; +use url::Url; + +use config::NymConfig; +use crypto::asymmetric::identity; +use gateway_client::GatewayClient; +use gateway_requests::registration::handshake::SharedKeys; +use topology::{filter::VersionFilterable, gateway}; + +use crate::{ + client::key_manager::KeyManager, + config::{persistence::key_pathfinder::ClientKeyPathfinder, Config}, + error::ClientCoreError, +}; + +pub(super) async fn query_gateway_details( + validator_servers: Vec, + chosen_gateway_id: Option, +) -> Result { + let validator_api = validator_servers + .choose(&mut thread_rng()) + .ok_or(ClientCoreError::ListOfValidatorApisIsEmpty)?; + let validator_client = validator_client::client::ApiClient::new(validator_api.clone()); + + log::trace!("Fetching list of gateways from: {}", validator_api); + let gateways = validator_client.get_cached_gateways().await?; + let valid_gateways = gateways + .into_iter() + .filter_map(|gateway| gateway.try_into().ok()) + .collect::>(); + + let filtered_gateways = valid_gateways.filter_by_version(env!("CARGO_PKG_VERSION")); + + // if we have chosen particular gateway - use it, otherwise choose a random one. + // (remember that in active topology all gateways have at least 100 reputation so should + // be working correctly) + if let Some(gateway_id) = chosen_gateway_id { + filtered_gateways + .iter() + .find(|gateway| gateway.identity_key.to_base58_string() == gateway_id) + .ok_or_else(|| ClientCoreError::NoGatewayWithId(gateway_id.to_string())) + .cloned() + } else { + filtered_gateways + .choose(&mut rand::thread_rng()) + .ok_or(ClientCoreError::NoGatewaysOnNetwork) + .cloned() + } +} + +async fn register_with_gateway( + gateway: &gateway::Node, + our_identity: Arc, +) -> Result, ClientCoreError> { + let timeout = Duration::from_millis(1500); + let mut gateway_client = GatewayClient::new_init( + gateway.clients_address(), + gateway.identity_key, + gateway.owner.clone(), + our_identity.clone(), + timeout, + ); + gateway_client + .establish_connection() + .await + .tap_err(|_| log::warn!("Failed to establish connection with gateway!"))?; + let shared_keys = gateway_client + .perform_initial_authentication() + .await + .tap_err(|_| log::warn!("Failed to register with the gateway!"))?; + Ok(shared_keys) +} + +pub(super) async fn register_with_gateway_and_store_keys( + gateway_details: gateway::Node, + config: &Config, +) -> Result<(), ClientCoreError> +where + T: NymConfig, +{ + let mut rng = OsRng; + let mut key_manager = KeyManager::new(&mut rng); + + let shared_keys = + register_with_gateway(&gateway_details, key_manager.identity_keypair()).await?; + key_manager.insert_gateway_shared_key(shared_keys); + + let pathfinder = ClientKeyPathfinder::new_from_config(config); + Ok(key_manager + .store_keys(&pathfinder) + .tap_err(|err| log::error!("Failed to generate keys: {err}"))?) +} diff --git a/clients/client-core/src/init/mod.rs b/clients/client-core/src/init/mod.rs new file mode 100644 index 0000000000..705cbf4eca --- /dev/null +++ b/clients/client-core/src/init/mod.rs @@ -0,0 +1,191 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +//! Collection of initialization steps used by client implementations + +use std::fmt::Display; + +use nymsphinx::addressing::{clients::Recipient, nodes::NodeIdentity}; +use serde::Serialize; +use tap::TapFallible; + +use config::NymConfig; +use crypto::asymmetric::{encryption, identity}; + +use crate::{ + config::{ + persistence::key_pathfinder::ClientKeyPathfinder, ClientCoreConfigTrait, Config, + GatewayEndpointConfig, + }, + error::ClientCoreError, + init::helpers::{query_gateway_details, register_with_gateway_and_store_keys}, +}; + +mod helpers; + +#[derive(Debug, Serialize)] +pub struct InitResults { + version: String, + id: String, + identity_key: String, + encryption_key: String, + gateway_id: String, + gateway_listener: String, +} + +impl InitResults { + pub fn new(config: &Config, address: &Recipient) -> Self + where + T: NymConfig, + { + Self { + version: config.get_version().to_string(), + id: config.get_id(), + identity_key: address.identity().to_base58_string(), + encryption_key: address.encryption_key().to_base58_string(), + gateway_id: config.get_gateway_id(), + gateway_listener: config.get_gateway_listener(), + } + } +} + +impl Display for InitResults { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + writeln!(f, "Version: {}", self.version)?; + writeln!(f, "ID: {}", self.id)?; + writeln!(f, "Identity key: {}", self.identity_key)?; + writeln!(f, "Encryption: {}", self.encryption_key)?; + writeln!(f, "Gateway ID: {}", self.gateway_id)?; + write!(f, "Gateway: {}", self.gateway_listener) + } +} + +/// Convenience function for setting up the gateway for a client. Depending on the arguments given +/// it will do the sensible thing. +pub async fn setup_gateway( + register_gateway: bool, + user_chosen_gateway_id: Option, + config: &Config, +) -> Result { + let id = config.get_id(); + if register_gateway { + register_with_gateway(user_chosen_gateway_id, config).await + } else if let Some(user_chosen_gateway_id) = user_chosen_gateway_id { + config_gateway_with_existing_keys(user_chosen_gateway_id, config).await + } else { + reuse_existing_gateway_config::(&id) + } +} + +/// Get the gateway details by querying the validator-api. Either pick one at random or use +/// the chosen one if it's among the available ones. +/// Saves keys to disk, specified by the paths in `config`. +pub async fn register_with_gateway( + user_chosen_gateway_id: Option, + config: &Config, +) -> Result { + println!("Configuring gateway"); + let gateway = + query_gateway_details(config.get_validator_api_endpoints(), user_chosen_gateway_id).await?; + log::debug!("Querying gateway gives: {}", gateway); + + // Registering with gateway by setting up and writing shared keys to disk + log::trace!("Registering gateway"); + register_with_gateway_and_store_keys(gateway.clone(), config).await?; + println!("Saved all generated keys"); + + Ok(gateway.into()) +} + +/// Set the gateway using the usual procedue of querying the validator-api, but don't register or +/// create any keys. +/// This assumes that the user knows what they are doing, and that the existing keys are valid for +/// the gateway being used +pub async fn config_gateway_with_existing_keys( + user_chosen_gateway_id: String, + config: &Config, +) -> Result { + println!("Using gateway provided by user, keeping existing keys"); + let gateway = query_gateway_details( + config.get_validator_api_endpoints(), + Some(user_chosen_gateway_id), + ) + .await?; + log::debug!("Querying gateway gives: {}", gateway); + Ok(gateway.into()) +} + +/// Read and reuse the existing gateway configuration from a file that was generate earlier. +pub fn reuse_existing_gateway_config( + id: &str, +) -> Result { + println!("Not registering gateway, will reuse existing config and keys"); + T::load_from_file(Some(id)) + .map(|existing_config| existing_config.get_gateway_endpoint().clone()) + .map_err(|err| { + log::error!( + "Unable to configure gateway: {err}. \n + Seems like the client was already initialized but it was not possible to read \ + the existing configuration file. \n + CAUTION: Consider backing up your gateway keys and try force gateway registration, or \ + removing the existing configuration and starting over." + ); + ClientCoreError::CouldNotLoadExistingGatewayConfiguration(err) + }) +} + +/// Get the client address by loading the keys from stored files. +pub fn get_client_address_from_stored_keys( + config: &Config, +) -> Result +where + T: config::NymConfig, +{ + fn load_identity_keys( + pathfinder: &ClientKeyPathfinder, + ) -> Result { + let identity_keypair: identity::KeyPair = + pemstore::load_keypair(&pemstore::KeyPairPath::new( + pathfinder.private_identity_key().to_owned(), + pathfinder.public_identity_key().to_owned(), + )) + .tap_err(|_| log::error!("Failed to read stored identity key files"))?; + Ok(identity_keypair) + } + + fn load_sphinx_keys( + pathfinder: &ClientKeyPathfinder, + ) -> Result { + let sphinx_keypair: encryption::KeyPair = + pemstore::load_keypair(&pemstore::KeyPairPath::new( + pathfinder.private_encryption_key().to_owned(), + pathfinder.public_encryption_key().to_owned(), + )) + .tap_err(|_| log::error!("Failed to read stored sphinx key files"))?; + Ok(sphinx_keypair) + } + + let pathfinder = ClientKeyPathfinder::new_from_config(config); + let identity_keypair = load_identity_keys(&pathfinder)?; + let sphinx_keypair = load_sphinx_keys(&pathfinder)?; + + let client_recipient = Recipient::new( + *identity_keypair.public_key(), + *sphinx_keypair.public_key(), + // TODO: below only works under assumption that gateway address == gateway id + // (which currently is true) + NodeIdentity::from_base58_string(config.get_gateway_id())?, + ); + + Ok(client_recipient) +} + +pub fn output_to_json(init_results: &T, output_file: &str) { + match std::fs::File::create(output_file) { + Ok(file) => match serde_json::to_writer_pretty(file, init_results) { + Ok(_) => println!("Saved: {}", output_file), + Err(err) => eprintln!("Could not save {}: {}", output_file, err), + }, + Err(err) => eprintln!("Could not save {}: {}", output_file, err), + } +} diff --git a/clients/native/src/client/config/mod.rs b/clients/native/src/client/config/mod.rs index 8ce268e9ea..bb2b7d7a15 100644 --- a/clients/native/src/client/config/mod.rs +++ b/clients/native/src/client/config/mod.rs @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 use crate::client::config::template::config_template; -use client_core::config::Config as BaseConfig; pub use client_core::config::MISSING_VALUE; +use client_core::config::{ClientCoreConfigTrait, Config as BaseConfig}; use config::defaults::DEFAULT_WEBSOCKET_LISTENING_PORT; use config::NymConfig; use serde::{Deserialize, Serialize}; @@ -28,7 +28,7 @@ impl SocketType { } } - pub fn is_websocket(&self) -> bool { + pub fn is_websocket(self) -> bool { matches!(self, SocketType::WebSocket) } } @@ -73,6 +73,12 @@ impl NymConfig for Config { } } +impl ClientCoreConfigTrait for Config { + fn get_gateway_endpoint(&self) -> &client_core::config::GatewayEndpointConfig { + self.base.get_gateway_endpoint() + } +} + impl Config { pub fn new>(id: S) -> Self { Config { diff --git a/clients/native/src/commands/init.rs b/clients/native/src/commands/init.rs index 56a9cc1da1..050e680f8e 100644 --- a/clients/native/src/commands/init.rs +++ b/clients/native/src/commands/init.rs @@ -4,14 +4,15 @@ use std::fmt::Display; use clap::Args; -use client_core::{config::GatewayEndpointConfig, error::ClientCoreError}; use config::NymConfig; use nymsphinx::addressing::clients::Recipient; use serde::Serialize; +use tap::TapFallible; use crate::{ client::config::Config, commands::{override_config, OverrideConfig}, + error::ClientError, }; #[derive(Args, Clone)] @@ -89,7 +90,7 @@ pub struct InitResults { } impl InitResults { - pub fn new(config: &Config, address: &Recipient) -> Self { + fn new(config: &Config, address: &Recipient) -> Self { Self { client_core: client_core::init::InitResults::new(config.get_base(), address), client_listening_port: config.get_listening_port().to_string(), @@ -104,7 +105,7 @@ impl Display for InitResults { } } -pub(crate) async fn execute(args: &Init) { +pub(crate) async fn execute(args: &Init) -> Result<(), ClientError> { println!("Initialising client..."); let id = &args.id; @@ -128,33 +129,44 @@ pub(crate) async fn execute(args: &Init) { let register_gateway = !already_init || user_wants_force_register; // Attempt to use a user-provided gateway, if possible - let user_chosen_gateway_id = args.gateway.as_deref(); + let user_chosen_gateway_id = args.gateway.clone(); - let mut config = Config::new(id); - let override_config_fields = OverrideConfig::from(args.clone()); - config = override_config(config, override_config_fields); + // Load and potentially override config + let mut config = override_config(Config::new(id), OverrideConfig::from(args.clone())); + + // Setup gateway by either registering a new one, or creating a new config from the selected + // one but with keys kept, or reusing the gateway configuration. + let gateway = client_core::init::setup_gateway::( + register_gateway, + user_chosen_gateway_id, + config.get_base(), + ) + .await + .tap_err(|err| eprintln!("Failed to setup gateway\nError: {err}"))?; - let gateway = if !register_gateway && user_chosen_gateway_id.is_none() { - reuse_gateway_config(id) - } else { - client_core::init::setup_gateway( - register_gateway, - user_chosen_gateway_id, - config.get_base(), - ) - .await - } - .unwrap_or_else(|err| { - eprintln!("Failed to setup gateway\nError: {err}"); - std::process::exit(1) - }); config.get_base_mut().with_gateway_endpoint(gateway); - let config_save_location = config.get_config_file_save_location(); - config - .save_to_file(None) - .expect("Failed to save the config file"); + config.save_to_file(None).tap_err(|_| { + log::error!("Failed to save the config file"); + })?; + print_saved_config(&config); + + let address = client_core::init::get_client_address_from_stored_keys(config.get_base())?; + let init_results = InitResults::new(&config, &address); + println!("{}", init_results); + + // Output summary to a json file, if specified + if args.output_json { + client_core::init::output_to_json(&init_results, "client_init_results.json"); + } + + println!("\nThe address of this client is: {}\n", address); + Ok(()) +} + +fn print_saved_config(config: &Config) { + let config_save_location = config.get_config_file_save_location(); println!("Saved configuration file to {:?}", config_save_location); println!("Using gateway: {}", config.get_base().get_gateway_id()); log::debug!("Gateway id: {}", config.get_base().get_gateway_id()); @@ -163,43 +175,5 @@ pub(crate) async fn execute(args: &Init) { "Gateway listener: {}", config.get_base().get_gateway_listener() ); - println!("Client configuration completed."); - - let address = client_core::init::get_client_address(config.get_base()).unwrap_or_else(|err| { - eprintln!("Failed to get address\nError: {err}"); - std::process::exit(1) - }); - - println!("\nThe address of this client is: {}\n", address); - - let init_results = InitResults::new(&config, &address); - println!("{}", init_results); - - // Output summary to a json file, if specified - if args.output_json { - let output_file = "client_init_results.json"; - match std::fs::File::create(output_file) { - Ok(file) => match serde_json::to_writer_pretty(file, &init_results) { - Ok(_) => println!("Saved: {}", output_file), - Err(err) => eprintln!("Could not save {}: {}", output_file, err), - }, - Err(err) => eprintln!("Could not save {}: {}", output_file, err), - } - } -} - -fn reuse_gateway_config(id: &str) -> Result { - println!("Not registering gateway, will reuse existing config and keys"); - Config::load_from_file(Some(id)) - .map(|existing_config| existing_config.get_base().get_gateway_endpoint().clone()) - .map_err(|err| { - log::error!( - "Unable to configure gateway: {err}. \n - Seems like the client was already initialized but it was not possible to read \ - the existing configuration file. \n - CAUTION: Consider backing up your gateway keys and try force gateway registration, or \ - removing the existing configuration and starting over." - ); - ClientCoreError::CouldNotLoadExistingGatewayConfiguration(err) - }) + println!("Client configuration completed.\n"); } diff --git a/clients/native/src/commands/mod.rs b/clients/native/src/commands/mod.rs index c3232165d8..9dc6a2ac33 100644 --- a/clients/native/src/commands/mod.rs +++ b/clients/native/src/commands/mod.rs @@ -90,7 +90,7 @@ pub(crate) async fn execute(args: &Cli) -> Result<(), ClientError> { let bin_name = "nym-native-client"; match &args.command { - Commands::Init(m) => init::execute(m).await, + Commands::Init(m) => init::execute(m).await?, Commands::Run(m) => run::execute(m).await?, Commands::Upgrade(m) => upgrade::execute(m), Commands::Completions(s) => s.generate(&mut Cli::into_app(), bin_name), diff --git a/clients/native/src/error.rs b/clients/native/src/error.rs index 06c45116b6..5ca3319cb7 100644 --- a/clients/native/src/error.rs +++ b/clients/native/src/error.rs @@ -2,6 +2,8 @@ use client_core::error::ClientCoreError; #[derive(thiserror::Error, Debug)] pub enum ClientError { + #[error("I/O error: {0}")] + IoError(#[from] std::io::Error), #[error("client-core error: {0}")] ClientCoreError(#[from] ClientCoreError), diff --git a/clients/socks5/Cargo.toml b/clients/socks5/Cargo.toml index de5ecf33ee..42c477efec 100644 --- a/clients/socks5/Cargo.toml +++ b/clients/socks5/Cargo.toml @@ -20,7 +20,6 @@ pretty_env_logger = "0.4" rand = { version = "0.7.3", features = ["wasm-bindgen"] } serde = { version = "1.0", features = ["derive"] } # for config serialization/deserialization serde_json = "1.0.89" -snafu = "0.6" tap = "1.0.1" thiserror = "1.0.34" tokio = { version = "1.21.2", features = ["rt-multi-thread", "net", "signal"] } diff --git a/clients/socks5/src/client/config/mod.rs b/clients/socks5/src/client/config/mod.rs index 4c43984f35..0bbab949ef 100644 --- a/clients/socks5/src/client/config/mod.rs +++ b/clients/socks5/src/client/config/mod.rs @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 use crate::client::config::template::config_template; -use client_core::config::Config as BaseConfig; pub use client_core::config::MISSING_VALUE; +use client_core::config::{ClientCoreConfigTrait, Config as BaseConfig}; use config::defaults::DEFAULT_SOCKS5_LISTENING_PORT; use config::NymConfig; use nymsphinx::addressing::clients::Recipient; @@ -52,6 +52,12 @@ impl NymConfig for Config { } } +impl ClientCoreConfigTrait for Config { + fn get_gateway_endpoint(&self) -> &client_core::config::GatewayEndpointConfig { + self.base.get_gateway_endpoint() + } +} + impl Config { pub fn new>(id: S, provider_mix_address: S) -> Self { Config { @@ -60,11 +66,13 @@ impl Config { } } + #[must_use] pub fn with_port(mut self, port: u16) -> Self { self.socks5.listening_port = port; self } + #[must_use] pub fn with_provider_mix_address(mut self, address: String) -> Self { self.socks5.provider_mix_address = address; self diff --git a/clients/socks5/src/client/mod.rs b/clients/socks5/src/client/mod.rs index 50fe2d0d49..ea0af81fd7 100644 --- a/clients/socks5/src/client/mod.rs +++ b/clients/socks5/src/client/mod.rs @@ -131,11 +131,8 @@ impl NymClient { } /// blocking version of `start` method. Will run forever (or until SIGINT is sent) - pub async fn run_forever(self) -> Result<(), Box> { - let mut shutdown = self - .start() - .await - .map_err(|err| Box::new(err) as Box)?; + pub async fn run_forever(self) -> Result<(), Box> { + let mut shutdown = self.start().await?; let res = wait_for_signal_and_error(&mut shutdown).await; @@ -153,12 +150,9 @@ impl NymClient { pub async fn run_and_listen( self, mut receiver: Socks5ControlMessageReceiver, - ) -> Result<(), Box> { + ) -> Result<(), Box> { // Start the main task - let mut shutdown = self - .start() - .await - .map_err(|err| Box::new(err) as Box)?; + let mut shutdown = self.start().await?; let res = tokio::select! { biased; diff --git a/clients/socks5/src/commands/init.rs b/clients/socks5/src/commands/init.rs index a71852913d..1e8b5c47f0 100644 --- a/clients/socks5/src/commands/init.rs +++ b/clients/socks5/src/commands/init.rs @@ -4,14 +4,15 @@ use std::fmt::Display; use clap::Args; -use client_core::{config::GatewayEndpointConfig, error::ClientCoreError}; use config::NymConfig; use nymsphinx::addressing::clients::Recipient; use serde::Serialize; +use tap::TapFallible; use crate::{ client::config::Config, commands::{override_config, OverrideConfig}, + error::Socks5ClientError, }; #[derive(Args, Clone)] @@ -87,7 +88,7 @@ pub struct InitResults { } impl InitResults { - pub fn new(config: &Config, address: &Recipient) -> Self { + fn new(config: &Config, address: &Recipient) -> Self { Self { client_core: client_core::init::InitResults::new(config.get_base(), address), socks5_listening_port: config.get_listening_port().to_string(), @@ -102,7 +103,7 @@ impl Display for InitResults { } } -pub(crate) async fn execute(args: &Init) { +pub(crate) async fn execute(args: &Init) -> Result<(), Socks5ClientError> { println!("Initialising client..."); let id = &args.id; @@ -127,33 +128,47 @@ pub(crate) async fn execute(args: &Init) { let register_gateway = !already_init || user_wants_force_register; // Attempt to use a user-provided gateway, if possible - let user_chosen_gateway_id = args.gateway.as_deref(); + let user_chosen_gateway_id = args.gateway.clone(); - let mut config = Config::new(id, provider_address); - let override_config_fields = OverrideConfig::from(args.clone()); - config = override_config(config, override_config_fields); + // Load and potentially override config + let mut config = override_config( + Config::new(id, provider_address), + OverrideConfig::from(args.clone()), + ); + + // Setup gateway by either registering a new one, or creating a new config from the selected + // one but with keys kept, or reusing the gateway configuration. + let gateway = client_core::init::setup_gateway::( + register_gateway, + user_chosen_gateway_id, + config.get_base(), + ) + .await + .tap_err(|err| eprintln!("Failed to setup gateway\nError: {err}"))?; - let gateway = if !register_gateway && user_chosen_gateway_id.is_none() { - reuse_gateway_config(id) - } else { - client_core::init::setup_gateway( - register_gateway, - user_chosen_gateway_id, - config.get_base(), - ) - .await - } - .unwrap_or_else(|err| { - eprintln!("Failed to setup gateway\nError: {err}"); - std::process::exit(1) - }); config.get_base_mut().with_gateway_endpoint(gateway); - let config_save_location = config.get_config_file_save_location(); - config - .save_to_file(None) - .expect("Failed to save the config file"); + config.save_to_file(None).tap_err(|_| { + log::error!("Failed to save the config file"); + })?; + print_saved_config(&config); + + let address = client_core::init::get_client_address_from_stored_keys(config.get_base())?; + let init_results = InitResults::new(&config, &address); + println!("{}", init_results); + + // Output summary to a json file, if specified + if args.output_json { + client_core::init::output_to_json(&init_results, "socks5_client_init_results.json"); + } + + println!("\nThe address of this client is: {}\n", address); + Ok(()) +} + +fn print_saved_config(config: &Config) { + let config_save_location = config.get_config_file_save_location(); println!("Saved configuration file to {:?}", config_save_location); println!("Using gateway: {}", config.get_base().get_gateway_id()); log::debug!("Gateway id: {}", config.get_base().get_gateway_id()); @@ -163,42 +178,4 @@ pub(crate) async fn execute(args: &Init) { config.get_base().get_gateway_listener() ); println!("Client configuration completed.\n"); - - let address = client_core::init::get_client_address(config.get_base()).unwrap_or_else(|err| { - eprintln!("Failed to get address\nError: {err}"); - std::process::exit(1) - }); - - let init_results = InitResults::new(&config, &address); - println!("{}", init_results); - - // Output summary to a json file, if specified - if args.output_json { - let output_file = "socks5_client_init_results.json"; - match std::fs::File::create(output_file) { - Ok(file) => match serde_json::to_writer_pretty(file, &init_results) { - Ok(_) => println!("Saved: {}", output_file), - Err(err) => eprintln!("Could not save {}: {}", output_file, err), - }, - Err(err) => eprintln!("Could not save {}: {}", output_file, err), - } - } - - println!("\nThe address of this client is: {}\n", address); -} - -fn reuse_gateway_config(id: &str) -> Result { - println!("Not registering gateway, will reuse existing config and keys"); - Config::load_from_file(Some(id)) - .map(|existing_config| existing_config.get_base().get_gateway_endpoint().clone()) - .map_err(|err| { - log::error!( - "Unable to configure gateway: {err}. \n - Seems like the client was already initialized but it was not possible to read \ - the existing configuration file. \n - CAUTION: Consider backing up your gateway keys and try force gateway registration, or \ - removing the existing configuration and starting over." - ); - ClientCoreError::CouldNotLoadExistingGatewayConfiguration(err) - }) } diff --git a/clients/socks5/src/commands/mod.rs b/clients/socks5/src/commands/mod.rs index 6a141808bb..f1da5a6fda 100644 --- a/clients/socks5/src/commands/mod.rs +++ b/clients/socks5/src/commands/mod.rs @@ -89,11 +89,11 @@ pub(crate) struct OverrideConfig { enabled_credentials_mode: bool, } -pub(crate) async fn execute(args: &Cli) -> Result<(), Box> { +pub(crate) async fn execute(args: &Cli) -> Result<(), Box> { let bin_name = "nym-socks5-client"; match &args.command { - Commands::Init(m) => init::execute(m).await, + Commands::Init(m) => init::execute(m).await?, Commands::Run(m) => run::execute(m).await?, Commands::Upgrade(m) => upgrade::execute(m), Commands::Completions(s) => s.generate(&mut Cli::into_app(), bin_name), diff --git a/clients/socks5/src/commands/run.rs b/clients/socks5/src/commands/run.rs index 16f4b7bc53..c1886fc003 100644 --- a/clients/socks5/src/commands/run.rs +++ b/clients/socks5/src/commands/run.rs @@ -95,7 +95,7 @@ fn version_check(cfg: &Config) -> bool { } } -pub(crate) async fn execute(args: &Run) -> Result<(), Box> { +pub(crate) async fn execute(args: &Run) -> Result<(), Box> { let id = &args.id; let mut config = match Config::load_from_file(Some(id)) { diff --git a/clients/socks5/src/main.rs b/clients/socks5/src/main.rs index d41e5e4bd8..ea0071f538 100644 --- a/clients/socks5/src/main.rs +++ b/clients/socks5/src/main.rs @@ -13,7 +13,7 @@ pub mod error; pub mod socks; #[tokio::main] -async fn main() -> Result<(), Box> { +async fn main() -> Result<(), Box> { setup_logging(); println!("{}", banner()); diff --git a/clients/socks5/src/socks/types.rs b/clients/socks5/src/socks/types.rs index 3d8e5b161c..669a6b1093 100644 --- a/clients/socks5/src/socks/types.rs +++ b/clients/socks5/src/socks/types.rs @@ -1,5 +1,3 @@ -use snafu::Snafu; - /// SOCKS4 Response codes #[allow(dead_code)] pub(crate) enum ResponseCodeV4 { @@ -10,24 +8,26 @@ pub(crate) enum ResponseCodeV4 { } /// Possible SOCKS5 Response Codes -#[derive(Debug, Snafu)] +#[allow(dead_code)] +#[derive(Debug, thiserror::Error)] pub(crate) enum ResponseCodeV5 { + #[error("SOCKS5 Server Success")] Success = 0x00, - #[snafu(display("SOCKS5 Server Failure"))] + #[error("SOCKS5 Server Failure")] Failure = 0x01, - #[snafu(display("SOCKS5 Rule failure"))] + #[error("SOCKS5 Rule failure")] RuleFailure = 0x02, - #[snafu(display("network unreachable"))] + #[error("network unreachable")] NetworkUnreachable = 0x03, - #[snafu(display("host unreachable"))] + #[error("host unreachable")] HostUnreachable = 0x04, - #[snafu(display("connection refused"))] + #[error("connection refused")] ConnectionRefused = 0x05, - #[snafu(display("TTL expired"))] + #[error("TTL expired")] TtlExpired = 0x06, - #[snafu(display("Command not supported"))] + #[error("Command not supported")] CommandNotSupported = 0x07, - #[snafu(display("Addr Type not supported"))] + #[error("Addr Type not supported")] AddrTypeNotSupported = 0x08, } diff --git a/common/task/src/shutdown.rs b/common/task/src/shutdown.rs index 0f88135f9c..93b0d925a7 100644 --- a/common/task/src/shutdown.rs +++ b/common/task/src/shutdown.rs @@ -14,7 +14,7 @@ use tokio::{ const DEFAULT_SHUTDOWN_TIMER_SECS: u64 = 5; -pub(crate) type SentError = Box; +pub(crate) type SentError = Box; type ErrorSender = mpsc::UnboundedSender; type ErrorReceiver = mpsc::UnboundedReceiver; diff --git a/common/task/src/spawn.rs b/common/task/src/spawn.rs index 1286abf6dc..ba66ea7f16 100644 --- a/common/task/src/spawn.rs +++ b/common/task/src/spawn.rs @@ -22,7 +22,7 @@ pub fn spawn_with_report_error(future: F, mut shutdown: ShutdownListene where F: Future> + Send + 'static, T: 'static, - E: std::error::Error + Send + 'static, + E: std::error::Error + Send + Sync + 'static, { let future_that_sends = async move { if let Err(err) = future.await { diff --git a/nym-connect/Cargo.lock b/nym-connect/Cargo.lock index dea013dc0c..c128c9d40c 100644 --- a/nym-connect/Cargo.lock +++ b/nym-connect/Cargo.lock @@ -647,6 +647,7 @@ dependencies = [ "pemstore", "rand 0.7.3", "serde", + "serde_json", "sled", "tap", "task", @@ -1415,12 +1416,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "doc-comment" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" - [[package]] name = "dotenv" version = "0.15.0" @@ -3377,7 +3372,6 @@ dependencies = [ "rand 0.7.3", "serde", "serde_json", - "snafu", "socks5-requests", "tap", "task", @@ -5039,27 +5033,6 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" -[[package]] -name = "snafu" -version = "0.6.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eab12d3c261b2308b0d80c26fffb58d17eba81a4be97890101f416b478c79ca7" -dependencies = [ - "doc-comment", - "snafu-derive", -] - -[[package]] -name = "snafu-derive" -version = "0.6.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1508efa03c362e23817f96cde18abed596a25219a8b2c66e8db33c03543d315b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "socket2" version = "0.4.7" diff --git a/nym-connect/src-tauri/src/config/mod.rs b/nym-connect/src-tauri/src/config/mod.rs index 3a851cdba5..ade4ac2d57 100644 --- a/nym-connect/src-tauri/src/config/mod.rs +++ b/nym-connect/src-tauri/src/config/mod.rs @@ -115,6 +115,9 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str // Future proofing. This flag exists for the other clients let user_wants_force_register = false; + // If the client was already initialized, don't generate new keys and don't re-register with + // the gateway (because this would create a new shared key). + // Unless the user really wants to. let register_gateway = !already_init || user_wants_force_register; log::trace!("Creating config for id: {}", id); @@ -126,9 +129,10 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str .set_custom_validator_apis(config_common::parse_validators(&raw_validators)); } - let gateway = client_core::init::setup_gateway( + // Setup gateway by either registering a new one, or reusing exiting keys + let gateway = client_core::init::setup_gateway::( register_gateway, - Some(&chosen_gateway_id), + Some(chosen_gateway_id), config.get_base(), ) .await?; @@ -139,14 +143,14 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str log::error!("Failed to save the config file"); })?; - print_save_config(&config); + print_saved_config(&config); - let address = client_core::init::get_client_address(config.get_base())?; + let address = client_core::init::get_client_address_from_stored_keys(config.get_base())?; log::info!("The address of this client is: {}", address); Ok(()) } -fn print_save_config(config: &Config) { +fn print_saved_config(config: &Config) { log::info!( "Saved configuration file to {:?}", config.get_socks5().get_config_file_save_location() @@ -157,7 +161,6 @@ fn print_save_config(config: &Config) { "Gateway listener: {}", config.get_base().get_gateway_listener() ); - log::info!( "Service provider address: {}", config.get_socks5().get_provider_mix_address() diff --git a/nym-connect/src-tauri/src/tasks.rs b/nym-connect/src-tauri/src/tasks.rs index cd7ab86ad1..15b6daf297 100644 --- a/nym-connect/src-tauri/src/tasks.rs +++ b/nym-connect/src-tauri/src/tasks.rs @@ -1,4 +1,4 @@ -use client_core::config::GatewayEndpointConfig; +use client_core::config::{ClientCoreConfigTrait, GatewayEndpointConfig}; use futures::channel::mpsc; use std::sync::Arc; use tap::TapFallible; From cd1d9d1a0db41214f1691bbc565c61d53a1bbfad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Fri, 9 Dec 2022 18:44:40 +0100 Subject: [PATCH 10/39] client: pick from old lanes probabilisticlly (#1877) * Pick from old lanes probabilisticly * changelog: update --- CHANGELOG.md | 1 + .../real_traffic_stream/transmission_buffer.rs | 12 +++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77afb36529..7d6679628a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// - validator-api: can recover from shutdown during DKG process ([#1872]) - client-core: deduplicate gateway inititialization, part of work towards a rust-sdk +- clients: keep all transmission lanes going at all times by making priority probabilistic ### Fixed diff --git a/clients/client-core/src/client/real_messages_control/real_traffic_stream/transmission_buffer.rs b/clients/client-core/src/client/real_messages_control/real_traffic_stream/transmission_buffer.rs index b47aaf470e..20c7ce6cb7 100644 --- a/clients/client-core/src/client/real_messages_control/real_traffic_stream/transmission_buffer.rs +++ b/clients/client-core/src/client/real_messages_control/real_traffic_stream/transmission_buffer.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use client_connections::TransmissionLane; -use rand::seq::SliceRandom; +use rand::{seq::SliceRandom, Rng}; use std::{ collections::{HashMap, HashSet, VecDeque}, time::Duration, @@ -116,9 +116,15 @@ impl TransmissionBuffer { lanes.choose(&mut rand::thread_rng()).copied() } + // 2/3 chance to pick from the old lanes fn pick_random_old_lane(&self) -> Option { - let lanes = self.get_oldest_set(); - lanes.choose(&mut rand::thread_rng()).copied() + let rand = &mut rand::thread_rng(); + if rand.gen_ratio(2, 3) { + let lanes = self.get_oldest_set(); + lanes.choose(rand).copied() + } else { + self.pick_random_lane().copied() + } } fn pop_front_from_lane(&mut self, lane: &TransmissionLane) -> Option { From 29dd121282018042157bbb32f0d9086b57856d7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Fri, 9 Dec 2022 21:43:37 +0100 Subject: [PATCH 11/39] clients: dont panic in base client gateway client handling (#1878) * client-core: fix some panics related to gateway-client * changelog: update * fix --- CHANGELOG.md | 1 + .../client-core/src/client/base_client/mod.rs | 20 +++++++++---------- .../src/client/cover_traffic_stream.rs | 2 +- .../real_traffic_stream.rs | 2 +- clients/client-core/src/error.rs | 10 ++++++++++ 5 files changed, 23 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d6679628a..de4dbca79b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// ### Fixed - network-requester: fix bug where websocket connection disconnect resulted in success error code +- clients: fix a few panics handling the gateway-client [#1872]: https://github.com/nymtech/nym/pull/1872 diff --git a/clients/client-core/src/client/base_client/mod.rs b/clients/client-core/src/client/base_client/mod.rs index 21e5616458..07a4705bd5 100644 --- a/clients/client-core/src/client/base_client/mod.rs +++ b/clients/client-core/src/client/base_client/mod.rs @@ -28,7 +28,6 @@ use nymsphinx::addressing::clients::Recipient; use nymsphinx::addressing::nodes::NodeIdentity; #[cfg(feature = "reply-surb")] use std::path::PathBuf; -#[cfg(feature = "reply-surb")] use tap::TapFallible; use task::{ShutdownListener, ShutdownNotifier}; use url::Url; @@ -236,22 +235,22 @@ impl<'a> BaseClientBuilder<'a> { mixnet_message_sender: MixnetMessageSender, ack_sender: AcknowledgementSender, shutdown: ShutdownListener, - ) -> GatewayClient { + ) -> Result { let gateway_id = self.gateway_config.gateway_id.clone(); if gateway_id.is_empty() { - panic!("The identity of the gateway is unknown - did you run `nym-client` init?") + return Err(ClientCoreError::GatewayIdUnknown); } let gateway_owner = self.gateway_config.gateway_owner.clone(); if gateway_owner.is_empty() { - panic!("The owner of the gateway is unknown - did you run `nym-client` init?") + return Err(ClientCoreError::GatewayOwnerUnknown); } let gateway_address = self.gateway_config.gateway_listener.clone(); if gateway_address.is_empty() { - panic!("The address of the gateway is unknown - did you run `nym-client` init?") + return Err(ClientCoreError::GatwayAddressUnknown); } let gateway_identity = identity::PublicKey::from_base58_string(gateway_id) - .expect("provided gateway id is invalid!"); + .map_err(ClientCoreError::UnableToCreatePublicKeyFromGatewayId)?; // disgusting wasm workaround since there's no key persistence there (nor `client init`) let shared_key = if self.key_manager.gateway_key_set() { @@ -278,9 +277,10 @@ impl<'a> BaseClientBuilder<'a> { gateway_client .authenticate_and_start() .await - .expect("could not authenticate and start up the gateway connection"); - - gateway_client + .tap_err(|err| { + log::error!("Could not authenticate and start up the gateway connection - {err}") + })?; + Ok(gateway_client) } // future responsible for periodically polling directory server and updating @@ -375,7 +375,7 @@ impl<'a> BaseClientBuilder<'a> { let gateway_client = self .start_gateway_client(mixnet_messages_sender, ack_sender, shutdown.subscribe()) - .await; + .await?; // The sphinx_message_sender is the transmitter for any component generating sphinx packets // that are to be sent to the mixnet. They are used by cover traffic stream and real diff --git a/clients/client-core/src/client/cover_traffic_stream.rs b/clients/client-core/src/client/cover_traffic_stream.rs index 061e5f0b98..b862f1bcfe 100644 --- a/clients/client-core/src/client/cover_traffic_stream.rs +++ b/clients/client-core/src/client/cover_traffic_stream.rs @@ -191,7 +191,7 @@ impl LoopCoverTrafficStream { // However it's still useful to alert the user that the gateway or the link to // the gateway can't keep up. Either due to insufficient bandwidth on the // client side, or that the gateway is overloaded. - log::warn!("Failed to send: gateway appears to not keep up"); + log::warn!("Failed to send sphinx packet - gateway or connection to gatway can't keep up"); } TrySendError::Closed(_) => { log::warn!("Failed to send cover message - channel closed"); diff --git a/clients/client-core/src/client/real_messages_control/real_traffic_stream.rs b/clients/client-core/src/client/real_messages_control/real_traffic_stream.rs index c6ec08c15e..565eb8726e 100644 --- a/clients/client-core/src/client/real_messages_control/real_traffic_stream.rs +++ b/clients/client-core/src/client/real_messages_control/real_traffic_stream.rs @@ -489,7 +489,7 @@ where fn log_status_infrequent(&self) { if self.sending_delay_controller.current_multiplier() > 1 { log::warn!( - "Unable to send packets fast enough - sending delay multiplier set to: {}", + "Unable to send packets at the default rate - rate reduced by setting the delay multiplier set to: {}", self.sending_delay_controller.current_multiplier() ); } diff --git a/clients/client-core/src/error.rs b/clients/client-core/src/error.rs index f81a7536e8..8d12d0be92 100644 --- a/clients/client-core/src/error.rs +++ b/clients/client-core/src/error.rs @@ -35,6 +35,16 @@ pub enum ClientCoreError { #[error("The current network topology seem to be insufficient to route any packets through")] InsufficientNetworkTopology, + #[error("The gateway id is invalid - {0}")] + UnableToCreatePublicKeyFromGatewayId(Ed25519RecoveryError), + + #[error("The identity of the gateway is unknwown - did you run init?")] + GatewayIdUnknown, + #[error("The owner of the gateway is unknown - did you run init?")] + GatewayOwnerUnknown, + #[error("The address of the gateway is unknown - did you run init?")] + GatwayAddressUnknown, + #[error("Unexpected exit")] UnexpectedExit, } From 5283329914f31ebb771d5a00ed7dfd516c813737 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Fri, 9 Dec 2022 22:35:37 +0100 Subject: [PATCH 12/39] changelog: fix wording --- CHANGELOG.md | 2 +- service-providers/network-requester/src/core.rs | 2 +- service-providers/network-requester/src/main.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de4dbca79b..a354758f75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// ### Changed - validator-api: can recover from shutdown during DKG process ([#1872]) -- client-core: deduplicate gateway inititialization, part of work towards a rust-sdk +- clients: deduplicate gateway inititialization, part of work towards a rust-sdk - clients: keep all transmission lanes going at all times by making priority probabilistic ### Fixed diff --git a/service-providers/network-requester/src/core.rs b/service-providers/network-requester/src/core.rs index 70e0518e27..40f9cefd25 100644 --- a/service-providers/network-requester/src/core.rs +++ b/service-providers/network-requester/src/core.rs @@ -437,7 +437,7 @@ impl ServiceProvider { .await; }); - println!("\nAll systems go. Press CTRL-C to stop the server."); + log::info!("All systems go. Press CTRL-C to stop the server."); // for each incoming message from the websocket... (which in 99.99% cases is going to be a mix message) loop { let Some(received) = Self::read_websocket_message( diff --git a/service-providers/network-requester/src/main.rs b/service-providers/network-requester/src/main.rs index e6cb277610..3534f4b749 100644 --- a/service-providers/network-requester/src/main.rs +++ b/service-providers/network-requester/src/main.rs @@ -63,7 +63,7 @@ impl Run { .unwrap_or(&DEFAULT_WEBSOCKET_LISTENING_PORT.to_string()) ); - println!("Starting socks5 service provider:"); + log::info!("Starting socks5 service provider"); let mut server = core::ServiceProvider::new( uri, self.open_proxy, From 00f17c376a0a37425de7e6a768069e2dbd1464c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C5=9Fu?= Date: Mon, 12 Dec 2022 16:34:56 +0200 Subject: [PATCH 13/39] Use default mainnet values when nothing is specified (#1884) --- CHANGELOG.md | 2 ++ common/network-defaults/src/mainnet.rs | 4 ++-- gateway/src/config/mod.rs | 7 ++++--- mixnode/src/config/mod.rs | 3 ++- validator-api/src/config/mod.rs | 3 ++- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a354758f75..e6cf4c0a5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,8 +14,10 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// - network-requester: fix bug where websocket connection disconnect resulted in success error code - clients: fix a few panics handling the gateway-client +- mixnode, gateway, validator-api: Use mainnet values as defaults for URLs and mixnet contract ([#1884]) [#1872]: https://github.com/nymtech/nym/pull/1872 +[#1884]: https://github.com/nymtech/nym/pull/1884 ## [v1.1.2] diff --git a/common/network-defaults/src/mainnet.rs b/common/network-defaults/src/mainnet.rs index 59242376f9..ebacd0ff0d 100644 --- a/common/network-defaults/src/mainnet.rs +++ b/common/network-defaults/src/mainnet.rs @@ -9,7 +9,7 @@ pub(crate) const BECH32_PREFIX: &str = "n"; pub const MIX_DENOM: DenomDetails = DenomDetails::new("unym", "nym", 6); pub const STAKE_DENOM: DenomDetails = DenomDetails::new("unyx", "nyx", 6); -pub(crate) const MIXNET_CONTRACT_ADDRESS: &str = +pub const MIXNET_CONTRACT_ADDRESS: &str = "n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr"; pub(crate) const VESTING_CONTRACT_ADDRESS: &str = "n1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq73f2nw"; @@ -25,7 +25,7 @@ pub(crate) const _ETH_ERC20_CONTRACT_ADDRESS: [u8; 20] = hex_literal::hex!("0000000000000000000000000000000000000000"); pub(crate) const REWARDING_VALIDATOR_ADDRESS: &str = "n10yyd98e2tuwu0f7ypz9dy3hhjw7v772q6287gy"; -pub(crate) const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "https://mainnet-stats.nymte.ch:8090/"; +pub const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "https://mainnet-stats.nymte.ch:8090/"; pub const NYMD_VALIDATOR: &str = "https://rpc.nymtech.net"; pub const API_VALIDATOR: &str = "https://validator.nymtech.net/api/"; pub(crate) fn validators() -> Vec { diff --git a/gateway/src/config/mod.rs b/gateway/src/config/mod.rs index 9b04052217..ac4f734dad 100644 --- a/gateway/src/config/mod.rs +++ b/gateway/src/config/mod.rs @@ -5,6 +5,7 @@ use crate::config::template::config_template; use config::defaults::{DEFAULT_CLIENT_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT}; use config::NymConfig; use log::error; +use network_defaults::mainnet::{API_VALIDATOR, NYMD_VALIDATOR, STATISTICS_SERVICE_DOMAIN_ADDRESS}; use serde::{Deserialize, Serialize}; use std::net::IpAddr; use std::path::PathBuf; @@ -416,9 +417,9 @@ impl Default for Gateway { private_sphinx_key_file: Default::default(), public_sphinx_key_file: Default::default(), enabled_statistics: false, - statistics_service_url: Url::from_str("http://127.0.0.1").unwrap(), - validator_api_urls: vec![], - validator_nymd_urls: vec![], + statistics_service_url: Url::from_str(STATISTICS_SERVICE_DOMAIN_ADDRESS).expect("Invalid default statistics service URL"), + validator_api_urls: vec![Url::from_str(API_VALIDATOR).expect("Invalid default API URL")], + validator_nymd_urls: vec![Url::from_str(NYMD_VALIDATOR).expect("Invalid default nymd URL")], cosmos_mnemonic: bip39::Mnemonic::from_str("exact antique hybrid width raise anchor puzzle degree fee quit long crack net vague hip despair write put useless civil mechanic broom music day").unwrap(), nym_root_directory: Config::default_root_directory(), persistent_storage: Default::default(), diff --git a/mixnode/src/config/mod.rs b/mixnode/src/config/mod.rs index 23a80a5127..3f5208cee8 100644 --- a/mixnode/src/config/mod.rs +++ b/mixnode/src/config/mod.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::config::template::config_template; +use config::defaults::mainnet::API_VALIDATOR; use config::defaults::{ DEFAULT_HTTP_API_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT, DEFAULT_VERLOC_LISTENING_PORT, }; @@ -411,7 +412,7 @@ impl Default for MixNode { public_identity_key_file: Default::default(), private_sphinx_key_file: Default::default(), public_sphinx_key_file: Default::default(), - validator_api_urls: vec![], + validator_api_urls: vec![Url::from_str(API_VALIDATOR).expect("Invalid default API URL")], nym_root_directory: Config::default_root_directory(), wallet_address: "nymXXXXXXXX".to_string(), } diff --git a/validator-api/src/config/mod.rs b/validator-api/src/config/mod.rs index 715ed19311..d38acfb546 100644 --- a/validator-api/src/config/mod.rs +++ b/validator-api/src/config/mod.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::config::template::config_template; +use config::defaults::mainnet::MIXNET_CONTRACT_ADDRESS; use config::defaults::DEFAULT_VALIDATOR_API_PORT; use config::NymConfig; use serde::{Deserialize, Serialize}; @@ -119,7 +120,7 @@ impl Default for Base { id: String::default(), local_validator: default_validator, announce_address: default_announce_address, - mixnet_contract_address: String::default(), + mixnet_contract_address: MIXNET_CONTRACT_ADDRESS.to_string(), mnemonic: "exact antique hybrid width raise anchor puzzle degree fee quit long crack net vague hip despair write put useless civil mechanic broom music day".to_string(), } } From 47ca0d03582497317a3aff96e7b62d1d99b0f0c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C5=9Fu?= Date: Tue, 13 Dec 2022 11:52:18 +0200 Subject: [PATCH 14/39] Feature/dkg contract threshold (#1885) * Save threshold in dkg contract * Simplify the mock db for tests * Add unit test --- .../src/nymd/traits/dkg_query_client.rs | 7 + .../coconut-dkg/src/msg.rs | 1 + contracts/coconut-dkg/src/contract.rs | 5 +- .../coconut-dkg/src/epoch_state/queries.rs | 15 +- .../coconut-dkg/src/epoch_state/storage.rs | 1 + .../src/epoch_state/transactions.rs | 60 +++- validator-api/src/coconut/client.rs | 2 + validator-api/src/coconut/dkg/client.rs | 7 + validator-api/src/coconut/dkg/dealing.rs | 14 +- validator-api/src/coconut/dkg/state.rs | 4 +- .../src/coconut/dkg/verification_key.rs | 263 +++++------------- validator-api/src/coconut/tests.rs | 12 + validator-api/src/nymd_client.rs | 12 + 13 files changed, 196 insertions(+), 207 deletions(-) diff --git a/common/client-libs/validator-client/src/nymd/traits/dkg_query_client.rs b/common/client-libs/validator-client/src/nymd/traits/dkg_query_client.rs index 561b9f44ef..b67627d316 100644 --- a/common/client-libs/validator-client/src/nymd/traits/dkg_query_client.rs +++ b/common/client-libs/validator-client/src/nymd/traits/dkg_query_client.rs @@ -15,6 +15,7 @@ use cosmrs::AccountId; #[async_trait] pub trait DkgQueryClient { async fn get_current_epoch_state(&self) -> Result; + async fn get_current_epoch_threshold(&self) -> Result, NymdError>; async fn get_dealer_details( &self, address: &AccountId, @@ -54,6 +55,12 @@ where .query_contract_smart(self.coconut_dkg_contract_address(), &request) .await } + async fn get_current_epoch_threshold(&self) -> Result, NymdError> { + let request = DkgQueryMsg::GetCurrentEpochThreshold {}; + self.client + .query_contract_smart(self.coconut_dkg_contract_address(), &request) + .await + } async fn get_dealer_details( &self, address: &AccountId, diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs index 357e56b968..b2d0f1ae20 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs @@ -42,6 +42,7 @@ pub enum ExecuteMsg { #[serde(rename_all = "snake_case")] pub enum QueryMsg { GetCurrentEpochState {}, + GetCurrentEpochThreshold {}, GetDealerDetails { dealer_address: String, }, diff --git a/contracts/coconut-dkg/src/contract.rs b/contracts/coconut-dkg/src/contract.rs index 283a49ad1b..5394e845af 100644 --- a/contracts/coconut-dkg/src/contract.rs +++ b/contracts/coconut-dkg/src/contract.rs @@ -7,7 +7,7 @@ use crate::dealers::queries::{ use crate::dealers::transactions::try_add_dealer; use crate::dealings::queries::query_dealings_paged; use crate::dealings::transactions::try_commit_dealings; -use crate::epoch_state::queries::query_current_epoch_state; +use crate::epoch_state::queries::{query_current_epoch_state, query_current_epoch_threshold}; use crate::epoch_state::storage::CURRENT_EPOCH_STATE; use crate::epoch_state::transactions::advance_epoch_state; use crate::error::ContractError; @@ -87,6 +87,9 @@ pub fn execute( pub fn query(deps: Deps<'_>, _env: Env, msg: QueryMsg) -> Result { let response = match msg { QueryMsg::GetCurrentEpochState {} => to_binary(&query_current_epoch_state(deps.storage)?)?, + QueryMsg::GetCurrentEpochThreshold {} => { + to_binary(&query_current_epoch_threshold(deps.storage)?)? + } QueryMsg::GetDealerDetails { dealer_address } => { to_binary(&query_dealer_details(deps, dealer_address)?)? } diff --git a/contracts/coconut-dkg/src/epoch_state/queries.rs b/contracts/coconut-dkg/src/epoch_state/queries.rs index 4c63f40c7e..a7027ca488 100644 --- a/contracts/coconut-dkg/src/epoch_state/queries.rs +++ b/contracts/coconut-dkg/src/epoch_state/queries.rs @@ -1,7 +1,7 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::epoch_state::storage::CURRENT_EPOCH_STATE; +use crate::epoch_state::storage::{CURRENT_EPOCH_STATE, THRESHOLD}; use crate::error::ContractError; use coconut_dkg_common::types::EpochState; use cosmwasm_std::Storage; @@ -14,6 +14,12 @@ pub(crate) fn query_current_epoch_state( .map_err(|_| ContractError::EpochNotInitialised) } +pub(crate) fn query_current_epoch_threshold( + storage: &dyn Storage, +) -> Result, ContractError> { + Ok(THRESHOLD.may_load(storage)?) +} + #[cfg(test)] pub(crate) mod test { use super::*; @@ -25,4 +31,11 @@ pub(crate) mod test { let state = query_current_epoch_state(deps.as_mut().storage).unwrap(); assert_eq!(state, EpochState::PublicKeySubmission); } + + #[test] + fn query_threshold() { + let mut deps = init_contract(); + let state = query_current_epoch_threshold(deps.as_mut().storage).unwrap(); + assert!(state.is_none()); + } } diff --git a/contracts/coconut-dkg/src/epoch_state/storage.rs b/contracts/coconut-dkg/src/epoch_state/storage.rs index 87d1769183..b5c670d899 100644 --- a/contracts/coconut-dkg/src/epoch_state/storage.rs +++ b/contracts/coconut-dkg/src/epoch_state/storage.rs @@ -5,3 +5,4 @@ use coconut_dkg_common::types::EpochState; use cw_storage_plus::Item; pub(crate) const CURRENT_EPOCH_STATE: Item<'_, EpochState> = Item::new("current_epoch_state"); +pub const THRESHOLD: Item = Item::new("threshold"); diff --git a/contracts/coconut-dkg/src/epoch_state/transactions.rs b/contracts/coconut-dkg/src/epoch_state/transactions.rs index ba70371fd8..fbb597f668 100644 --- a/contracts/coconut-dkg/src/epoch_state/transactions.rs +++ b/contracts/coconut-dkg/src/epoch_state/transactions.rs @@ -1,22 +1,33 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::epoch_state::storage::CURRENT_EPOCH_STATE; +use crate::dealers::storage::current_dealers; +use crate::epoch_state::storage::{CURRENT_EPOCH_STATE, THRESHOLD}; use crate::error::ContractError; use crate::state::ADMIN; -use cosmwasm_std::{DepsMut, MessageInfo, Response}; +use coconut_dkg_common::types::EpochState; +use cosmwasm_std::{DepsMut, MessageInfo, Order, Response}; pub(crate) fn advance_epoch_state( deps: DepsMut<'_>, info: MessageInfo, ) -> Result { ADMIN.assert_admin(deps.as_ref(), &info.sender)?; - CURRENT_EPOCH_STATE.update::<_, ContractError>(deps.storage, |mut epoch_state| { - // TODO: When defaulting to the first state, some action will probably need to be taken on the - // rest of the contract, as we're starting with a new set of signers - epoch_state = epoch_state.next().unwrap_or_default(); - Ok(epoch_state) - })?; + let current_epoch_state = + CURRENT_EPOCH_STATE.update::<_, ContractError>(deps.storage, |mut epoch_state| { + // TODO: When defaulting to the first state, some action will probably need to be taken on the + // rest of the contract, as we're starting with a new set of signers + epoch_state = epoch_state.next().unwrap_or_default(); + Ok(epoch_state) + })?; + if current_epoch_state == EpochState::DealingExchange { + let current_dealer_count = current_dealers() + .keys(deps.storage, None, None, Order::Ascending) + .count(); + // note: ceiling in integer division can be achieved via q = (x + y - 1) / y; + let threshold = (2 * current_dealer_count as u64 + 3 - 1) / 3; + THRESHOLD.save(deps.storage, &threshold)?; + } Ok(Response::default()) } @@ -24,8 +35,9 @@ pub(crate) fn advance_epoch_state( pub(crate) mod tests { use super::*; use crate::support::tests::helpers::{init_contract, ADMIN_ADDRESS}; - use coconut_dkg_common::types::EpochState; + use coconut_dkg_common::types::{DealerDetails, EpochState}; use cosmwasm_std::testing::mock_info; + use cosmwasm_std::Addr; use cw_controllers::AdminError; #[test] @@ -75,4 +87,34 @@ pub(crate) mod tests { EpochState::PublicKeySubmission ); } + + #[test] + fn verify_threshold() { + let mut deps = init_contract(); + let admin_info = mock_info(ADMIN_ADDRESS, &[]); + + assert!(THRESHOLD.may_load(deps.as_mut().storage).unwrap().is_none()); + + for i in 1..101 { + let address = Addr::unchecked(format!("dealer{}", i)); + current_dealers() + .save( + deps.as_mut().storage, + &address, + &DealerDetails { + address: address.clone(), + bte_public_key_with_proof: "bte_public_key_with_proof".to_string(), + announce_address: "127.0.0.1".to_string(), + assigned_index: i, + }, + ) + .unwrap(); + } + + advance_epoch_state(deps.as_mut(), admin_info.clone()).unwrap(); + assert_eq!( + THRESHOLD.may_load(deps.as_mut().storage).unwrap().unwrap(), + 67 + ); + } } diff --git a/validator-api/src/coconut/client.rs b/validator-api/src/coconut/client.rs index 41fffd4856..87a64a4e6e 100644 --- a/validator-api/src/coconut/client.rs +++ b/validator-api/src/coconut/client.rs @@ -8,6 +8,7 @@ use coconut_dkg_common::types::{EncodedBTEPublicKeyWithProof, EpochState}; use coconut_dkg_common::verification_key::{ContractVKShare, VerificationKeyShare}; use contracts_common::dealings::ContractSafeBytes; use cw3::ProposalResponse; +use dkg::Threshold; use validator_client::nymd::cosmwasm_client::types::ExecuteResult; use validator_client::nymd::{AccountId, Fee, TxResponse}; @@ -22,6 +23,7 @@ pub trait Client { blinded_serial_number: String, ) -> Result; async fn get_current_epoch_state(&self) -> Result; + async fn get_current_epoch_threshold(&self) -> Result>; async fn get_self_registered_dealer_details(&self) -> Result; async fn get_current_dealers(&self) -> Result>; async fn get_dealings(&self, idx: usize) -> Result>; diff --git a/validator-api/src/coconut/dkg/client.rs b/validator-api/src/coconut/dkg/client.rs index 6850dabc1c..d8a0cf5d69 100644 --- a/validator-api/src/coconut/dkg/client.rs +++ b/validator-api/src/coconut/dkg/client.rs @@ -8,6 +8,7 @@ use coconut_dkg_common::types::{EncodedBTEPublicKeyWithProof, EpochState, NodeIn use coconut_dkg_common::verification_key::{ContractVKShare, VerificationKeyShare}; use contracts_common::dealings::ContractSafeBytes; use cw3::ProposalResponse; +use dkg::Threshold; use validator_client::nymd::cosmwasm_client::logs::{find_attribute, NODE_INDEX}; use validator_client::nymd::cosmwasm_client::types::ExecuteResult; use validator_client::nymd::AccountId; @@ -45,6 +46,12 @@ impl DkgClient { ret } + pub(crate) async fn get_current_epoch_threshold( + &self, + ) -> Result, CoconutError> { + self.inner.get_current_epoch_threshold().await + } + pub(crate) async fn get_self_registered_dealer_details( &self, ) -> Result { diff --git a/validator-api/src/coconut/dkg/dealing.rs b/validator-api/src/coconut/dkg/dealing.rs index 7e53202dac..1ecf272176 100644 --- a/validator-api/src/coconut/dkg/dealing.rs +++ b/validator-api/src/coconut/dkg/dealing.rs @@ -20,9 +20,7 @@ pub(crate) async fn dealing_exchange( } let dealers = dkg_client.get_current_dealers().await?; - // note: ceiling in integer division can be achieved via q = (x + y - 1) / y; - let threshold = (2 * dealers.len() as u64 + 3 - 1) / 3; - + let threshold = dkg_client.get_current_epoch_threshold().await?; state.set_dealers(dealers); state.set_threshold(threshold); let receivers = state.current_dealers_by_idx(); @@ -36,7 +34,7 @@ pub(crate) async fn dealing_exchange( rng.clone(), ¶ms, dealer_index, - threshold, + state.threshold()?, &receivers, None, ); @@ -105,10 +103,12 @@ pub(crate) mod tests { let self_index = 2; let dealer_details_db = Arc::new(RwLock::new(HashMap::new())); let dealings_db = Arc::new(RwLock::new(HashMap::new())); + let threshold_db = Arc::new(RwLock::new(Some(2))); let dkg_client = DkgClient::new( DummyClient::new(AccountId::from_str(TEST_VALIDATORS_ADDRESS[0]).unwrap()) .with_dealer_details(&dealer_details_db) - .with_dealings(&dealings_db), + .with_dealings(&dealings_db) + .with_threshold(&threshold_db), ); let params = setup(); let mut state = State::new( @@ -160,10 +160,12 @@ pub(crate) mod tests { let self_index = 2; let dealer_details_db = Arc::new(RwLock::new(HashMap::new())); let dealings_db = Arc::new(RwLock::new(HashMap::new())); + let threshold_db = Arc::new(RwLock::new(Some(2))); let dkg_client = DkgClient::new( DummyClient::new(AccountId::from_str(TEST_VALIDATORS_ADDRESS[0]).unwrap()) .with_dealer_details(&dealer_details_db) - .with_dealings(&dealings_db), + .with_dealings(&dealings_db) + .with_threshold(&threshold_db), ); let params = setup(); let mut state = State::new( diff --git a/validator-api/src/coconut/dkg/state.rs b/validator-api/src/coconut/dkg/state.rs index b7d7796ca0..9ba1dfaffd 100644 --- a/validator-api/src/coconut/dkg/state.rs +++ b/validator-api/src/coconut/dkg/state.rs @@ -333,8 +333,8 @@ impl State { self.receiver_index = receiver_index; } - pub fn set_threshold(&mut self, threshold: Threshold) { - self.threshold = Some(threshold); + pub fn set_threshold(&mut self, threshold: Option) { + self.threshold = threshold; } pub fn set_proposal_id(&mut self, proposal_id: u64) { diff --git a/validator-api/src/coconut/dkg/verification_key.rs b/validator-api/src/coconut/dkg/verification_key.rs index cecd825154..1ef88e0d54 100644 --- a/validator-api/src/coconut/dkg/verification_key.rs +++ b/validator-api/src/coconut/dkg/verification_key.rs @@ -266,28 +266,44 @@ pub(crate) mod tests { use url::Url; use validator_client::nymd::AccountId; + struct MockContractDb { + dealer_details_db: Arc>>, + dealings_db: Arc>>>, + proposal_db: Arc>>, + verification_share_db: Arc>>, + threshold_db: Arc>>, + } + + impl MockContractDb { + pub fn new() -> Self { + MockContractDb { + dealer_details_db: Arc::new(Default::default()), + dealings_db: Arc::new(Default::default()), + proposal_db: Arc::new(Default::default()), + verification_share_db: Arc::new(Default::default()), + threshold_db: Arc::new(RwLock::new(Some(2))), + } + } + } + const TEST_VALIDATORS_ADDRESS: [&str; 3] = [ "n1aq9kakfgwqcufr23lsv644apavcntrsqsk4yus", "n1s9l3xr4g0rglvk4yctktmck3h4eq0gp6z2e20v", "n19kl4py32vsk297dm93ezem992cdyzdy4zuc2x6", ]; - async fn prepare_clients_and_states( - dealer_details_db: &Arc>>, - dealings_db: &Arc>>>, - proposal_db: &Arc>>, - verification_share_db: &Arc>>, - ) -> Vec<(DkgClient, State)> { + async fn prepare_clients_and_states(db: &MockContractDb) -> Vec<(DkgClient, State)> { let params = setup(); let mut clients_and_states = vec![]; for addr in TEST_VALIDATORS_ADDRESS { let dkg_client = DkgClient::new( DummyClient::new(AccountId::from_str(addr).unwrap()) - .with_dealer_details(dealer_details_db) - .with_dealings(dealings_db) - .with_proposal_db(proposal_db) - .with_verification_share(verification_share_db), + .with_dealer_details(&db.dealer_details_db) + .with_dealings(&db.dealings_db) + .with_proposal_db(&db.proposal_db) + .with_verification_share(&db.verification_share_db) + .with_threshold(&db.threshold_db), ); let keypair = DkgKeyPair::new(¶ms, OsRng); let state = State::new( @@ -309,18 +325,9 @@ pub(crate) mod tests { } async fn prepare_clients_and_states_with_submission( - dealer_details_db: &Arc>>, - dealings_db: &Arc>>>, - proposal_db: &Arc>>, - verification_share_db: &Arc>>, + db: &MockContractDb, ) -> Vec<(DkgClient, State)> { - let mut clients_and_states = prepare_clients_and_states( - dealer_details_db, - dealings_db, - proposal_db, - verification_share_db, - ) - .await; + let mut clients_and_states = prepare_clients_and_states(db).await; for (dkg_client, state) in clients_and_states.iter_mut() { let random_file: usize = OsRng.gen(); let private_key_path = temp_dir().join(format!("private{}.pem", random_file)); @@ -336,18 +343,9 @@ pub(crate) mod tests { } async fn prepare_clients_and_states_with_validation( - dealer_details_db: &Arc>>, - dealings_db: &Arc>>>, - proposal_db: &Arc>>, - verification_share_db: &Arc>>, + db: &MockContractDb, ) -> Vec<(DkgClient, State)> { - let mut clients_and_states = prepare_clients_and_states_with_submission( - dealer_details_db, - dealings_db, - proposal_db, - verification_share_db, - ) - .await; + let mut clients_and_states = prepare_clients_and_states_with_submission(db).await; for (dkg_client, state) in clients_and_states.iter_mut() { verification_key_validation(dkg_client, state) .await @@ -357,18 +355,9 @@ pub(crate) mod tests { } async fn prepare_clients_and_states_with_finalization( - dealer_details_db: &Arc>>, - dealings_db: &Arc>>>, - proposal_db: &Arc>>, - verification_share_db: &Arc>>, + db: &MockContractDb, ) -> Vec<(DkgClient, State)> { - let mut clients_and_states = prepare_clients_and_states_with_validation( - dealer_details_db, - dealings_db, - proposal_db, - verification_share_db, - ) - .await; + let mut clients_and_states = prepare_clients_and_states_with_validation(db).await; for (dkg_client, state) in clients_and_states.iter_mut() { verification_key_finalization(dkg_client, state) .await @@ -380,17 +369,8 @@ pub(crate) mod tests { #[tokio::test] #[ignore] // expensive test async fn check_dealers_filter_all_good() { - let dealer_details_db = Arc::new(RwLock::new(HashMap::new())); - let dealings_db = Arc::new(RwLock::new(HashMap::new())); - let proposal_db = Arc::new(RwLock::new(HashMap::new())); - let verification_share_db = Arc::new(RwLock::new(HashMap::new())); - let mut clients_and_states = prepare_clients_and_states( - &dealer_details_db, - &dealings_db, - &proposal_db, - &verification_share_db, - ) - .await; + let db = MockContractDb::new(); + let mut clients_and_states = prepare_clients_and_states(&db).await; for (dkg_client, state) in clients_and_states.iter_mut() { let filtered = deterministic_filter_dealers(dkg_client, state, 2) .await @@ -405,20 +385,11 @@ pub(crate) mod tests { #[tokio::test] #[ignore] // expensive test async fn check_dealers_filter_one_bad_dealing() { - let dealer_details_db = Arc::new(RwLock::new(HashMap::new())); - let dealings_db = Arc::new(RwLock::new(HashMap::new())); - let proposal_db = Arc::new(RwLock::new(HashMap::new())); - let verification_share_db = Arc::new(RwLock::new(HashMap::new())); - let mut clients_and_states = prepare_clients_and_states( - &dealer_details_db, - &dealings_db, - &proposal_db, - &verification_share_db, - ) - .await; + let db = MockContractDb::new(); + let mut clients_and_states = prepare_clients_and_states(&db).await; // corrupt just one dealing - dealings_db + db.dealings_db .write() .unwrap() .entry(TEST_VALIDATORS_ADDRESS[0].to_string()) @@ -446,20 +417,11 @@ pub(crate) mod tests { #[tokio::test] #[ignore] // expensive test async fn check_dealers_filter_all_bad_dealings() { - let dealer_details_db = Arc::new(RwLock::new(HashMap::new())); - let dealings_db = Arc::new(RwLock::new(HashMap::new())); - let proposal_db = Arc::new(RwLock::new(HashMap::new())); - let verification_share_db = Arc::new(RwLock::new(HashMap::new())); - let mut clients_and_states = prepare_clients_and_states( - &dealer_details_db, - &dealings_db, - &proposal_db, - &verification_share_db, - ) - .await; + let db = MockContractDb::new(); + let mut clients_and_states = prepare_clients_and_states(&db).await; // corrupt all dealings of one address - dealings_db + db.dealings_db .write() .unwrap() .entry(TEST_VALIDATORS_ADDRESS[0].to_string()) @@ -490,20 +452,11 @@ pub(crate) mod tests { #[tokio::test] #[ignore] // expensive test async fn check_dealers_filter_malformed_dealing() { - let dealer_details_db = Arc::new(RwLock::new(HashMap::new())); - let dealings_db = Arc::new(RwLock::new(HashMap::new())); - let proposal_db = Arc::new(RwLock::new(HashMap::new())); - let verification_share_db = Arc::new(RwLock::new(HashMap::new())); - let mut clients_and_states = prepare_clients_and_states( - &dealer_details_db, - &dealings_db, - &proposal_db, - &verification_share_db, - ) - .await; + let db = MockContractDb::new(); + let mut clients_and_states = prepare_clients_and_states(&db).await; // corrupt just one dealing - dealings_db + db.dealings_db .write() .unwrap() .entry(TEST_VALIDATORS_ADDRESS[0].to_string()) @@ -536,20 +489,11 @@ pub(crate) mod tests { #[tokio::test] #[ignore] // expensive test async fn check_dealers_filter_dealing_verification_error() { - let dealer_details_db = Arc::new(RwLock::new(HashMap::new())); - let dealings_db = Arc::new(RwLock::new(HashMap::new())); - let proposal_db = Arc::new(RwLock::new(HashMap::new())); - let verification_share_db = Arc::new(RwLock::new(HashMap::new())); - let mut clients_and_states = prepare_clients_and_states( - &dealer_details_db, - &dealings_db, - &proposal_db, - &verification_share_db, - ) - .await; + let db = MockContractDb::new(); + let mut clients_and_states = prepare_clients_and_states(&db).await; // corrupt just one dealing - dealings_db + db.dealings_db .write() .unwrap() .entry(TEST_VALIDATORS_ADDRESS[0].to_string()) @@ -583,17 +527,8 @@ pub(crate) mod tests { #[tokio::test] #[ignore] // expensive test async fn partial_keypair_derivation() { - let dealer_details_db = Arc::new(RwLock::new(HashMap::new())); - let dealings_db = Arc::new(RwLock::new(HashMap::new())); - let proposal_db = Arc::new(RwLock::new(HashMap::new())); - let verification_share_db = Arc::new(RwLock::new(HashMap::new())); - let mut clients_and_states = prepare_clients_and_states( - &dealer_details_db, - &dealings_db, - &proposal_db, - &verification_share_db, - ) - .await; + let db = MockContractDb::new(); + let mut clients_and_states = prepare_clients_and_states(&db).await; for (dkg_client, state) in clients_and_states.iter_mut() { let filtered = deterministic_filter_dealers(dkg_client, state, 2) .await @@ -605,20 +540,11 @@ pub(crate) mod tests { #[tokio::test] #[ignore] // expensive test async fn partial_keypair_derivation_with_threshold() { - let dealer_details_db = Arc::new(RwLock::new(HashMap::new())); - let dealings_db = Arc::new(RwLock::new(HashMap::new())); - let proposal_db = Arc::new(RwLock::new(HashMap::new())); - let verification_share_db = Arc::new(RwLock::new(HashMap::new())); - let mut clients_and_states = prepare_clients_and_states( - &dealer_details_db, - &dealings_db, - &proposal_db, - &verification_share_db, - ) - .await; + let db = MockContractDb::new(); + let mut clients_and_states = prepare_clients_and_states(&db).await; // corrupt just one dealing - dealings_db + db.dealings_db .write() .unwrap() .entry(TEST_VALIDATORS_ADDRESS[0].to_string()) @@ -639,20 +565,12 @@ pub(crate) mod tests { #[tokio::test] #[ignore] // expensive test async fn submit_verification_key() { - let dealer_details_db = Arc::new(RwLock::new(HashMap::new())); - let dealings_db = Arc::new(RwLock::new(HashMap::new())); - let proposal_db = Arc::new(RwLock::new(HashMap::new())); - let verification_share_db = Arc::new(RwLock::new(HashMap::new())); - let mut clients_and_states = prepare_clients_and_states_with_submission( - &dealer_details_db, - &dealings_db, - &proposal_db, - &verification_share_db, - ) - .await; + let db = MockContractDb::new(); + let mut clients_and_states = prepare_clients_and_states_with_submission(&db).await; for (_, state) in clients_and_states.iter_mut() { - assert!(proposal_db + assert!(db + .proposal_db .read() .unwrap() .contains_key(&state.proposal_id_value().unwrap())); @@ -663,19 +581,11 @@ pub(crate) mod tests { #[tokio::test] #[ignore] // expensive test async fn validate_verification_key() { - let dealer_details_db = Arc::new(RwLock::new(HashMap::new())); - let dealings_db = Arc::new(RwLock::new(HashMap::new())); - let proposal_db = Arc::new(RwLock::new(HashMap::new())); - let verification_share_db = Arc::new(RwLock::new(HashMap::new())); - let mut clients_and_states = prepare_clients_and_states_with_validation( - &dealer_details_db, - &dealings_db, - &proposal_db, - &verification_share_db, - ) - .await; + let db = MockContractDb::new(); + let mut clients_and_states = prepare_clients_and_states_with_validation(&db).await; for (_, state) in clients_and_states.iter_mut() { - let proposal = proposal_db + let proposal = db + .proposal_db .read() .unwrap() .get(&state.proposal_id_value().unwrap()) @@ -688,19 +598,10 @@ pub(crate) mod tests { #[tokio::test] #[ignore] // expensive test async fn validate_verification_key_malformed_share() { - let dealer_details_db = Arc::new(RwLock::new(HashMap::new())); - let dealings_db = Arc::new(RwLock::new(HashMap::new())); - let proposal_db = Arc::new(RwLock::new(HashMap::new())); - let verification_share_db = Arc::new(RwLock::new(HashMap::new())); - let mut clients_and_states = prepare_clients_and_states_with_submission( - &dealer_details_db, - &dealings_db, - &proposal_db, - &verification_share_db, - ) - .await; + let db = MockContractDb::new(); + let mut clients_and_states = prepare_clients_and_states_with_submission(&db).await; - verification_share_db + db.verification_share_db .write() .unwrap() .entry(TEST_VALIDATORS_ADDRESS[0].to_string()) @@ -713,7 +614,8 @@ pub(crate) mod tests { } for (idx, (_, state)) in clients_and_states.iter().enumerate() { - let proposal = proposal_db + let proposal = db + .proposal_db .read() .unwrap() .get(&state.proposal_id_value().unwrap()) @@ -730,26 +632,18 @@ pub(crate) mod tests { #[tokio::test] #[ignore] // expensive test async fn validate_verification_key_unpaired_share() { - let dealer_details_db = Arc::new(RwLock::new(HashMap::new())); - let dealings_db = Arc::new(RwLock::new(HashMap::new())); - let proposal_db = Arc::new(RwLock::new(HashMap::new())); - let verification_share_db = Arc::new(RwLock::new(HashMap::new())); - let mut clients_and_states = prepare_clients_and_states_with_submission( - &dealer_details_db, - &dealings_db, - &proposal_db, - &verification_share_db, - ) - .await; + let db = MockContractDb::new(); + let mut clients_and_states = prepare_clients_and_states_with_submission(&db).await; - let second_share = verification_share_db + let second_share = db + .verification_share_db .write() .unwrap() .get(TEST_VALIDATORS_ADDRESS[1]) .unwrap() .share .clone(); - verification_share_db + db.verification_share_db .write() .unwrap() .entry(TEST_VALIDATORS_ADDRESS[0].to_string()) @@ -762,7 +656,8 @@ pub(crate) mod tests { } for (idx, (_, state)) in clients_and_states.iter().enumerate() { - let proposal = proposal_db + let proposal = db + .proposal_db .read() .unwrap() .get(&state.proposal_id_value().unwrap()) @@ -779,20 +674,12 @@ pub(crate) mod tests { #[tokio::test] #[ignore] // expensive test async fn finalize_verification_key() { - let dealer_details_db = Arc::new(RwLock::new(HashMap::new())); - let dealings_db = Arc::new(RwLock::new(HashMap::new())); - let proposal_db = Arc::new(RwLock::new(HashMap::new())); - let verification_share_db = Arc::new(RwLock::new(HashMap::new())); - let clients_and_states = prepare_clients_and_states_with_finalization( - &dealer_details_db, - &dealings_db, - &proposal_db, - &verification_share_db, - ) - .await; + let db = MockContractDb::new(); + let clients_and_states = prepare_clients_and_states_with_finalization(&db).await; for (_, state) in clients_and_states.iter() { - let proposal = proposal_db + let proposal = db + .proposal_db .read() .unwrap() .get(&state.proposal_id_value().unwrap()) diff --git a/validator-api/src/coconut/tests.rs b/validator-api/src/coconut/tests.rs index 66aee4f745..2a687eef24 100644 --- a/validator-api/src/coconut/tests.rs +++ b/validator-api/src/coconut/tests.rs @@ -45,6 +45,7 @@ use coconut_dkg_common::verification_key::{ContractVKShare, VerificationKeyShare use contracts_common::dealings::ContractSafeBytes; use crypto::asymmetric::{encryption, identity}; use cw3::ProposalResponse; +use dkg::Threshold; use rand_07::rngs::OsRng; use rand_07::Rng; use rocket::http::Status; @@ -67,6 +68,7 @@ pub(crate) struct DummyClient { epoch_state: Arc>, dealer_details: Arc>>, + threshold: Arc>>, dealings: Arc>>>, verification_share: Arc>>, } @@ -80,6 +82,7 @@ impl DummyClient { spent_credential_db: Arc::new(RwLock::new(HashMap::new())), epoch_state: Arc::new(RwLock::new(EpochState::default())), dealer_details: Arc::new(RwLock::new(HashMap::new())), + threshold: Arc::new(RwLock::new(None)), dealings: Arc::new(RwLock::new(HashMap::new())), verification_share: Arc::new(RwLock::new(HashMap::new())), } @@ -119,6 +122,11 @@ impl DummyClient { self } + pub fn with_threshold(mut self, threshold: &Arc>>) -> Self { + self.threshold = Arc::clone(threshold); + self + } + pub fn with_dealings( mut self, dealings: &Arc>>>, @@ -184,6 +192,10 @@ impl super::client::Client for DummyClient { Ok(*self.epoch_state.read().unwrap()) } + async fn get_current_epoch_threshold(&self) -> Result> { + Ok(*self.threshold.read().unwrap()) + } + async fn get_self_registered_dealer_details(&self) -> Result { Ok(DealerDetailsResponse { details: self diff --git a/validator-api/src/nymd_client.rs b/validator-api/src/nymd_client.rs index 676a65e8d9..1f126d6fdc 100644 --- a/validator-api/src/nymd_client.rs +++ b/validator-api/src/nymd_client.rs @@ -333,6 +333,18 @@ where Ok(self.0.read().await.nymd.get_current_epoch_state().await?) } + async fn get_current_epoch_threshold( + &self, + ) -> crate::coconut::error::Result> { + Ok(self + .0 + .read() + .await + .nymd + .get_current_epoch_threshold() + .await?) + } + async fn get_self_registered_dealer_details( &self, ) -> crate::coconut::error::Result { From e18946efe1e16a359395e541349afa874c630f11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Tue, 13 Dec 2022 10:53:01 +0100 Subject: [PATCH 15/39] nym-connect: send status messages from socks5 task to tauri backend (#1882) * nym-connect: send status messages from socks5 task to tauri backend * common/tasks: fix spawn for wasm * Tidy up some names * make status channel bounded in case there is no one listening --- .../real_traffic_stream.rs | 13 +++- .../sending_delay_controller.rs | 8 +++ clients/client-core/src/error.rs | 9 +++ clients/socks5/src/client/mod.rs | 5 ++ common/task/src/lib.rs | 3 +- common/task/src/shutdown.rs | 59 ++++++++++++++++- nym-connect/Cargo.lock | 1 + nym-connect/src-tauri/Cargo.toml | 1 + .../src/operations/connection/connect.rs | 5 +- nym-connect/src-tauri/src/state.rs | 15 +++-- nym-connect/src-tauri/src/tasks.rs | 65 ++++++++++++++----- 11 files changed, 156 insertions(+), 28 deletions(-) diff --git a/clients/client-core/src/client/real_messages_control/real_traffic_stream.rs b/clients/client-core/src/client/real_messages_control/real_traffic_stream.rs index 565eb8726e..734b75bb70 100644 --- a/clients/client-core/src/client/real_messages_control/real_traffic_stream.rs +++ b/clients/client-core/src/client/real_messages_control/real_traffic_stream.rs @@ -459,7 +459,9 @@ where } #[cfg(not(target_arch = "wasm32"))] - fn log_status(&self) { + fn log_status(&self, shutdown: &mut task::ShutdownListener) { + use crate::error::ClientCoreStatusMessage; + let packets = self.transmission_buffer.total_size(); let backlog = self.transmission_buffer.total_size_in_bytes() as f64 / 1024.0; let lanes = self.transmission_buffer.num_lanes(); @@ -483,6 +485,13 @@ where } else { log::debug!("{status_str}"); } + + // Send status message to whoever is listening (possibly UI) + if mult == self.sending_delay_controller.max_multiplier() { + shutdown.send_status_msg(Box::new(ClientCoreStatusMessage::GatewayIsVerySlow)); + } else if mult > self.sending_delay_controller.min_multiplier() { + shutdown.send_status_msg(Box::new(ClientCoreStatusMessage::GatewayIsSlow)); + } } #[cfg(not(target_arch = "wasm32"))] @@ -510,7 +519,7 @@ where log::trace!("OutQueueControl: Received shutdown"); } _ = status_timer.tick() => { - self.log_status(); + self.log_status(&mut shutdown); } _ = infrequent_status_timer.tick() => { self.log_status_infrequent(); diff --git a/clients/client-core/src/client/real_messages_control/real_traffic_stream/sending_delay_controller.rs b/clients/client-core/src/client/real_messages_control/real_traffic_stream/sending_delay_controller.rs index b22ffae7ff..4ae2632b85 100644 --- a/clients/client-core/src/client/real_messages_control/real_traffic_stream/sending_delay_controller.rs +++ b/clients/client-core/src/client/real_messages_control/real_traffic_stream/sending_delay_controller.rs @@ -77,6 +77,14 @@ impl SendingDelayController { self.current_multiplier } + pub(crate) fn min_multiplier(&self) -> u32 { + self.lower_bound + } + + pub(crate) fn max_multiplier(&self) -> u32 { + self.upper_bound + } + pub(crate) fn increase_delay_multiplier(&mut self) { if self.current_multiplier < self.upper_bound { self.current_multiplier = diff --git a/clients/client-core/src/error.rs b/clients/client-core/src/error.rs index 8d12d0be92..37538d9e04 100644 --- a/clients/client-core/src/error.rs +++ b/clients/client-core/src/error.rs @@ -48,3 +48,12 @@ pub enum ClientCoreError { #[error("Unexpected exit")] UnexpectedExit, } + +/// Set of messages that the client can send to listeners via the task manager +#[derive(thiserror::Error, Debug)] +pub enum ClientCoreStatusMessage { + #[error("The connected gateway is slow, or the connection to it is slow")] + GatewayIsSlow, + #[error("The connected gateway is very slow, or the connection to it is very slow")] + GatewayIsVerySlow, +} diff --git a/clients/socks5/src/client/mod.rs b/clients/socks5/src/client/mod.rs index ea0af81fd7..4103dd2788 100644 --- a/clients/socks5/src/client/mod.rs +++ b/clients/socks5/src/client/mod.rs @@ -150,10 +150,15 @@ impl NymClient { pub async fn run_and_listen( self, mut receiver: Socks5ControlMessageReceiver, + sender: task::StatusSender, ) -> Result<(), Box> { // Start the main task let mut shutdown = self.start().await?; + // Listen to status messages from task, that we forward back to the caller + shutdown.start_status_listener(sender); + + // Listen for conditions to stop let res = tokio::select! { biased; message = receiver.next() => { diff --git a/common/task/src/lib.rs b/common/task/src/lib.rs index 667936a830..5d3d0ea2f5 100644 --- a/common/task/src/lib.rs +++ b/common/task/src/lib.rs @@ -6,7 +6,8 @@ pub mod shutdown; pub mod signal; pub mod spawn; -pub use shutdown::{ShutdownListener, ShutdownNotifier}; +// WIP(JON): those both need to be public? +pub use shutdown::{ShutdownListener, ShutdownNotifier, StatusReceiver, StatusSender}; #[cfg(not(target_arch = "wasm32"))] pub use signal::{wait_for_signal, wait_for_signal_and_error}; diff --git a/common/task/src/shutdown.rs b/common/task/src/shutdown.rs index 93b0d925a7..09e8abcb50 100644 --- a/common/task/src/shutdown.rs +++ b/common/task/src/shutdown.rs @@ -3,7 +3,7 @@ use std::{error::Error, time::Duration}; -use futures::{future::pending, FutureExt}; +use futures::{future::pending, FutureExt, SinkExt, StreamExt}; use tokio::{ sync::{ mpsc, @@ -14,10 +14,15 @@ use tokio::{ const DEFAULT_SHUTDOWN_TIMER_SECS: u64 = 5; +// WIP(JON): can these be from futures channel too? pub(crate) type SentError = Box; type ErrorSender = mpsc::UnboundedSender; type ErrorReceiver = mpsc::UnboundedReceiver; +pub type SentStatus = Box; +pub type StatusSender = futures::channel::mpsc::Sender; +pub type StatusReceiver = futures::channel::mpsc::Receiver; + #[derive(thiserror::Error, Debug)] enum TaskError { #[error("Task halted unexpectedly")] @@ -43,6 +48,11 @@ pub struct ShutdownNotifier { // didn't manage to reliably get the explicitly sent error (and not the error sent during drop) task_drop_tx: ErrorSender, task_drop_rx: Option, + + // A task might also send non-fatal errors (effectively, warnings) while running that is not + // the result of exiting. + task_status_tx: StatusSender, + task_status_rx: Option, } impl Default for ShutdownNotifier { @@ -50,6 +60,9 @@ impl Default for ShutdownNotifier { let (notify_tx, notify_rx) = watch::channel(()); let (task_halt_tx, task_halt_rx) = mpsc::unbounded_channel(); let (task_drop_tx, task_drop_rx) = mpsc::unbounded_channel(); + // The status channel is bounded (unlike the others), since it's not always the case that + // there is a listener. + let (task_status_tx, task_status_rx) = futures::channel::mpsc::channel(128); Self { notify_tx, notify_rx: Some(notify_rx), @@ -58,11 +71,17 @@ impl Default for ShutdownNotifier { task_return_error_rx: Some(task_halt_rx), task_drop_tx, task_drop_rx: Some(task_drop_rx), + task_status_tx, + task_status_rx: Some(task_status_rx), } } } impl ShutdownNotifier { + pub fn take_task_status_rx(&mut self) -> Option { + self.task_status_rx.take() + } + pub fn new(shutdown_timer_secs: u64) -> Self { Self { shutdown_timer_secs, @@ -78,6 +97,7 @@ impl ShutdownNotifier { .clone(), self.task_return_error_tx.clone(), self.task_drop_tx.clone(), + self.task_status_tx.clone(), ) } @@ -85,6 +105,26 @@ impl ShutdownNotifier { self.notify_tx.send(()) } + pub fn start_status_listener(&mut self, mut sender: StatusSender) { + if let Some(mut task_status_rx) = self.task_status_rx.take() { + log::info!("Starting status message listener"); + crate::spawn::spawn(async move { + loop { + if let Some(msg) = task_status_rx.next().await { + log::trace!("Got msg: {}", msg); + if sender.send(msg).await.is_err() { + log::error!("Error sending status message"); + } + } else { + log::trace!("Stopping since channel closed"); + break; + } + } + log::debug!("Status listener: Exiting"); + }); + } + } + pub async fn wait_for_error(&mut self) -> Option { let mut error_rx = self .task_return_error_rx @@ -149,6 +189,9 @@ pub struct ShutdownListener { // Also notify if we dropped without shutdown being registered drop_error: ErrorSender, + // Send non-exit messages + status_msg: StatusSender, + // The current operating mode mode: ShutdownListenerMode, } @@ -161,12 +204,14 @@ impl ShutdownListener { notify: watch::Receiver<()>, return_error: ErrorSender, drop_error: ErrorSender, + status_msg: StatusSender, ) -> ShutdownListener { ShutdownListener { shutdown: false, notify, return_error, drop_error, + status_msg, mode: ShutdownListenerMode::Listening, } } @@ -176,11 +221,14 @@ impl ShutdownListener { let (_notify_tx, notify_rx) = watch::channel(()); let (task_halt_tx, _task_halt_rx) = mpsc::unbounded_channel(); let (task_drop_tx, _task_drop_rx) = mpsc::unbounded_channel(); + //let (task_status_tx, _task_status_rx) = futures::channel::mpsc::unbounded(); + let (task_status_tx, _task_status_rx) = futures::channel::mpsc::channel(128); ShutdownListener { shutdown: false, notify: notify_rx, return_error: task_halt_tx, drop_error: task_drop_tx, + status_msg: task_status_tx, mode: ShutdownListenerMode::Dummy, } } @@ -256,6 +304,15 @@ impl ShutdownListener { log::error!("Failed to send back error message"); } } + + pub fn send_status_msg(&mut self, msg: SentStatus) { + if self.mode.is_dummy() { + return; + } + // Since it's not always the case that anyone is listening, just try send and ignore any + // failures. + self.status_msg.try_send(msg).ok(); + } } impl Drop for ShutdownListener { diff --git a/nym-connect/Cargo.lock b/nym-connect/Cargo.lock index c128c9d40c..1c6bd7ed3e 100644 --- a/nym-connect/Cargo.lock +++ b/nym-connect/Cargo.lock @@ -3332,6 +3332,7 @@ dependencies = [ "serde", "serde_json", "tap", + "task", "tauri", "tauri-build", "tauri-codegen", diff --git a/nym-connect/src-tauri/Cargo.toml b/nym-connect/src-tauri/Cargo.toml index d5ae83e869..e507f78dc5 100644 --- a/nym-connect/src-tauri/Cargo.toml +++ b/nym-connect/src-tauri/Cargo.toml @@ -42,6 +42,7 @@ client-core = { path = "../../clients/client-core" } config-common = { path = "../../common/config", package = "config" } logging = { path = "../../common/logging"} nym-socks5-client = { path = "../../clients/socks5" } +task = { path = "../../common/task" } topology = { path = "../../common/topology" } [dev-dependencies] diff --git a/nym-connect/src-tauri/src/operations/connection/connect.rs b/nym-connect/src-tauri/src/operations/connection/connect.rs index 032221d456..b377dfcec7 100644 --- a/nym-connect/src-tauri/src/operations/connection/connect.rs +++ b/nym-connect/src-tauri/src/operations/connection/connect.rs @@ -11,14 +11,15 @@ pub async fn start_connecting( state: tauri::State<'_, Arc>>, window: tauri::Window, ) -> Result { - let status_receiver = { + let (msg_receiver, exit_status_receiver) = { let mut state_w = state.write().await; state_w.start_connecting(&window).await? }; // Setup task for checking status let state = state.inner().clone(); - tasks::start_disconnect_listener(state, window, status_receiver); + tasks::start_disconnect_listener(state, window.clone(), exit_status_receiver); + tasks::start_status_listener(window, msg_receiver); Ok(ConnectResult { address: "PLACEHOLDER".to_string(), diff --git a/nym-connect/src-tauri/src/state.rs b/nym-connect/src-tauri/src/state.rs index 6d0f34bc8f..3a98aa3747 100644 --- a/nym-connect/src-tauri/src/state.rs +++ b/nym-connect/src-tauri/src/state.rs @@ -16,7 +16,7 @@ use crate::{ AppEventConnectionStatusChangedPayload, ConnectionStatusKind, APP_EVENT_CONNECTION_STATUS_CHANGED, }, - tasks::{self, StatusReceiver}, + tasks::{self, ExitStatusReceiver}, }; pub struct State { @@ -96,7 +96,7 @@ impl State { pub async fn start_connecting( &mut self, window: &tauri::Window, - ) -> Result { + ) -> Result<(task::StatusReceiver, ExitStatusReceiver)> { self.set_state(ConnectionStatusKind::Connecting, window); // Setup configuration by writing to file @@ -111,9 +111,9 @@ impl State { } // Kick off the main task and get the channel for controlling it - let status_receiver = self.start_nym_socks5_client().await?; + let (msg_receiver, exit_status_receiver) = self.start_nym_socks5_client()?; self.set_state(ConnectionStatusKind::Connected, window); - Ok(status_receiver) + Ok((msg_receiver, exit_status_receiver)) } /// Create a configuration file @@ -133,12 +133,13 @@ impl State { } /// Spawn a new thread running the SOCKS5 client - async fn start_nym_socks5_client(&mut self) -> Result { + fn start_nym_socks5_client(&mut self) -> Result<(task::StatusReceiver, ExitStatusReceiver)> { let id = self.get_config_id()?; - let (control_tx, status_rx, used_gateway) = tasks::start_nym_socks5_client(&id)?; + let (control_tx, msg_rx, exit_status_rx, used_gateway) = + tasks::start_nym_socks5_client(&id)?; self.socks5_client_sender = Some(control_tx); self.gateway = Some(used_gateway.gateway_id); - Ok(status_rx) + Ok((msg_rx, exit_status_rx)) } /// Disconnect by sending a message to the SOCKS5 client thread. Once it has finished and is diff --git a/nym-connect/src-tauri/src/tasks.rs b/nym-connect/src-tauri/src/tasks.rs index 15b6daf297..ef54fddcaa 100644 --- a/nym-connect/src-tauri/src/tasks.rs +++ b/nym-connect/src-tauri/src/tasks.rs @@ -1,5 +1,5 @@ use client_core::config::{ClientCoreConfigTrait, GatewayEndpointConfig}; -use futures::channel::mpsc; +use futures::{channel::mpsc, StreamExt}; use std::sync::Arc; use tap::TapFallible; use tokio::sync::RwLock; @@ -11,11 +11,11 @@ use nym_socks5::client::{config::Config as Socks5Config, Socks5ControlMessageSen use crate::{error::Result, state::State}; -pub type StatusReceiver = futures::channel::oneshot::Receiver; +pub type ExitStatusReceiver = futures::channel::oneshot::Receiver; /// Status messages sent by the SOCKS5 client task to the main tauri task. #[derive(Debug)] -pub enum Socks5StatusMessage { +pub enum Socks5ExitStatusMessage { /// The SOCKS5 task successfully stopped Stopped, /// The SOCKS5 task failed to start @@ -27,7 +27,8 @@ pub fn start_nym_socks5_client( id: &str, ) -> Result<( Socks5ControlMessageSender, - StatusReceiver, + task::StatusReceiver, + ExitStatusReceiver, GatewayEndpointConfig, )> { log::info!("Loading config from file: {id}"); @@ -41,8 +42,11 @@ pub fn start_nym_socks5_client( // Channel to send control messages to the socks5 client let (socks5_ctrl_tx, socks5_ctrl_rx) = mpsc::unbounded(); + // Channel to send status update messages from the background socks5 task to the frontend. + let (socks5_status_tx, socks5_status_rx) = mpsc::channel(128); + // Channel to signal back to the main task when the socks5 client finishes, and why - let (socks5_status_tx, socks5_status_rx) = futures::channel::oneshot::channel(); + let (socks5_exit_tx, socks5_exit_rx) = futures::channel::oneshot::channel(); // Spawn a separate runtime for the socks5 client so we can forcefully terminate. // Once we can gracefully shutdown the socks5 client we can get rid of this. @@ -51,23 +55,32 @@ pub fn start_nym_socks5_client( std::thread::spawn(|| { let result = tokio::runtime::Runtime::new() .expect("Failed to create runtime for SOCKS5 client") - .block_on(async move { socks5_client.run_and_listen(socks5_ctrl_rx).await }); + .block_on(async move { + socks5_client + .run_and_listen(socks5_ctrl_rx, socks5_status_tx) + .await + }); if let Err(err) = result { log::error!("SOCKS5 proxy failed: {err}"); - socks5_status_tx - .send(Socks5StatusMessage::Failed(err)) + socks5_exit_tx + .send(Socks5ExitStatusMessage::Failed(err)) .expect("Failed to send status message back to main task"); return; } log::info!("SOCKS5 task finished"); - socks5_status_tx - .send(Socks5StatusMessage::Stopped) + socks5_exit_tx + .send(Socks5ExitStatusMessage::Stopped) .expect("Failed to send status message back to main task"); }); - Ok((socks5_ctrl_tx, socks5_status_rx, used_gateway)) + Ok(( + socks5_ctrl_tx, + socks5_status_rx, + socks5_exit_rx, + used_gateway, + )) } #[derive(Clone, serde::Serialize)] @@ -76,17 +89,39 @@ struct Payload { message: String, } +/// The status listener listens for non-exit status messages from the background socks5 proxy task. +pub fn start_status_listener( + window: tauri::Window, + mut msg_receiver: task::StatusReceiver, +) { + log::info!("Starting status listener"); + tokio::spawn(async move { + while let Some(msg) = msg_receiver.next().await { + log::info!("SOCKS5 proxy sent status message: {}", msg); + window + .emit( + "socks5-event", + Payload { + title: "SOCKS5 update".into(), + message: msg.to_string(), + }, + ) + .unwrap(); + } + }); +} + /// The disconnect listener listens to the channel setup between the socks5 proxy task and the main /// tauri task. Primarily it listens for shutdown messages, and updates the state accordingly. pub fn start_disconnect_listener( state: Arc>, window: tauri::Window, - status_receiver: StatusReceiver, + exit_status_receiver: ExitStatusReceiver, ) { log::trace!("Starting disconnect listener"); tokio::spawn(async move { - match status_receiver.await { - Ok(Socks5StatusMessage::Stopped) => { + match exit_status_receiver.await { + Ok(Socks5ExitStatusMessage::Stopped) => { log::info!("SOCKS5 task reported it has finished"); window .emit( @@ -98,7 +133,7 @@ pub fn start_disconnect_listener( ) .unwrap(); } - Ok(Socks5StatusMessage::Failed(err)) => { + Ok(Socks5ExitStatusMessage::Failed(err)) => { log::info!("SOCKS5 task reported error: {}", err); window .emit( From c720481a45d0c08c012aa864c90f3cd0f667efae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Tue, 13 Dec 2022 11:39:02 +0100 Subject: [PATCH 16/39] socks5: rework waiting in inbound.rs (#1880) * socks5: rework waiting in inbound.rs * changelog: add note * out queue control: reduce old set size to 4 --- CHANGELOG.md | 1 + .../transmission_buffer.rs | 2 +- .../proxy-helpers/src/proxy_runner/inbound.rs | 45 +++++++++++-------- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6cf4c0a5a..5b03ddd8ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// - network-requester: fix bug where websocket connection disconnect resulted in success error code - clients: fix a few panics handling the gateway-client - mixnode, gateway, validator-api: Use mainnet values as defaults for URLs and mixnet contract ([#1884]) +- socks5: fixed bug where connections sometimes where closed too early [#1872]: https://github.com/nymtech/nym/pull/1872 [#1884]: https://github.com/nymtech/nym/pull/1884 diff --git a/clients/client-core/src/client/real_messages_control/real_traffic_stream/transmission_buffer.rs b/clients/client-core/src/client/real_messages_control/real_traffic_stream/transmission_buffer.rs index 20c7ce6cb7..1f16f472c1 100644 --- a/clients/client-core/src/client/real_messages_control/real_traffic_stream/transmission_buffer.rs +++ b/clients/client-core/src/client/real_messages_control/real_traffic_stream/transmission_buffer.rs @@ -17,7 +17,7 @@ use wasm_timer; use super::{get_time_now, RealMessage}; // The number of lanes included in the oldest set. Used when we need to prioritize traffic. -const OLDEST_LANE_SET_SIZE: usize = 5; +const OLDEST_LANE_SET_SIZE: usize = 4; // As a way of prune connections we also check for timeouts. const MSG_CONSIDERED_STALE_AFTER_SECS: u64 = 10 * 60; diff --git a/common/socks5/proxy-helpers/src/proxy_runner/inbound.rs b/common/socks5/proxy-helpers/src/proxy_runner/inbound.rs index f2ebc2cd9b..37403c33ad 100644 --- a/common/socks5/proxy-helpers/src/proxy_runner/inbound.rs +++ b/common/socks5/proxy-helpers/src/proxy_runner/inbound.rs @@ -77,16 +77,11 @@ where ordered_msg.len() ); - // If we are closing the socket, wait until the data has passed `OutQueueControl` and the lane - // is empty, otherwise just wait until we are reasonably close to finish sending as a way to - // throttle the incoming data. - if let Some(lane_queue_lengths) = lane_queue_lengths { - if is_finished { - wait_until_lane_empty(lane_queue_lengths, connection_id).await; - } else { - // We allow a bit of slack when this is not the last msg - wait_until_lane_almost_empty(lane_queue_lengths, connection_id).await; - } + // Before sending the data downstream, wait for the lane at the `OutQueueControl` is reasonably + // close to finishing. This is a way of pacing the sending application (backpressure). + if let Some(ref lane_queue_lengths) = lane_queue_lengths { + // We allow a bit of slack to try to keep the pipeline >0 + wait_until_lane_almost_empty(lane_queue_lengths, connection_id).await; } mix_sender @@ -95,16 +90,30 @@ where .expect("InputMessageReceiver has stopped receiving!"); if is_finished { - // technically we already informed it when we sent the message to mixnet above - debug!(target: &*format!("({}) socks5 inbound", connection_id), "The local socket is closed - won't receive any more data. Informing remote about that..."); + // After sending, if this is the last message, wait until we've actually transmitted the data + // in the `OutQueueControl` and the lane is empty. + if let Some(ref lane_queue_lengths) = lane_queue_lengths { + // This is basically an ugly workaround to make sure that we don't start waiting until + // the data that we pushed arrived at the OutQueueControl. + // This usually not a problem in the socks5-client, but for the network-requester this + // info is synced at up to every 500ms. + sleep(Duration::from_secs(2)).await; + wait_until_lane_empty(lane_queue_lengths, connection_id).await; + } + + // Technically we already informed it when we sent the message to mixnet above + debug!( + target: &*format!("({}) socks5 inbound", connection_id), + "The local socket is closed - won't receive any more data. Informing remote about that..." + ); } is_finished } -async fn wait_until_lane_empty(lane_queue_lengths: LaneQueueLengths, connection_id: u64) { +async fn wait_until_lane_empty(lane_queue_lengths: &LaneQueueLengths, connection_id: u64) { if tokio::time::timeout( - Duration::from_secs(2 * 60), + Duration::from_secs(4 * 60), wait_for_lane( lane_queue_lengths, connection_id, @@ -119,13 +128,13 @@ async fn wait_until_lane_empty(lane_queue_lengths: LaneQueueLengths, connection_ } } -async fn wait_until_lane_almost_empty(lane_queue_lengths: LaneQueueLengths, connection_id: u64) { +async fn wait_until_lane_almost_empty(lane_queue_lengths: &LaneQueueLengths, connection_id: u64) { if tokio::time::timeout( - Duration::from_secs(2 * 60), + Duration::from_secs(4 * 60), wait_for_lane( lane_queue_lengths, connection_id, - 10, + 30, Duration::from_millis(100), ), ) @@ -137,7 +146,7 @@ async fn wait_until_lane_almost_empty(lane_queue_lengths: LaneQueueLengths, conn } async fn wait_for_lane( - lane_queue_lengths: LaneQueueLengths, + lane_queue_lengths: &LaneQueueLengths, connection_id: u64, queue_length_threshold: usize, sleep_duration: Duration, From a7d8613c9d714f4f4d2d1a27e1fd3a079189b87f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 13 Dec 2022 12:11:30 +0000 Subject: [PATCH 17/39] Multi-surbs (#2667) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Feature/multi surbs (#1796) * bunch of wip with focus on serialization * Being able to send normal data (NO SURBS yet) to yourself again * Fixed RepliableMessage deserialization * Recovering data from surb messages * Extracted common code in sphinx payload construction * Cleanup within received buffer * requesting, sending and using additional reply surbs * Following discussion with @simonwicky, removing sender proof and decreasing size of sender tag * Made sender tag more easily configurable * Refactoring of message creation * Propagating reply surb acks but not retransmitting them yet * Surb retransmissions * requesting additional surbs from the retransmission flow * correctly determining the point of requesting additional surbs * Ability to use socks5 (and network requester) with surbs * Improved surbs retranmsission reliability * naive way of not over-requesting surbs * wip on tag storage * Improved error propagation for message construction * Requesting more surbs for stale entries * Better controlling the point of having to request additional surbs * Using pseudorandom sender tag instead of a hardcoded one * First cleanup round in MessageHandler * Error cleanup and if simplification * Assigned a more permanent name to the ReplyController * Removed PendingReply redundant type * Made socks5 client less eager to over-send reply surbs * 'anonymous' field on socks5 client to decide whether to use surbs or attach address * Dead code and import removal in client-core * Updating ClientRequest variants * Adjusted decision threshold for requesting more surbs * Native client cleanup * Made socks5 client usage of surbs configurable * Restored statistics in network requester * Validator-api compiles once again * Further improved surb request logic * boxing the recipient in controller requests * Removal of hardcoded values in favour of propagating them from the config * more validation during surb requests * Fixed ClientRequest::Send deserialization * Added length checks for request deserialization * post-merge formatting * Unit tests once again compile and pass * controlling retransmission_reply_surb_request_size from config * More Recipient boxing action * Requesting additional reply surbs for retransmission BEFORE dipping below the threshold * Making clippy generally happier * Wasm client compiles (but might not yet work correctly) * Feature/use expect instead of panicking (#1797) * Implementation of 'Debug' on 'RealMessage' * expect with failed channel name instead of throwing empty panics * Introduced Debug trait constraint in ProxyRunner * Derive Debug for socks5_requests::Message * Fix decrypting stored received msg (#1786) * Fix decrypting stored received msg * rustfmt * Moving binary message recovery to separate function Co-authored-by: Jędrzej Stuczyński * real_traffic_stream: reduce frequency of status print (#1794) * Properly defined unnamed errors * Dealing with previously ignored errors * logging improvements * Removed old example code Co-authored-by: Jon Häggblad * Missing changelog entry for multi-surbs (#1802) * Making anonymous sender tag human readable (#1801) * Created wrapper with string serialization for AnonymousSenderTag * Using Display implementation of AnonymousSenderTag for logs * Using Display implementation of MessageRecoveryError when logging (#1803) * Using Display implementation of MessageRecoveryError when logging * Updated changelog * Defined socks5 client startup flag to enable reply-surb communication (#1804) * Feature/persistent surbs data (#1835) * prototyping wip * Implemented ReplyStorageBackend trait for the sql-backed storage * Storing correct surb threshold * using correct database path * Starting surb persistent storage in native and socks5 clients * loading or creating fresh surb storage in socks5 and native clients * making clippy happier + fixing config templates * Creating status table on database rotation * Completed the 'Empty' ReplyStorageBackend * feature locking wasm-incompatible bits and pieces * Feature/develop resync (#1844) * Network-requester: throttle inbound connections (#1789) * Return and handle ClientRequest::LaneQueueLenghts * Pass lane queue lengths to inbound future * Remove unused self reference * Request lane queue lengths periodically for all open connections * Add timeouts * Rename to ConnectionCommandSender and Receiver * Rename to client_connection_tx/rx * Fix wasm build * Replace bool with enum * rust: bump required version to 1.65 in some crates that need it * Add step to release GH actions (#1792) * feat: add a release step to nym contracts GH action * feat: add shrinking the size of wasm * Possibilty to change gateway ws listener (#1779) * add: set gatewayListener * Update types.ts * Update worker.ts * Update contracts-build.yml * real_traffic_stream: reduce frequency of status print (#1794) * Update wallet and connect lock files (#1793) * client-core: add warning when delay multiplier is larger than 1 * Fix decrypting stored received msg (#1786) * Fix decrypting stored received msg * rustfmt * Moving binary message recovery to separate function Co-authored-by: Jędrzej Stuczyński * Feature/use expect instead of panicking (#1797) * Implementation of 'Debug' on 'RealMessage' * expect with failed channel name instead of throwing empty panics * Introduced Debug trait constraint in ProxyRunner * Derive Debug for socks5_requests::Message * Make connection_id optional in ClientRequest::Send (#1798) * changelog: add missing entry for fixing message decrypt in gateway-client * websocket-requests: fix length check before deserialize (#1799) * Fix export dkg contract addr (#1800) * Export dkg contract for mainnet when no config file present * Remove redundant env files * nym-cli: improve error reporting/handling and changed `vesting-schedule` queries to use query client instead of signing client * Feature/gateway client protocol version (#1795) * Introducing concept of gateway protocol version * Remove version-based gateway filtering * Fixed the unit test * grammar * Set build on latest release on schedule event * Added nightly build workflow on second latest release * socks5: if any task panics, signal all other tasks to shutdown (#1805) * socks5: signal shutdown on error * Mark as success * Tidy * Reduce wait to 5 sec * Replace unwrap with expect * Two more unwraps * Update changelog * client-core: less frequent status logging (#1806) * Feature/nym connect UI updates (#1784) * create custom titlebar * create help page * create generic modal component * create separate connection time component * link to shipyard docs * move timer to separate component and update connection status component usage * use separate component for copying ip and port details * only show infomodal once after connection * set service provider on tauri side * Emit events when stopped * listen and unlisten for tauri events * connect: add trace log to get_services * Add back CI notifications * Update README Co-authored-by: Jon Häggblad Co-authored-by: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com> * Use default serde value for upgrade (#1807) * fix ui overflow bug (#1808) * update nym connect error text (#1809) * set flag to false * Fix wait_for_signal_and_error on win (#1811) * Add socks5-client changes to nym-connect changelog * Fix links in nym-connect changelog * More entries in nym-connect CHANGELOG * Fix typo in changelog * Update CHANGELOG.md * Experiment/client refactoring (#1814) * experimenting with extracting more common client code * drying up the wasm client * allowing some dead code for the time being * fixed formatting in nym-connect * made socks5 client inside nym-connect immutable * made clippy a bit happier * hidden away target locking for recv timeout * New transactions for increasing amount of pledged tokens * unit tests * Added an option to pledge extra tokens through the vesting contract * Introduced wallet endpoints for new operations * Using updated pledge cap in the vesting contract * Bumping version numbers * Changelog for v1.1.1 * Bumping final version numbers for 1.1.1 * Bumping nym-cli version, missed it last time * socks5-client: SOCKS4a support (#1822) * socks5-client: SOCKS4a support * Tidy * Fix a few errors in socks5 client and network-requester (#1823) * Fix two unwraps in socks5 and network-requester * Make sure client task never sends shutdown signal * Fix panic on getting socks version * wip * connecting to the back and making the requests work * display details modal * logs removal * Feature/pledge more (#1679) * New transactions for increasing amount of pledged tokens * unit tests * Added an option to pledge extra tokens through the vesting contract * Introduced wallet endpoints for new operations * Using updated pledge cap in the vesting contract * Changelog update * nym-connect: update lock file * avoid mix tokens pools * amount error * envs/mainnet: update to latest mixnet contract and nymd validator url * validator-api: add missing shortform for --config-env-file (#1830) * gateway-client: handle shutdown listener (#1829) * WIP * WIP: try another approach * WIP * Reworked * Tidy * fix * validator-api: remove storage dependency in contract cache (#1685) * validator-api: remove storage dependency in contract cache * validator-client: update detailed routes * contract_cache: forward to new endpoints for compat * Move reward_estimate * client: add --no-cover and update --fastmode (#1831) * adding a oversaturaded bonding more modal * common/task: extract out spawn_with_report_error (#1837) * stop panic on failed buffer request * Compilable wasm client * Enabled hard error on lack of gateway-client protocol version * Missing generic parameter for ClientCoreError in BackendError * Removed unused imports * Additional wasm feature locking Co-authored-by: Jon Häggblad Co-authored-by: Fran Arbanas Co-authored-by: cgi-bin/ <6095048+sven-hash@users.noreply.github.com> Co-authored-by: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com> Co-authored-by: Bogdan-Ștefan Neacşu Co-authored-by: Mark Sinclair Co-authored-by: Raphaël Walther Co-authored-by: Fouad Co-authored-by: Gala Co-authored-by: Dave Hrycyszyn * Making native client wait for shutdown * Marking dead test code * Feature/multi surbs invalidation (#1858) * Cleaned up RealMessagesController constructor * introduced config field for maximum_reply_surb_age * Handling edge-case reply-surb failures * invalidating old reply surbs * Removing old reply keys from cache * Invalidating old reply keys * missing config changes * logging created tag details * Fixed clippy warning in test code * Saving reply key timestamp on data flush (#1867) * Remove panic if ReconstructedMessagesReceiver is closed (#1868) Instead log error and return because presumably the shutdown procedure has started * Feature/multi surbs basic wasm interface (#1846) * Added builder to wasm client * missing wasm_bindgen macros * Added constructor macro on GatewayEndpointConfig * Attempting to use updated wasm client api * Removing dead code * Exposed other messages types in wasm client * cleanup in js-example * Changed 'self_address' to be a method call * Removed needless borrow when cloning an Arc * Improving arguments in 'on_message' callback * fixed wasm-client dependency/features * Reverted hard requirement for gateway protocol presence (#1875) * Feature/prioritise surb retransmission (#1883) * Improved error messages + removed redundant variants * Improved estimation of 'expected_forward_delay' * Removed old wasm-specific startup code * Removed old unused reply-related code * hacky and temporary way of buffering retransmission data * offloading retransmission reply handling to ReplyController * fixed linter errors + rebuffering retransmission data on failure * Removed unused fields from wasm client debug config * Chore/v1.2.0 update (#2666) * Network-requester: throttle inbound connections (#1789) * Return and handle ClientRequest::LaneQueueLenghts * Pass lane queue lengths to inbound future * Remove unused self reference * Request lane queue lengths periodically for all open connections * Add timeouts * Rename to ConnectionCommandSender and Receiver * Rename to client_connection_tx/rx * Fix wasm build * Replace bool with enum * rust: bump required version to 1.65 in some crates that need it * Add step to release GH actions (#1792) * feat: add a release step to nym contracts GH action * feat: add shrinking the size of wasm * Possibilty to change gateway ws listener (#1779) * add: set gatewayListener * Update types.ts * Update worker.ts * Update contracts-build.yml * real_traffic_stream: reduce frequency of status print (#1794) * Update wallet and connect lock files (#1793) * client-core: add warning when delay multiplier is larger than 1 * Fix decrypting stored received msg (#1786) * Fix decrypting stored received msg * rustfmt * Moving binary message recovery to separate function Co-authored-by: Jędrzej Stuczyński * Feature/use expect instead of panicking (#1797) * Implementation of 'Debug' on 'RealMessage' * expect with failed channel name instead of throwing empty panics * Introduced Debug trait constraint in ProxyRunner * Derive Debug for socks5_requests::Message * Make connection_id optional in ClientRequest::Send (#1798) * changelog: add missing entry for fixing message decrypt in gateway-client * websocket-requests: fix length check before deserialize (#1799) * Fix export dkg contract addr (#1800) * Export dkg contract for mainnet when no config file present * Remove redundant env files * nym-cli: improve error reporting/handling and changed `vesting-schedule` queries to use query client instead of signing client * Feature/gateway client protocol version (#1795) * Introducing concept of gateway protocol version * Remove version-based gateway filtering * Fixed the unit test * grammar * Set build on latest release on schedule event * feat(wallet): buy page bootstrap * feat(wallet-buy): tutorial * feat(explorer-api): add route to fetch nym terms&cdts * Revert "feat(explorer-api): add route to fetch nym terms&cdts" This reverts commit 876f752697d89061b1904e1ddd1d5bcb7045dc5c. * feat(wallet-buy-nym): buy page new ui * fix(wallet-buy-nym): signature output * feat(wallet-buy-nym): update signature modal ui * Added nightly build workflow on second latest release * socks5: if any task panics, signal all other tasks to shutdown (#1805) * socks5: signal shutdown on error * Mark as success * Tidy * Reduce wait to 5 sec * Replace unwrap with expect * Two more unwraps * Update changelog * client-core: less frequent status logging (#1806) * Feature/nym connect UI updates (#1784) * create custom titlebar * create help page * create generic modal component * create separate connection time component * link to shipyard docs * move timer to separate component and update connection status component usage * use separate component for copying ip and port details * only show infomodal once after connection * set service provider on tauri side * Emit events when stopped * listen and unlisten for tauri events * connect: add trace log to get_services * Add back CI notifications * Update README Co-authored-by: Jon Häggblad Co-authored-by: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com> * Use default serde value for upgrade (#1807) * fix ui overflow bug (#1808) * feat(wallet): add link to nym exchange interface * update nym connect error text (#1809) * refactor(wallet): clean code * set flag to false * Fix wait_for_signal_and_error on win (#1811) * Use config URLs in clients before the env values (#1813) * Add socks5-client changes to nym-connect changelog * Fix links in nym-connect changelog * More entries in nym-connect CHANGELOG * Fix typo in changelog * Update CHANGELOG.md * Experiment/client refactoring (#1814) * experimenting with extracting more common client code * drying up the wasm client * allowing some dead code for the time being * fixed formatting in nym-connect * made socks5 client inside nym-connect immutable * made clippy a bit happier * hidden away target locking for recv timeout * New transactions for increasing amount of pledged tokens * unit tests * Added an option to pledge extra tokens through the vesting contract * Introduced wallet endpoints for new operations * Using updated pledge cap in the vesting contract * Feature/dkg integration tests (#1815) * DKG contract e2e test * Refactor to the same format as other contracts * Vk share tests * State tests * Dealings tests * Dealer tests * Api dkg tests * Fix path to contract after refactor * Fix test target clippy * Bumping version numbers * Changelog for v1.1.1 * Bumping final version numbers for 1.1.1 * Bumping nym-cli version, missed it last time * socks5-client: SOCKS4a support (#1822) * socks5-client: SOCKS4a support * Tidy * Fix a few errors in socks5 client and network-requester (#1823) * Fix two unwraps in socks5 and network-requester * Make sure client task never sends shutdown signal * Fix panic on getting socks version * wip * connecting to the back and making the requests work * display details modal * logs removal * Feature/pledge more (#1679) * New transactions for increasing amount of pledged tokens * unit tests * Added an option to pledge extra tokens through the vesting contract * Introduced wallet endpoints for new operations * Using updated pledge cap in the vesting contract * Changelog update * Feature/pledge more (#1679) * New transactions for increasing amount of pledged tokens * unit tests * Added an option to pledge extra tokens through the vesting contract * Introduced wallet endpoints for new operations * Using updated pledge cap in the vesting contract * Changelog update * Fix a few errors in socks5 client and network-requester (backport) (#1824) * Fix two unwraps in socks5 and network-requester * Make sure client task never sends shutdown signal * nym-connect: update lock file * fix(wallet): typo * avoid mix tokens pools * fix(wallet): typo * fix(wallet): buy tutorial ui responsivness * amount error * envs/mainnet: update to latest mixnet contract and nymd validator url * validator-api: add missing shortform for --config-env-file (#1830) * gateway-client: handle shutdown listener (#1829) * WIP * WIP: try another approach * WIP * Reworked * Tidy * fix * validator-api: remove storage dependency in contract cache (#1685) * validator-api: remove storage dependency in contract cache * validator-client: update detailed routes * contract_cache: forward to new endpoints for compat * Move reward_estimate * Node family management (#1670) * Family management messages * Add family queries * Add queries to client * Layer assignment message * Paged family queries, annotate mixnodes with family * Add layer assignments to epoch operations * Remove family layer peristence * Add NotImplemented error for kick Co-authored-by: Jędrzej Stuczyński * Fixed layer distribution skewness check (#1766) * client: add --no-cover and update --fastmode (#1831) * adding a oversaturaded bonding more modal * Use better naming on gateway credential handling (#1834) * Fix comment in configuration file (#1836) * common/task: extract out spawn_with_report_error (#1837) * nym-connect/changelog: add note about disconnect fix * Feature/simplify credential binary (#1841) * Expose name of standard directories * Use one command instead of two * nym-connect: append error to failed message (#1839) * nym-connect: append error to failed message * changelog: add note * Fix clippy * remove extra checks to display vesting schedule(#1826) * Set explorer to use rpc.nymtech.net * update versions for platfrom, nym-connect and nym-wallet to v1.1.2 * changed nym-connect version to 1.1.1 * Modifying changelog for v1.1.2 * changed nym-connect version to 1.1.2 * update nym-connect CHANGELOG * Updated changelog for wallet * Feature/wallet content updates (#1825) * fix up balance screen * fix up app bar and nym logo alignment * fix up delegation action icon font weight * fix up bond page * Corrected env variable name in workflows * Use config URLs in clients before the env values (#1813) * Feature/dkg integration tests (#1815) * DKG contract e2e test * Refactor to the same format as other contracts * Vk share tests * State tests * Dealings tests * Dealer tests * Api dkg tests * Fix path to contract after refactor * Fix test target clippy * Node family management (#1670) * Family management messages * Add family queries * Add queries to client * Layer assignment message * Paged family queries, annotate mixnodes with family * Add layer assignments to epoch operations * Remove family layer peristence * Add NotImplemented error for kick Co-authored-by: Jędrzej Stuczyński * Fixed layer distribution skewness check (#1766) * Use better naming on gateway credential handling (#1834) * Fix comment in configuration file (#1836) * nym-connect/changelog: add note about disconnect fix * Feature/simplify credential binary (#1841) * Expose name of standard directories * Use one command instead of two * Fix clippy * feat(wallet): buy page bootstrap * feat(wallet-buy): tutorial * feat(explorer-api): add route to fetch nym terms&cdts * Revert "feat(explorer-api): add route to fetch nym terms&cdts" This reverts commit 876f752697d89061b1904e1ddd1d5bcb7045dc5c. * feat(wallet-buy-nym): buy page new ui * fix(wallet-buy-nym): signature output * feat(wallet-buy-nym): update signature modal ui * feat(wallet): add link to nym exchange interface * refactor(wallet): clean code * fix(wallet): typo * fix(wallet): typo * fix(wallet): buy tutorial ui responsivness * update versions for platfrom, nym-connect and nym-wallet to v1.1.2 * changed nym-connect version to 1.1.1 * Modifying changelog for v1.1.2 * changed nym-connect version to 1.1.2 * update nym-connect CHANGELOG * Updated changelog for wallet * Resolve merge conflicts * Update qa-qwerty.env * Fixed URL to branch * changed ubuntu-latest on GH actions to ubuntu-20.04 * docs: updated changelog for contracts release v1.1.2 and updated versions of mixnet and vesting contracts as well * Add ignore to dkg expensive tests (#1856) * introduce minimize button in custom title bar (#1843) * refresh balance after sending tokens (#1857) * Feature/fix client multi cred consume (#1859) * Mark consumed credentials in the db * Add signature log * Fix wasm mock Storage trait * Fix clippy * Feature/verify bte proof (#1866) * Update lock file * Include bte public key verification * Wallet - Buy, copy changes (#1855) * use mix_id for account to get correct pending cost event (#1869) * use mix_id for account to get correct pending cost event * Properly add consumed to table (#1870) * nym-connect: update Cargo.lock to 1.1.2 * Clients: save init results to JSON (#1865) * clients: output results of init to json * Remove leftover dbg * Tidy * Fix nym-connect * Client: dedup setup gateway during init (#1871) * clients: dedup gateway setup logic * nym-connect: extract out print_save_config * Feature/dkg state to disk (#1872) * Add PersistentState * Save and load state to/from disk * If in progress, don't continually write the same state * Fix tests and add serde one * Update changelog * Fix clippy * network-requester: return error on socket close (#1876) * network-requester: return error when the socket closes * changelog: add note * clients: further deduplicate init code (#1873) * client-core: move init helpers to module * WIP * socks5: return error instead of terminate in init * Extract out reuse_existing_gateway_config * rustfmt * Remove comment out code * nym-connect: use setup_gateway * Linebreak * changelog: update * Tweak log * rustfmt * client: pick from old lanes probabilisticlly (#1877) * Pick from old lanes probabilisticly * changelog: update * clients: dont panic in base client gateway client handling (#1878) * client-core: fix some panics related to gateway-client * changelog: update * fix * changelog: fix wording * Use default mainnet values when nothing is specified (#1884) Co-authored-by: Jon Häggblad Co-authored-by: Fran Arbanas Co-authored-by: cgi-bin/ <6095048+sven-hash@users.noreply.github.com> Co-authored-by: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com> Co-authored-by: Bogdan-Ștefan Neacşu Co-authored-by: Mark Sinclair Co-authored-by: Raphaël Walther Co-authored-by: pierre Co-authored-by: Fouad Co-authored-by: Gala Co-authored-by: Dave Hrycyszyn Co-authored-by: Drazen Urch Co-authored-by: durch Co-authored-by: Tommy Verrall <60836166+tommyv1987@users.noreply.github.com> Co-authored-by: Jon Häggblad Co-authored-by: Fran Arbanas Co-authored-by: cgi-bin/ <6095048+sven-hash@users.noreply.github.com> Co-authored-by: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com> Co-authored-by: Bogdan-Ștefan Neacşu Co-authored-by: Mark Sinclair Co-authored-by: Raphaël Walther Co-authored-by: Fouad Co-authored-by: Gala Co-authored-by: Dave Hrycyszyn Co-authored-by: pierre Co-authored-by: Drazen Urch Co-authored-by: durch Co-authored-by: Tommy Verrall <60836166+tommyv1987@users.noreply.github.com> --- .gitignore | 3 +- CHANGELOG.md | 10 +- Cargo.lock | 247 ++--- clients/client-core/Cargo.toml | 31 +- clients/client-core/build.rs | 31 + .../20221130120000_create_initial_tables.sql | 40 + .../client-core/src/client/base_client/mod.rs | 205 ++-- .../client/base_client/non_wasm_helpers.rs | 51 + .../src/client/cover_traffic_stream.rs | 30 +- .../src/client/inbound_messages.rs | 70 +- clients/client-core/src/client/mix_traffic.rs | 10 - clients/client-core/src/client/mod.rs | 3 +- .../acknowledgement_listener.rs | 21 +- .../action_controller.rs | 63 +- .../input_message_listener.rs | 214 ++-- .../acknowledgement_control/mod.rs | 166 ++-- .../retransmission_request_listener.rs | 130 +-- .../sent_notification_listener.rs | 21 +- .../real_messages_control/message_handler.rs | 548 +++++++++++ .../src/client/real_messages_control/mod.rs | 197 ++-- .../real_traffic_stream.rs | 68 +- .../client-core/src/client/received_buffer.rs | 350 ++++--- clients/client-core/src/client/replies/mod.rs | 5 + .../src/client/replies/reply_controller.rs | 928 ++++++++++++++++++ .../reply_storage/backend/browser_backend.rs | 43 + .../reply_storage/backend/fs_backend/error.rs | 53 + .../backend/fs_backend/manager.rs | 257 +++++ .../reply_storage/backend/fs_backend/mod.rs | 336 +++++++ .../backend/fs_backend/models.rs | 185 ++++ .../replies/reply_storage/backend/mod.rs | 78 ++ .../client/replies/reply_storage/combined.rs | 60 ++ .../replies/reply_storage/key_storage.rs | 86 ++ .../src/client/replies/reply_storage/mod.rs | 64 ++ .../replies/reply_storage/surb_storage.rs | 278 ++++++ .../replies/reply_storage/tag_storage.rs | 59 ++ .../src/client/reply_key_storage.rs | 97 -- .../src/client/topology_control.rs | 82 +- clients/client-core/src/config/mod.rs | 154 ++- clients/client-core/src/error.rs | 25 +- clients/client-core/src/init/helpers.rs | 42 +- clients/client-core/src/init/mod.rs | 55 +- clients/native/Cargo.toml | 5 +- .../native/examples/websocket_binarysend.rs | 96 +- clients/native/src/client/config/mod.rs | 8 +- clients/native/src/client/config/template.rs | 7 +- clients/native/src/client/mod.rs | 57 +- clients/native/src/commands/init.rs | 16 +- clients/native/src/error.rs | 5 +- clients/native/src/websocket/handler.rs | 176 +++- clients/native/src/websocket/listener.rs | 3 +- .../native/websocket-requests/src/error.rs | 32 +- .../native/websocket-requests/src/requests.rs | 403 +++++--- .../websocket-requests/src/responses.rs | 258 +++-- clients/native/websocket-requests/src/text.rs | 63 +- clients/socks5/Cargo.toml | 2 +- clients/socks5/src/client/config/mod.rs | 70 +- clients/socks5/src/client/config/template.rs | 16 +- clients/socks5/src/client/mod.rs | 16 +- clients/socks5/src/commands/init.rs | 25 +- clients/socks5/src/commands/mod.rs | 5 + clients/socks5/src/commands/run.rs | 9 + clients/socks5/src/error.rs | 9 +- clients/socks5/src/socks/client.rs | 69 +- clients/socks5/src/socks/mixnet_responses.rs | 4 +- clients/socks5/src/socks/mod.rs | 2 +- clients/socks5/src/socks/server.rs | 5 + clients/webassembly/js-example/index.js | 12 +- clients/webassembly/js-example/worker.js | 60 +- clients/webassembly/src/client/config.rs | 48 + clients/webassembly/src/client/helpers.rs | 30 + clients/webassembly/src/client/mod.rs | 295 +++--- .../webassembly/src/client/response_pusher.rs | 45 +- common/client-connections/src/lib.rs | 6 +- common/client-libs/gateway-client/Cargo.toml | 1 + .../client-libs/gateway-client/src/client.rs | 2 +- common/client-libs/gateway-client/src/lib.rs | 2 +- .../validator-client/src/client.rs | 25 +- .../src/packet_processor/processor.rs | 2 +- common/nymsphinx/Cargo.toml | 1 + .../acknowledgements/src/surb_ack.rs | 4 + common/nymsphinx/addressing/Cargo.toml | 1 + common/nymsphinx/addressing/src/clients.rs | 62 +- common/nymsphinx/addressing/src/nodes.rs | 53 +- common/nymsphinx/anonymous-replies/Cargo.toml | 6 +- .../anonymous-replies/src/encryption_key.rs | 2 +- common/nymsphinx/anonymous-replies/src/lib.rs | 1 + .../anonymous-replies/src/reply_surb.rs | 53 +- .../anonymous-replies/src/requests.rs | 476 +++++++++ common/nymsphinx/chunking/Cargo.toml | 1 + common/nymsphinx/chunking/src/fragment.rs | 84 +- common/nymsphinx/chunking/src/lib.rs | 31 +- common/nymsphinx/cover/Cargo.toml | 1 + common/nymsphinx/cover/src/lib.rs | 31 +- common/nymsphinx/framing/src/codec.rs | 2 +- common/nymsphinx/src/lib.rs | 4 + common/nymsphinx/src/message.rs | 238 +++++ common/nymsphinx/src/preparer/mod.rs | 313 ++---- common/nymsphinx/src/preparer/payload.rs | 97 ++ common/nymsphinx/src/receiver.rs | 221 ++--- common/nymsphinx/types/Cargo.toml | 2 +- common/socks5/requests/src/request.rs | 92 +- common/topology/Cargo.toml | 1 + common/topology/src/lib.rs | 83 +- common/wasm-utils/Cargo.toml | 7 + common/wasm-utils/src/lib.rs | 5 +- .../websocket/connection_handler/fresh.rs | 2 +- mixnode/src/node/packet_delayforwarder.rs | 2 +- nym-connect/Cargo.lock | 383 ++++++-- nym-connect/src-tauri/src/config/mod.rs | 19 +- nym-connect/src-tauri/src/error.rs | 3 +- .../network-requester/src/connection.rs | 12 +- .../network-requester/src/core.rs | 152 ++- .../src/statistics/collector.rs | 14 +- validator-api/src/network_monitor/chunker.rs | 6 +- .../src/network_monitor/monitor/processor.rs | 15 +- 115 files changed, 7201 insertions(+), 2564 deletions(-) create mode 100644 clients/client-core/build.rs create mode 100644 clients/client-core/fs_surbs_migrations/20221130120000_create_initial_tables.sql create mode 100644 clients/client-core/src/client/base_client/non_wasm_helpers.rs create mode 100644 clients/client-core/src/client/real_messages_control/message_handler.rs create mode 100644 clients/client-core/src/client/replies/mod.rs create mode 100644 clients/client-core/src/client/replies/reply_controller.rs create mode 100644 clients/client-core/src/client/replies/reply_storage/backend/browser_backend.rs create mode 100644 clients/client-core/src/client/replies/reply_storage/backend/fs_backend/error.rs create mode 100644 clients/client-core/src/client/replies/reply_storage/backend/fs_backend/manager.rs create mode 100644 clients/client-core/src/client/replies/reply_storage/backend/fs_backend/mod.rs create mode 100644 clients/client-core/src/client/replies/reply_storage/backend/fs_backend/models.rs create mode 100644 clients/client-core/src/client/replies/reply_storage/backend/mod.rs create mode 100644 clients/client-core/src/client/replies/reply_storage/combined.rs create mode 100644 clients/client-core/src/client/replies/reply_storage/key_storage.rs create mode 100644 clients/client-core/src/client/replies/reply_storage/mod.rs create mode 100644 clients/client-core/src/client/replies/reply_storage/surb_storage.rs create mode 100644 clients/client-core/src/client/replies/reply_storage/tag_storage.rs delete mode 100644 clients/client-core/src/client/reply_key_storage.rs create mode 100644 clients/webassembly/src/client/helpers.rs create mode 100644 common/nymsphinx/anonymous-replies/src/requests.rs create mode 100644 common/nymsphinx/src/message.rs create mode 100644 common/nymsphinx/src/preparer/payload.rs diff --git a/.gitignore b/.gitignore index f102743734..b8df49d1a7 100644 --- a/.gitignore +++ b/.gitignore @@ -37,4 +37,5 @@ validator-config *.patch validator-api-config.toml dist -storybook-static \ No newline at end of file +storybook-static +envs/qwerty.env \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b03ddd8ba..1c9ae78385 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// - validator-api: can recover from shutdown during DKG process ([#1872]) - clients: deduplicate gateway inititialization, part of work towards a rust-sdk - clients: keep all transmission lanes going at all times by making priority probabilistic +- clients: ability to use multi-reply SURBs to send arbitrarily long messages fully anonymously whilst requesting additional reply blocks whenever they're about to run out ([#1796], [#1801], [#1804], [#1835], [#1858], [#1883])) ### Fixed @@ -16,11 +17,18 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// - clients: fix a few panics handling the gateway-client - mixnode, gateway, validator-api: Use mainnet values as defaults for URLs and mixnet contract ([#1884]) - socks5: fixed bug where connections sometimes where closed too early +- clients: improve message logging when received message fails to get reconstructed ([#1803]) +[#1796]: https://github.com/nymtech/nym/pull/1796 +[#1801]: https://github.com/nymtech/nym/pull/1801 +[#1803]: https://github.com/nymtech/nym/pull/1803 +[#1804]: https://github.com/nymtech/nym/pull/1804 +[#1835]: https://github.com/nymtech/nym/pull/1835 +[#1858]: https://github.com/nymtech/nym/pull/1858 [#1872]: https://github.com/nymtech/nym/pull/1872 +[#1883]: https://github.com/nymtech/nym/pull/1883 [#1884]: https://github.com/nymtech/nym/pull/1884 - ## [v1.1.2] ### Changed diff --git a/Cargo.lock b/Cargo.lock index e755f118fc..822fa26726 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -131,9 +131,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.53" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600" +checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" dependencies = [ "proc-macro2", "quote", @@ -588,9 +588,11 @@ dependencies = [ name = "client-core" version = "1.1.2" dependencies = [ + "async-trait", "client-connections", "config", "crypto", + "dashmap 5.4.0", "dirs", "futures", "gateway-client", @@ -604,11 +606,12 @@ dependencies = [ "rand 0.7.3", "serde", "serde_json", - "sled", + "sqlx 0.6.2", "tap", "task", "tempfile", "thiserror", + "time 0.3.17", "tokio", "tokio-stream", "topology", @@ -617,6 +620,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "wasm-timer", + "wasm-utils", ] [[package]] @@ -782,7 +786,7 @@ dependencies = [ "rand 0.8.5", "sha2 0.10.2", "subtle 2.4.1", - "time 0.3.14", + "time 0.3.17", "version_check", ] @@ -1350,6 +1354,19 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "dashmap" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" +dependencies = [ + "cfg-if 1.0.0", + "hashbrown 0.12.3", + "lock_api", + "once_cell", + "parking_lot_core 0.9.4", +] + [[package]] name = "der" version = "0.5.1" @@ -1798,16 +1815,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" -[[package]] -name = "fs2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -1920,15 +1927,6 @@ dependencies = [ "slab", ] -[[package]] -name = "fxhash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -dependencies = [ - "byteorder", -] - [[package]] name = "gateway-client" version = "0.1.0" @@ -2274,13 +2272,14 @@ checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" [[package]] name = "hidapi" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d26e1151deaab68f34fbfd16d491a2a0170cf98d69d3efa23873b567a4199e1" +checksum = "798154e4b6570af74899d71155fb0072d5b17e6aa12f39c8ef22c60fb8ec99e7" dependencies = [ "cc", "libc", "pkg-config", + "winapi", ] [[package]] @@ -2611,9 +2610,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.55" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" dependencies = [ "wasm-bindgen", ] @@ -2759,9 +2758,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" dependencies = [ "autocfg 1.1.0", "scopeguard", @@ -2913,7 +2912,7 @@ dependencies = [ "serde_json", "serde_repr", "thiserror", - "time 0.3.14", + "time 0.3.17", "ts-rs", ] @@ -3090,15 +3089,6 @@ dependencies = [ "libc", ] -[[package]] -name = "num_threads" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aba1801fb138d8e85e11d0fc70baf4fe1cdfffda7c6cd34a854905df588e5ed0" -dependencies = [ - "libc", -] - [[package]] name = "nym-bity-integration" version = "0.1.0" @@ -3161,7 +3151,7 @@ dependencies = [ "serde_json", "tap", "thiserror", - "time 0.3.14", + "time 0.3.17", "toml", "url", "validator-client", @@ -3194,7 +3184,6 @@ dependencies = [ "rand 0.7.3", "serde", "serde_json", - "sled", "tap", "task", "thiserror", @@ -3223,7 +3212,7 @@ dependencies = [ "config", "credentials", "crypto", - "dashmap", + "dashmap 4.0.2", "dirs", "dotenv", "futures", @@ -3464,7 +3453,7 @@ dependencies = [ "tap", "task", "thiserror", - "time 0.3.14", + "time 0.3.17", "tokio", "tokio-stream", "topology", @@ -3537,6 +3526,7 @@ dependencies = [ "nymsphinx-types", "rand 0.7.3", "rand_distr", + "thiserror", "tokio", "topology", ] @@ -3562,6 +3552,7 @@ dependencies = [ "nymsphinx-types", "rand 0.7.3", "serde", + "thiserror", ] [[package]] @@ -3575,7 +3566,9 @@ dependencies = [ "nymsphinx-types", "rand 0.7.3", "serde", + "thiserror", "topology", + "wasm-bindgen", ] [[package]] @@ -3587,6 +3580,7 @@ dependencies = [ "nymsphinx-params", "nymsphinx-types", "rand 0.7.3", + "thiserror", ] [[package]] @@ -3601,6 +3595,7 @@ dependencies = [ "nymsphinx-params", "nymsphinx-types", "rand 0.7.3", + "thiserror", "topology", ] @@ -3652,9 +3647,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.13.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" [[package]] name = "oorandom" @@ -3756,7 +3751,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" dependencies = [ "lock_api", - "parking_lot_core 0.9.2", + "parking_lot_core 0.9.4", ] [[package]] @@ -3775,15 +3770,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.2" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "995f667a6c822200b0433ac218e05582f0e2efa1b922a3fd2fbaadc5f87bab37" +checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" dependencies = [ "cfg-if 1.0.0", "libc", "redox_syscall", "smallvec 1.8.0", - "windows-sys 0.34.0", + "windows-sys 0.42.0", ] [[package]] @@ -4059,11 +4054,11 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.37" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] @@ -4622,7 +4617,7 @@ dependencies = [ "serde_json", "state", "tempfile", - "time 0.3.14", + "time 0.3.17", "tokio", "tokio-stream", "tokio-util 0.7.3", @@ -4684,7 +4679,7 @@ dependencies = [ "smallvec 1.8.0", "stable-pattern", "state", - "time 0.3.14", + "time 0.3.17", "tokio", "uncased", ] @@ -5165,22 +5160,6 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" -[[package]] -name = "sled" -version = "0.34.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f96b4737c2ce5987354855aed3797279def4ebf734436c6aa4552cf8e169935" -dependencies = [ - "crc32fast", - "crossbeam-epoch", - "crossbeam-utils", - "fs2", - "fxhash", - "libc", - "log", - "parking_lot 0.11.2", -] - [[package]] name = "smallvec" version = "0.6.14" @@ -5198,9 +5177,9 @@ checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" [[package]] name = "snafu" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5177903bf45656592d9eb5c0e22f408fc023aae51dbe2088889b71633ba451f2" +checksum = "a152ba99b054b22972ee794cf04e5ef572da1229e33b65f3c57abbff0525a454" dependencies = [ "doc-comment", "snafu-derive", @@ -5208,9 +5187,9 @@ dependencies = [ [[package]] name = "snafu-derive" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "410b26ed97440d90ced3e2488c868d56a86e2064f5d7d6f417909b286afe25e5" +checksum = "d5e79cdebbabaebb06a9bdbaedc7f159b410461f63611d4d0e3fb0fab8fed850" dependencies = [ "heck 0.4.0", "proc-macro2", @@ -5239,7 +5218,7 @@ dependencies = [ [[package]] name = "sphinx" version = "0.1.0" -source = "git+https://github.com/nymtech/sphinx?rev=c494250f2a78bed33a618d470792418eee932859#c494250f2a78bed33a618d470792418eee932859" +source = "git+https://github.com/nymtech/sphinx?rev=e05a1992522ed0afd3c6fcac160313ffc9bb306a#e05a1992522ed0afd3c6fcac160313ffc9bb306a" dependencies = [ "aes 0.7.5", "arrayref", @@ -5597,13 +5576,13 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.91" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" +checksum = "4ae548ec36cf198c0ef7710d3c230987c2d6d7bd98ad6edc0274462724c585ce" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -5692,7 +5671,7 @@ dependencies = [ "subtle 2.4.1", "subtle-encoding", "tendermint-proto", - "time 0.3.14", + "time 0.3.17", "zeroize", ] @@ -5725,7 +5704,7 @@ dependencies = [ "serde", "serde_bytes", "subtle-encoding", - "time 0.3.14", + "time 0.3.17", ] [[package]] @@ -5753,7 +5732,7 @@ dependencies = [ "tendermint-config", "tendermint-proto", "thiserror", - "time 0.3.14", + "time 0.3.17", "tokio", "tracing", "url", @@ -5827,22 +5806,31 @@ dependencies = [ [[package]] name = "time" -version = "0.3.14" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3f9a28b618c3a6b9251b6908e9c99e04b9e5c02e6581ccbb67d59c34ef7f9b" +checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" dependencies = [ "itoa 1.0.1", - "libc", - "num_threads", + "js-sys", "serde", + "time-core", "time-macros", ] [[package]] -name = "time-macros" -version = "0.2.4" +name = "time-core" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +dependencies = [ + "time-core", +] [[package]] name = "tinytemplate" @@ -5856,9 +5844,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.21.2" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" +checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3" dependencies = [ "autocfg 1.1.0", "bytes", @@ -6070,6 +6058,7 @@ dependencies = [ "nymsphinx-addressing", "nymsphinx-types", "rand 0.7.3", + "thiserror", "version-checker", ] @@ -6329,6 +6318,12 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" + [[package]] name = "unicode-normalization" version = "0.1.9" @@ -6499,7 +6494,7 @@ dependencies = [ "rustc_version 0.4.0", "rustversion", "thiserror", - "time 0.3.14", + "time 0.3.17", ] [[package]] @@ -6772,19 +6767,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825" -dependencies = [ - "windows_aarch64_msvc 0.34.0", - "windows_i686_gnu 0.34.0", - "windows_i686_msvc 0.34.0", - "windows_x86_64_gnu 0.34.0", - "windows_x86_64_msvc 0.34.0", -] - [[package]] name = "windows-sys" version = "0.36.1" @@ -6799,10 +6781,25 @@ dependencies = [ ] [[package]] -name = "windows_aarch64_msvc" -version = "0.34.0" +name = "windows-sys" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" [[package]] name = "windows_aarch64_msvc" @@ -6811,10 +6808,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" [[package]] -name = "windows_i686_gnu" -version = "0.34.0" +name = "windows_aarch64_msvc" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" [[package]] name = "windows_i686_gnu" @@ -6823,10 +6820,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" [[package]] -name = "windows_i686_msvc" -version = "0.34.0" +name = "windows_i686_gnu" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" [[package]] name = "windows_i686_msvc" @@ -6835,10 +6832,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" [[package]] -name = "windows_x86_64_gnu" -version = "0.34.0" +name = "windows_i686_msvc" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" [[package]] name = "windows_x86_64_gnu" @@ -6847,10 +6844,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" [[package]] -name = "windows_x86_64_msvc" -version = "0.34.0" +name = "windows_x86_64_gnu" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" [[package]] name = "windows_x86_64_msvc" @@ -6858,6 +6861,12 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" + [[package]] name = "winreg" version = "0.10.1" diff --git a/clients/client-core/Cargo.toml b/clients/client-core/Cargo.toml index 56edca335b..87595d125f 100644 --- a/clients/client-core/Cargo.toml +++ b/clients/client-core/Cargo.toml @@ -7,18 +7,20 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +async-trait = { version = "0.1.58" } dirs = "4.0" +dashmap = "5.4.0" futures = "0.3" humantime-serde = "1.0" log = "0.4" rand = { version = "0.7.3", features = ["wasm-bindgen"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.89" -sled = { version = "0.34", optional = true } tap = "1.0.1" thiserror = "1.0.34" -tokio = { version = "1.21.2", features = ["time", "macros"]} url = { version ="2.2", features = ["serde"] } +tokio = { version = "1.21.2", features = ["macros"]} +time = "0.3.17" # internal config = { path = "../../common/config" } @@ -38,6 +40,15 @@ task = { path = "../../common/task" } version = "0.1.9" features = ["time"] +[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio] +version = "1.21.2" +features = ["time"] + +[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx] +version = "0.6.2" +features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] +optional = true + [target."cfg(target_arch = \"wasm32\")".dependencies.wasm-bindgen-futures] version = "0.4" @@ -52,15 +63,23 @@ rev = "b9d1a54ad514c2f230a026afe0dde341e98cd7b6" version = "0.2.4" features = ["futures"] -#[target."cfg(not(target_arch = \"wasm32\"))".dependencies.task] -#path = "../../common/task" +[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-utils] +path = "../../common/wasm-utils" + +[target."cfg(target_arch = \"wasm32\")".dependencies.time] +version = "0.3.17" +features = ["wasm-bindgen"] [dev-dependencies] tempfile = "3.1.0" +[build-dependencies] +tokio = { version = "1.21.2", features = ["rt-multi-thread", "macros"] } +sqlx = { version = "0.6.2", features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] } + [features] -default = ["reply-surb"] +default = [] +fs-surb-storage = ["sqlx"] wasm = ["gateway-client/wasm"] coconut = ["gateway-client/coconut", "gateway-requests/coconut"] -reply-surb = ["sled"] diff --git a/clients/client-core/build.rs b/clients/client-core/build.rs new file mode 100644 index 0000000000..bac1b20c53 --- /dev/null +++ b/clients/client-core/build.rs @@ -0,0 +1,31 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +#[tokio::main] +async fn main() { + #[cfg(feature = "fs-surb-storage")] + { + use sqlx::{Connection, SqliteConnection}; + use std::env; + + let out_dir = env::var("OUT_DIR").unwrap(); + let database_path = format!("{}/fs-surbs-example.sqlite", out_dir); + + let mut conn = SqliteConnection::connect(&format!("sqlite://{}?mode=rwc", database_path)) + .await + .expect("Failed to create SQLx database connection"); + + sqlx::migrate!("./fs_surbs_migrations") + .run(&mut conn) + .await + .expect("Failed to perform SQLx migrations"); + + #[cfg(target_family = "unix")] + println!("cargo:rustc-env=DATABASE_URL=sqlite://{}", &database_path); + + #[cfg(target_family = "windows")] + // for some strange reason we need to add a leading `/` to the windows path even though it's + // not a valid windows path... but hey, it works... + println!("cargo:rustc-env=DATABASE_URL=sqlite:///{}", &database_path); + } +} diff --git a/clients/client-core/fs_surbs_migrations/20221130120000_create_initial_tables.sql b/clients/client-core/fs_surbs_migrations/20221130120000_create_initial_tables.sql new file mode 100644 index 0000000000..0143475a37 --- /dev/null +++ b/clients/client-core/fs_surbs_migrations/20221130120000_create_initial_tables.sql @@ -0,0 +1,40 @@ +CREATE TABLE status +( + flush_in_progress INTEGER NOT NULL, + previous_flush_timestamp INTEGER NOT NULL, + client_in_use INTEGER NOT NULL +); + +CREATE TABLE reply_surb_storage_metadata +( + min_reply_surb_threshold INTEGER NOT NULL, + max_reply_surb_threshold INTEGER NOT NULL +); + +CREATE TABLE sender_tag +( + recipient BLOB NOT NULL UNIQUE, + tag BLOB NOT NULL UNIQUE +); + +CREATE TABLE reply_key +( + key_digest BLOB NOT NULL UNIQUE, + reply_key BLOB NOT NULL UNIQUE, + sent_at_timestamp INTEGER NOT NULL +); + +CREATE TABLE reply_surb_sender +( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + last_sent_timestamp INTEGER NOT NULL, + tag BLOB NOT NULL UNIQUE +); + +CREATE TABLE reply_surb +( + reply_surb_sender_id INTEGER NOT NULL, + reply_surb BLOB NOT NULL, + + FOREIGN KEY (reply_surb_sender_id) REFERENCES reply_surb_sender (id) +); \ No newline at end of file diff --git a/clients/client-core/src/client/base_client/mod.rs b/clients/client-core/src/client/base_client/mod.rs index 07a4705bd5..932fb77b31 100644 --- a/clients/client-core/src/client/base_client/mod.rs +++ b/clients/client-core/src/client/base_client/mod.rs @@ -10,13 +10,19 @@ use crate::client::real_messages_control::RealMessagesController; use crate::client::received_buffer::{ ReceivedBufferRequestReceiver, ReceivedBufferRequestSender, ReceivedMessagesBufferController, }; +use crate::client::replies::reply_controller; +use crate::client::replies::reply_controller::{ReplyControllerReceiver, ReplyControllerSender}; +use crate::client::replies::reply_storage::{ + CombinedReplyStorage, PersistentReplyStorage, ReplyStorageBackend, SentReplyKeys, +}; use crate::client::topology_control::{ TopologyAccessor, TopologyRefresher, TopologyRefresherConfig, }; use crate::config::{Config, DebugConfig, GatewayEndpointConfig}; use crate::error::ClientCoreError; +use crate::spawn_future; use client_connections::{ConnectionCommandReceiver, ConnectionCommandSender, LaneQueueLengths}; -use crypto::asymmetric::identity; +use crypto::asymmetric::{encryption, identity}; use futures::channel::mpsc; use gateway_client::bandwidth::BandwidthController; use gateway_client::{ @@ -24,18 +30,17 @@ use gateway_client::{ MixnetMessageSender, }; use log::{debug, info}; +use nymsphinx::acknowledgements::AckKey; use nymsphinx::addressing::clients::Recipient; use nymsphinx::addressing::nodes::NodeIdentity; -#[cfg(feature = "reply-surb")] -use std::path::PathBuf; +use std::sync::Arc; +use std::time::Duration; use tap::TapFallible; use task::{ShutdownListener, ShutdownNotifier}; use url::Url; -// it's fine to do this disgusting compilation flag business here as this problem -// is going to go away in 1.2.0 -#[cfg(feature = "reply-surb")] -use crate::client::reply_key_storage::ReplyKeyStorage; +#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] +pub mod non_wasm_helpers; pub struct ClientInput { pub shared_lane_queue_lengths: LaneQueueLengths, @@ -75,35 +80,36 @@ impl ClientOutputStatus { } } -pub struct BaseClientBuilder<'a> { +pub struct BaseClientBuilder<'a, B> { // due to wasm limitations I had to split it like this : ( gateway_config: &'a GatewayEndpointConfig, debug_config: &'a DebugConfig, disabled_credentials: bool, validator_api_endpoints: Vec, - - #[cfg(feature = "reply-surb")] - reply_surb_keys_store_path: PathBuf, + reply_storage_backend: B, bandwidth_controller: Option, key_manager: KeyManager, } -impl<'a> BaseClientBuilder<'a> { +impl<'a, B> BaseClientBuilder<'a, B> +where + B: ReplyStorageBackend + Send + Sync + 'static, +{ pub fn new_from_base_config( base_config: &'a Config, key_manager: KeyManager, bandwidth_controller: Option, - ) -> BaseClientBuilder<'a> { + reply_storage_backend: B, + ) -> BaseClientBuilder<'a, B> { BaseClientBuilder { gateway_config: base_config.get_gateway_endpoint_config(), debug_config: base_config.get_debug_config(), disabled_credentials: base_config.get_disabled_credentials_mode(), validator_api_endpoints: base_config.get_validator_api_endpoints(), bandwidth_controller, + reply_storage_backend, key_manager, - #[cfg(feature = "reply-surb")] - reply_surb_keys_store_path: base_config.get_reply_encryption_key_store_path(), } } @@ -112,19 +118,18 @@ impl<'a> BaseClientBuilder<'a> { debug_config: &'a DebugConfig, key_manager: KeyManager, bandwidth_controller: Option, + reply_storage_backend: B, disabled_credentials: bool, validator_api_endpoints: Vec, - #[cfg(feature = "reply-surb")] reply_surb_keys_store_path: PathBuf, - ) -> BaseClientBuilder<'a> { + ) -> BaseClientBuilder<'a, B> { BaseClientBuilder { gateway_config, debug_config, disabled_credentials, validator_api_endpoints, bandwidth_controller, + reply_storage_backend, key_manager, - #[cfg(feature = "reply-surb")] - reply_surb_keys_store_path, } } @@ -141,7 +146,9 @@ impl<'a> BaseClientBuilder<'a> { // future constantly pumping loop cover traffic at some specified average rate // the pumped traffic goes to the MixTrafficController fn start_cover_traffic_stream( - &self, + debug_config: &DebugConfig, + ack_key: Arc, + self_address: Recipient, topology_accessor: TopologyAccessor, mix_tx: BatchMixMessageSender, shutdown: ShutdownListener, @@ -149,16 +156,16 @@ impl<'a> BaseClientBuilder<'a> { info!("Starting loop cover traffic stream..."); let mut stream = LoopCoverTrafficStream::new( - self.key_manager.ack_key(), - self.debug_config.average_ack_delay, - self.debug_config.average_packet_delay, - self.debug_config.loop_cover_traffic_average_delay, + ack_key, + debug_config.average_ack_delay, + debug_config.average_packet_delay, + debug_config.loop_cover_traffic_average_delay, mix_tx, - self.as_mix_recipient(), + self_address, topology_accessor, ); - if let Some(size) = self.debug_config.use_extended_packet_size { + if let Some(size) = debug_config.use_extended_packet_size { log::debug!("Setting extended packet size: {:?}", size); stream.set_custom_packet_size(size.into()); } @@ -168,32 +175,18 @@ impl<'a> BaseClientBuilder<'a> { #[allow(clippy::too_many_arguments)] fn start_real_traffic_controller( - &self, + controller_config: real_messages_control::Config, topology_accessor: TopologyAccessor, ack_receiver: AcknowledgementReceiver, input_receiver: InputMessageReceiver, mix_sender: BatchMixMessageSender, + reply_storage: CombinedReplyStorage, + reply_controller_sender: ReplyControllerSender, + reply_controller_receiver: ReplyControllerReceiver, lane_queue_lengths: LaneQueueLengths, client_connection_rx: ConnectionCommandReceiver, shutdown: ShutdownListener, - #[cfg(feature = "reply-surb")] reply_key_storage: ReplyKeyStorage, ) { - let mut controller_config = real_messages_control::Config::new( - self.key_manager.ack_key(), - self.debug_config.ack_wait_multiplier, - self.debug_config.ack_wait_addition, - self.debug_config.average_ack_delay, - self.debug_config.message_sending_average_delay, - self.debug_config.average_packet_delay, - self.debug_config.disable_main_poisson_packet_distribution, - self.as_mix_recipient(), - ); - - if let Some(size) = self.debug_config.use_extended_packet_size { - log::debug!("Setting extended packet size: {:?}", size); - controller_config.set_custom_packet_size(size.into()); - } - info!("Starting real traffic stream..."); RealMessagesController::new( @@ -202,10 +195,11 @@ impl<'a> BaseClientBuilder<'a> { input_receiver, mix_sender, topology_accessor, + reply_storage, + reply_controller_sender, + reply_controller_receiver, lane_queue_lengths, client_connection_rx, - #[cfg(feature = "reply-surb")] - reply_key_storage, ) .start_with_shutdown(shutdown); } @@ -213,19 +207,20 @@ impl<'a> BaseClientBuilder<'a> { // buffer controlling all messages fetched from provider // required so that other components would be able to use them (say the websocket) fn start_received_messages_buffer_controller( - &self, + local_encryption_keypair: Arc, query_receiver: ReceivedBufferRequestReceiver, mixnet_receiver: MixnetMessageReceiver, + reply_key_storage: SentReplyKeys, + reply_controller_sender: ReplyControllerSender, shutdown: ShutdownListener, - #[cfg(feature = "reply-surb")] reply_key_storage: ReplyKeyStorage, ) { info!("Starting received messages buffer controller..."); ReceivedMessagesBufferController::new( - self.key_manager.encryption_keypair(), + local_encryption_keypair, query_receiver, mixnet_receiver, - #[cfg(feature = "reply-surb")] reply_key_storage, + reply_controller_sender, ) .start_with_shutdown(shutdown) } @@ -235,7 +230,7 @@ impl<'a> BaseClientBuilder<'a> { mixnet_message_sender: MixnetMessageSender, ack_sender: AcknowledgementSender, shutdown: ShutdownListener, - ) -> Result { + ) -> Result> { let gateway_id = self.gateway_config.gateway_id.clone(); if gateway_id.is_empty() { return Err(ClientCoreError::GatewayIdUnknown); @@ -286,13 +281,14 @@ impl<'a> BaseClientBuilder<'a> { // future responsible for periodically polling directory server and updating // the current global view of topology async fn start_topology_refresher( - &mut self, + validator_api_urls: Vec, + refresh_rate: Duration, topology_accessor: TopologyAccessor, shutdown: ShutdownListener, - ) -> Result<(), ClientCoreError> { + ) -> Result<(), ClientCoreError> { let topology_refresher_config = TopologyRefresherConfig::new( - self.validator_api_endpoints.clone(), - self.debug_config.topology_refresh_rate, + validator_api_urls, + refresh_rate, env!("CARGO_PKG_VERSION").to_string(), ); let mut topology_refresher = @@ -302,13 +298,12 @@ impl<'a> BaseClientBuilder<'a> { info!("Obtaining initial network topology"); topology_refresher.refresh().await; - // TODO: a slightly more graceful termination here - if !topology_refresher.is_topology_routable().await { + if let Err(err) = topology_refresher.ensure_topology_is_routable().await { log::error!( "The current network topology seem to be insufficient to route any packets through \ - - check if enough nodes and a gateway are online" + - check if enough nodes and a gateway are online - source: {err}" ); - return Err(ClientCoreError::InsufficientNetworkTopology); + return Err(ClientCoreError::InsufficientNetworkTopology(err)); } info!("Starting topology refresher..."); @@ -330,7 +325,27 @@ impl<'a> BaseClientBuilder<'a> { mix_tx } - pub async fn start_base(mut self) -> Result { + async fn setup_persistent_reply_storage( + backend: B, + shutdown: ShutdownListener, + ) -> Result> { + let persistent_storage = PersistentReplyStorage::new(backend); + let mem_store = persistent_storage + .load_state_from_backend() + .await + .map_err(|err| ClientCoreError::SurbStorageError { source: err })?; + + let store_clone = mem_store.clone(); + spawn_future(async move { + persistent_storage + .flush_on_shutdown(store_clone, shutdown) + .await + }); + + Ok(mem_store) + } + + pub async fn start_base(mut self) -> Result> { info!("Starting nym client"); // channels for inter-component communication // TODO: make the channels be internally created by the relevant components @@ -351,32 +366,42 @@ impl<'a> BaseClientBuilder<'a> { let (ack_sender, ack_receiver) = mpsc::unbounded(); let shared_topology_accessor = TopologyAccessor::new(); - #[cfg(feature = "reply-surb")] - let reply_key_storage = - ReplyKeyStorage::load(&self.reply_surb_keys_store_path).tap_err(|err| { - log::error!("Failed to load reply key storage - is it perhaps already in use?"); - log::error!("{:?}", err); - })?; - // Shutdown notifier for signalling tasks to stop let shutdown = ShutdownNotifier::default(); + // channels responsible for dealing with reply-related fun + let (reply_controller_sender, reply_controller_receiver) = + reply_controller::new_control_channels(); + + let self_address = self.as_mix_recipient(); + // the components are started in very specific order. Unless you know what you are doing, // do not change that. - self.start_topology_refresher(shared_topology_accessor.clone(), shutdown.subscribe()) - .await?; - self.start_received_messages_buffer_controller( - received_buffer_request_receiver, - mixnet_messages_receiver, - shutdown.subscribe(), - #[cfg(feature = "reply-surb")] - reply_key_storage.clone(), - ); - let gateway_client = self .start_gateway_client(mixnet_messages_sender, ack_sender, shutdown.subscribe()) .await?; + let reply_storage = + Self::setup_persistent_reply_storage(self.reply_storage_backend, shutdown.subscribe()) + .await?; + + Self::start_topology_refresher( + self.validator_api_endpoints.clone(), + self.debug_config.topology_refresh_rate, + shared_topology_accessor.clone(), + shutdown.subscribe(), + ) + .await?; + + Self::start_received_messages_buffer_controller( + self.key_manager.encryption_keypair(), + received_buffer_request_receiver, + mixnet_messages_receiver, + reply_storage.key_storage(), + reply_controller_sender.clone(), + shutdown.subscribe(), + ); + // The sphinx_message_sender is the transmitter for any component generating sphinx packets // that are to be sent to the mixnet. They are used by cover traffic stream and real // traffic stream. @@ -392,20 +417,36 @@ impl<'a> BaseClientBuilder<'a> { // primarily to throttle incoming connections (e.g socks5 for attached network-requesters) let shared_lane_queue_lengths = LaneQueueLengths::new(); - self.start_real_traffic_controller( + let mut controller_config = real_messages_control::Config::new( + self.debug_config, + self.key_manager.ack_key(), + self_address, + ); + + if let Some(size) = self.debug_config.use_extended_packet_size { + log::debug!("Setting extended packet size: {:?}", size); + controller_config.set_custom_packet_size(size.into()); + } + + Self::start_real_traffic_controller( + controller_config, shared_topology_accessor.clone(), ack_receiver, input_receiver, sphinx_message_sender.clone(), + reply_storage, + reply_controller_sender, + reply_controller_receiver, shared_lane_queue_lengths.clone(), client_connection_rx, shutdown.subscribe(), - #[cfg(feature = "reply-surb")] - reply_key_storage, ); if !self.debug_config.disable_loop_cover_traffic_stream { - self.start_cover_traffic_stream( + Self::start_cover_traffic_stream( + self.debug_config, + self.key_manager.ack_key(), + self_address, shared_topology_accessor, sphinx_message_sender, shutdown.subscribe(), @@ -413,7 +454,7 @@ impl<'a> BaseClientBuilder<'a> { } debug!("Core client startup finished!"); - debug!("The address of this client is: {}", self.as_mix_recipient()); + debug!("The address of this client is: {self_address}"); Ok(BaseClient { client_input: ClientInputStatus::AwaitingProducer { diff --git a/clients/client-core/src/client/base_client/non_wasm_helpers.rs b/clients/client-core/src/client/base_client/non_wasm_helpers.rs new file mode 100644 index 0000000000..8c51c784c8 --- /dev/null +++ b/clients/client-core/src/client/base_client/non_wasm_helpers.rs @@ -0,0 +1,51 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::client::replies::reply_storage::{ + fs_backend, CombinedReplyStorage, ReplyStorageBackend, +}; +use crate::config::DebugConfig; +use crate::error::ClientCoreError; +use log::{error, info}; +use std::path::Path; + +pub async fn setup_fs_reply_surb_backend>( + db_path: P, + debug_config: &DebugConfig, +) -> Result> { + // if the database file doesnt exist, initialise fresh storage, otherwise attempt to load the existing one + let db_path = db_path.as_ref(); + if db_path.exists() { + info!("loading existing surb database"); + match fs_backend::Backend::try_load(db_path).await { + Ok(backend) => Ok(backend), + Err(err) => { + error!("failed to setup persistent storage backend for our reply needs: {err}"); + Err(ClientCoreError::SurbStorageError { source: err }) + } + } + } else { + info!("creating fresh surb database"); + let mut storage_backend = match fs_backend::Backend::init(db_path).await { + Ok(backend) => backend, + Err(err) => { + error!("failed to setup persistent storage backend for our reply needs: {err}"); + return Err(ClientCoreError::SurbStorageError { source: err }); + } + }; + + // while I kinda hate that we're going to be creating `CombinedReplyStorage` twice, + // it will only be happening on the very first run and in practice won't incur huge + // costs since the storage is going to be empty + let mem_store = CombinedReplyStorage::new( + debug_config.minimum_reply_surb_storage_threshold, + debug_config.maximum_reply_surb_storage_threshold, + ); + storage_backend + .init_fresh(&mem_store) + .await + .map_err(|err| ClientCoreError::SurbStorageError { source: err })?; + + Ok(storage_backend) + } +} diff --git a/clients/client-core/src/client/cover_traffic_stream.rs b/clients/client-core/src/client/cover_traffic_stream.rs index b862f1bcfe..e3fd0ca197 100644 --- a/clients/client-core/src/client/cover_traffic_stream.rs +++ b/clients/client-core/src/client/cover_traffic_stream.rs @@ -161,15 +161,16 @@ impl LoopCoverTrafficStream { // poisson delay, but is it really a problem? let topology_permit = self.topology_access.get_read_permit().await; // the ack is sent back to ourselves (and then ignored) - let topology_ref_option = topology_permit.try_get_valid_topology_ref( + let topology_ref = match topology_permit.try_get_valid_topology_ref( &self.our_full_destination, Some(&self.our_full_destination), - ); - if topology_ref_option.is_none() { - warn!("No valid topology detected - won't send any loop cover message this time"); - return; - } - let topology_ref = topology_ref_option.unwrap(); + ) { + Ok(topology) => topology, + Err(err) => { + warn!("We're not going to send any loop cover message this time, as the current topology seem to be invalid - {err}"); + return; + } + }; let cover_message = generate_loop_cover_packet( &mut self.rng, @@ -241,19 +242,4 @@ impl LoopCoverTrafficStream { log::debug!("LoopCoverTrafficStream: Exiting"); }) } - - pub fn start(mut self) { - // we should set initial delay only when we actually start the stream - let sampled = - sample_poisson_duration(&mut self.rng, self.average_cover_message_sending_delay); - self.set_next_delay(sampled); - - spawn_future(async move { - debug!("Started LoopCoverTrafficStream without graceful shutdown support"); - - while self.next().await.is_some() { - self.on_new_message().await; - } - }) - } } diff --git a/clients/client-core/src/client/inbound_messages.rs b/clients/client-core/src/client/inbound_messages.rs index 909e3720f9..890787aa60 100644 --- a/clients/client-core/src/client/inbound_messages.rs +++ b/clients/client-core/src/client/inbound_messages.rs @@ -1,40 +1,80 @@ use client_connections::TransmissionLane; use nymsphinx::addressing::clients::Recipient; -use nymsphinx::anonymous_replies::ReplySurb; +use nymsphinx::anonymous_replies::requests::AnonymousSenderTag; pub type InputMessageSender = tokio::sync::mpsc::Sender; pub type InputMessageReceiver = tokio::sync::mpsc::Receiver; #[derive(Debug)] pub enum InputMessage { - Fresh { + /// The simplest message variant where no additional information is attached. + /// You're simply sending your `data` to specified `recipient` without any tagging. + /// + /// Ends up with `NymMessage::Plain` variant + Regular { recipient: Recipient, data: Vec, - with_reply_surb: bool, lane: TransmissionLane, }, - Reply { - reply_surb: ReplySurb, + + /// Creates a message used for a duplex anonymous communication where the recipient + /// will never learn of our true identity. This is achieved by carefully sending `reply_surbs`. + /// + /// Note that if reply_surbs is set to zero then + /// this variant requires the client having sent some reply_surbs in the past + /// (and thus the recipient also knowing our sender tag). + /// + /// Ends up with `NymMessage::Repliable` variant + Anonymous { + recipient: Recipient, data: Vec, + reply_surbs: u32, + lane: TransmissionLane, + }, + + /// Attempt to use our internally received and stored `ReplySurb` to send the message back + /// to specified recipient whilst not knowing its full identity (or even gateway). + /// + /// Ends up with `NymMessage::Reply` variant + Reply { + recipient_tag: AnonymousSenderTag, + data: Vec, + lane: TransmissionLane, }, } impl InputMessage { - pub fn new_fresh( - recipient: Recipient, - data: Vec, - with_reply_surb: bool, - lane: TransmissionLane, - ) -> Self { - InputMessage::Fresh { + pub fn new_regular(recipient: Recipient, data: Vec, lane: TransmissionLane) -> Self { + InputMessage::Regular { recipient, data, - with_reply_surb, lane, } } - pub fn new_reply(reply_surb: ReplySurb, data: Vec) -> Self { - InputMessage::Reply { reply_surb, data } + pub fn new_anonymous( + recipient: Recipient, + data: Vec, + reply_surbs: u32, + lane: TransmissionLane, + ) -> Self { + InputMessage::Anonymous { + recipient, + data, + reply_surbs, + lane, + } + } + + pub fn new_reply( + recipient_tag: AnonymousSenderTag, + data: Vec, + lane: TransmissionLane, + ) -> Self { + InputMessage::Reply { + recipient_tag, + data, + lane, + } } } diff --git a/clients/client-core/src/client/mix_traffic.rs b/clients/client-core/src/client/mix_traffic.rs index 0d3aab9513..f61a83af95 100644 --- a/clients/client-core/src/client/mix_traffic.rs +++ b/clients/client-core/src/client/mix_traffic.rs @@ -91,14 +91,4 @@ impl MixTrafficController { log::debug!("MixTrafficController: Exiting"); }) } - - pub fn start(mut self) { - spawn_future(async move { - debug!("Started MixTrafficController without graceful shutdown support"); - - while let Some(mix_packets) = self.mix_rx.recv().await { - self.on_messages(mix_packets).await; - } - }) - } } diff --git a/clients/client-core/src/client/mod.rs b/clients/client-core/src/client/mod.rs index 8c09544ce6..8110d52909 100644 --- a/clients/client-core/src/client/mod.rs +++ b/clients/client-core/src/client/mod.rs @@ -8,6 +8,5 @@ pub mod key_manager; pub mod mix_traffic; pub mod real_messages_control; pub mod received_buffer; -#[cfg(feature = "reply-surb")] -pub mod reply_key_storage; +pub mod replies; pub mod topology_control; diff --git a/clients/client-core/src/client/real_messages_control/acknowledgement_control/acknowledgement_listener.rs b/clients/client-core/src/client/real_messages_control/acknowledgement_control/acknowledgement_listener.rs index bd7b34e93d..95c431fd59 100644 --- a/clients/client-core/src/client/real_messages_control/acknowledgement_control/acknowledgement_listener.rs +++ b/clients/client-core/src/client/real_messages_control/acknowledgement_control/acknowledgement_listener.rs @@ -1,7 +1,7 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use super::action_controller::{Action, ActionSender}; +use super::action_controller::{AckActionSender, Action}; use futures::StreamExt; use gateway_client::AcknowledgementReceiver; use log::*; @@ -16,14 +16,14 @@ use std::sync::Arc; pub(super) struct AcknowledgementListener { ack_key: Arc, ack_receiver: AcknowledgementReceiver, - action_sender: ActionSender, + action_sender: AckActionSender, } impl AcknowledgementListener { pub(super) fn new( ack_key: Arc, ack_receiver: AcknowledgementReceiver, - action_sender: ActionSender, + action_sender: AckActionSender, ) -> Self { AcknowledgementListener { ack_key, @@ -49,11 +49,6 @@ impl AcknowledgementListener { if frag_id == COVER_FRAG_ID { trace!("Received an ack for a cover message - no need to do anything"); return; - } else if frag_id.is_reply() { - info!("Received an ack for a reply message - no need to do anything! (don't know what to do!)"); - // TODO: probably there will need to be some extra procedure here, something to notify - // user that his reply reached the recipient (since we got an ack) - return; } trace!("Received {} from the mix network", frag_id); @@ -90,14 +85,4 @@ impl AcknowledgementListener { shutdown.recv_timeout().await; log::debug!("AcknowledgementListener: Exiting"); } - - // todo: think whether this is still required - #[allow(dead_code)] - pub(super) async fn run(&mut self) { - debug!("Started AcknowledgementListener without graceful shutdown support"); - - while let Some(acks) = self.ack_receiver.next().await { - self.handle_ack_receiver_item(acks).await - } - } } diff --git a/clients/client-core/src/client/real_messages_control/acknowledgement_control/action_controller.rs b/clients/client-core/src/client/real_messages_control/acknowledgement_control/action_controller.rs index 09cf48185a..cb2e0cc7ca 100644 --- a/clients/client-core/src/client/real_messages_control/acknowledgement_control/action_controller.rs +++ b/clients/client-core/src/client/real_messages_control/acknowledgement_control/action_controller.rs @@ -3,7 +3,7 @@ use super::PendingAcknowledgement; use crate::client::real_messages_control::acknowledgement_control::RetransmissionRequestSender; -use futures::channel::mpsc::{self, UnboundedReceiver, UnboundedSender}; +use futures::channel::mpsc; use futures::StreamExt; use log::*; use nonexhaustive_delayqueue::{Expired, NonExhaustiveDelayQueue, QueueKey}; @@ -13,7 +13,8 @@ use std::collections::HashMap; use std::sync::Arc; use std::time::Duration; -pub(crate) type ActionSender = UnboundedSender; +pub(crate) type AckActionSender = mpsc::UnboundedSender; +pub(crate) type AckActionReceiver = mpsc::UnboundedReceiver; // The actual data being sent off as well as potential key to the delay queue type PendingAckEntry = (Arc, Option); @@ -95,7 +96,7 @@ pub(super) struct ActionController { pending_acks_timers: NonExhaustiveDelayQueue, /// Channel for receiving `Action`s from other modules. - incoming_actions: UnboundedReceiver, + incoming_actions: AckActionReceiver, /// Channel for notifying `RetransmissionRequestListener` about expired acknowledgements. retransmission_sender: RetransmissionRequestSender, @@ -105,18 +106,15 @@ impl ActionController { pub(super) fn new( config: Config, retransmission_sender: RetransmissionRequestSender, - ) -> (Self, ActionSender) { - let (sender, receiver) = mpsc::unbounded(); - ( - ActionController { - config, - pending_acks_data: HashMap::new(), - pending_acks_timers: NonExhaustiveDelayQueue::new(), - incoming_actions: receiver, - retransmission_sender, - }, - sender, - ) + incoming_actions: AckActionReceiver, + ) -> Self { + ActionController { + config, + pending_acks_data: HashMap::new(), + pending_acks_timers: NonExhaustiveDelayQueue::new(), + incoming_actions, + retransmission_sender, + } } fn handle_insert(&mut self, pending_acks: Vec) { @@ -138,13 +136,18 @@ impl ActionController { trace!("{} is starting its timer", frag_id); if let Some((pending_ack_data, queue_key)) = self.pending_acks_data.get_mut(&frag_id) { - if queue_key.is_some() { - // this branch should be IMPOSSIBLE under ANY condition. It would imply starting - // timer TWICE for the SAME PendingAcknowledgement - panic!("Tried to start an already started ack timer!") - } - let timeout = (pending_ack_data.delay.clone() * self.config.ack_wait_multiplier) - .to_duration() + // the fact that this branch is now POSSIBLE is a sign of a need to refactor this whole + // retransmission procedure + // + // (it can happen as timer is started when ack expires to make sure it's not stuck in memory + // and the second instance can be fired when we finally get reply surbs for data we failed to retransmit) + + // if queue_key.is_some() { + // // this branch should be IMPOSSIBLE under ANY condition. It would imply starting + // // timer TWICE for the SAME PendingAcknowledgement + // panic!("Tried to start an already started ack timer!") + // } + let timeout = (pending_ack_data.delay * self.config.ack_wait_multiplier).to_duration() + self.config.ack_wait_addition; let new_queue_key = self.pending_acks_timers.insert(frag_id, timeout); @@ -192,7 +195,8 @@ impl ActionController { trace!("{} is updating its delay", frag_id); // TODO: is it possible to solve this without either locking or temporarily removing the value? if let Some((pending_ack_data, queue_key)) = self.pending_acks_data.remove(&frag_id) { - // this Action is triggered by `RetransmissionRequestListener` which held the other potential + // this Action is triggered by `RetransmissionRequestListener` (for 'normal' packets) + // or `ReplyController` (for 'reply' packets) which held the other potential // reference to this Arc. HOWEVER, before the Action was pushed onto the queue, the reference // was dropped hence this unwrap is safe. let mut inner_data = Arc::try_unwrap(pending_ack_data).unwrap(); @@ -277,17 +281,4 @@ impl ActionController { .expect("Task stopped without shutdown called"); log::debug!("ActionController: Exiting"); } - - // todo: think whether this is still required - #[allow(dead_code)] - pub(super) async fn run(&mut self) { - debug!("Started ActionController without graceful shutdown support"); - - loop { - tokio::select! { - action = self.incoming_actions.next() => self.process_action(action.unwrap()), - expired_ack = self.pending_acks_timers.next() => self.handle_expired_ack_timer(expired_ack.unwrap()) - } - } - } } diff --git a/clients/client-core/src/client/real_messages_control/acknowledgement_control/input_message_listener.rs b/clients/client-core/src/client/real_messages_control/acknowledgement_control/input_message_listener.rs index dec2d153d6..cff6b6d719 100644 --- a/clients/client-core/src/client/real_messages_control/acknowledgement_control/input_message_listener.rs +++ b/clients/client-core/src/client/real_messages_control/acknowledgement_control/input_message_listener.rs @@ -1,23 +1,14 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use super::action_controller::{Action, ActionSender}; -use super::PendingAcknowledgement; -use crate::client::{ - inbound_messages::{InputMessage, InputMessageReceiver}, - real_messages_control::real_traffic_stream::{BatchRealMessageSender, RealMessage}, - topology_control::TopologyAccessor, -}; +use crate::client::inbound_messages::{InputMessage, InputMessageReceiver}; +use crate::client::real_messages_control::message_handler::MessageHandler; +use crate::client::replies::reply_controller::ReplyControllerSender; use client_connections::TransmissionLane; use log::*; -use nymsphinx::anonymous_replies::ReplySurb; -use nymsphinx::preparer::MessagePreparer; -use nymsphinx::{acknowledgements::AckKey, addressing::clients::Recipient}; +use nymsphinx::addressing::clients::Recipient; +use nymsphinx::anonymous_replies::requests::AnonymousSenderTag; use rand::{CryptoRng, Rng}; -use std::sync::Arc; - -#[cfg(feature = "reply-surb")] -use crate::client::reply_key_storage::ReplyKeyStorage; /// Module responsible for dealing with the received messages: splitting them, creating acknowledgements, /// putting everything into sphinx packets, etc. @@ -26,15 +17,9 @@ pub(super) struct InputMessageListener where R: CryptoRng + Rng, { - ack_key: Arc, - ack_recipient: Recipient, input_receiver: InputMessageReceiver, - message_preparer: MessagePreparer, - action_sender: ActionSender, - real_message_sender: BatchRealMessageSender, - topology_access: TopologyAccessor, - #[cfg(feature = "reply-surb")] - reply_key_storage: ReplyKeyStorage, + message_handler: MessageHandler, + reply_controller_sender: ReplyControllerSender, } impl InputMessageListener @@ -45,153 +30,83 @@ where // some considerable refactoring #[allow(clippy::too_many_arguments)] pub(super) fn new( - ack_key: Arc, - ack_recipient: Recipient, input_receiver: InputMessageReceiver, - message_preparer: MessagePreparer, - action_sender: ActionSender, - real_message_sender: BatchRealMessageSender, - topology_access: TopologyAccessor, - #[cfg(feature = "reply-surb")] reply_key_storage: ReplyKeyStorage, + message_handler: MessageHandler, + reply_controller_sender: ReplyControllerSender, ) -> Self { InputMessageListener { - ack_key, - ack_recipient, input_receiver, - message_preparer, - action_sender, - real_message_sender, - topology_access, - #[cfg(feature = "reply-surb")] - reply_key_storage, + message_handler, + reply_controller_sender, } } - // we require topology for replies to generate surb_acks - async fn handle_reply(&mut self, reply_surb: ReplySurb, data: Vec) -> Option { - let topology_permit = self.topology_access.get_read_permit().await; - let topology = match topology_permit.try_get_valid_topology_ref(&self.ack_recipient, None) { - Some(topology_ref) => topology_ref, - None => { - warn!("Could not process the message - the network topology is invalid"); - return None; - } - }; - - match self - .message_preparer - .prepare_reply_for_use(data, reply_surb, topology, &self.ack_key) - .await - { - Ok((mix_packet, reply_id)) => { - // TODO: later probably write pending ack here - // and deal with them.... - // ... somehow - Some(RealMessage::new(mix_packet, reply_id)) - } - Err(err) => { - // TODO: should we have some mechanism to indicate to the user that the `reply_surb` - // could be reused since technically it wasn't used up here? - warn!("failed to deal with received reply surb - {:?}", err); - None - } - } + async fn handle_reply( + &mut self, + recipient_tag: AnonymousSenderTag, + data: Vec, + lane: TransmissionLane, + ) { + // offload reply handling to the dedicated task + self.reply_controller_sender + .send_reply(recipient_tag, data, lane) } - async fn handle_fresh_message( + async fn handle_plain_message( &mut self, recipient: Recipient, content: Vec, - with_reply_surb: bool, - ) -> Option> { - log::trace!("handling msg size: {}", content.len()); - let topology_permit = self.topology_access.get_read_permit().await; - let topology = match topology_permit - .try_get_valid_topology_ref(&self.ack_recipient, Some(&recipient)) + lane: TransmissionLane, + ) { + if let Err(err) = self + .message_handler + .try_send_plain_message(recipient, content, lane) + .await { - Some(topology_ref) => topology_ref, - None => { - warn!("Could not process the message - the network topology is invalid"); - return None; - } - }; - - // split the message, attach optional reply surb - let (split_message, reply_key) = self - .message_preparer - .prepare_and_split_message(content, with_reply_surb, topology) - .expect("somehow the topology was invalid after all!"); - - #[cfg(feature = "reply-surb")] - if let Some(reply_key) = reply_key { - self.reply_key_storage - .insert_encryption_key(reply_key) - .expect("Failed to insert surb reply key to the store!") + warn!("failed to send a plain message - {err}") } + } - #[cfg(not(feature = "reply-surb"))] - let _reply_key = reply_key; - - // encrypt chunks, put them inside sphinx packets and generate acks - let mut pending_acks = Vec::with_capacity(split_message.len()); - let mut real_messages = Vec::with_capacity(split_message.len()); - for message_chunk in split_message { - // we need to clone it because we need to keep it in memory in case we had to retransmit - // it. And then we'd need to recreate entire ACK again. - let chunk_clone = message_chunk.clone(); - let prepared_fragment = self - .message_preparer - .prepare_chunk_for_sending(chunk_clone, topology, &self.ack_key, &recipient) - .unwrap(); - - real_messages.push(RealMessage::new( - prepared_fragment.mix_packet, - message_chunk.fragment_identifier(), - )); - - pending_acks.push(PendingAcknowledgement::new( - message_chunk, - prepared_fragment.total_delay, - recipient, - )); + async fn handle_repliable_message( + &mut self, + recipient: Recipient, + content: Vec, + reply_surbs: u32, + lane: TransmissionLane, + ) { + if let Err(err) = self + .message_handler + .try_send_message_with_reply_surbs(recipient, content, reply_surbs, lane) + .await + { + warn!("failed to send a repliable message - {err}") } - - // tells the controller to put this into the hashmap - self.action_sender - .unbounded_send(Action::new_insert(pending_acks)) - .unwrap(); - - Some(real_messages) } async fn on_input_message(&mut self, msg: InputMessage) { - let (real_messages, lane) = match msg { - InputMessage::Fresh { + match msg { + InputMessage::Regular { recipient, data, - with_reply_surb, lane, - } => ( - self.handle_fresh_message(recipient, data, with_reply_surb) - .await, + } => self.handle_plain_message(recipient, data, lane).await, + InputMessage::Anonymous { + recipient, + data, + reply_surbs, lane, - ), - InputMessage::Reply { reply_surb, data } => ( - self.handle_reply(reply_surb, data) + } => { + self.handle_repliable_message(recipient, data, reply_surbs, lane) .await - .map(|message| vec![message]), - TransmissionLane::Reply, - ), + } + InputMessage::Reply { + recipient_tag, + data, + lane, + } => { + self.handle_reply(recipient_tag, data, lane).await; + } }; - - // there's no point in trying to send nothing - if let Some(real_messages) = real_messages { - // tells real message sender (with the poisson timer) to send this to the mix network - self.real_message_sender - .send((real_messages, lane)) - .await - .expect("BatchRealMessageReceiver has stopped receiving!"); - } } pub(super) async fn run_with_shutdown(&mut self, mut shutdown: task::ShutdownListener) { @@ -216,13 +131,4 @@ where shutdown.recv_timeout().await; log::debug!("InputMessageListener: Exiting"); } - - // todo: think whether this is still required - #[allow(dead_code)] - pub(super) async fn run(&mut self) { - debug!("Started InputMessageListener without graceful shutdown support"); - while let Some(input_msg) = self.input_receiver.recv().await { - self.on_input_message(input_msg).await; - } - } } diff --git a/clients/client-core/src/client/real_messages_control/acknowledgement_control/mod.rs b/clients/client-core/src/client/real_messages_control/acknowledgement_control/mod.rs index 5bf2331555..5587958f33 100644 --- a/clients/client-core/src/client/real_messages_control/acknowledgement_control/mod.rs +++ b/clients/client-core/src/client/real_messages_control/acknowledgement_control/mod.rs @@ -7,18 +7,20 @@ use self::{ retransmission_request_listener::RetransmissionRequestListener, sent_notification_listener::SentNotificationListener, }; -use super::real_traffic_stream::BatchRealMessageSender; -use crate::client::{inbound_messages::InputMessageReceiver, topology_control::TopologyAccessor}; +use crate::client::inbound_messages::InputMessageReceiver; +use crate::client::real_messages_control::message_handler::MessageHandler; +use crate::client::replies::reply_controller::ReplyControllerSender; use crate::spawn_future; +use action_controller::AckActionReceiver; use futures::channel::mpsc; use gateway_client::AcknowledgementReceiver; use log::*; +use nymsphinx::anonymous_replies::requests::AnonymousSenderTag; use nymsphinx::params::PacketSize; use nymsphinx::{ acknowledgements::AckKey, addressing::clients::Recipient, chunking::fragment::{Fragment, FragmentIdentifier}, - preparer::MessagePreparer, Delay as SphinxDelay, }; use rand::{CryptoRng, Rng}; @@ -27,8 +29,7 @@ use std::{ time::Duration, }; -#[cfg(feature = "reply-surb")] -use crate::client::reply_key_storage::ReplyKeyStorage; +pub(crate) use action_controller::{AckActionSender, Action}; mod acknowledgement_listener; mod action_controller; @@ -50,24 +51,64 @@ pub(super) type SentPacketNotificationSender = mpsc::UnboundedSender; +#[derive(Debug)] +pub(crate) enum PacketDestination { + Anonymous { + recipient_tag: AnonymousSenderTag, + // special flag to indicate whether this was an ack for requesting additional surbs, + // in that case we have to do everything we can to get it through, even if it means going + // below our stored reply surb threshold + extra_surb_request: bool, + }, + KnownRecipient(Box), +} + /// Structure representing a data `Fragment` that is on-route to the specified `Recipient` #[derive(Debug)] pub(crate) struct PendingAcknowledgement { message_chunk: Fragment, delay: SphinxDelay, - recipient: Recipient, + destination: PacketDestination, } impl PendingAcknowledgement { /// Creates new instance of `PendingAcknowledgement` using the provided data. - fn new(message_chunk: Fragment, delay: SphinxDelay, recipient: Recipient) -> Self { + pub(crate) fn new_known( + message_chunk: Fragment, + delay: SphinxDelay, + recipient: Recipient, + ) -> Self { PendingAcknowledgement { message_chunk, delay, - recipient, + destination: PacketDestination::KnownRecipient(recipient.into()), } } + pub(crate) fn new_anonymous( + message_chunk: Fragment, + delay: SphinxDelay, + recipient_tag: AnonymousSenderTag, + extra_surb_request: bool, + ) -> Self { + PendingAcknowledgement { + message_chunk, + delay, + destination: PacketDestination::Anonymous { + recipient_tag, + extra_surb_request, + }, + } + } + + pub(crate) fn inner_fragment_identifier(&self) -> FragmentIdentifier { + self.message_chunk.fragment_identifier() + } + + pub(crate) fn fragment_data(&self) -> Fragment { + self.message_chunk.clone() + } + fn update_delay(&mut self, new_delay: SphinxDelay) { self.delay = new_delay; } @@ -76,10 +117,6 @@ impl PendingAcknowledgement { /// AcknowledgementControllerConnectors represents set of channels for communication with /// other parts of the system in order to support acknowledgements and retransmission. pub(super) struct AcknowledgementControllerConnectors { - /// Channel used for forwarding prepared sphinx messages into the poisson sender - /// to be sent to the mix network. - real_message_sender: BatchRealMessageSender, - /// Channel used for receiving raw messages from a client. The messages need to be put /// into sphinx packets first. input_receiver: InputMessageReceiver, @@ -91,20 +128,28 @@ pub(super) struct AcknowledgementControllerConnectors { /// Channel used for receiving acknowledgements from the mix network. ack_receiver: AcknowledgementReceiver, + + /// Channel used for sending request to `ActionController` to deal with anything ack-related, + ack_action_sender: AckActionSender, + + /// Channel used for receiving request by `ActionController` to deal with anything ack-related, + ack_action_receiver: AckActionReceiver, } impl AcknowledgementControllerConnectors { pub(super) fn new( - real_message_sender: BatchRealMessageSender, input_receiver: InputMessageReceiver, sent_notifier: SentPacketNotificationReceiver, ack_receiver: AcknowledgementReceiver, + ack_action_sender: AckActionSender, + ack_action_receiver: AckActionReceiver, ) -> Self { AcknowledgementControllerConnectors { - real_message_sender, input_receiver, sent_notifier, ack_receiver, + ack_action_sender, + ack_action_receiver, } } } @@ -117,28 +162,15 @@ pub(super) struct Config { /// Given ack timeout in the form a * BASE_DELAY + b, it specifies the multiplier `a` ack_wait_multiplier: f64, - /// Average delay an acknowledgement packet is going to get delayed at a single mixnode. - average_ack_delay: Duration, - - /// Average delay a data packet is going to get delayed at a single mixnode. - average_packet_delay: Duration, - /// Predefined packet size used for the encapsulated messages. packet_size: PacketSize, } impl Config { - pub(super) fn new( - ack_wait_addition: Duration, - ack_wait_multiplier: f64, - average_ack_delay: Duration, - average_packet_delay: Duration, - ) -> Self { + pub(super) fn new(ack_wait_addition: Duration, ack_wait_multiplier: f64) -> Self { Config { ack_wait_addition, ack_wait_multiplier, - average_ack_delay, - average_packet_delay, packet_size: Default::default(), } } @@ -162,68 +194,51 @@ where impl AcknowledgementController where - R: 'static + CryptoRng + Rng + Clone + Send, + R: 'static + CryptoRng + Rng + Clone + Send + Sync, { - #[allow(clippy::too_many_arguments)] pub(super) fn new( config: Config, - rng: R, - topology_access: TopologyAccessor, ack_key: Arc, - ack_recipient: Recipient, connectors: AcknowledgementControllerConnectors, - #[cfg(feature = "reply-surb")] reply_key_storage: ReplyKeyStorage, + message_handler: MessageHandler, + reply_controller_sender: ReplyControllerSender, ) -> Self { let (retransmission_tx, retransmission_rx) = mpsc::unbounded(); let action_config = action_controller::Config::new(config.ack_wait_addition, config.ack_wait_multiplier); - let (action_controller, action_sender) = - ActionController::new(action_config, retransmission_tx); - - let message_preparer = MessagePreparer::new( - rng, - ack_recipient, - config.average_packet_delay, - config.average_ack_delay, - ) - .with_custom_real_message_packet_size(config.packet_size); + let action_controller = ActionController::new( + action_config, + retransmission_tx, + connectors.ack_action_receiver, + ); // will listen for any acks coming from the network let acknowledgement_listener = AcknowledgementListener::new( Arc::clone(&ack_key), connectors.ack_receiver, - action_sender.clone(), + connectors.ack_action_sender.clone(), ); // will listen for any new messages from the client let input_message_listener = InputMessageListener::new( - Arc::clone(&ack_key), - ack_recipient, connectors.input_receiver, - message_preparer.clone(), - action_sender.clone(), - connectors.real_message_sender.clone(), - topology_access.clone(), - #[cfg(feature = "reply-surb")] - reply_key_storage, + message_handler.clone(), + reply_controller_sender.clone(), ); // will listen for any ack timeouts and trigger retransmission let retransmission_request_listener = RetransmissionRequestListener::new( - Arc::clone(&ack_key), - ack_recipient, - message_preparer, - action_sender.clone(), - connectors.real_message_sender, + connectors.ack_action_sender.clone(), + message_handler, retransmission_rx, - topology_access, + reply_controller_sender, ); // will listen for events indicating the packet was sent through the network so that // the retransmission timer should be started. let sent_notification_listener = - SentNotificationListener::new(connectors.sent_notifier, action_sender); + SentNotificationListener::new(connectors.sent_notifier, connectors.ack_action_sender); AcknowledgementController { acknowledgement_listener, @@ -278,35 +293,4 @@ where debug!("The controller has finished execution!"); }); } - - // todo: think whether this is still required - #[allow(dead_code)] - pub(super) fn start(self) { - let mut acknowledgement_listener = self.acknowledgement_listener; - let mut input_message_listener = self.input_message_listener; - let mut retransmission_request_listener = self.retransmission_request_listener; - let mut sent_notification_listener = self.sent_notification_listener; - let mut action_controller = self.action_controller; - - spawn_future(async move { - acknowledgement_listener.run().await; - error!("The acknowledgement listener has finished execution!"); - }); - spawn_future(async move { - input_message_listener.run().await; - error!("The input listener has finished execution!"); - }); - spawn_future(async move { - retransmission_request_listener.run().await; - error!("The retransmission request listener has finished execution!"); - }); - spawn_future(async move { - sent_notification_listener.run().await; - error!("The sent notification listener has finished execution!"); - }); - spawn_future(async move { - action_controller.run().await; - error!("The controller has finished execution!"); - }); - } } diff --git a/clients/client-core/src/client/real_messages_control/acknowledgement_control/retransmission_request_listener.rs b/clients/client-core/src/client/real_messages_control/acknowledgement_control/retransmission_request_listener.rs index 190f23e50c..b5c6e6a2a8 100644 --- a/clients/client-core/src/client/real_messages_control/acknowledgement_control/retransmission_request_listener.rs +++ b/clients/client-core/src/client/real_messages_control/acknowledgement_control/retransmission_request_listener.rs @@ -1,82 +1,101 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use super::{ - action_controller::{Action, ActionSender}, + action_controller::{AckActionSender, Action}, PendingAcknowledgement, RetransmissionRequestReceiver, }; -use crate::client::{ - real_messages_control::real_traffic_stream::{BatchRealMessageSender, RealMessage}, - topology_control::TopologyAccessor, -}; - +use crate::client::real_messages_control::acknowledgement_control::PacketDestination; +use crate::client::real_messages_control::message_handler::{MessageHandler, PreparationError}; +use crate::client::real_messages_control::real_traffic_stream::RealMessage; +use crate::client::replies::reply_controller::ReplyControllerSender; use client_connections::TransmissionLane; use futures::StreamExt; use log::*; -use nymsphinx::{ - acknowledgements::AckKey, addressing::clients::Recipient, preparer::MessagePreparer, -}; +use nymsphinx::addressing::clients::Recipient; +use nymsphinx::chunking::fragment::Fragment; +use nymsphinx::preparer::PreparedFragment; use rand::{CryptoRng, Rng}; use std::sync::{Arc, Weak}; // responsible for packet retransmission upon fired timer -pub(super) struct RetransmissionRequestListener -where - R: CryptoRng + Rng, -{ - ack_key: Arc, - ack_recipient: Recipient, - message_preparer: MessagePreparer, - action_sender: ActionSender, - real_message_sender: BatchRealMessageSender, +pub(super) struct RetransmissionRequestListener { + action_sender: AckActionSender, + message_handler: MessageHandler, request_receiver: RetransmissionRequestReceiver, - topology_access: TopologyAccessor, + reply_controller_sender: ReplyControllerSender, } impl RetransmissionRequestListener where R: CryptoRng + Rng, { - #[allow(clippy::too_many_arguments)] pub(super) fn new( - ack_key: Arc, - ack_recipient: Recipient, - message_preparer: MessagePreparer, - action_sender: ActionSender, - real_message_sender: BatchRealMessageSender, + action_sender: AckActionSender, + message_handler: MessageHandler, request_receiver: RetransmissionRequestReceiver, - topology_access: TopologyAccessor, + reply_controller_sender: ReplyControllerSender, ) -> Self { RetransmissionRequestListener { - ack_key, - ack_recipient, - message_preparer, action_sender, - real_message_sender, + message_handler, request_receiver, - topology_access, + reply_controller_sender, } } - async fn on_retransmission_request(&mut self, timed_out_ack: Weak) { - let timed_out_ack = match timed_out_ack.upgrade() { + async fn prepare_normal_retransmission_chunk( + &mut self, + packet_recipient: Recipient, + chunk_data: Fragment, + ) -> Result { + debug!("retransmitting normal packet..."); + + self.message_handler + .try_prepare_single_chunk_for_sending(packet_recipient, chunk_data) + .await + } + + async fn on_retransmission_request( + &mut self, + weak_timed_out_ack: Weak, + ) { + let timed_out_ack = match weak_timed_out_ack.upgrade() { Some(timed_out_ack) => timed_out_ack, None => { debug!("We received an ack JUST as we were about to retransmit [1]"); return; } }; - let packet_recipient = &timed_out_ack.recipient; - let chunk_clone = timed_out_ack.message_chunk.clone(); - let frag_id = chunk_clone.fragment_identifier(); - let topology_permit = self.topology_access.get_read_permit().await; - let topology_ref = match topology_permit - .try_get_valid_topology_ref(&self.ack_recipient, Some(packet_recipient)) - { - Some(topology_ref) => topology_ref, - None => { - warn!("Could not retransmit the packet - the network topology is invalid"); + let maybe_prepared_fragment = match &timed_out_ack.destination { + PacketDestination::Anonymous { + recipient_tag, + extra_surb_request, + } => { + // if this is retransmission for reply, offload it to the dedicated task + // that deals with all the surbs + return self.reply_controller_sender.send_retransmission_data( + *recipient_tag, + weak_timed_out_ack, + *extra_surb_request, + ); + } + PacketDestination::KnownRecipient(recipient) => { + self.prepare_normal_retransmission_chunk( + **recipient, + timed_out_ack.message_chunk.clone(), + ) + .await + } + }; + + let frag_id = timed_out_ack.message_chunk.fragment_identifier(); + + let prepared_fragment = match maybe_prepared_fragment { + Ok(prepared_fragment) => prepared_fragment, + Err(err) => { + warn!("Could not retransmit the packet - {err}"); // we NEED to start timer here otherwise we will have this guy permanently stuck in memory self.action_sender .unbounded_send(Action::new_start_timer(frag_id)) @@ -85,11 +104,6 @@ where } }; - let prepared_fragment = self - .message_preparer - .prepare_chunk_for_sending(chunk_clone, topology_ref, &self.ack_key, packet_recipient) - .unwrap(); - // if we have the ONLY strong reference to the ack data, it means it was removed from the // pending acks if Arc::strong_count(&timed_out_ack) == 1 { @@ -101,7 +115,6 @@ where // we no longer need the reference - let's drop it so that if somehow `UpdateTimer` action // reached the controller before this function terminated, the controller would not panic. drop(timed_out_ack); - let new_delay = prepared_fragment.total_delay; // We know this update will be reflected by the `StartTimer` Action performed when this @@ -116,13 +129,12 @@ where .unwrap(); // send to `OutQueueControl` to eventually send to the mix network - self.real_message_sender - .send(( + self.message_handler + .forward_messages( vec![RealMessage::new(prepared_fragment.mix_packet, frag_id)], TransmissionLane::Retransmission, - )) + ) .await - .expect("BatchRealMessageReceiver has stopped receiving!"); } pub(super) async fn run_with_shutdown(&mut self, mut shutdown: task::ShutdownListener) { @@ -145,14 +157,4 @@ where shutdown.recv_timeout().await; log::debug!("RetransmissionRequestListener: Exiting"); } - - // todo: think whether this is still required - #[allow(dead_code)] - pub(super) async fn run(&mut self) { - debug!("Started RetransmissionRequestListener without graceful shutdown support"); - - while let Some(timed_out_ack) = self.request_receiver.next().await { - self.on_retransmission_request(timed_out_ack).await; - } - } } diff --git a/clients/client-core/src/client/real_messages_control/acknowledgement_control/sent_notification_listener.rs b/clients/client-core/src/client/real_messages_control/acknowledgement_control/sent_notification_listener.rs index 958c696aa7..c273182d59 100644 --- a/clients/client-core/src/client/real_messages_control/acknowledgement_control/sent_notification_listener.rs +++ b/clients/client-core/src/client/real_messages_control/acknowledgement_control/sent_notification_listener.rs @@ -1,7 +1,7 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use super::action_controller::{Action, ActionSender}; +use super::action_controller::{AckActionSender, Action}; use super::SentPacketNotificationReceiver; use futures::StreamExt; use log::*; @@ -13,13 +13,13 @@ use nymsphinx::chunking::fragment::{FragmentIdentifier, COVER_FRAG_ID}; /// accidentally fire retransmission way quicker than we should have. pub(super) struct SentNotificationListener { sent_notifier: SentPacketNotificationReceiver, - action_sender: ActionSender, + action_sender: AckActionSender, } impl SentNotificationListener { pub(super) fn new( sent_notifier: SentPacketNotificationReceiver, - action_sender: ActionSender, + action_sender: AckActionSender, ) -> Self { SentNotificationListener { sent_notifier, @@ -31,11 +31,6 @@ impl SentNotificationListener { if frag_id == COVER_FRAG_ID { trace!("sent off a cover message - no need to start retransmission timer!"); return; - } else if frag_id.is_reply() { - debug!("sent off a reply message - no need to start retransmission timer!"); - // TODO: probably there will need to be some extra procedure here, like it would - // be nice to know that our reply actually reached the recipient (i.e. we got the ack) - return; } self.action_sender .unbounded_send(Action::new_start_timer(frag_id)) @@ -64,14 +59,4 @@ impl SentNotificationListener { assert!(shutdown.is_shutdown_poll()); log::debug!("SentNotificationListener: Exiting"); } - - // todo: think whether this is still required - #[allow(dead_code)] - pub(super) async fn run(&mut self) { - debug!("Started SentNotificationListener without graceful shutdown support"); - - while let Some(frag_id) = self.sent_notifier.next().await { - self.on_sent_message(frag_id).await; - } - } } diff --git a/clients/client-core/src/client/real_messages_control/message_handler.rs b/clients/client-core/src/client/real_messages_control/message_handler.rs new file mode 100644 index 0000000000..1c80ef519f --- /dev/null +++ b/clients/client-core/src/client/real_messages_control/message_handler.rs @@ -0,0 +1,548 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::client::real_messages_control::acknowledgement_control::PendingAcknowledgement; +use crate::client::real_messages_control::real_traffic_stream::{ + BatchRealMessageSender, RealMessage, +}; +use crate::client::real_messages_control::{AckActionSender, Action}; +use crate::client::replies::reply_storage::{ReceivedReplySurbsMap, SentReplyKeys, UsedSenderTags}; +use crate::client::topology_control::{TopologyAccessor, TopologyReadPermit}; +use client_connections::TransmissionLane; +use log::{debug, error, info, trace, warn}; +use nymsphinx::acknowledgements::AckKey; +use nymsphinx::addressing::clients::Recipient; +use nymsphinx::anonymous_replies::requests::{AnonymousSenderTag, RepliableMessage, ReplyMessage}; +use nymsphinx::anonymous_replies::{ReplySurb, SurbEncryptionKey}; +use nymsphinx::chunking::fragment::{Fragment, FragmentIdentifier}; +use nymsphinx::message::NymMessage; +use nymsphinx::params::{PacketSize, DEFAULT_NUM_MIX_HOPS}; +use nymsphinx::preparer::{MessagePreparer, PreparedFragment}; +use nymsphinx::Delay; +use rand::{CryptoRng, Rng}; +use std::sync::Arc; +use std::time::Duration; +use thiserror::Error; +use topology::{NymTopology, NymTopologyError}; + +// TODO: move that error elsewhere since it seems to be contaminating different files +#[derive(Debug, Clone, Error)] +pub enum PreparationError { + #[error(transparent)] + NymTopologyError(#[from] NymTopologyError), + + #[error("The received message cannot be sent using a single reply surb. It ended up getting split into {fragments} fragments.")] + MessageTooLongForSingleSurb { fragments: usize }, + + #[error("Not enough reply SURBs to send the message. We have {available} available and require at least {required}.")] + NotEnoughSurbs { available: usize, required: usize }, +} + +impl PreparationError { + fn return_surbs(self, returned_surbs: Vec) -> SurbWrappedPreparationError { + SurbWrappedPreparationError { + source: self, + returned_surbs: Some(returned_surbs), + } + } +} + +#[derive(Debug, Error)] +#[error("Failed to prepare packets - {source}. {} reply surbs will be returned", .returned_surbs.as_ref().map(|s| s.len()).unwrap_or_default())] +pub struct SurbWrappedPreparationError { + #[source] + source: PreparationError, + + returned_surbs: Option>, +} + +impl From for SurbWrappedPreparationError +where + T: Into, +{ + fn from(err: T) -> Self { + SurbWrappedPreparationError { + source: err.into(), + returned_surbs: None, + } + } +} + +impl SurbWrappedPreparationError { + pub(crate) fn return_unused_surbs( + self, + surb_storage: &ReceivedReplySurbsMap, + target: &AnonymousSenderTag, + ) -> PreparationError { + if let Some(reply_surbs) = self.returned_surbs { + surb_storage.insert_surbs(target, reply_surbs) + } + self.source + } +} + +#[derive(Clone)] +pub(crate) struct Config { + /// Key used to decrypt contents of received SURBAcks + ack_key: Arc, + + /// Address of this client which also represent an address to which all acknowledgements + /// and surb-based are going to be sent. + sender_address: Recipient, + + /// Average delay a data packet is going to get delay at a single mixnode. + average_packet_delay: Duration, + + /// Average delay an acknowledgement packet is going to get delay at a single mixnode. + average_ack_delay: Duration, + + /// Number of mix hops each packet ('real' message, ack, reply) is expected to take. + /// Note that it does not include gateway hops. + num_mix_hops: u8, + + /// Predefined packet size used for the encapsulated messages. + packet_size: PacketSize, +} + +impl Config { + pub fn new( + ack_key: Arc, + sender_address: Recipient, + average_packet_delay: Duration, + average_ack_delay: Duration, + ) -> Self { + Config { + ack_key, + sender_address, + average_packet_delay, + average_ack_delay, + num_mix_hops: DEFAULT_NUM_MIX_HOPS, + packet_size: PacketSize::default(), + } + } + + /// Allows setting non-default number of expected mix hops in the network. + #[allow(dead_code)] + pub fn with_mix_hops(mut self, hops: u8) -> Self { + self.num_mix_hops = hops; + self + } + + /// Allows setting non-default size of the sphinx packets sent out. + pub fn with_custom_packet_size(mut self, packet_size: PacketSize) -> Self { + self.packet_size = packet_size; + self + } +} + +#[derive(Clone)] +pub(crate) struct MessageHandler { + config: Config, + rng: R, + message_preparer: MessagePreparer, + action_sender: AckActionSender, + real_message_sender: BatchRealMessageSender, + topology_access: TopologyAccessor, + reply_key_storage: SentReplyKeys, + tag_storage: UsedSenderTags, +} + +impl MessageHandler +where + R: CryptoRng + Rng, +{ + pub(crate) fn new( + config: Config, + rng: R, + action_sender: AckActionSender, + real_message_sender: BatchRealMessageSender, + topology_access: TopologyAccessor, + reply_key_storage: SentReplyKeys, + tag_storage: UsedSenderTags, + ) -> Self + where + R: Copy, + { + let message_preparer = MessagePreparer::new( + rng, + config.sender_address, + config.average_packet_delay, + config.average_ack_delay, + ) + .with_custom_real_message_packet_size(config.packet_size) + .with_mix_hops(config.num_mix_hops); + + MessageHandler { + config, + rng, + message_preparer, + action_sender, + real_message_sender, + topology_access, + reply_key_storage, + tag_storage, + } + } + + fn get_or_create_sender_tag(&mut self, recipient: &Recipient) -> AnonymousSenderTag { + if let Some(existing) = self.tag_storage.try_get_existing(recipient) { + trace!("we already had sender tag for {recipient}"); + existing + } else { + info!("creating new sender tag for {recipient}"); + let new_tag = AnonymousSenderTag::new_random(&mut self.rng); + self.tag_storage.insert_new(recipient, new_tag); + info!("we'll be using {new_tag} for all anonymous messages sent to {recipient}"); + new_tag + } + } + + fn get_topology<'a>( + &self, + permit: &'a TopologyReadPermit<'a>, + ) -> Result<&'a NymTopology, PreparationError> { + match permit.try_get_valid_topology_ref(&self.config.sender_address, None) { + Ok(topology_ref) => Ok(topology_ref), + Err(err) => { + warn!("Could not process the packet - the network topology is invalid - {err}"); + Err(err.into()) + } + } + } + + async fn generate_reply_surbs_with_keys( + &mut self, + amount: usize, + ) -> Result<(Vec, Vec), PreparationError> { + let topology_permit = self.topology_access.get_read_permit().await; + let topology = self.get_topology(&topology_permit)?; + + let reply_surbs = self + .message_preparer + .generate_reply_surbs(amount, topology)?; + + let reply_keys = reply_surbs + .iter() + .map(|s| *s.encryption_key()) + .collect::>(); + + Ok((reply_surbs, reply_keys)) + } + + pub(crate) async fn try_send_single_surb_message( + &mut self, + target: AnonymousSenderTag, + message: ReplyMessage, + reply_surb: ReplySurb, + is_extra_surb_request: bool, + ) -> Result<(), SurbWrappedPreparationError> { + let mut fragment = self + .message_preparer + .pad_and_split_message(NymMessage::new_reply(message)); + if fragment.len() > 1 { + // well, it's not a single surb message + return Err(SurbWrappedPreparationError { + source: PreparationError::MessageTooLongForSingleSurb { + fragments: fragment.len(), + }, + returned_surbs: Some(vec![reply_surb]), + }); + } + + let chunk = fragment.pop().unwrap(); + let chunk_clone = chunk.clone(); + let prepared_fragment = self + .try_prepare_single_reply_chunk_for_sending(reply_surb, chunk_clone) + .await?; + + let real_messages = + RealMessage::new(prepared_fragment.mix_packet, chunk.fragment_identifier()); + let delay = prepared_fragment.total_delay; + let pending_ack = + PendingAcknowledgement::new_anonymous(chunk, delay, target, is_extra_surb_request); + + let lane = if is_extra_surb_request { + TransmissionLane::ReplySurbRequest + } else { + TransmissionLane::General + }; + + self.forward_messages(vec![real_messages], lane).await; + self.insert_pending_acks(vec![pending_ack]); + Ok(()) + } + + pub(crate) async fn try_request_additional_reply_surbs( + &mut self, + from: AnonymousSenderTag, + reply_surb: ReplySurb, + amount: u32, + ) -> Result<(), SurbWrappedPreparationError> { + debug!("requesting {amount} reply SURBs from {from:?}"); + + let surbs_request = + ReplyMessage::new_surb_request_message(self.config.sender_address, amount); + self.try_send_single_surb_message(from, surbs_request, reply_surb, true) + .await + } + + // // TODO: this will require additional argument to make it use different variant of `ReplyMessage` + pub(crate) fn split_reply_message(&mut self, message: Vec) -> Vec { + self.message_preparer + .pad_and_split_message(NymMessage::new_reply(ReplyMessage::new_data_message( + message, + ))) + } + + // the only difference between this method and `try_send_reply_chunks` is that + // here we are not creating acks as acks are already in memory waiting to get cleared. + // we are only updating their existing delays + pub(crate) async fn try_send_retransmission_reply_chunks( + &mut self, + fragments: Vec, + reply_surbs: Vec, + lane: TransmissionLane, + ) -> Result<(), SurbWrappedPreparationError> { + let prepared_fragments = self + .prepare_reply_chunks_for_sending(fragments.clone(), reply_surbs) + .await?; + + let mut real_messages = Vec::with_capacity(prepared_fragments.len()); + + for prepared in prepared_fragments { + self.update_ack_delay(prepared.fragment_identifier, prepared.total_delay); + real_messages.push(prepared.into()) + } + + self.forward_messages(real_messages, lane).await; + Ok(()) + } + + pub(crate) async fn try_send_reply_chunks( + &mut self, + target: AnonymousSenderTag, + fragments: Vec, + reply_surbs: Vec, + lane: TransmissionLane, + ) -> Result<(), SurbWrappedPreparationError> { + let prepared_fragments = self + .prepare_reply_chunks_for_sending(fragments.clone(), reply_surbs) + .await?; + + let mut pending_acks = Vec::with_capacity(fragments.len()); + let mut real_messages = Vec::with_capacity(fragments.len()); + + for (raw, prepared) in fragments.into_iter().zip(prepared_fragments.into_iter()) { + let real_message = RealMessage::new(prepared.mix_packet, prepared.fragment_identifier); + let delay = prepared.total_delay; + let pending_ack = PendingAcknowledgement::new_anonymous(raw, delay, target, false); + + real_messages.push(real_message); + pending_acks.push(pending_ack); + } + + self.forward_messages(real_messages, lane).await; + self.insert_pending_acks(pending_acks); + Ok(()) + } + + pub(crate) async fn try_send_plain_message( + &mut self, + recipient: Recipient, + message: Vec, + lane: TransmissionLane, + ) -> Result<(), PreparationError> { + let message = NymMessage::new_plain(message); + self.try_split_and_send_non_reply_message(message, recipient, lane) + .await + } + + pub(crate) async fn try_split_and_send_non_reply_message( + &mut self, + message: NymMessage, + recipient: Recipient, + lane: TransmissionLane, + ) -> Result<(), PreparationError> { + // TODO: I really dislike existence of this assertion, it implies code has to be re-organised + debug_assert!(!matches!(message, NymMessage::Reply(_))); + + // TODO2: it's really annoying we have to get topology permit again here due to borrow-checker + let topology_permit = self.topology_access.get_read_permit().await; + let topology = self.get_topology(&topology_permit)?; + + let fragments = self.message_preparer.pad_and_split_message(message); + + let mut pending_acks = Vec::with_capacity(fragments.len()); + let mut real_messages = Vec::with_capacity(fragments.len()); + for fragment in fragments { + // we need to clone it because we need to keep it in memory in case we had to retransmit + // it. And then we'd need to recreate entire ACK again. + let chunk_clone = fragment.clone(); + let prepared_fragment = self.message_preparer.prepare_chunk_for_sending( + chunk_clone, + topology, + &self.config.ack_key, + &recipient, + )?; + + let real_message = + RealMessage::new(prepared_fragment.mix_packet, fragment.fragment_identifier()); + let delay = prepared_fragment.total_delay; + let pending_ack = PendingAcknowledgement::new_known(fragment, delay, recipient); + + real_messages.push(real_message); + pending_acks.push(pending_ack); + } + + self.insert_pending_acks(pending_acks); + self.forward_messages(real_messages, lane).await; + + Ok(()) + } + + pub(crate) async fn try_send_additional_reply_surbs( + &mut self, + recipient: Recipient, + amount: u32, + ) -> Result<(), PreparationError> { + let sender_tag = self.get_or_create_sender_tag(&recipient); + let (reply_surbs, reply_keys) = + self.generate_reply_surbs_with_keys(amount as usize).await?; + + let message = NymMessage::new_repliable(RepliableMessage::new_additional_surbs( + sender_tag, + reply_surbs, + )); + + self.try_split_and_send_non_reply_message( + message, + recipient, + TransmissionLane::AdditionalReplySurbs, + ) + .await?; + + log::trace!("storing {} reply keys", reply_keys.len()); + self.reply_key_storage.insert_multiple(reply_keys); + + Ok(()) + } + + pub(crate) async fn try_send_message_with_reply_surbs( + &mut self, + recipient: Recipient, + message: Vec, + num_reply_surbs: u32, + lane: TransmissionLane, + ) -> Result<(), SurbWrappedPreparationError> { + let sender_tag = self.get_or_create_sender_tag(&recipient); + let (reply_surbs, reply_keys) = self + .generate_reply_surbs_with_keys(num_reply_surbs as usize) + .await?; + + let message = + NymMessage::new_repliable(RepliableMessage::new_data(message, sender_tag, reply_surbs)); + + self.try_split_and_send_non_reply_message(message, recipient, lane) + .await?; + + log::trace!("storing {} reply keys", reply_keys.len()); + self.reply_key_storage.insert_multiple(reply_keys); + + Ok(()) + } + + pub(crate) async fn try_prepare_single_chunk_for_sending( + &mut self, + recipient: Recipient, + chunk: Fragment, + ) -> Result { + let topology_permit = self.topology_access.get_read_permit().await; + let topology = self.get_topology(&topology_permit)?; + + let prepared_fragment = self + .message_preparer + .prepare_chunk_for_sending(chunk, topology, &self.config.ack_key, &recipient) + .unwrap(); + + Ok(prepared_fragment) + } + + async fn prepare_reply_chunks_for_sending( + &mut self, + fragments: Vec, + reply_surbs: Vec, + ) -> Result, SurbWrappedPreparationError> { + debug_assert_ne!( + fragments.len(), + reply_surbs.len(), + "attempted to send {} fragments with {} reply surbs", + fragments.len(), + reply_surbs.len() + ); + + let topology_permit = self.topology_access.get_read_permit().await; + let topology = match self.get_topology(&topology_permit) { + Ok(topology) => topology, + Err(err) => return Err(err.return_surbs(reply_surbs)), + }; + + Ok(fragments + .into_iter() + .zip(reply_surbs.into_iter()) + .map(|(fragment, reply_surb)| { + // unwrap here is fine as we know we have a valid topology + self.message_preparer + .prepare_reply_chunk_for_sending( + fragment, + topology, + &self.config.ack_key, + reply_surb, + ) + .unwrap() + }) + .collect()) + } + + pub(crate) async fn try_prepare_single_reply_chunk_for_sending( + &mut self, + reply_surb: ReplySurb, + chunk: Fragment, + ) -> Result { + let topology_permit = self.topology_access.get_read_permit().await; + let topology = match self.get_topology(&topology_permit) { + Ok(topology) => topology, + Err(err) => return Err(err.return_surbs(vec![reply_surb])), + }; + + let prepared_fragment = self + .message_preparer + .prepare_reply_chunk_for_sending(chunk, topology, &self.config.ack_key, reply_surb) + .unwrap(); + + Ok(prepared_fragment) + } + + pub(crate) fn update_ack_delay(&self, id: FragmentIdentifier, new_delay: Delay) { + self.action_sender + .unbounded_send(Action::UpdateDelay(id, new_delay)) + .expect("action control task has died") + } + + pub(crate) fn insert_pending_acks(&self, pending_acks: Vec) { + self.action_sender + .unbounded_send(Action::new_insert(pending_acks)) + .expect("action control task has died") + } + + // tells real message sender (with the poisson timer) to send this to the mix network + pub(crate) async fn forward_messages( + &self, + messages: Vec, + transmission_lane: TransmissionLane, + ) { + self.real_message_sender + .send((messages, transmission_lane)) + .await + .expect("real message receiver task (OutQueueControl) has died"); + } +} diff --git a/clients/client-core/src/client/real_messages_control/mod.rs b/clients/client-core/src/client/real_messages_control/mod.rs index e46c02e31e..8789cbdf6a 100644 --- a/clients/client-core/src/client/real_messages_control/mod.rs +++ b/clients/client-core/src/client/real_messages_control/mod.rs @@ -8,6 +8,11 @@ use self::{ acknowledgement_control::AcknowledgementController, real_traffic_stream::OutQueueControl, }; +use crate::client::real_messages_control::message_handler::MessageHandler; +use crate::client::replies::reply_controller::{ + ReplyController, ReplyControllerReceiver, ReplyControllerSender, +}; +use crate::client::replies::reply_storage::CombinedReplyStorage; use crate::{ client::{ inbound_messages::InputMessageReceiver, mix_traffic::BatchMixMessageSender, @@ -27,11 +32,13 @@ use rand::{rngs::OsRng, CryptoRng, Rng}; use std::sync::Arc; use std::time::Duration; -#[cfg(feature = "reply-surb")] -use crate::client::reply_key_storage::ReplyKeyStorage; +use crate::client::replies::reply_controller; +use crate::config; +pub(crate) use acknowledgement_control::{AckActionSender, Action}; -mod acknowledgement_control; -mod real_traffic_stream; +pub(crate) mod acknowledgement_control; +pub(crate) mod message_handler; +pub(crate) mod real_traffic_stream; // TODO: ack_key and self_recipient shouldn't really be part of this config pub struct Config { @@ -62,31 +69,102 @@ pub struct Config { /// Predefined packet size used for the encapsulated messages. packet_size: PacketSize, + + /// Defines the minimum number of reply surbs the client would request. + minimum_reply_surb_request_size: u32, + + /// Defines the maximum number of reply surbs the client would request. + maximum_reply_surb_request_size: u32, + + /// Defines the maximum number of reply surbs a remote party is allowed to request from this client at once. + maximum_allowed_reply_surb_request_size: u32, + + /// Defines maximum amount of time the client is going to wait for reply surbs before explicitly asking + /// for more even though in theory they wouldn't need to. + maximum_reply_surb_waiting_period: Duration, + + /// Defines maximum amount of time given reply surb is going to be valid for. + /// This is going to be superseded by key rotation once implemented. + maximum_reply_surb_age: Duration, + + /// Defines maximum amount of time given reply key is going to be valid for. + /// This is going to be superseded by key rotation once implemented. + maximum_reply_key_age: Duration, +} + +impl<'a> From<&'a Config> for acknowledgement_control::Config { + fn from(cfg: &'a Config) -> Self { + acknowledgement_control::Config::new(cfg.ack_wait_addition, cfg.ack_wait_multiplier) + .with_custom_packet_size(cfg.packet_size) + } +} + +impl<'a> From<&'a Config> for real_traffic_stream::Config { + fn from(cfg: &'a Config) -> Self { + real_traffic_stream::Config::new( + Arc::clone(&cfg.ack_key), + cfg.self_recipient, + cfg.average_ack_delay_duration, + cfg.average_packet_delay_duration, + cfg.average_message_sending_delay, + cfg.disable_main_poisson_packet_distribution, + ) + .with_custom_cover_packet_size(cfg.packet_size) + } +} + +impl<'a> From<&'a Config> for reply_controller::Config { + fn from(cfg: &'a Config) -> Self { + reply_controller::Config::new( + cfg.minimum_reply_surb_request_size, + cfg.maximum_reply_surb_request_size, + cfg.maximum_allowed_reply_surb_request_size, + cfg.maximum_reply_surb_waiting_period, + cfg.maximum_reply_surb_age, + cfg.maximum_reply_key_age, + ) + } +} + +impl<'a> From<&'a Config> for message_handler::Config { + fn from(cfg: &'a Config) -> Self { + message_handler::Config::new( + Arc::clone(&cfg.ack_key), + cfg.self_recipient, + cfg.average_packet_delay_duration, + cfg.average_ack_delay_duration, + ) + .with_custom_packet_size(cfg.packet_size) + } } impl Config { - // TODO: change the config into a builder - #[allow(clippy::too_many_arguments)] pub fn new( + base_client_debug_config: &config::DebugConfig, ack_key: Arc, - ack_wait_multiplier: f64, - ack_wait_addition: Duration, - average_ack_delay_duration: Duration, - average_message_sending_delay: Duration, - average_packet_delay_duration: Duration, - disable_main_poisson_packet_distribution: bool, self_recipient: Recipient, ) -> Self { Config { ack_key, - ack_wait_addition, - ack_wait_multiplier, self_recipient, - average_message_sending_delay, - average_packet_delay_duration, - average_ack_delay_duration, - disable_main_poisson_packet_distribution, packet_size: Default::default(), + ack_wait_addition: base_client_debug_config.ack_wait_addition, + ack_wait_multiplier: base_client_debug_config.ack_wait_multiplier, + average_message_sending_delay: base_client_debug_config.message_sending_average_delay, + average_packet_delay_duration: base_client_debug_config.average_packet_delay, + average_ack_delay_duration: base_client_debug_config.average_ack_delay, + disable_main_poisson_packet_distribution: base_client_debug_config + .disable_main_poisson_packet_distribution, + minimum_reply_surb_request_size: base_client_debug_config + .minimum_reply_surb_request_size, + maximum_reply_surb_request_size: base_client_debug_config + .maximum_reply_surb_request_size, + maximum_allowed_reply_surb_request_size: base_client_debug_config + .maximum_allowed_reply_surb_request_size, + maximum_reply_surb_waiting_period: base_client_debug_config + .maximum_reply_surb_waiting_period, + maximum_reply_surb_age: base_client_debug_config.maximum_reply_surb_age, + maximum_reply_key_age: base_client_debug_config.maximum_reply_key_age, } } @@ -95,75 +173,84 @@ impl Config { } } -pub struct RealMessagesController +pub(crate) struct RealMessagesController where R: CryptoRng + Rng, { out_queue_control: OutQueueControl, ack_control: AcknowledgementController, + reply_control: ReplyController, } // obviously when we finally make shared rng that is on 'higher' level, this should become // generic `R` impl RealMessagesController { #[allow(clippy::too_many_arguments)] - pub fn new( + pub(crate) fn new( config: Config, ack_receiver: AcknowledgementReceiver, input_receiver: InputMessageReceiver, mix_sender: BatchMixMessageSender, topology_access: TopologyAccessor, + reply_storage: CombinedReplyStorage, + // so much refactoring needed, but this is temporary just to test things out + reply_controller_sender: ReplyControllerSender, + reply_controller_receiver: ReplyControllerReceiver, lane_queue_lengths: LaneQueueLengths, client_connection_rx: ConnectionCommandReceiver, - #[cfg(feature = "reply-surb")] reply_key_storage: ReplyKeyStorage, ) -> Self { let rng = OsRng; + // create channels for inter-task communication let (real_message_sender, real_message_receiver) = tokio::sync::mpsc::channel(1); let (sent_notifier_tx, sent_notifier_rx) = mpsc::unbounded(); - + let (ack_action_tx, ack_action_rx) = mpsc::unbounded(); let ack_controller_connectors = AcknowledgementControllerConnectors::new( - real_message_sender, input_receiver, sent_notifier_rx, ack_receiver, + ack_action_tx.clone(), + ack_action_rx, ); - let ack_control_config = acknowledgement_control::Config::new( - config.ack_wait_addition, - config.ack_wait_multiplier, - config.average_ack_delay_duration, - config.average_packet_delay_duration, - ) - .with_custom_packet_size(config.packet_size); + // create all configs for the components + let ack_control_config = (&config).into(); + let out_queue_config = (&config).into(); + let reply_controller_config = (&config).into(); + let message_handler_config = (&config).into(); + + // create the actual components + let message_handler = MessageHandler::new( + message_handler_config, + rng, + ack_action_tx, + real_message_sender, + topology_access.clone(), + reply_storage.key_storage(), + reply_storage.tags_storage(), + ); let ack_control = AcknowledgementController::new( ack_control_config, - rng, - topology_access.clone(), Arc::clone(&config.ack_key), - config.self_recipient, ack_controller_connectors, - #[cfg(feature = "reply-surb")] - reply_key_storage, + message_handler.clone(), + reply_controller_sender, ); - let out_queue_config = real_traffic_stream::Config::new( - config.average_ack_delay_duration, - config.average_packet_delay_duration, - config.average_message_sending_delay, - config.disable_main_poisson_packet_distribution, - ) - .with_custom_cover_packet_size(config.packet_size); + let reply_control = ReplyController::new( + reply_controller_config, + message_handler, + reply_storage, + reply_controller_receiver, + ); let out_queue_control = OutQueueControl::new( out_queue_config, - Arc::clone(&config.ack_key), + rng, sent_notifier_tx, mix_sender, real_message_receiver, - rng, - config.self_recipient, topology_access, lane_queue_lengths, client_connection_rx, @@ -172,30 +259,26 @@ impl RealMessagesController { RealMessagesController { out_queue_control, ack_control, + reply_control, } } pub fn start_with_shutdown(self, shutdown: task::ShutdownListener) { let mut out_queue_control = self.out_queue_control; let ack_control = self.ack_control; + let mut reply_control = self.reply_control; let shutdown_handle = shutdown.clone(); spawn_future(async move { out_queue_control.run_with_shutdown(shutdown_handle).await; debug!("The out queue controller has finished execution!"); }); + let shutdown_handle = shutdown.clone(); + spawn_future(async move { + reply_control.run_with_shutdown(shutdown_handle).await; + debug!("The reply controller has finished execution!"); + }); + ack_control.start_with_shutdown(shutdown); } - - #[cfg(target_arch = "wasm32")] - pub fn start(self) { - let mut out_queue_control = self.out_queue_control; - let ack_control = self.ack_control; - - spawn_future(async move { - out_queue_control.run().await; - debug!("The out queue controller has finished execution!"); - }); - ack_control.start(); - } } diff --git a/clients/client-core/src/client/real_messages_control/real_traffic_stream.rs b/clients/client-core/src/client/real_messages_control/real_traffic_stream.rs index 734b75bb70..9b75669960 100644 --- a/clients/client-core/src/client/real_messages_control/real_traffic_stream.rs +++ b/clients/client-core/src/client/real_messages_control/real_traffic_stream.rs @@ -16,6 +16,7 @@ use nymsphinx::chunking::fragment::FragmentIdentifier; use nymsphinx::cover::generate_loop_cover_packet; use nymsphinx::forwarding::packet::MixPacket; use nymsphinx::params::PacketSize; +use nymsphinx::preparer::PreparedFragment; use nymsphinx::utils::sample_poisson_duration; use rand::{CryptoRng, Rng}; use std::pin::Pin; @@ -47,6 +48,12 @@ fn get_time_now() -> wasm_timer::Instant { /// Configurable parameters of the `OutQueueControl` pub(crate) struct Config { + /// Key used to encrypt and decrypt content of an ACK packet. + ack_key: Arc, + + /// Represents full address of this client. + our_full_destination: Recipient, + /// Average delay an acknowledgement packet is going to get delay at a single mixnode. average_ack_delay: Duration, @@ -66,12 +73,16 @@ pub(crate) struct Config { impl Config { pub(crate) fn new( + ack_key: Arc, + our_full_destination: Recipient, average_ack_delay: Duration, average_packet_delay: Duration, average_message_sending_delay: Duration, disable_poisson_packet_distribution: bool, ) -> Self { Config { + ack_key, + our_full_destination, average_ack_delay, average_packet_delay, average_message_sending_delay, @@ -93,9 +104,6 @@ where /// Configurable parameters of the `ActionController` config: Config, - /// Key used to encrypt and decrypt content of an ACK packet. - ack_key: Arc, - /// Channel used for notifying of a real packet being sent out. Used to start up retransmission timer. sent_notifier: SentPacketNotificationSender, @@ -119,9 +127,6 @@ where /// before being sent out into the network. real_receiver: BatchRealMessageReceiver, - /// Represents full address of this client. - our_full_destination: Recipient, - /// Instance of a cryptographically secure random number generator. rng: R, @@ -144,6 +149,16 @@ where pub(crate) struct RealMessage { mix_packet: MixPacket, fragment_id: FragmentIdentifier, + // TODO: add info about it being constructed with reply-surb +} + +impl From for RealMessage { + fn from(fragment: PreparedFragment) -> Self { + RealMessage { + mix_packet: fragment.mix_packet, + fragment_id: fragment.fragment_identifier, + } + } } impl RealMessage { @@ -175,25 +190,21 @@ where #[allow(clippy::too_many_arguments)] pub(crate) fn new( config: Config, - ack_key: Arc, + rng: R, sent_notifier: SentPacketNotificationSender, mix_tx: BatchMixMessageSender, real_receiver: BatchRealMessageReceiver, - rng: R, - our_full_destination: Recipient, topology_access: TopologyAccessor, lane_queue_lengths: LaneQueueLengths, client_connection_rx: ConnectionCommandReceiver, ) -> Self { OutQueueControl { config, - ack_key, sent_notifier, next_delay: None, sending_delay_controller: Default::default(), mix_tx, real_receiver, - our_full_destination, rng, topology_access, transmission_buffer: Default::default(), @@ -220,24 +231,23 @@ where // poisson delay, but is it really a problem? let topology_permit = self.topology_access.get_read_permit().await; // the ack is sent back to ourselves (and then ignored) - let topology_ref_option = topology_permit.try_get_valid_topology_ref( - &self.our_full_destination, - Some(&self.our_full_destination), - ); - if topology_ref_option.is_none() { - warn!( - "No valid topology detected - won't send any loop cover message this time" - ); - return; - } - let topology_ref = topology_ref_option.unwrap(); + let topology_ref = match topology_permit.try_get_valid_topology_ref( + &self.config.our_full_destination, + Some(&self.config.our_full_destination), + ) { + Ok(topology) => topology, + Err(err) => { + warn!("We're not going to send any loop cover message this time, as the current topology seem to be invalid - {err}"); + return; + } + }; ( generate_loop_cover_packet( &mut self.rng, topology_ref, - &self.ack_key, - &self.our_full_destination, + &self.config.ack_key, + &self.config.our_full_destination, self.config.average_ack_delay, self.config.average_packet_delay, self.config.cover_packet_size, @@ -556,16 +566,6 @@ where } log::debug!("OutQueueControl: Exiting"); } - - // todo: think whether this is still required - #[allow(dead_code)] - pub(super) async fn run(&mut self) { - debug!("Started OutQueueControl without graceful shutdown support"); - - while let Some(next_message) = self.next().await { - self.on_message(next_message).await; - } - } } impl Stream for OutQueueControl diff --git a/clients/client-core/src/client/received_buffer.rs b/clients/client-core/src/client/received_buffer.rs index ed693993a2..2e7876ae62 100644 --- a/clients/client-core/src/client/received_buffer.rs +++ b/clients/client-core/src/client/received_buffer.rs @@ -1,26 +1,26 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::client::replies::reply_controller::ReplyControllerSender; +use crate::client::replies::reply_storage::SentReplyKeys; use crate::spawn_future; use crypto::asymmetric::encryption; +use crypto::Digest; use futures::channel::mpsc; use futures::lock::Mutex; use futures::StreamExt; use gateway_client::MixnetMessageReceiver; use log::*; +use nymsphinx::anonymous_replies::requests::{ + RepliableMessage, RepliableMessageContent, ReplyMessage, ReplyMessageContent, +}; +use nymsphinx::anonymous_replies::{encryption_key::EncryptionKeyDigest, SurbEncryptionKey}; +use nymsphinx::message::{NymMessage, PlainMessage}; +use nymsphinx::params::ReplySurbKeyDigestAlgorithm; use nymsphinx::receiver::{MessageReceiver, MessageRecoveryError, ReconstructedMessage}; use std::collections::HashSet; use std::sync::Arc; -#[cfg(feature = "reply-surb")] -use crate::client::reply_key_storage::ReplyKeyStorage; -#[cfg(feature = "reply-surb")] -use crypto::{symmetric::stream_cipher, Digest}; -#[cfg(feature = "reply-surb")] -use nymsphinx::anonymous_replies::{encryption_key::EncryptionKeyDigest, SurbEncryptionKey}; -#[cfg(feature = "reply-surb")] -use nymsphinx::params::{ReplySurbEncryptionAlgorithm, ReplySurbKeyDigestAlgorithm}; - // Buffer Requests to say "hey, send any reconstructed messages to this channel" // or to say "hey, I'm going offline, don't send anything more to me. Just buffer them instead" pub type ReceivedBufferRequestSender = mpsc::UnboundedSender; @@ -46,26 +46,15 @@ struct ReceivedMessagesBufferInner { } impl ReceivedMessagesBufferInner { - fn process_received_fragment(&mut self, raw_fragment: Vec) -> Option { - let fragment_data = match self - .message_receiver - .recover_plaintext(self.local_encryption_keypair.private_key(), raw_fragment) - { - Err(e) => { - warn!("failed to recover fragment data: {:?}. The whole underlying message might be corrupted and unrecoverable!", e); - return None; - } - Ok(frag_data) => frag_data, - }; - - if nymsphinx::cover::is_cover(&fragment_data) { + fn recover_from_fragment(&mut self, fragment_data: &[u8]) -> Option { + if nymsphinx::cover::is_cover(fragment_data) { trace!("The message was a loop cover message! Skipping it"); return None; } - let fragment = match self.message_receiver.recover_fragment(&fragment_data) { - Err(e) => { - warn!("failed to recover fragment from raw data: {:?}. The whole underlying message might be corrupted and unrecoverable!", e); + let fragment = match self.message_receiver.recover_fragment(fragment_data) { + Err(err) => { + warn!("failed to recover fragment from raw data: {err}. The whole underlying message might be corrupted and unrecoverable!"); return None; } Ok(frag) => frag, @@ -79,9 +68,10 @@ impl ReceivedMessagesBufferInner { // if we returned an error the underlying message is malformed in some way match self.message_receiver.insert_new_fragment(fragment) { Err(err) => match err { - MessageRecoveryError::MalformedReconstructedMessage(message_sets) => { + MessageRecoveryError::MalformedReconstructedMessage { source, used_sets } => { + error!("message reconstruction failed - {source}. Attempting to re-use the message sets..."); // TODO: should we really insert reconstructed sets? could this be abused for some attack? - for set_id in message_sets { + for set_id in used_sets { if !self.recently_reconstructed.insert(set_id) { // or perhaps we should even panic at this point? error!("Reconstructed another message containing already used set id!") @@ -107,6 +97,34 @@ impl ReceivedMessagesBufferInner { }, } } + + fn process_received_reply( + &mut self, + reply_ciphertext: &mut [u8], + reply_key: SurbEncryptionKey, + ) -> Option { + // note: this performs decryption IN PLACE without extra allocation + self.message_receiver + .recover_plaintext_from_reply(reply_ciphertext, reply_key); + let fragment_data = reply_ciphertext; + + self.recover_from_fragment(fragment_data) + } + + fn process_received_regular_packet(&mut self, mut raw_fragment: Vec) -> Option { + let fragment_data = match self.message_receiver.recover_plaintext_from_regular_packet( + self.local_encryption_keypair.private_key(), + &mut raw_fragment, + ) { + Err(err) => { + warn!("failed to recover fragment data: {err}. The whole underlying message might be corrupted and unrecoverable!"); + return None; + } + Ok(frag_data) => frag_data, + }; + + self.recover_from_fragment(fragment_data) + } } #[derive(Debug, Clone)] @@ -114,17 +132,15 @@ impl ReceivedMessagesBufferInner { // You should always use .clone() to create additional instances struct ReceivedMessagesBuffer { inner: Arc>, - - /// Storage containing keys to all [`ReplySURB`]s ever sent out that we did not receive back. - // There's no need to put it behind a Mutex since it's already properly concurrent - #[cfg(feature = "reply-surb")] - reply_key_storage: ReplyKeyStorage, + reply_key_storage: SentReplyKeys, + reply_controller_sender: ReplyControllerSender, } impl ReceivedMessagesBuffer { fn new( local_encryption_keypair: Arc, - #[cfg(feature = "reply-surb")] reply_key_storage: ReplyKeyStorage, + reply_key_storage: SentReplyKeys, + reply_controller_sender: ReplyControllerSender, ) -> Self { ReceivedMessagesBuffer { inner: Arc::new(Mutex::new(ReceivedMessagesBufferInner { @@ -134,8 +150,8 @@ impl ReceivedMessagesBuffer { message_sender: None, recently_reconstructed: HashSet::new(), })), - #[cfg(feature = "reply-surb")] reply_key_storage, + reply_controller_sender, } } @@ -177,34 +193,139 @@ impl ReceivedMessagesBuffer { guard.message_sender = Some(sender); } - async fn add_reconstructed_messages(&mut self, msgs: Vec) { - debug!("Adding {:?} new messages to the buffer!", msgs.len()); - trace!("Adding new messages to the buffer! {:?}", msgs); - self.inner.lock().await.messages.extend(msgs) + fn handle_reconstructed_plain_messages( + &mut self, + msgs: Vec, + ) -> Vec { + msgs.into_iter().map(Into::into).collect() } - #[cfg(feature = "reply-surb")] - fn process_received_reply( - reply_ciphertext: &[u8], - reply_key: SurbEncryptionKey, - ) -> Option { - let zero_iv = stream_cipher::zero_iv::(); + fn handle_reconstructed_repliable_messages( + &mut self, + msgs: Vec, + ) -> Vec { + let mut reconstructed = Vec::new(); + for msg in msgs { + let (reply_surbs, from_surb_request) = match msg.content { + RepliableMessageContent::Data { + message, + reply_surbs, + } => { + trace!( + "received message that also contained additional {} reply surbs from {:?}!", + reply_surbs.len(), + msg.sender_tag + ); - let mut reply_msg = stream_cipher::decrypt::( - reply_key.inner(), - &zero_iv, - reply_ciphertext, - ); - if let Err(err) = MessageReceiver::remove_padding(&mut reply_msg) { - warn!("Received reply had malformed padding! - {:?}", err); - None - } else { - // TODO: perhaps having to say it doesn't have a surb an indication the type should be changed? - Some(ReconstructedMessage { - message: reply_msg, - reply_surb: None, - }) + reconstructed.push(ReconstructedMessage::new(message, msg.sender_tag)); + + (reply_surbs, false) + } + RepliableMessageContent::AdditionalSurbs { reply_surbs } => { + trace!( + "received additional {} reply surbs from {:?}!", + reply_surbs.len(), + msg.sender_tag + ); + (reply_surbs, true) + } + RepliableMessageContent::Heartbeat { + additional_reply_surbs, + } => { + error!("received a repliable heartbeat message - we don't know how to handle it yet (and we won't know until future PRs)"); + (additional_reply_surbs, false) + } + }; + + self.reply_controller_sender.send_additional_surbs( + msg.sender_tag, + reply_surbs, + from_surb_request, + ) } + reconstructed + } + + fn handle_reconstructed_reply_messages( + &mut self, + msgs: Vec, + ) -> Vec { + let mut reconstructed = Vec::new(); + for msg in msgs { + match msg.content { + ReplyMessageContent::Data { message } => reconstructed.push(message.into()), + ReplyMessageContent::SurbRequest { recipient, amount } => { + debug!("received request for {amount} additional reply SURBs from {recipient}"); + self.reply_controller_sender + .send_additional_surbs_request(*recipient, amount); + } + } + } + reconstructed + } + + async fn handle_reconstructed_messages(&mut self, msgs: Vec) { + if msgs.is_empty() { + return; + } + + let mut plain_messages = Vec::new(); + let mut repliable_messages = Vec::new(); + let mut reply_messages = Vec::new(); + + for msg in msgs { + match msg { + NymMessage::Plain(plain) => plain_messages.push(plain), + NymMessage::Repliable(repliable) => repliable_messages.push(repliable), + NymMessage::Reply(reply) => reply_messages.push(reply), + } + } + + let mut reconstructed_messages = self.handle_reconstructed_plain_messages(plain_messages); + reconstructed_messages + .append(&mut self.handle_reconstructed_repliable_messages(repliable_messages)); + reconstructed_messages + .append(&mut self.handle_reconstructed_reply_messages(reply_messages)); + + let mut inner_guard = self.inner.lock().await; + debug!( + "Adding {:?} new messages to the buffer!", + reconstructed_messages.len() + ); + + if let Some(sender) = &inner_guard.message_sender { + trace!("Sending reconstructed messages to announced sender"); + if let Err(err) = sender.unbounded_send(reconstructed_messages) { + warn!("The reconstructed message receiver went offline without explicit notification (relevant error: - {err})"); + inner_guard.message_sender = None; + inner_guard.messages.extend(err.into_inner()); + } + } else { + trace!("No sender available - buffering reconstructed messages"); + inner_guard.messages.extend(reconstructed_messages) + } + } + + // this function doesn't really belong here... + fn get_reply_key<'a>( + &self, + raw_message: &'a mut [u8], + ) -> Option<(SurbEncryptionKey, &'a mut [u8])> { + let reply_surb_digest_size = ReplySurbKeyDigestAlgorithm::output_size(); + if raw_message.len() < reply_surb_digest_size { + return None; + } + + let possible_key_digest = + EncryptionKeyDigest::clone_from_slice(&raw_message[..reply_surb_digest_size]); + self.reply_key_storage + .try_pop(possible_key_digest) + .map(|reply_encryption_key| { + ( + *reply_encryption_key, + &mut raw_message[reply_surb_digest_size..], + ) + }) } async fn handle_new_received(&mut self, msgs: Vec>) { @@ -217,69 +338,27 @@ impl ReceivedMessagesBuffer { let mut inner_guard = self.inner.lock().await; // first check if this is a reply or a chunked message - // TODO: verify with @AP if this way of doing it is safe or whether it could - // cause some attacks due to, I don't know, stupid edge case collisions? - // Update: this DOES introduce a possible leakage: https://github.com/nymtech/nym/issues/296 - for msg in msgs { - // TODO: - // 1. make it nicer - // 2. make it not feature-locked - - #[cfg(feature = "reply-surb")] - { - let reply_surb_digest_size = ReplySurbKeyDigestAlgorithm::output_size(); - - let possible_key_digest = - EncryptionKeyDigest::clone_from_slice(&msg[..reply_surb_digest_size]); - - // check first `HasherOutputSize` bytes if they correspond to known encryption key - // if yes - this is a reply message - - // TODO: this might be a bottleneck - since the keys are stored on disk we, presumably, - // are doing a disk operation every single received fragment - if let Some(reply_encryption_key) = self - .reply_key_storage - .get_and_remove_encryption_key(possible_key_digest) - .expect("storage operation failed!") - { - if let Some(completed_message) = Self::process_received_reply( - &msg[reply_surb_digest_size..], - reply_encryption_key, - ) { - completed_messages.push(completed_message) - } + // note: there's a possible information leakage associated with this check https://github.com/nymtech/nym/issues/296 + for mut msg in msgs { + // check first `HasherOutputSize` bytes if they correspond to known encryption key + // if yes - this is a reply message + let completed_message = + if let Some((reply_key, reply_message)) = self.get_reply_key(&mut msg) { + inner_guard.process_received_reply(reply_message, reply_key) } else { - // otherwise - it's a 'normal' message - if let Some(completed_message) = inner_guard.process_received_fragment(msg) { - completed_messages.push(completed_message) - } - } - } + inner_guard.process_received_regular_packet(msg) + }; - #[cfg(not(feature = "reply-surb"))] - if let Some(completed_message) = inner_guard.process_received_fragment(msg) { - completed_messages.push(completed_message) + if let Some(completed) = completed_message { + info!("received {completed}"); + completed_messages.push(completed) } } + drop(inner_guard); + if !completed_messages.is_empty() { - if let Some(sender) = &inner_guard.message_sender { - trace!("Sending reconstructed messages to announced sender"); - if let Err(err) = sender.unbounded_send(completed_messages) { - warn!("The reconstructed message receiver went offline without explicit notification (relevant error: - {:?})", err); - // make sure to drop the lock to not deadlock - // (it is required by `add_reconstructed_messages`) - inner_guard.message_sender = None; - drop(inner_guard); - self.add_reconstructed_messages(err.into_inner()).await; - } - } else { - // make sure to drop the lock to not deadlock - // (it is required by `add_reconstructed_messages`) - drop(inner_guard); - trace!("No sender available - buffering reconstructed messages"); - self.add_reconstructed_messages(completed_messages).await; - } + self.handle_reconstructed_messages(completed_messages).await } } } @@ -342,16 +421,6 @@ impl RequestReceiver { shutdown.recv_timeout().await; log::debug!("RequestReceiver: Exiting"); } - - // todo: think whether this is still required - #[allow(dead_code)] - async fn run(&mut self) { - debug!("Started RequestReceiver without graceful shutdown support"); - - while let Some(message) = self.query_receiver.next().await { - self.handle_message(message).await - } - } } struct FragmentedMessageReceiver { @@ -391,34 +460,25 @@ impl FragmentedMessageReceiver { shutdown.recv_timeout().await; log::debug!("FragmentedMessageReceiver: Exiting"); } - - // todo: think whether this is still required - #[allow(dead_code)] - async fn run(&mut self) { - debug!("Started FragmentedMessageReceiver without graceful shutdown support"); - - while let Some(new_messages) = self.mixnet_packet_receiver.next().await { - self.received_buffer.handle_new_received(new_messages).await; - } - } } -pub struct ReceivedMessagesBufferController { +pub(crate) struct ReceivedMessagesBufferController { fragmented_message_receiver: FragmentedMessageReceiver, request_receiver: RequestReceiver, } impl ReceivedMessagesBufferController { - pub fn new( + pub(crate) fn new( local_encryption_keypair: Arc, query_receiver: ReceivedBufferRequestReceiver, mixnet_packet_receiver: MixnetMessageReceiver, - #[cfg(feature = "reply-surb")] reply_key_storage: ReplyKeyStorage, + reply_key_storage: SentReplyKeys, + reply_controller_sender: ReplyControllerSender, ) -> Self { let received_buffer = ReceivedMessagesBuffer::new( local_encryption_keypair, - #[cfg(feature = "reply-surb")] reply_key_storage, + reply_controller_sender, ); ReceivedMessagesBufferController { @@ -444,16 +504,4 @@ impl ReceivedMessagesBufferController { request_receiver.run_with_shutdown(shutdown).await; }); } - - #[cfg(target_arch = "wasm32")] - pub fn start(self) { - let mut fragmented_message_receiver = self.fragmented_message_receiver; - let mut request_receiver = self.request_receiver; - spawn_future(async move { - fragmented_message_receiver.run().await; - }); - spawn_future(async move { - request_receiver.run().await; - }); - } } diff --git a/clients/client-core/src/client/replies/mod.rs b/clients/client-core/src/client/replies/mod.rs new file mode 100644 index 0000000000..61b5f19abf --- /dev/null +++ b/clients/client-core/src/client/replies/mod.rs @@ -0,0 +1,5 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +pub mod reply_controller; +pub mod reply_storage; diff --git a/clients/client-core/src/client/replies/reply_controller.rs b/clients/client-core/src/client/replies/reply_controller.rs new file mode 100644 index 0000000000..99687527f0 --- /dev/null +++ b/clients/client-core/src/client/replies/reply_controller.rs @@ -0,0 +1,928 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::client::real_messages_control::acknowledgement_control::PendingAcknowledgement; +use crate::client::real_messages_control::message_handler::{MessageHandler, PreparationError}; +use crate::client::replies::reply_storage::CombinedReplyStorage; +use client_connections::TransmissionLane; +use futures::channel::mpsc; +use futures::StreamExt; +use log::{debug, error, info, trace, warn}; +use nymsphinx::addressing::clients::Recipient; +use nymsphinx::anonymous_replies::requests::AnonymousSenderTag; +use nymsphinx::anonymous_replies::ReplySurb; +use nymsphinx::chunking::fragment::{Fragment, FragmentIdentifier}; +use rand::{CryptoRng, Rng}; +use std::cmp::{max, min}; +use std::collections::btree_map::Entry; +use std::collections::{BTreeMap, HashMap, VecDeque}; +use std::sync::{Arc, Weak}; +use std::time::Duration; +use time::OffsetDateTime; + +#[cfg(not(target_arch = "wasm32"))] +type IntervalStream = tokio_stream::wrappers::IntervalStream; + +#[cfg(target_arch = "wasm32")] +type IntervalStream = gloo_timers::future::IntervalStream; + +pub(crate) fn new_control_channels() -> (ReplyControllerSender, ReplyControllerReceiver) { + let (tx, rx) = mpsc::unbounded(); + (tx.into(), rx) +} + +#[derive(Debug, Clone)] +pub(crate) struct ReplyControllerSender(mpsc::UnboundedSender); + +impl From> for ReplyControllerSender { + fn from(inner: mpsc::UnboundedSender) -> Self { + ReplyControllerSender(inner) + } +} + +impl ReplyControllerSender { + pub(crate) fn send_retransmission_data( + &self, + recipient: AnonymousSenderTag, + timed_out_ack: Weak, + extra_surb_request: bool, + ) { + self.0 + .unbounded_send(ReplyControllerMessage::RetransmitReply { + recipient, + timed_out_ack, + extra_surb_request, + }) + .expect("ReplyControllerReceiver has died!") + } + + pub(crate) fn send_reply( + &self, + recipient: AnonymousSenderTag, + message: Vec, + lane: TransmissionLane, + ) { + self.0 + .unbounded_send(ReplyControllerMessage::SendReply { + recipient, + message, + lane, + }) + .expect("ReplyControllerReceiver has died!") + } + + pub(crate) fn send_additional_surbs( + &self, + sender_tag: AnonymousSenderTag, + reply_surbs: Vec, + from_surb_request: bool, + ) { + self.0 + .unbounded_send(ReplyControllerMessage::AdditionalSurbs { + sender_tag, + reply_surbs, + from_surb_request, + }) + .expect("ReplyControllerReceiver has died!") + } + + pub(crate) fn send_additional_surbs_request(&self, recipient: Recipient, amount: u32) { + self.0 + .unbounded_send(ReplyControllerMessage::AdditionalSurbsRequest { + recipient: Box::new(recipient), + amount, + }) + .expect("ReplyControllerReceiver has died!") + } +} + +pub(crate) type ReplyControllerReceiver = mpsc::UnboundedReceiver; + +#[derive(Debug)] +pub(crate) enum ReplyControllerMessage { + RetransmitReply { + recipient: AnonymousSenderTag, + timed_out_ack: Weak, + extra_surb_request: bool, + }, + + SendReply { + recipient: AnonymousSenderTag, + message: Vec, + lane: TransmissionLane, + }, + + AdditionalSurbs { + sender_tag: AnonymousSenderTag, + reply_surbs: Vec, + from_surb_request: bool, + }, + + // Should this also be handled in here? it's technically a completely different side of the pipe + // let's see how it works when combined, might split it before creating PR + AdditionalSurbsRequest { + recipient: Box, + amount: u32, + }, +} + +pub struct Config { + min_surb_request_size: u32, + max_surb_request_size: u32, + maximum_allowed_reply_surb_request_size: u32, + max_surb_waiting_period: Duration, + max_reply_surb_age: Duration, + max_reply_key_age: Duration, +} + +impl Config { + pub(crate) fn new( + min_surb_request_size: u32, + max_surb_request_size: u32, + maximum_allowed_reply_surb_request_size: u32, + max_surb_waiting_period: Duration, + max_reply_surb_age: Duration, + max_reply_key_age: Duration, + ) -> Self { + Self { + min_surb_request_size, + max_surb_request_size, + maximum_allowed_reply_surb_request_size, + max_surb_waiting_period, + max_reply_surb_age, + max_reply_key_age, + } + } +} + +// the purpose of this task: +// - buffers split messages from input message listener if there were insufficient surbs to send them +// - upon getting extra surbs, resends them +// - so I guess it will handle all 'RepliableMessage' and requests from 'ReplyMessage' +// - replies to "give additional surbs" requests +// - will reply to future heartbeats + +// TODO: this should be split into ingress and egress controllers +// because currently its trying to perform two distinct jobs +pub struct ReplyController { + config: Config, + + // TODO: incorporate that field at some point + // and use binomial distribution to determine the expected required number + // of surbs required to send the message through + // expected_reliability: f32, + request_receiver: ReplyControllerReceiver, + pending_replies: HashMap>, + + /// Retransmission packets that have already timed out and are waiting for additional reply SURBs + /// so that they could be sent back to the network. Once we receive more SURBs, we should send them ASAP. + // TODO: when purging stale entries, we must take extra care to also purge all pending ACK data!! + pending_retransmissions: + HashMap>>, + + message_handler: MessageHandler, + full_reply_storage: CombinedReplyStorage, +} + +impl ReplyController +where + R: CryptoRng + Rng, +{ + pub(crate) fn new( + config: Config, + message_handler: MessageHandler, + full_reply_storage: CombinedReplyStorage, + request_receiver: ReplyControllerReceiver, + ) -> Self { + ReplyController { + config, + request_receiver, + pending_replies: HashMap::new(), + pending_retransmissions: HashMap::new(), + message_handler, + full_reply_storage, + } + } + + /// Inserts the pending replies into the BACK of the queue fn insert_pending_replies>>( + fn insert_pending_replies>>( + &mut self, + recipient: &AnonymousSenderTag, + fragments: V, + ) { + if let Some(existing) = self.pending_replies.get_mut(recipient) { + existing.append(&mut fragments.into()) + } else { + self.pending_replies.insert(*recipient, fragments.into()); + } + } + + fn re_insert_pending_retransmission( + &mut self, + recipient: &AnonymousSenderTag, + data: Vec>, + ) { + // the underlying entry MUST exist as we've just got data from there + let map_entry = self + .pending_retransmissions + .get_mut(recipient) + .expect("our pending retransmission entry is somehow gone!"); + + for pending in data { + // if it's 0, we don't need to do anything - we just got that ack! + if Arc::strong_count(&pending) > 1 { + let id = pending.inner_fragment_identifier(); + let downgraded = Arc::downgrade(&pending); + map_entry.insert(id, downgraded); + } + } + } + + fn should_request_more_surbs(&self, target: &AnonymousSenderTag) -> bool { + trace!("checking if we should request more surbs from {:?}", target); + + let pending_queue_size = self + .pending_replies + .get(target) + .map(|pending_queue| pending_queue.len()) + .unwrap_or_default(); + + let retransmission_queue = self + .pending_retransmissions + .get(target) + .map(|pending_queue| pending_queue.len()) + .unwrap_or_default(); + + let total_queue = pending_queue_size + retransmission_queue; + + // simple as that - there's absolutely nothing to retransmit + if total_queue == 0 { + return false; + } + + let available_surbs = self + .full_reply_storage + .surbs_storage_ref() + .available_surbs(target); + let pending_surbs = self + .full_reply_storage + .surbs_storage_ref() + .pending_reception(target) as usize; + let min_surbs_threshold = self + .full_reply_storage + .surbs_storage_ref() + .min_surb_threshold(); + let max_surbs_threshold = self + .full_reply_storage + .surbs_storage_ref() + .max_surb_threshold(); + + debug!("total queue size: {total_queue} = pending data {pending_queue_size} + pending retransmission {retransmission_queue}, available surbs: {available_surbs} pending surbs: {pending_surbs} threshold range: {min_surbs_threshold}..{max_surbs_threshold}"); + + (pending_surbs + available_surbs) < max_surbs_threshold + && (pending_surbs + available_surbs) < (total_queue + min_surbs_threshold) + } + + async fn handle_send_reply( + &mut self, + recipient_tag: AnonymousSenderTag, + data: Vec, + lane: TransmissionLane, + ) { + if !self + .full_reply_storage + .surbs_storage_ref() + .contains_surbs_for(&recipient_tag) + { + warn!("received reply request for {:?} but we don't have any surbs stored for that recipient!", recipient_tag); + return; + } + + trace!("handling reply to {:?}", recipient_tag); + let fragments = self.message_handler.split_reply_message(data); + + let required_surbs = fragments.len(); + trace!("This reply requires {:?} SURBs", required_surbs); + + // TODO: edge case: + // we're making a lot of requests and have to request a lot of surbs + // (but at some point we run out of surbs for surb requests) + + let (surbs, _surbs_left) = self + .full_reply_storage + .surbs_storage_ref() + .get_reply_surbs(&recipient_tag, required_surbs); + + if let Some(reply_surbs) = surbs { + if let Err(err) = self + .message_handler + .try_send_reply_chunks(recipient_tag, fragments, reply_surbs, lane) + .await + { + let err = err.return_unused_surbs( + self.full_reply_storage.surbs_storage_ref(), + &recipient_tag, + ); + warn!("failed to send reply to {:?} - {err}", recipient_tag); + + // TODO: should we buffer that data to try again? + } + } else { + // we don't have enough surbs for this reply + self.insert_pending_replies(&recipient_tag, fragments); + + if self.should_request_more_surbs(&recipient_tag) { + self.request_reply_surbs_for_queue_clearing(recipient_tag) + .await; + } + } + } + + async fn request_additional_reply_surbs( + &mut self, + target: AnonymousSenderTag, + amount: u32, + ) -> Result<(), PreparationError> { + let reply_surb = self + .full_reply_storage + .surbs_storage_ref() + .get_reply_surb_ignoring_threshold(&target) + .and_then(|(reply_surb, _)| reply_surb) + .ok_or(PreparationError::NotEnoughSurbs { + available: 0, + required: 1, + })?; + + if let Err(err) = self + .message_handler + .try_request_additional_reply_surbs(target, reply_surb, amount) + .await + { + let err = err.return_unused_surbs(self.full_reply_storage.surbs_storage_ref(), &target); + warn!( + "failed to request additional surbs from {:?} - {err}", + target + ); + return Err(err); + } else { + self.full_reply_storage + .surbs_storage_ref() + .increment_pending_reception(&target, amount); + } + + Ok(()) + } + + async fn try_clear_pending_retransmission(&mut self, target: AnonymousSenderTag) { + trace!("trying to clear pending retransmission queue"); + let available_surbs = self + .full_reply_storage + .surbs_storage_ref() + .available_surbs(&target); + let min_surbs_threshold = self + .full_reply_storage + .surbs_storage_ref() + .min_surb_threshold(); + + let max_to_clear = if available_surbs > min_surbs_threshold { + available_surbs - min_surbs_threshold + } else { + trace!("we don't have enough surbs for retransmission queue clearing..."); + return; + }; + trace!("we can clear up to {max_to_clear} entries"); + + let Some(pending) = self.pending_retransmissions.get_mut(&target) else { + trace!("there are no pending retransmissions for {target}!"); + return; + }; + + let mut to_take = Vec::new(); + let mut to_remove = Vec::new(); + + // TODO: once rust 1.66.0 is stabilised on 15.12.22, just change it to + // `.pop_front()` to directly take ownership + for (k, data) in pending.iter() { + let upgraded = match data.upgrade() { + Some(upgraded) => upgraded, + None => { + // we got the ack while the data was waiting in the queue + to_remove.push(*k); + continue; + } + }; + + to_take.push(upgraded); + + // we have taken as many entries as we could have + if to_take.len() >= max_to_clear { + break; + } + // TODO: use if upgraded.is_extra_surb_request() to bypass the limit + } + + for ack in &to_take { + pending.remove(&ack.inner_fragment_identifier()); + } + + for id in to_remove { + pending.remove(&id); + } + + if to_take.is_empty() { + // no need to do anything + return; + } + + let (surbs_for_reply, _) = self + .full_reply_storage + .surbs_storage_ref() + .get_reply_surbs(&target, to_take.len()); + + let Some(surbs_for_reply) = surbs_for_reply else { + error!("somehow different task has stolen our reply surbs! - this should have been impossible"); + self.re_insert_pending_retransmission(&target, to_take); + return; + }; + + let to_send_vec = to_take.iter().map(|ack| ack.fragment_data()).collect(); + + if let Err(err) = self + .message_handler + .try_send_retransmission_reply_chunks( + to_send_vec, + surbs_for_reply, + TransmissionLane::Retransmission, + ) + .await + { + let err = err.return_unused_surbs(self.full_reply_storage.surbs_storage_ref(), &target); + self.re_insert_pending_retransmission(&target, to_take); + + warn!( + "failed to clear pending retransmission queue for {:?} - {err}", + target + ); + } + } + + fn pop_at_most_pending_replies( + &mut self, + from: &AnonymousSenderTag, + amount: usize, + ) -> Option> { + // if possible, pop all pending replies, if not, pop only entries for which we'd have a reply surb + let total = self.pending_replies.get(from)?.len(); + trace!("pending queue has {total} elements"); + if total == 0 { + return None; + } + if total < amount { + self.pending_replies.remove(from) + } else { + Some( + self.pending_replies + .get_mut(from)? + .drain(..amount) + .collect(), + ) + } + } + + async fn try_clear_pending_queue(&mut self, target: AnonymousSenderTag) { + trace!("trying to clear pending queue"); + let available_surbs = self + .full_reply_storage + .surbs_storage_ref() + .available_surbs(&target); + let min_surbs_threshold = self + .full_reply_storage + .surbs_storage_ref() + .min_surb_threshold(); + + let max_to_clear = if available_surbs > min_surbs_threshold { + available_surbs - min_surbs_threshold + } else { + trace!("we don't have enough surbs for queue clearing..."); + return; + }; + trace!("we can clear up to {max_to_clear} entries"); + + // we're guaranteed to not get more entries than we have reply surbs for + if let Some(to_send) = self.pop_at_most_pending_replies(&target, max_to_clear) { + let to_send_vec = to_send.iter().cloned().collect::>(); + + if to_send_vec.is_empty() { + panic!( + "please let the devs know if you ever see this message (reply_controller.rs)" + ); + } + + let (surbs_for_reply, _) = self + .full_reply_storage + .surbs_storage_ref() + .get_reply_surbs(&target, to_send_vec.len()); + + let Some(surbs_for_reply) = surbs_for_reply else { + error!("somehow different task has stolen our reply surbs! - this should have been impossible"); + self.insert_pending_replies(&target, to_send); + return; + }; + + if let Err(err) = self + .message_handler + .try_send_reply_chunks( + target, + to_send_vec, + surbs_for_reply, + TransmissionLane::General, + ) + .await + { + let err = + err.return_unused_surbs(self.full_reply_storage.surbs_storage_ref(), &target); + self.insert_pending_replies(&target, to_send); + warn!("failed to clear pending queue for {:?} - {err}", target); + } + } else { + trace!("the pending queue is empty"); + } + } + + async fn handle_received_surbs( + &mut self, + from: AnonymousSenderTag, + reply_surbs: Vec, + from_surb_request: bool, + ) { + trace!("handling received surbs"); + + // clear the requesting flag since we should have been asking for surbs + self.full_reply_storage + .surbs_storage_ref() + .reset_surbs_last_received_at(&from); + if from_surb_request { + self.full_reply_storage + .surbs_storage_ref() + .decrement_pending_reception(&from, reply_surbs.len() as u32); + } + + // store received surbs + self.full_reply_storage + .surbs_storage_ref() + .insert_surbs(&from, reply_surbs); + + // use as many as we can for clearing pending retransmission queue + self.try_clear_pending_retransmission(from).await; + + // use as many as we can for clearing pending 'normal' queue + self.try_clear_pending_queue(from).await; + + // if we have to, request more + if self.should_request_more_surbs(&from) { + self.request_reply_surbs_for_queue_clearing(from).await; + } + } + + async fn handle_surb_request(&mut self, recipient: Recipient, mut amount: u32) { + // 1. check whether we sent any surbs in the past to this recipient, otherwise + // they have no business in asking for more + if !self + .full_reply_storage + .tags_storage_ref() + .exists(&recipient) + { + warn!("{recipient} asked us for reply SURBs even though we never sent them any anonymous messages before!"); + return; + } + + // 2. check whether the requested amount is within sane range + if amount > self.config.maximum_allowed_reply_surb_request_size { + warn!("The requested reply surb amount is larger than our maximum allowed ({amount} > {}). Lowering it to a more sane value...", self.config.maximum_allowed_reply_surb_request_size); + amount = self.config.maximum_allowed_reply_surb_request_size; + } + + // 3. construct and send the surbs away + // (send them in smaller batches to make the experience a bit smoother + let mut remaining = amount; + while remaining > 0 { + let to_send = min(remaining, 100); + if let Err(err) = self + .message_handler + .try_send_additional_reply_surbs(recipient, to_send) + .await + { + warn!("failed to send additional surbs to {recipient} - {err}"); + } else { + trace!("sent {to_send} reply SURBs to {recipient}"); + } + + remaining -= to_send; + } + } + + fn buffer_pending_ack( + &mut self, + recipient: AnonymousSenderTag, + ack_ref: Arc, + weak_ack_ref: Weak, + ) { + let frag_id = ack_ref.inner_fragment_identifier(); + if let Some(existing) = self.pending_retransmissions.get_mut(&recipient) { + if let Entry::Vacant(e) = existing.entry(frag_id) { + e.insert(weak_ack_ref); + } else { + warn!("we're already trying to retransmit {frag_id}. We must be really behind in surbs!"); + } + } else { + let mut inner = BTreeMap::new(); + inner.insert(frag_id, weak_ack_ref); + self.pending_retransmissions.insert(recipient, inner); + } + } + + async fn handle_reply_retransmission( + &mut self, + recipient_tag: AnonymousSenderTag, + timed_out_ack: Weak, + extra_surbs_request: bool, + ) { + // seems we got the ack in the end + let ack_ref = match timed_out_ack.upgrade() { + Some(ack) => ack, + None => { + debug!("we received the ack for one of the reply packets as we were putting it in the retransmission queue"); + return; + } + }; + + // if this is retransmission for obtaining additional reply surbs, + // we can dip below the storage threshold + let (maybe_reply_surb, _) = if extra_surbs_request { + self.full_reply_storage + .surbs_storage_ref() + .get_reply_surb_ignoring_threshold(&recipient_tag) + } else { + self.full_reply_storage + .surbs_storage_ref() + .get_reply_surb(&recipient_tag) + } + .expect("attempted to retransmit a packet to an unknown recipient - we shouldn't have sent the original packet in the first place!"); + + if let Some(reply_surb) = maybe_reply_surb { + match self + .message_handler + .try_prepare_single_reply_chunk_for_sending(reply_surb, ack_ref.fragment_data()) + .await + { + Ok(prepared) => { + // drop the ack ref so that controller would not panic on `UpdateTimer` if that task + // got to handle the action before this function terminated (which is very much + // possible if `forward_messages` takes a while) + drop(ack_ref); + + self.message_handler + .update_ack_delay(prepared.fragment_identifier, prepared.total_delay); + self.message_handler + .forward_messages(vec![prepared.into()], TransmissionLane::Retransmission) + .await; + } + Err(err) => { + let err = err.return_unused_surbs( + self.full_reply_storage.surbs_storage_ref(), + &recipient_tag, + ); + warn!("failed to prepare message for retransmission - {err}"); + // we buffer that packet and to try another day + self.buffer_pending_ack(recipient_tag, ack_ref, timed_out_ack); + + if self.should_request_more_surbs(&recipient_tag) { + self.request_reply_surbs_for_queue_clearing(recipient_tag) + .await; + } + } + }; + } else { + self.buffer_pending_ack(recipient_tag, ack_ref, timed_out_ack); + + if self.should_request_more_surbs(&recipient_tag) { + self.request_reply_surbs_for_queue_clearing(recipient_tag) + .await; + } + } + } + + async fn handle_request(&mut self, request: ReplyControllerMessage) { + match request { + ReplyControllerMessage::RetransmitReply { + recipient, + timed_out_ack, + extra_surb_request, + } => { + self.handle_reply_retransmission(recipient, timed_out_ack, extra_surb_request) + .await + } + ReplyControllerMessage::SendReply { + recipient, + message, + lane, + } => self.handle_send_reply(recipient, message, lane).await, + ReplyControllerMessage::AdditionalSurbs { + sender_tag, + reply_surbs, + from_surb_request, + } => { + self.handle_received_surbs(sender_tag, reply_surbs, from_surb_request) + .await + } + ReplyControllerMessage::AdditionalSurbsRequest { recipient, amount } => { + self.handle_surb_request(*recipient, amount).await + } + } + } + + async fn request_reply_surbs_for_queue_clearing(&mut self, target: AnonymousSenderTag) { + trace!("requesting surbs for queues clearing"); + + let pending_queue_size = self + .pending_replies + .get(&target) + .map(|pending_queue| pending_queue.len()) + .unwrap_or_default(); + + let retransmission_queue = self + .pending_retransmissions + .get(&target) + .map(|pending_queue| pending_queue.len()) + .unwrap_or_default(); + + let total_queue = (pending_queue_size + retransmission_queue) as u32; + + if total_queue == 0 { + trace!("the pending queues for {:?} are already empty", target); + return; + } + + let request_size = min( + self.config.max_surb_request_size, + max(total_queue, self.config.min_surb_request_size), + ); + + if let Err(err) = self + .request_additional_reply_surbs(target, request_size) + .await + { + warn!("failed to request additional surbs... - {err}") + } + } + + async fn inspect_stale_entries(&mut self) { + let mut to_request = Vec::new(); + let mut to_remove = Vec::new(); + + let now = OffsetDateTime::now_utc(); + for (pending_reply_target, vals) in &self.pending_replies { + if vals.is_empty() { + continue; + } + + let Some(last_received) = self.full_reply_storage.surbs_storage_ref().surbs_last_received_at(pending_reply_target) else { + error!("we have {} pending replies for {pending_reply_target}, but we somehow never received any reply surbs from them!", vals.len()); + to_remove.push(*pending_reply_target); + continue; + }; + + // this should never ever happen (famous last words, eh?), but in case it DOES happen eventually + // purge that malformed data + let Ok(last_received_time) = OffsetDateTime::from_unix_timestamp(last_received) else { + error!("somehow our stored timestamp ({last_received}) for surbs from {pending_reply_target} is corrupted!. Going to remove all the associated entries"); + to_remove.push(*pending_reply_target); + continue; + }; + + let diff = now - last_received_time; + + if diff > self.config.max_surb_waiting_period { + warn!("We haven't received any surbs in {:?} from {pending_reply_target}. Going to explicitly ask for more", diff); + to_request.push(*pending_reply_target); + } + } + + for pending_reply_target in to_request { + self.request_reply_surbs_for_queue_clearing(pending_reply_target) + .await; + self.full_reply_storage + .surbs_storage_ref() + .reset_pending_reception(&pending_reply_target) + } + for to_remove in to_remove { + self.pending_replies.remove(&to_remove); + } + } + + async fn invalidate_old_data(&self) { + let now = OffsetDateTime::now_utc(); + + let mut to_remove_surbs = Vec::new(); + let mut to_remove_keys = Vec::new(); + for map_ref in self.full_reply_storage.surbs_storage_ref().as_raw_iter() { + let (sender, received) = map_ref.pair(); + // TODO: handle the following edge case: + // there's a malicious client sending us exactly one reply surb just before we should have invalidated + // the data thus making us keep everything in memory + // possible solution: keep timestamp PER reply surb (but that seems like an overkill) + // but I doubt this is ever going to be a problem... + // ... + // However, if you're reading this message, it probably became a legit problem, + // so I guess add timestamp per surb then? chop-chop. + + let last_received = received.surbs_last_received_at(); + // this should never ever happen (famous last words, eh?), but in case it DOES happen eventually + // purge that malformed data + let Ok(last_received_time) = OffsetDateTime::from_unix_timestamp(last_received) else { + error!("somehow our stored timestamp ({last_received}) for surbs from {sender} is corrupted!. Going to remove all the associated entries"); + to_remove_surbs.push(*sender); + continue; + }; + let diff = now - last_received_time; + + if diff > self.config.max_reply_surb_age { + info!("it's been {diff:?} since we last received any reply surb from {sender}. Going to remove all stored entries..."); + + to_remove_surbs.push(*sender); + } + } + + for map_ref in self.full_reply_storage.key_storage_ref().as_raw_iter() { + let (digest, reply_key) = map_ref.pair(); + + // this should never ever happen (famous last words, eh?), but in case it DOES happen eventually + // purge that malformed data + let Ok(sent_at) = OffsetDateTime::from_unix_timestamp(reply_key.sent_at_timestamp) else { + error!("somehow our stored timestamp ({}) for one of our reply key is corrupted!. Going to remove all the entry", reply_key.sent_at_timestamp); + to_remove_keys.push(*digest); + continue; + }; + + let diff = now - sent_at; + + if diff > self.config.max_reply_key_age { + debug!("it's been {diff:?} since we created this reply key. it's probably never going to get used, so we're going to purge it..."); + to_remove_keys.push(*digest); + } + } + + for to_remove in to_remove_surbs { + self.full_reply_storage + .surbs_storage_ref() + .remove(&to_remove); + } + + for to_remove in to_remove_keys { + self.full_reply_storage.key_storage().remove(to_remove) + } + } + + fn create_interval_stream(polling_rate: Duration) -> IntervalStream { + #[cfg(not(target_arch = "wasm32"))] + return tokio_stream::wrappers::IntervalStream::new(tokio::time::interval(polling_rate)); + + #[cfg(target_arch = "wasm32")] + return gloo_timers::future::IntervalStream::new(polling_rate.as_millis() as u32); + } + + pub(crate) async fn run_with_shutdown(&mut self, mut shutdown: task::ShutdownListener) { + debug!("Started ReplyController with graceful shutdown support"); + + let polling_rate = Duration::from_secs(5); + let mut stale_inspection = Self::create_interval_stream(polling_rate); + + // this is in the order of hours/days so we don't have to poll it that often + let polling_rate = Duration::from_secs(self.config.max_reply_surb_age.as_secs() / 10); + let mut invalidation_inspection = Self::create_interval_stream(polling_rate); + + while !shutdown.is_shutdown() { + tokio::select! { + biased; + _ = shutdown.recv() => { + log::trace!("ReplyController: Received shutdown"); + }, + req = self.request_receiver.next() => match req { + Some(req) => self.handle_request(req).await, + None => { + log::trace!("ReplyController: Stopping since channel closed"); + break; + } + }, + _ = stale_inspection.next() => { + self.inspect_stale_entries().await + }, + _ = invalidation_inspection.next() => { + self.invalidate_old_data().await + } + } + } + assert!(shutdown.is_shutdown_poll()); + log::debug!("ReplyController: Exiting"); + } +} diff --git a/clients/client-core/src/client/replies/reply_storage/backend/browser_backend.rs b/clients/client-core/src/client/replies/reply_storage/backend/browser_backend.rs new file mode 100644 index 0000000000..9711ea759f --- /dev/null +++ b/clients/client-core/src/client/replies/reply_storage/backend/browser_backend.rs @@ -0,0 +1,43 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::client::replies::reply_storage::backend::Empty; +use crate::client::replies::reply_storage::{CombinedReplyStorage, ReplyStorageBackend}; +use async_trait::async_trait; + +// well, right now we don't have the browser storage : ( +// so we keep everything in memory +pub struct Backend { + empty: Empty, +} + +impl Backend { + pub fn new(min_surb_threshold: usize, max_surb_threshold: usize) -> Self { + Backend { + empty: Empty { + min_surb_threshold, + max_surb_threshold, + }, + } + } +} + +#[async_trait] +impl ReplyStorageBackend for Backend { + type StorageError = ::StorageError; + + async fn flush_surb_storage( + &mut self, + storage: &CombinedReplyStorage, + ) -> Result<(), Self::StorageError> { + self.empty.flush_surb_storage(storage).await + } + + async fn init_fresh(&mut self, fresh: &CombinedReplyStorage) -> Result<(), Self::StorageError> { + self.empty.init_fresh(fresh).await + } + + async fn load_surb_storage(&self) -> Result { + self.empty.load_surb_storage().await + } +} diff --git a/clients/client-core/src/client/replies/reply_storage/backend/fs_backend/error.rs b/clients/client-core/src/client/replies/reply_storage/backend/fs_backend/error.rs new file mode 100644 index 0000000000..8164762123 --- /dev/null +++ b/clients/client-core/src/client/replies/reply_storage/backend/fs_backend/error.rs @@ -0,0 +1,53 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use std::io; +use std::path::PathBuf; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum StorageError { + #[error("the provided database path doesn't have a filename defined")] + DatabasePathWithoutFilename { provided_path: PathBuf }, + + #[error("failed to rename our databse file - {source}")] + DatabaseRenameError { + #[source] + source: io::Error, + }, + + #[error("failed to rename our old databse file - {source}")] + DatabaseOldFileRemoveError { + #[source] + source: io::Error, + }, + + #[error("failed to perform sqlx migration: {source}")] + MigrationError { + #[source] + #[from] + source: sqlx::migrate::MigrateError, + }, + + #[error("failed to connect to the underlying connection pool: {source}")] + DatabaseConnectionError { + #[source] + source: sqlx::error::Error, + }, + + #[error("failed to run the SQL query: {source}")] + QueryError { + #[source] + #[from] + source: sqlx::error::Error, + }, + + #[error("The loaded data is inconsistent - it seems that on the last shutdown the client hasn't finished the data flush. You may have to remove the entire storage manually")] + IncompleteDataFlush, + + #[error("data retrieved from the underlying storage is corrupted: {details}")] + CorruptedData { + details: String, + // err: Option> + }, +} diff --git a/clients/client-core/src/client/replies/reply_storage/backend/fs_backend/manager.rs b/clients/client-core/src/client/replies/reply_storage/backend/fs_backend/manager.rs new file mode 100644 index 0000000000..578c0021a3 --- /dev/null +++ b/clients/client-core/src/client/replies/reply_storage/backend/fs_backend/manager.rs @@ -0,0 +1,257 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::client::replies::reply_storage::backend::fs_backend::error::StorageError; +use crate::client::replies::reply_storage::backend::fs_backend::models::{ + ReplySurbStorageMetadata, StoredReplyKey, StoredReplySurb, StoredSenderTag, StoredSurbSender, +}; +use log::{error, info}; +use sqlx::ConnectOptions; +use std::path::Path; + +#[derive(Debug, Clone)] +pub(crate) struct StorageManager { + pub(crate) connection_pool: sqlx::SqlitePool, +} + +// all SQL goes here +impl StorageManager { + pub(crate) async fn init>( + database_path: P, + fresh: bool, + ) -> Result { + let mut opts = sqlx::sqlite::SqliteConnectOptions::new() + .filename(database_path) + .create_if_missing(fresh); + + opts.disable_statement_logging(); + + let connection_pool = match sqlx::SqlitePool::connect_with(opts).await { + Ok(pool) => pool, + Err(err) => { + error!("Failed to connect to SQLx database: {err}"); + return Err(StorageError::DatabaseConnectionError { source: err }); + } + }; + + if let Err(err) = sqlx::migrate!("./fs_surbs_migrations") + .run(&connection_pool) + .await + { + error!("Failed to initialize SQLx database: {err}"); + return Err(err.into()); + } + + info!("Database migration finished!"); + Ok(StorageManager { connection_pool }) + } + + #[allow(dead_code)] + pub(crate) async fn status_table_exists(&self) -> Result { + sqlx::query!("SELECT name FROM sqlite_master WHERE type='table' AND name='status'") + .fetch_optional(&self.connection_pool) + .await + .map(|r| r.is_some()) + } + + pub(crate) async fn create_status_table(&self) -> Result<(), sqlx::Error> { + sqlx::query!("INSERT INTO status(flush_in_progress, previous_flush_timestamp, client_in_use) VALUES (0, 0, 1)") + .execute(&self.connection_pool) + .await?; + Ok(()) + } + + pub(crate) async fn get_flush_status(&self) -> Result { + sqlx::query!("SELECT flush_in_progress FROM status;") + .fetch_one(&self.connection_pool) + .await + .map(|r| r.flush_in_progress > 0) + } + + pub(crate) async fn set_previous_flush_timestamp( + &self, + timestamp: i64, + ) -> Result<(), sqlx::Error> { + sqlx::query!("UPDATE status SET previous_flush_timestamp = ?", timestamp) + .execute(&self.connection_pool) + .await?; + Ok(()) + } + + pub(crate) async fn get_previous_flush_timestamp(&self) -> Result { + sqlx::query!("SELECT previous_flush_timestamp FROM status;") + .fetch_one(&self.connection_pool) + .await + .map(|r| r.previous_flush_timestamp) + } + + pub(crate) async fn set_flush_status(&self, in_progress: bool) -> Result<(), sqlx::Error> { + let in_progress_int = i64::from(in_progress); + sqlx::query!("UPDATE status SET flush_in_progress = ?", in_progress_int) + .execute(&self.connection_pool) + .await?; + Ok(()) + } + + pub(crate) async fn get_client_in_use_status(&self) -> Result { + sqlx::query!("SELECT client_in_use FROM status;") + .fetch_one(&self.connection_pool) + .await + .map(|r| r.client_in_use > 0) + } + + pub(crate) async fn set_client_in_use_status(&self, in_use: bool) -> Result<(), sqlx::Error> { + let in_use_int = i64::from(in_use); + sqlx::query!("UPDATE status SET client_in_use = ?", in_use_int) + .execute(&self.connection_pool) + .await?; + Ok(()) + } + + pub(crate) async fn delete_all_tags(&self) -> Result<(), sqlx::Error> { + sqlx::query!("DELETE FROM sender_tag;") + .execute(&self.connection_pool) + .await?; + Ok(()) + } + + pub(crate) async fn get_tags(&self) -> Result, sqlx::Error> { + sqlx::query_as!(StoredSenderTag, "SELECT * FROM sender_tag;",) + .fetch_all(&self.connection_pool) + .await + } + + pub(crate) async fn insert_tag(&self, stored_tag: StoredSenderTag) -> Result<(), sqlx::Error> { + sqlx::query!( + r#" + INSERT INTO sender_tag(recipient, tag) VALUES (?, ?); + "#, + stored_tag.recipient, + stored_tag.tag + ) + .execute(&self.connection_pool) + .await?; + Ok(()) + } + + pub(crate) async fn delete_all_reply_keys(&self) -> Result<(), sqlx::Error> { + sqlx::query!("DELETE FROM reply_key;") + .execute(&self.connection_pool) + .await?; + Ok(()) + } + + pub(crate) async fn get_reply_keys(&self) -> Result, sqlx::Error> { + sqlx::query_as!(StoredReplyKey, "SELECT * FROM reply_key;",) + .fetch_all(&self.connection_pool) + .await + } + + pub(crate) async fn insert_reply_key( + &self, + stored_reply_key: StoredReplyKey, + ) -> Result<(), sqlx::Error> { + sqlx::query!( + r#" + INSERT INTO reply_key(key_digest, reply_key, sent_at_timestamp) VALUES (?, ?, ?); + "#, + stored_reply_key.key_digest, + stored_reply_key.reply_key, + stored_reply_key.sent_at_timestamp + ) + .execute(&self.connection_pool) + .await?; + Ok(()) + } + + pub(crate) async fn get_surb_senders(&self) -> Result, sqlx::Error> { + sqlx::query_as!(StoredSurbSender, "SELECT * FROM reply_surb_sender;",) + .fetch_all(&self.connection_pool) + .await + } + + pub(crate) async fn insert_surb_sender( + &self, + stored_surb_sender: StoredSurbSender, + ) -> Result { + let id = sqlx::query!( + r#" + INSERT INTO reply_surb_sender(tag, last_sent_timestamp) VALUES (?, ?); + "#, + stored_surb_sender.tag, + stored_surb_sender.last_sent_timestamp + ) + .execute(&self.connection_pool) + .await? + .last_insert_rowid(); + Ok(id) + } + + pub(crate) async fn get_reply_surbs( + &self, + sender_id: i64, + ) -> Result, sqlx::Error> { + sqlx::query_as!( + StoredReplySurb, + "SELECT * FROM reply_surb WHERE reply_surb_sender_id = ?", + sender_id + ) + .fetch_all(&self.connection_pool) + .await + } + + pub(crate) async fn delete_all_reply_surb_data(&self) -> Result<(), sqlx::Error> { + sqlx::query!("DELETE FROM reply_surb;") + .execute(&self.connection_pool) + .await?; + + sqlx::query!("DELETE FROM reply_surb_sender;") + .execute(&self.connection_pool) + .await?; + + Ok(()) + } + + pub(crate) async fn insert_reply_surb( + &self, + stored_reply_surb: StoredReplySurb, + ) -> Result<(), sqlx::Error> { + sqlx::query!( + r#" + INSERT INTO reply_surb(reply_surb_sender_id, reply_surb) VALUES (?, ?); + "#, + stored_reply_surb.reply_surb_sender_id, + stored_reply_surb.reply_surb + ) + .execute(&self.connection_pool) + .await?; + Ok(()) + } + + pub(crate) async fn get_reply_surb_storage_metadata( + &self, + ) -> Result { + sqlx::query_as!( + ReplySurbStorageMetadata, + r#" + SELECT min_reply_surb_threshold as "min_reply_surb_threshold: u32", max_reply_surb_threshold as "max_reply_surb_threshold: u32" FROM reply_surb_storage_metadata; + "#, + ) + .fetch_one(&self.connection_pool) + .await + } + + pub(crate) async fn insert_reply_surb_storage_metadata( + &self, + metadata: ReplySurbStorageMetadata, + ) -> Result<(), sqlx::Error> { + sqlx::query!(r#" + INSERT INTO reply_surb_storage_metadata(min_reply_surb_threshold, max_reply_surb_threshold) + VALUES (?, ?); + "#, + metadata.min_reply_surb_threshold, + metadata.max_reply_surb_threshold, + ).execute(&self.connection_pool).await?; + Ok(()) + } +} diff --git a/clients/client-core/src/client/replies/reply_storage/backend/fs_backend/mod.rs b/clients/client-core/src/client/replies/reply_storage/backend/fs_backend/mod.rs new file mode 100644 index 0000000000..50916e00c3 --- /dev/null +++ b/clients/client-core/src/client/replies/reply_storage/backend/fs_backend/mod.rs @@ -0,0 +1,336 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +pub use self::error::StorageError; +use crate::client::replies::reply_storage::backend::fs_backend::manager::StorageManager; +use crate::client::replies::reply_storage::backend::fs_backend::models::{ + ReplySurbStorageMetadata, StoredReplyKey, StoredReplySurb, StoredSenderTag, StoredSurbSender, +}; +use crate::client::replies::reply_storage::surb_storage::ReceivedReplySurbs; +use crate::client::replies::reply_storage::{ + CombinedReplyStorage, ReceivedReplySurbsMap, ReplyStorageBackend, SentReplyKeys, UsedSenderTags, +}; +use async_trait::async_trait; +use log::{error, info, warn}; +use nymsphinx::anonymous_replies::requests::AnonymousSenderTag; +use std::fs; +use std::path::{Path, PathBuf}; +use time::OffsetDateTime; + +mod error; +mod manager; +mod models; + +#[derive(Debug)] +pub struct Backend { + temporary_old_path: Option, + database_path: PathBuf, + manager: StorageManager, +} + +impl Backend { + const OLD_EXTENSION: &'static str = "old"; + + pub async fn init>(database_path: P) -> Result { + let owned_path: PathBuf = database_path.as_ref().into(); + if owned_path.file_name().is_none() { + return Err(StorageError::DatabasePathWithoutFilename { + provided_path: owned_path, + }); + } + + let backend = Backend { + temporary_old_path: None, + database_path: owned_path, + manager: StorageManager::init(database_path, true).await?, + }; + + backend.manager.create_status_table().await?; + + Ok(backend) + } + + pub async fn try_load>(database_path: P) -> Result { + let owned_path: PathBuf = database_path.as_ref().into(); + if owned_path.file_name().is_none() { + return Err(StorageError::DatabasePathWithoutFilename { + provided_path: owned_path, + }); + } + + let manager = StorageManager::init(database_path, false).await?; + + // the database flush wasn't fully finished and thus the data is in inconsistent state + // (we don't really know what's properly saved or what's not) + if manager.get_flush_status().await? { + return Err(StorageError::IncompleteDataFlush); + } + + // the process has gone down without full graceful shutdown, + // meaning the database doesn't contain valid data anymore + // so we have to purge it + if manager.get_client_in_use_status().await? { + error!("the client hasn't undergone through graceful shutdown the last time it's gone down - we can't trust its reply surbs or stored encryption keys. They shall get purged"); + manager.delete_all_reply_surb_data().await?; + manager.delete_all_reply_keys().await?; + } + + let last_flush_timestamp = manager.get_previous_flush_timestamp().await?; + let last_flush = match OffsetDateTime::from_unix_timestamp(last_flush_timestamp) { + Ok(last_flush) => last_flush, + Err(err) => { + return Err(StorageError::CorruptedData { + details: format!("failed to parse stored timestamp - {err}"), + }); + } + }; + + // in theory clients can use our reply surbs whenever they want, even a year in the future + // (assuming no key rotation has happened) + // but the way it's currently coded, everyone will purge old data + let since_last_flush = OffsetDateTime::now_utc() - last_flush; + if since_last_flush.whole_days() > 0 { + info!("it's been over {} days and {} hours since we last used our data store. our reply surbs are already outdated - we're going to purge them now.", since_last_flush.whole_days(), since_last_flush.whole_hours()); + manager.delete_all_reply_surb_data().await?; + } + + if since_last_flush.whole_days() > 1 { + info!("it's been over {} days and {} hours since we last used our data store. our reply keys are already outdated - we're going to purge them now.", since_last_flush.whole_days(), since_last_flush.whole_hours()); + manager.delete_all_reply_keys().await?; + } + + if since_last_flush.whole_days() > 2 { + info!("it's been over {} days and {} hours since we last used our data store. our used sender tags are already outdated - we're going to purge them now.", since_last_flush.whole_days(), since_last_flush.whole_hours()); + manager.delete_all_tags().await?; + } + + Ok(Backend { + temporary_old_path: None, + database_path: owned_path, + manager, + }) + } + + async fn close_pool(&mut self) { + self.manager.connection_pool.close().await; + } + + async fn rotate(&mut self) -> Result<(), StorageError> { + self.close_pool().await; + + let new_extension = if let Some(existing_extension) = + self.database_path.extension().and_then(|ext| ext.to_str()) + { + format!("{existing_extension}.{}", Self::OLD_EXTENSION) + } else { + Self::OLD_EXTENSION.to_string() + }; + + let mut temp_old = self.database_path.clone(); + temp_old.set_extension(new_extension); + + fs::rename(&self.database_path, &temp_old) + .map_err(|err| StorageError::DatabaseRenameError { source: err })?; + self.manager = StorageManager::init(&self.database_path, true).await?; + self.manager.create_status_table().await?; + + self.temporary_old_path = Some(temp_old); + Ok(()) + } + + fn remove_old(&mut self) -> Result<(), StorageError> { + if let Some(old_path) = self.temporary_old_path.take() { + fs::remove_file(old_path) + .map_err(|err| StorageError::DatabaseOldFileRemoveError { source: err }) + } else { + warn!("the old database file doesn't seem to exist!"); + Ok(()) + } + } + + async fn start_storage_flush(&self) -> Result<(), StorageError> { + Ok(self.manager.set_flush_status(true).await?) + } + + async fn end_storage_flush(&self) -> Result<(), StorageError> { + self.manager + .set_previous_flush_timestamp(OffsetDateTime::now_utc().unix_timestamp()) + .await?; + Ok(self.manager.set_flush_status(false).await?) + } + + async fn start_client_use(&self) -> Result<(), StorageError> { + Ok(self.manager.set_client_in_use_status(true).await?) + } + + async fn stop_client_use(&self) -> Result<(), StorageError> { + Ok(self.manager.set_client_in_use_status(false).await?) + } + + async fn get_stored_tags(&self) -> Result { + let stored = self.manager.get_tags().await?; + + // stop at the first instance of corruption. if even a single entry is malformed, + // something weird has happened and we can't trust the rest of the data + let raw = stored + .into_iter() + .map(TryInto::try_into) + .collect::>()?; + + Ok(UsedSenderTags::from_raw(raw)) + } + + async fn dump_sender_tags(&self, tags: &UsedSenderTags) -> Result<(), StorageError> { + for map_ref in tags.as_raw_iter() { + let (recipient, tag) = map_ref.pair(); + self.manager + .insert_tag(StoredSenderTag::new(*recipient, *tag)) + .await?; + } + Ok(()) + } + + async fn get_stored_reply_keys(&self) -> Result { + let stored = self.manager.get_reply_keys().await?; + + // stop at the first instance of corruption. if even a single entry is malformed, + // something weird has happened and we can't trust the rest of the data + let raw = stored + .into_iter() + .map(TryInto::try_into) + .collect::>()?; + + Ok(SentReplyKeys::from_raw(raw)) + } + + async fn dump_sender_reply_keys(&self, reply_keys: &SentReplyKeys) -> Result<(), StorageError> { + for map_ref in reply_keys.as_raw_iter() { + let (digest, key) = map_ref.pair(); + self.manager + .insert_reply_key(StoredReplyKey::new(*digest, *key)) + .await?; + } + Ok(()) + } + + async fn get_stored_reply_surbs(&self) -> Result { + let surb_senders = self.manager.get_surb_senders().await?; + + let metadata = self.get_reply_surb_storage_metadata().await?; + let mut received_surbs = Vec::with_capacity(surb_senders.len()); + for sender in surb_senders { + let sender_id = sender.id; + let (sender_tag, surbs_last_received_at_timestamp): (AnonymousSenderTag, i64) = + sender.try_into()?; + let stored_surbs = self + .manager + .get_reply_surbs(sender_id) + .await? + .into_iter() + .map(|raw| raw.try_into()) + .collect::>()?; + + received_surbs.push(( + sender_tag, + ReceivedReplySurbs::new_retrieved(stored_surbs, surbs_last_received_at_timestamp), + )) + } + + Ok(ReceivedReplySurbsMap::from_raw( + metadata.min_reply_surb_threshold as usize, + metadata.max_reply_surb_threshold as usize, + received_surbs, + )) + } + + async fn dump_reply_surbs( + &self, + reply_surbs: &ReceivedReplySurbsMap, + ) -> Result<(), StorageError> { + for map_ref in reply_surbs.as_raw_iter() { + let (tag, received_surbs) = map_ref.pair(); + let sender_id = self + .manager + .insert_surb_sender(StoredSurbSender::new( + *tag, + received_surbs.surbs_last_received_at(), + )) + .await?; + + for reply_surb in received_surbs.surbs_ref() { + self.manager + .insert_reply_surb(StoredReplySurb::new(sender_id, reply_surb)) + .await? + } + } + Ok(()) + } + + async fn get_reply_surb_storage_metadata( + &self, + ) -> Result { + self.manager + .get_reply_surb_storage_metadata() + .await + .map_err(Into::into) + } + + async fn dump_reply_surb_storage_metadata( + &self, + reply_surbs: &ReceivedReplySurbsMap, + ) -> Result<(), StorageError> { + self.manager + .insert_reply_surb_storage_metadata(ReplySurbStorageMetadata::new( + reply_surbs.min_surb_threshold(), + reply_surbs.max_surb_threshold(), + )) + .await + .map_err(Into::into) + } +} + +#[async_trait] +impl ReplyStorageBackend for Backend { + type StorageError = error::StorageError; + + async fn start_storage_session(&self) -> Result<(), Self::StorageError> { + self.start_client_use().await + } + + async fn flush_surb_storage( + &mut self, + storage: &CombinedReplyStorage, + ) -> Result<(), Self::StorageError> { + // close all connections (there should be none! and rename the file to contain .old extension) + self.rotate().await?; + self.start_storage_flush().await?; + + self.dump_sender_tags(storage.tags_storage_ref()).await?; + self.dump_sender_reply_keys(storage.key_storage_ref()) + .await?; + let surbs_ref = storage.surbs_storage_ref(); + self.dump_reply_surb_storage_metadata(surbs_ref).await?; + self.dump_reply_surbs(surbs_ref).await?; + + self.remove_old()?; + self.end_storage_flush().await + } + + async fn init_fresh(&mut self, fresh: &CombinedReplyStorage) -> Result<(), Self::StorageError> { + // for now nothing more to do apart from dumping the metadata + self.dump_reply_surb_storage_metadata(fresh.surbs_storage_ref()) + .await + } + + async fn load_surb_storage(&self) -> Result { + let reply_keys = self.get_stored_reply_keys().await?; + let tags = self.get_stored_tags().await?; + let reply_surbs = self.get_stored_reply_surbs().await?; + + Ok(CombinedReplyStorage::load(reply_keys, reply_surbs, tags)) + } + + async fn stop_storage_session(self) -> Result<(), Self::StorageError> { + self.stop_client_use().await + } +} diff --git a/clients/client-core/src/client/replies/reply_storage/backend/fs_backend/models.rs b/clients/client-core/src/client/replies/reply_storage/backend/fs_backend/models.rs new file mode 100644 index 0000000000..65088ad05e --- /dev/null +++ b/clients/client-core/src/client/replies/reply_storage/backend/fs_backend/models.rs @@ -0,0 +1,185 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::client::replies::reply_storage::backend::fs_backend::error::StorageError; +use crate::client::replies::reply_storage::key_storage::UsedReplyKey; +use crypto::generic_array::typenum::Unsigned; +use crypto::Digest; +use nymsphinx::addressing::clients::{Recipient, RecipientBytes}; +use nymsphinx::anonymous_replies::encryption_key::EncryptionKeyDigest; +use nymsphinx::anonymous_replies::requests::{AnonymousSenderTag, SENDER_TAG_SIZE}; +use nymsphinx::anonymous_replies::{ReplySurb, SurbEncryptionKey, SurbEncryptionKeySize}; +use nymsphinx::params::ReplySurbKeyDigestAlgorithm; + +#[derive(Debug, Clone)] +pub(crate) struct StoredSenderTag { + pub(crate) recipient: Vec, + pub(crate) tag: Vec, +} + +impl StoredSenderTag { + pub(crate) fn new(recipient: RecipientBytes, tag: AnonymousSenderTag) -> StoredSenderTag { + StoredSenderTag { + recipient: recipient.to_vec(), + tag: tag.to_bytes().to_vec(), + } + } +} + +impl TryFrom for (RecipientBytes, AnonymousSenderTag) { + type Error = StorageError; + + fn try_from(value: StoredSenderTag) -> Result { + let recipient_len = value.recipient.len(); + let Ok(recipient_bytes) = value.recipient.try_into() else { + return Err(StorageError::CorruptedData { + details: format!( + "the retrieved recipient has length of {recipient_len} while {} was expected", + Recipient::LEN + ), + }); + }; + + let tag_len = value.tag.len(); + let Ok(sender_tag_bytes) = value.tag.try_into() else { + return Err(StorageError::CorruptedData { + details: format!( + "the retrieved sender tag has length of {tag_len} while {} was expected", + SENDER_TAG_SIZE + ), + }); + }; + + Ok(( + recipient_bytes, + AnonymousSenderTag::from_bytes(sender_tag_bytes), + )) + } +} + +#[derive(Debug, Clone)] +pub(crate) struct StoredReplyKey { + pub(crate) key_digest: Vec, + pub(crate) reply_key: Vec, + pub(crate) sent_at_timestamp: i64, +} + +impl StoredReplyKey { + pub(crate) fn new(key_digest: EncryptionKeyDigest, reply_key: UsedReplyKey) -> StoredReplyKey { + StoredReplyKey { + key_digest: key_digest.to_vec(), + reply_key: (*reply_key).to_bytes(), + sent_at_timestamp: reply_key.sent_at_timestamp, + } + } +} + +impl TryFrom for (EncryptionKeyDigest, UsedReplyKey) { + type Error = StorageError; + + fn try_from(value: StoredReplyKey) -> Result { + let expected_reply_key_digest_size = ReplySurbKeyDigestAlgorithm::output_size(); + let reply_key_digest_size = value.key_digest.len(); + + let Some(digest) = EncryptionKeyDigest::from_exact_iter(value.key_digest) else { + return Err(StorageError::CorruptedData { + details: format!( + "the reply surb digest has length of {reply_key_digest_size} while {expected_reply_key_digest_size} was expected", + ), + }); + }; + + let reply_key_len = value.reply_key.len(); + let Ok(reply_key) = SurbEncryptionKey::try_from_bytes(&value.reply_key) else { + return Err(StorageError::CorruptedData { + details: format!( + "the reply key has length of {reply_key_len} while {} was expected", + SurbEncryptionKeySize::USIZE + ), + }); + }; + + Ok(( + digest, + UsedReplyKey::new(reply_key, value.sent_at_timestamp), + )) + } +} + +pub(crate) struct StoredSurbSender { + pub(crate) id: i64, + pub(crate) tag: Vec, + pub(crate) last_sent_timestamp: i64, +} + +impl StoredSurbSender { + pub(crate) fn new(tag: AnonymousSenderTag, last_sent_timestamp: i64) -> Self { + StoredSurbSender { + // for the purposes of STORING data, + // we ignore that field anyway + id: 0, + tag: tag.to_bytes().to_vec(), + last_sent_timestamp, + } + } +} + +impl TryFrom for (AnonymousSenderTag, i64) { + type Error = StorageError; + + fn try_from(value: StoredSurbSender) -> Result { + let tag_len = value.tag.len(); + let Ok(sender_tag_bytes) = value.tag.try_into() else { + return Err(StorageError::CorruptedData { + details: format!( + "the retrieved sender tag has length of {tag_len} while {} was expected", + SENDER_TAG_SIZE + ), + }); + }; + + Ok(( + AnonymousSenderTag::from_bytes(sender_tag_bytes), + value.last_sent_timestamp, + )) + } +} + +pub(crate) struct StoredReplySurb { + pub(crate) reply_surb_sender_id: i64, + pub(crate) reply_surb: Vec, +} + +impl StoredReplySurb { + pub(crate) fn new(reply_surb_sender_id: i64, reply_surb: &ReplySurb) -> Self { + StoredReplySurb { + reply_surb_sender_id, + reply_surb: reply_surb.to_bytes(), + } + } +} + +impl TryFrom for ReplySurb { + type Error = StorageError; + + fn try_from(value: StoredReplySurb) -> Result { + ReplySurb::from_bytes(&value.reply_surb).map_err(|err| StorageError::CorruptedData { + details: format!("failed to recover the reply surb: {err}"), + }) + } +} + +#[derive(Copy, Clone)] +pub(crate) struct ReplySurbStorageMetadata { + pub(crate) min_reply_surb_threshold: u32, + pub(crate) max_reply_surb_threshold: u32, +} + +impl ReplySurbStorageMetadata { + pub(crate) fn new(min_reply_surb_threshold: usize, max_reply_surb_threshold: usize) -> Self { + Self { + min_reply_surb_threshold: min_reply_surb_threshold as u32, + max_reply_surb_threshold: max_reply_surb_threshold as u32, + } + } +} diff --git a/clients/client-core/src/client/replies/reply_storage/backend/mod.rs b/clients/client-core/src/client/replies/reply_storage/backend/mod.rs new file mode 100644 index 0000000000..d80231ae1e --- /dev/null +++ b/clients/client-core/src/client/replies/reply_storage/backend/mod.rs @@ -0,0 +1,78 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::client::replies::reply_storage::CombinedReplyStorage; +use async_trait::async_trait; +use std::error::Error; +use thiserror::Error; + +#[cfg(target_arch = "wasm32")] +pub mod browser_backend; + +#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] +pub mod fs_backend; + +// #[cfg(all(test, feature = "std"))] +// third case: node with actual filesystem + +#[derive(Debug, Error)] +#[error("no information provided")] +pub struct UndefinedError; + +pub struct Empty { + // we need to keep 'basic' metadata here to "load" the CombinedReplyStorage + min_surb_threshold: usize, + max_surb_threshold: usize, +} + +#[async_trait] +impl ReplyStorageBackend for Empty { + type StorageError = UndefinedError; + + async fn flush_surb_storage( + &mut self, + _storage: &CombinedReplyStorage, + ) -> Result<(), Self::StorageError> { + Ok(()) + } + + async fn init_fresh( + &mut self, + _fresh: &CombinedReplyStorage, + ) -> Result<(), Self::StorageError> { + Ok(()) + } + + async fn load_surb_storage(&self) -> Result { + Ok(CombinedReplyStorage::new( + self.min_surb_threshold, + self.max_surb_threshold, + )) + } +} + +#[async_trait] +pub trait ReplyStorageBackend: Sized { + type StorageError: Error + 'static; + + async fn start_storage_session(&self) -> Result<(), Self::StorageError> { + Ok(()) + } + + // reply keys and surbs would need additional field set when data is loaded + // so if there's some failure, we'd trash it all + async fn flush_surb_storage( + &mut self, + storage: &CombinedReplyStorage, + ) -> Result<(), Self::StorageError>; + + /// The purpose of this call is to save any metadata that might be present. + /// (such as surb thresholds) + async fn init_fresh(&mut self, fresh: &CombinedReplyStorage) -> Result<(), Self::StorageError>; + + async fn load_surb_storage(&self) -> Result; + + async fn stop_storage_session(self) -> Result<(), Self::StorageError> { + Ok(()) + } +} diff --git a/clients/client-core/src/client/replies/reply_storage/combined.rs b/clients/client-core/src/client/replies/reply_storage/combined.rs new file mode 100644 index 0000000000..c9fb9e4a5c --- /dev/null +++ b/clients/client-core/src/client/replies/reply_storage/combined.rs @@ -0,0 +1,60 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::client::replies::reply_storage::{ReceivedReplySurbsMap, SentReplyKeys, UsedSenderTags}; + +#[derive(Debug, Clone)] +pub struct CombinedReplyStorage { + sent_reply_keys: SentReplyKeys, + received_reply_surbs: ReceivedReplySurbsMap, + used_tags: UsedSenderTags, +} + +impl CombinedReplyStorage { + pub fn new(min_surb_threshold: usize, max_surb_threshold: usize) -> CombinedReplyStorage { + CombinedReplyStorage { + sent_reply_keys: SentReplyKeys::new(), + received_reply_surbs: ReceivedReplySurbsMap::new( + min_surb_threshold, + max_surb_threshold, + ), + used_tags: UsedSenderTags::new(), + } + } + + pub fn load( + sent_reply_keys: SentReplyKeys, + received_reply_surbs: ReceivedReplySurbsMap, + used_tags: UsedSenderTags, + ) -> Self { + CombinedReplyStorage { + sent_reply_keys, + received_reply_surbs, + used_tags, + } + } + + pub fn key_storage(&self) -> SentReplyKeys { + self.sent_reply_keys.clone() + } + + pub fn surbs_storage(&self) -> ReceivedReplySurbsMap { + self.received_reply_surbs.clone() + } + + pub fn tags_storage(&self) -> UsedSenderTags { + self.used_tags.clone() + } + + pub fn key_storage_ref(&self) -> &SentReplyKeys { + &self.sent_reply_keys + } + + pub fn surbs_storage_ref(&self) -> &ReceivedReplySurbsMap { + &self.received_reply_surbs + } + + pub fn tags_storage_ref(&self) -> &UsedSenderTags { + &self.used_tags + } +} diff --git a/clients/client-core/src/client/replies/reply_storage/key_storage.rs b/clients/client-core/src/client/replies/reply_storage/key_storage.rs new file mode 100644 index 0000000000..9c68f40e06 --- /dev/null +++ b/clients/client-core/src/client/replies/reply_storage/key_storage.rs @@ -0,0 +1,86 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use dashmap::iter::Iter; +use dashmap::DashMap; +use nymsphinx::anonymous_replies::encryption_key::EncryptionKeyDigest; +use nymsphinx::anonymous_replies::SurbEncryptionKey; +use std::ops::Deref; +use std::sync::Arc; +use time::OffsetDateTime; + +#[derive(Debug, Clone)] +pub struct SentReplyKeys { + inner: Arc, +} + +#[derive(Debug)] +struct SentReplyKeysInner { + data: DashMap, +} + +impl SentReplyKeys { + pub(crate) fn new() -> SentReplyKeys { + SentReplyKeys { + inner: Arc::new(SentReplyKeysInner { + data: DashMap::new(), + }), + } + } + + #[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] + pub(crate) fn from_raw(raw: Vec<(EncryptionKeyDigest, UsedReplyKey)>) -> SentReplyKeys { + SentReplyKeys { + inner: Arc::new(SentReplyKeysInner { + data: raw.into_iter().collect(), + }), + } + } + + pub(crate) fn as_raw_iter(&self) -> Iter<'_, EncryptionKeyDigest, UsedReplyKey> { + self.inner.data.iter() + } + + pub(crate) fn insert_multiple(&self, keys: Vec) { + let now = OffsetDateTime::now_utc().unix_timestamp(); + for key in keys { + self.insert(UsedReplyKey::new(key, now)) + } + } + + pub(crate) fn insert(&self, key: UsedReplyKey) { + self.inner.data.insert(key.compute_digest(), key); + } + + pub(crate) fn try_pop(&self, digest: EncryptionKeyDigest) -> Option { + self.inner.data.remove(&digest).map(|(_k, v)| v) + } + + pub(crate) fn remove(&self, digest: EncryptionKeyDigest) { + self.inner.data.remove(&digest); + } +} + +#[derive(Debug, Copy, Clone)] +pub(crate) struct UsedReplyKey { + key: SurbEncryptionKey, + // the purpose of this field is to perform invalidation at relatively very long intervals + pub(crate) sent_at_timestamp: i64, +} + +impl UsedReplyKey { + pub(crate) fn new(key: SurbEncryptionKey, sent_at_timestamp: i64) -> Self { + UsedReplyKey { + key, + sent_at_timestamp, + } + } +} + +impl Deref for UsedReplyKey { + type Target = SurbEncryptionKey; + + fn deref(&self) -> &Self::Target { + &self.key + } +} diff --git a/clients/client-core/src/client/replies/reply_storage/mod.rs b/clients/client-core/src/client/replies/reply_storage/mod.rs new file mode 100644 index 0000000000..83c0e0e34f --- /dev/null +++ b/clients/client-core/src/client/replies/reply_storage/mod.rs @@ -0,0 +1,64 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +pub use crate::client::replies::reply_storage::combined::CombinedReplyStorage; +pub use crate::client::replies::reply_storage::key_storage::SentReplyKeys; +pub use crate::client::replies::reply_storage::surb_storage::ReceivedReplySurbsMap; +pub use crate::client::replies::reply_storage::tag_storage::UsedSenderTags; +pub use backend::*; + +mod backend; +mod combined; +mod key_storage; +mod surb_storage; +mod tag_storage; + +// only really exists to get information about shutdown and save data to the backing storage +pub struct PersistentReplyStorage +where + T: ReplyStorageBackend, +{ + backend: T, +} + +impl PersistentReplyStorage +where + T: ReplyStorageBackend + Send + Sync, +{ + pub fn new(backend: T) -> Self { + PersistentReplyStorage { backend } + } + + pub async fn load_state_from_backend(&self) -> Result { + self.backend.load_surb_storage().await + } + + // this will have to get enabled after merging develop + pub async fn flush_on_shutdown( + mut self, + mem_state: CombinedReplyStorage, + mut shutdown: task::ShutdownListener, + ) { + use log::{debug, error, info, warn}; + + debug!("Started PersistentReplyStorage"); + if let Err(err) = self.backend.start_storage_session().await { + error!("failed to start the storage session - {err}"); + return; + } + + shutdown.recv().await; + + info!("PersistentReplyStorage is flushing all reply-related data to underlying storage"); + warn!("you MUST NOT forcefully shutdown now or you risk data corruption!"); + if let Err(err) = self.backend.flush_surb_storage(&mem_state).await { + error!("failed to flush our reply-related data to the persistent storage: {err}") + } else { + info!("Data flush is complete") + } + + if let Err(err) = self.backend.stop_storage_session().await { + error!("failed to properly stop the storage session - {err}. We might not be able to smoothly restore it") + } + } +} diff --git a/clients/client-core/src/client/replies/reply_storage/surb_storage.rs b/clients/client-core/src/client/replies/reply_storage/surb_storage.rs new file mode 100644 index 0000000000..ed2fd8d846 --- /dev/null +++ b/clients/client-core/src/client/replies/reply_storage/surb_storage.rs @@ -0,0 +1,278 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use dashmap::iter::Iter; +use dashmap::DashMap; +use log::trace; +use nymsphinx::anonymous_replies::requests::AnonymousSenderTag; +use nymsphinx::anonymous_replies::ReplySurb; +use std::collections::VecDeque; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Arc; +use time::OffsetDateTime; + +#[derive(Debug, Clone)] +pub struct ReceivedReplySurbsMap { + inner: Arc, +} + +#[derive(Debug)] +struct ReceivedReplySurbsMapInner { + data: DashMap, + + // the minimum amount of surbs that have to be kept in storage for requests for more surbs + min_surb_threshold: AtomicUsize, + + // the maximum amount of surbs that we want to keep in storage so that we don't over-request them + max_surb_threshold: AtomicUsize, +} + +impl ReceivedReplySurbsMap { + pub(crate) fn new( + min_surb_threshold: usize, + max_surb_threshold: usize, + ) -> ReceivedReplySurbsMap { + ReceivedReplySurbsMap { + inner: Arc::new(ReceivedReplySurbsMapInner { + data: DashMap::new(), + min_surb_threshold: AtomicUsize::new(min_surb_threshold), + max_surb_threshold: AtomicUsize::new(max_surb_threshold), + }), + } + } + + #[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] + pub(crate) fn from_raw( + min_surb_threshold: usize, + max_surb_threshold: usize, + raw: Vec<(AnonymousSenderTag, ReceivedReplySurbs)>, + ) -> ReceivedReplySurbsMap { + ReceivedReplySurbsMap { + inner: Arc::new(ReceivedReplySurbsMapInner { + data: raw.into_iter().collect(), + min_surb_threshold: AtomicUsize::new(min_surb_threshold), + max_surb_threshold: AtomicUsize::new(max_surb_threshold), + }), + } + } + + pub(crate) fn as_raw_iter(&self) -> Iter<'_, AnonymousSenderTag, ReceivedReplySurbs> { + self.inner.data.iter() + } + + pub(crate) fn remove(&self, target: &AnonymousSenderTag) { + self.inner.data.remove(target); + } + + pub(crate) fn reset_surbs_last_received_at(&self, target: &AnonymousSenderTag) { + if let Some(mut entry) = self.inner.data.get_mut(target) { + entry.surbs_last_received_at_timestamp = OffsetDateTime::now_utc().unix_timestamp(); + } + } + + pub(crate) fn surbs_last_received_at(&self, target: &AnonymousSenderTag) -> Option { + self.inner + .data + .get(target) + .map(|e| e.surbs_last_received_at()) + } + + pub(crate) fn pending_reception(&self, target: &AnonymousSenderTag) -> u32 { + self.inner + .data + .get(target) + .map(|e| e.pending_reception()) + .unwrap_or_default() + } + + pub(crate) fn increment_pending_reception( + &self, + target: &AnonymousSenderTag, + amount: u32, + ) -> Option { + self.inner + .data + .get_mut(target) + .map(|mut e| e.increment_pending_reception(amount)) + } + + pub(crate) fn decrement_pending_reception( + &self, + target: &AnonymousSenderTag, + amount: u32, + ) -> Option { + self.inner + .data + .get_mut(target) + .map(|mut e| e.decrement_pending_reception(amount)) + } + + pub(crate) fn reset_pending_reception(&self, target: &AnonymousSenderTag) { + if let Some(mut e) = self.inner.data.get_mut(target) { + e.reset_pending_reception() + } + } + + pub(crate) fn min_surb_threshold(&self) -> usize { + self.inner.min_surb_threshold.load(Ordering::Relaxed) + } + + pub(crate) fn max_surb_threshold(&self) -> usize { + self.inner.max_surb_threshold.load(Ordering::Relaxed) + } + + pub(crate) fn available_surbs(&self, target: &AnonymousSenderTag) -> usize { + self.inner + .data + .get(target) + .map(|entry| entry.items_left()) + .unwrap_or_default() + } + + pub(crate) fn contains_surbs_for(&self, target: &AnonymousSenderTag) -> bool { + self.inner.data.contains_key(target) + } + + pub(crate) fn get_reply_surbs( + &self, + target: &AnonymousSenderTag, + amount: usize, + ) -> (Option>, usize) { + if let Some(mut entry) = self.inner.data.get_mut(target) { + let surbs_left = entry.items_left(); + if surbs_left < self.min_surb_threshold() + amount { + (None, surbs_left) + } else { + entry.get_reply_surbs(amount) + } + } else { + (None, 0) + } + } + + pub(crate) fn get_reply_surb_ignoring_threshold( + &self, + target: &AnonymousSenderTag, + ) -> Option<(Option, usize)> { + self.inner + .data + .get_mut(target) + .map(|mut s| s.get_reply_surb()) + } + + pub(crate) fn get_reply_surb( + &self, + target: &AnonymousSenderTag, + ) -> Option<(Option, usize)> { + self.inner.data.get_mut(target).map(|mut entry| { + let surbs_left = entry.items_left(); + if surbs_left < self.min_surb_threshold() { + (None, surbs_left) + } else { + entry.get_reply_surb() + } + }) + } + + pub(crate) fn insert_surbs>( + &self, + target: &AnonymousSenderTag, + surbs: I, + ) { + if let Some(mut existing_data) = self.inner.data.get_mut(target) { + existing_data.insert_reply_surbs(surbs) + } else { + let new_entry = ReceivedReplySurbs::new(surbs.into_iter().collect()); + self.inner.data.insert(*target, new_entry); + } + } +} + +#[derive(Debug)] +pub(crate) struct ReceivedReplySurbs { + // in the future we'd probably want to put extra data here to indicate when the SURBs got received + // so we could invalidate entries from the previous key rotations + data: VecDeque, + + pending_reception: u32, + surbs_last_received_at_timestamp: i64, +} + +impl ReceivedReplySurbs { + fn new(initial_surbs: VecDeque) -> Self { + ReceivedReplySurbs { + data: initial_surbs, + pending_reception: 0, + surbs_last_received_at_timestamp: OffsetDateTime::now_utc().unix_timestamp(), + } + } + + #[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] + pub(crate) fn new_retrieved( + surbs: Vec, + surbs_last_received_at_timestamp: i64, + ) -> ReceivedReplySurbs { + ReceivedReplySurbs { + data: surbs.into(), + pending_reception: 0, + surbs_last_received_at_timestamp, + } + } + + #[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] + pub(crate) fn surbs_ref(&self) -> &VecDeque { + &self.data + } + + pub(crate) fn surbs_last_received_at(&self) -> i64 { + self.surbs_last_received_at_timestamp + } + + pub(crate) fn pending_reception(&self) -> u32 { + self.pending_reception + } + + pub(crate) fn increment_pending_reception(&mut self, amount: u32) -> u32 { + self.pending_reception += amount; + self.pending_reception + } + + pub(crate) fn decrement_pending_reception(&mut self, amount: u32) -> u32 { + self.pending_reception = self.pending_reception.saturating_sub(amount); + self.pending_reception + } + + pub(crate) fn reset_pending_reception(&mut self) { + self.pending_reception = 0; + } + + pub(crate) fn get_reply_surbs(&mut self, amount: usize) -> (Option>, usize) { + if self.items_left() < amount { + (None, self.items_left()) + } else { + let surbs = self.data.drain(..amount).collect(); + (Some(surbs), self.items_left()) + } + } + + pub(crate) fn get_reply_surb(&mut self) -> (Option, usize) { + (self.pop_surb(), self.items_left()) + } + + fn pop_surb(&mut self) -> Option { + self.data.pop_front() + } + + fn items_left(&self) -> usize { + self.data.len() + } + + // realistically we're always going to be getting multiple surbs at once + pub(crate) fn insert_reply_surbs>(&mut self, surbs: I) { + let mut v = surbs.into_iter().collect::>(); + trace!("storing {} surbs in the storage", v.len()); + self.data.append(&mut v); + self.surbs_last_received_at_timestamp = OffsetDateTime::now_utc().unix_timestamp(); + trace!("we now have {} surbs!", self.data.len()); + } +} diff --git a/clients/client-core/src/client/replies/reply_storage/tag_storage.rs b/clients/client-core/src/client/replies/reply_storage/tag_storage.rs new file mode 100644 index 0000000000..c91d2b003e --- /dev/null +++ b/clients/client-core/src/client/replies/reply_storage/tag_storage.rs @@ -0,0 +1,59 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use dashmap::DashMap; +use nymsphinx::addressing::clients::{Recipient, RecipientBytes}; +use nymsphinx::anonymous_replies::requests::AnonymousSenderTag; +use std::sync::Arc; + +#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] +use dashmap::iter::Iter; + +#[derive(Debug, Clone)] +pub struct UsedSenderTags { + inner: Arc, +} + +#[derive(Debug)] +struct UsedSenderTagsInner { + data: DashMap, +} + +impl UsedSenderTags { + pub(crate) fn new() -> UsedSenderTags { + UsedSenderTags { + inner: Arc::new(UsedSenderTagsInner { + data: DashMap::new(), + }), + } + } + + #[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] + pub(crate) fn from_raw(raw: Vec<(RecipientBytes, AnonymousSenderTag)>) -> UsedSenderTags { + UsedSenderTags { + inner: Arc::new(UsedSenderTagsInner { + data: raw.into_iter().collect(), + }), + } + } + + #[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] + pub(crate) fn as_raw_iter(&self) -> Iter<'_, RecipientBytes, AnonymousSenderTag> { + self.inner.data.iter() + } + + pub(crate) fn insert_new(&self, recipient: &Recipient, tag: AnonymousSenderTag) { + self.inner.data.insert(recipient.to_bytes(), tag); + } + + pub(crate) fn try_get_existing(&self, recipient: &Recipient) -> Option { + self.inner + .data + .get(&recipient.to_bytes()) + .map(|r| *r.value()) + } + + pub(crate) fn exists(&self, recipient: &Recipient) -> bool { + self.inner.data.contains_key(&recipient.to_bytes()) + } +} diff --git a/clients/client-core/src/client/reply_key_storage.rs b/clients/client-core/src/client/reply_key_storage.rs deleted file mode 100644 index bfe1c43b9b..0000000000 --- a/clients/client-core/src/client/reply_key_storage.rs +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2021 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use crypto::generic_array::typenum::Unsigned; -use log::*; -use nymsphinx::anonymous_replies::{ - encryption_key::EncryptionKeyDigest, SurbEncryptionKey, SurbEncryptionKeySize, -}; -use std::path::Path; - -#[derive(Debug, thiserror::Error)] -pub enum ReplyKeyStorageError { - #[error("DB Read Error: {0}")] - DbReadError(sled::Error), - #[error("DB Write Error: {0}")] - DbWriteError(sled::Error), - #[error("DB Open Error: {0}")] - DbOpenError(sled::Error), -} - -/// Permanent storage for keys in all sent [`ReplySURB`] -/// -/// Each sent out [`ReplySURB`] has a new key associated with it that is going to be used for -/// payload encryption. In order to -decrypt whatever reply we receive, we need to know which -/// key to use for that purpose. We do it based on received `H(t)` which has to be included -/// with each reply. -/// Moreover, there is no restriction when the [`ReplySURB`] might get used so we need to -/// have a permanent storage for all the keys that we might ever see in the future. -#[derive(Debug, Clone)] -pub struct ReplyKeyStorage { - db: sled::Db, -} - -impl ReplyKeyStorage { - pub fn load>(path: P) -> Result { - let db = match sled::open(path) { - Err(e) => return Err(ReplyKeyStorageError::DbOpenError(e)), - Ok(db) => db, - }; - - Ok(ReplyKeyStorage { db }) - } - - fn read_encryption_key(&self, raw_key: sled::IVec) -> SurbEncryptionKey { - let key_bytes_ref = raw_key.as_ref(); - // if this fails it means we have some database corruption and we - // absolutely can't continue - - if key_bytes_ref.len() != SurbEncryptionKeySize::USIZE { - error!("REPLY KEY STORAGE DATA CORRUPTION - ENCRYPTION KEY HAS INVALID LENGTH"); - panic!("REPLY KEY STORAGE DATA CORRUPTION - ENCRYPTION KEY HAS INVALID LENGTH"); - } - - // this can only fail if the bytes have invalid length but we already asserted it - SurbEncryptionKey::try_from_bytes(key_bytes_ref).unwrap() - } - - // TOOD: perhaps we could also store some part of original message here too? - pub fn insert_encryption_key( - &mut self, - encryption_key: SurbEncryptionKey, - ) -> Result<(), ReplyKeyStorageError> { - let digest = encryption_key.compute_digest(); - - let insertion_result = match self.db.insert(digest, encryption_key.to_bytes()) { - Err(e) => Err(ReplyKeyStorageError::DbWriteError(e)), - Ok(existing_key) => { - if existing_key.is_some() { - panic!("HASH COLLISION DETECTED") - }; - Ok(()) - } - }; - - // TODO: perhaps we could implement some batching mechanism to avoid frequent flushes? - self.db.flush().unwrap(); - insertion_result - } - - // Once we use key once, we do not expect to use it again - pub fn get_and_remove_encryption_key( - &self, - key_digest: EncryptionKeyDigest, - ) -> Result, ReplyKeyStorageError> { - let removal_result = match self.db.remove(key_digest) { - Err(e) => Err(ReplyKeyStorageError::DbReadError(e)), - Ok(existing_key) => { - Ok(existing_key.map(|existing_key| self.read_encryption_key(existing_key))) - } - }; - - // TODO: not sure how to feel about flushing it every single time here... - // same with insertion - self.db.flush().unwrap(); - removal_result - } -} diff --git a/clients/client-core/src/client/topology_control.rs b/clients/client-core/src/client/topology_control.rs index 82f6249f40..ad9e4a4ce6 100644 --- a/clients/client-core/src/client/topology_control.rs +++ b/clients/client-core/src/client/topology_control.rs @@ -1,4 +1,4 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use crate::spawn_future; @@ -10,10 +10,9 @@ use rand::seq::SliceRandom; use rand::thread_rng; use std::ops::Deref; use std::sync::Arc; -use std::time; use std::time::Duration; use tokio::sync::{RwLock, RwLockReadGuard}; -use topology::{nym_topology_from_detailed, NymTopology}; +use topology::{nym_topology_from_detailed, NymTopology, NymTopologyError}; use url::Url; // I'm extremely curious why compiler NEVER complained about lack of Debug here before @@ -55,18 +54,36 @@ impl<'a> TopologyReadPermit<'a> { &'a self, ack_recipient: &Recipient, packet_recipient: Option<&Recipient>, - ) -> Option<&'a NymTopology> { - // Note: implicit deref with Deref for TopologyReadPermit is happening here - let topology_ref_option = self.permit.as_ref(); - topology_ref_option.as_ref().filter(|topology_ref| { - !(!topology_ref.can_construct_path_through(DEFAULT_NUM_MIX_HOPS) - || !topology_ref.gateway_exists(ack_recipient.gateway()) - || if let Some(packet_recipient) = packet_recipient { - !topology_ref.gateway_exists(packet_recipient.gateway()) - } else { - false - }) - }) + ) -> Result<&'a NymTopology, NymTopologyError> { + // 1. Have we managed to get anything from the refresher, i.e. have the nym-api queries gone through? + let topology = self + .permit + .as_ref() + .as_ref() + .ok_or(NymTopologyError::EmptyNetworkTopology)?; + + // 2. does it have any mixnode at all? + // 3. does it have any gateways at all? + // 4. does it have a mixnode on each layer? + topology.ensure_can_construct_path_through(DEFAULT_NUM_MIX_HOPS)?; + + // 5. does it contain OUR gateway (so that we could create an ack packet)? + if !topology.gateway_exists(ack_recipient.gateway()) { + return Err(NymTopologyError::NonExistentGatewayError { + identity_key: ack_recipient.gateway().to_base58_string(), + }); + } + + // 6. for our target recipient, does it contain THEIR gateway (so that we could create + if let Some(recipient) = packet_recipient { + if !topology.gateway_exists(recipient.gateway()) { + return Err(NymTopologyError::NonExistentGatewayError { + identity_key: recipient.gateway().to_base58_string(), + }); + } + } + + Ok(topology) } } @@ -104,10 +121,10 @@ impl TopologyAccessor { // only used by the client at startup to get a slightly more reasonable error message // (currently displays as unused because health checker is disabled due to required changes) - pub async fn is_routable(&self) -> bool { + pub async fn ensure_is_routable(&self) -> Result<(), NymTopologyError> { match &self.inner.read().await.0 { - None => false, - Some(ref topology) => topology.can_construct_path_through(DEFAULT_NUM_MIX_HOPS), + None => Err(NymTopologyError::EmptyNetworkTopology), + Some(ref topology) => topology.ensure_can_construct_path_through(DEFAULT_NUM_MIX_HOPS), } } } @@ -120,14 +137,14 @@ impl Default for TopologyAccessor { pub struct TopologyRefresherConfig { validator_api_urls: Vec, - refresh_rate: time::Duration, + refresh_rate: Duration, client_version: String, } impl TopologyRefresherConfig { pub fn new( validator_api_urls: Vec, - refresh_rate: time::Duration, + refresh_rate: Duration, client_version: String, ) -> Self { TopologyRefresherConfig { @@ -241,7 +258,7 @@ impl TopologyRefresher { let mixnodes = match self.validator_client.get_cached_active_mixnodes().await { Err(err) => { - error!("failed to get network mixnodes - {}", err); + error!("failed to get network mixnodes - {err}"); return None; } Ok(mixes) => mixes, @@ -249,7 +266,7 @@ impl TopologyRefresher { let gateways = match self.validator_client.get_cached_gateways().await { Err(err) => { - error!("failed to get network gateways - {}", err); + error!("failed to get network gateways - {err}"); return None; } Ok(gateways) => gateways, @@ -289,8 +306,8 @@ impl TopologyRefresher { .await; } - pub async fn is_topology_routable(&self) -> bool { - self.topology_accessor.is_routable().await + pub async fn ensure_topology_is_routable(&self) -> Result<(), NymTopologyError> { + self.topology_accessor.ensure_is_routable().await } pub fn start_with_shutdown(mut self, mut shutdown: task::ShutdownListener) { @@ -320,21 +337,4 @@ impl TopologyRefresher { log::debug!("TopologyRefresher: Exiting"); }) } - - pub fn start(mut self) { - spawn_future(async move { - #[cfg(not(target_arch = "wasm32"))] - let mut interval = tokio_stream::wrappers::IntervalStream::new(tokio::time::interval( - self.refresh_rate, - )); - - #[cfg(target_arch = "wasm32")] - let mut interval = - gloo_timers::future::IntervalStream::new(self.refresh_rate.as_millis() as u32); - - while (interval.next().await).is_some() { - self.refresh().await; - } - }) - } } diff --git a/clients/client-core/src/config/mod.rs b/clients/client-core/src/config/mod.rs index 8236fff213..0ce94ba646 100644 --- a/clients/client-core/src/config/mod.rs +++ b/clients/client-core/src/config/mod.rs @@ -30,6 +30,28 @@ const DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT: Duration = Duration::from_millis(5_00 // bandwidth bridging protocol, we can come back to a smaller timeout value const DEFAULT_GATEWAY_RESPONSE_TIMEOUT: Duration = Duration::from_secs(5 * 60); +// reply-surbs related: + +// define when to request +// clients/client-core/src/client/replies/reply_storage/surb_storage.rs +const DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD: usize = 10; +const DEFAULT_MAXIMUM_REPLY_SURB_STORAGE_THRESHOLD: usize = 200; + +// define how much to request at once +// clients/client-core/src/client/replies/reply_controller.rs +const DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE: u32 = 10; +const DEFAULT_MAXIMUM_REPLY_SURB_REQUEST_SIZE: u32 = 100; + +const DEFAULT_MAXIMUM_ALLOWED_SURB_REQUEST_SIZE: u32 = 500; + +const DEFAULT_MAXIMUM_REPLY_SURB_WAITING_PERIOD: Duration = Duration::from_secs(10); + +// 12 hours +const DEFAULT_MAXIMUM_REPLY_SURB_AGE: Duration = Duration::from_secs(12 * 60 * 60); + +// 24 hours +const DEFAULT_MAXIMUM_REPLY_KEY_AGE: Duration = Duration::from_secs(24 * 60 * 60); + pub fn missing_string_value() -> String { MISSING_VALUE.to_string() } @@ -48,7 +70,6 @@ pub struct Config { #[serde(default)] debug: DebugConfig, } - impl ClientCoreConfigTrait for Config { fn get_gateway_endpoint(&self) -> &GatewayEndpointConfig { &self.client.gateway_endpoint @@ -60,12 +81,10 @@ impl Config { where T: NymConfig, { - let mut cfg = Config::default(); - cfg.with_id(id); - cfg + Config::default().with_id(id) } - pub fn with_id>(&mut self, id: S) + pub fn with_id>(mut self, id: S) -> Self where T: NymConfig, { @@ -112,14 +131,9 @@ impl Config { self.client.ack_key_file = self::Client::::default_ack_key_file(&id); } - if self - .client - .reply_encryption_key_store_path - .as_os_str() - .is_empty() - { - self.client.reply_encryption_key_store_path = - self::Client::::default_reply_encryption_key_store_path(&id); + if self.client.reply_surb_database_path.as_os_str().is_empty() { + self.client.reply_surb_database_path = + self::Client::::default_reply_surb_database_path(&id); } if self.client.database_path.as_os_str().is_empty() { @@ -127,6 +141,7 @@ impl Config { } self.client.id = id; + self } pub fn with_disabled_credentials(&mut self, disabled_credentials_mode: bool) { @@ -198,10 +213,6 @@ impl Config { self.client.gateway_shared_key_file.clone() } - pub fn get_reply_encryption_key_store_path(&self) -> PathBuf { - self.client.reply_encryption_key_store_path.clone() - } - pub fn get_ack_key_file(&self) -> PathBuf { self.client.ack_key_file.clone() } @@ -234,6 +245,14 @@ impl Config { self.client.database_path.clone() } + pub fn get_reply_surb_database_path(&self) -> PathBuf { + self.client.reply_surb_database_path.clone() + } + + pub fn get_version(&self) -> &str { + &self.client.version + } + // Debug getters pub fn get_debug_config(&self) -> &DebugConfig { &self.debug @@ -287,8 +306,36 @@ impl Config { self.debug.use_extended_packet_size } - pub fn get_version(&self) -> &str { - &self.client.version + pub fn get_minimum_reply_surb_storage_threshold(&self) -> usize { + self.debug.minimum_reply_surb_storage_threshold + } + + pub fn get_maximum_reply_surb_storage_threshold(&self) -> usize { + self.debug.maximum_reply_surb_storage_threshold + } + + pub fn get_minimum_reply_surb_request_size(&self) -> u32 { + self.debug.minimum_reply_surb_request_size + } + + pub fn get_maximum_reply_surb_request_size(&self) -> u32 { + self.debug.maximum_reply_surb_request_size + } + + pub fn get_maximum_allowed_reply_surb_request_size(&self) -> u32 { + self.debug.maximum_allowed_reply_surb_request_size + } + + pub fn get_maximum_reply_surb_waiting_period(&self) -> Duration { + self.debug.maximum_reply_surb_waiting_period + } + + pub fn get_maximum_reply_surb_age(&self) -> Duration { + self.debug.maximum_reply_surb_age + } + + pub fn get_maximum_reply_key_age(&self) -> Duration { + self.debug.maximum_reply_key_age } } @@ -316,6 +363,22 @@ pub struct GatewayEndpointConfig { pub gateway_listener: String, } +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] +impl GatewayEndpointConfig { + #[cfg_attr(target_arch = "wasm32", wasm_bindgen(constructor))] + pub fn new( + gateway_id: String, + gateway_owner: String, + gateway_listener: String, + ) -> GatewayEndpointConfig { + GatewayEndpointConfig { + gateway_id, + gateway_owner, + gateway_listener, + } + } +} + impl From for GatewayEndpointConfig { fn from(node: topology::gateway::Node) -> GatewayEndpointConfig { let gateway_listener = node.clients_address(); @@ -368,16 +431,15 @@ pub struct Client { /// acknowledgement so that nobody besides the client knows which packet it refers to. ack_key_file: PathBuf, - /// Full path to file containing reply encryption keys of all reply-SURBs we have ever - /// sent but not received back. - reply_encryption_key_store_path: PathBuf, - /// Information regarding how the client should send data to gateway. gateway_endpoint: GatewayEndpointConfig, /// Path to the database containing bandwidth credentials of this client. database_path: PathBuf, + /// Path to the persistent store for received reply surbs, unused encryption keys and used sender tags. + reply_surb_database_path: PathBuf, + /// nym_home_directory specifies absolute path to the home nym Clients directory. /// It is expected to use default value and hence .toml file should not redefine this field. nym_root_directory: PathBuf, @@ -401,9 +463,9 @@ impl Default for Client { public_encryption_key_file: Default::default(), gateway_shared_key_file: Default::default(), ack_key_file: Default::default(), - reply_encryption_key_store_path: Default::default(), gateway_endpoint: Default::default(), database_path: Default::default(), + reply_surb_database_path: Default::default(), nym_root_directory: T::default_root_directory(), super_struct: Default::default(), } @@ -435,9 +497,10 @@ impl Client { T::default_data_directory(Some(id)).join("ack_key.pem") } - fn default_reply_encryption_key_store_path(id: &str) -> PathBuf { - T::default_data_directory(Some(id)).join("reply_key_store") + fn default_reply_surb_database_path(id: &str) -> PathBuf { + T::default_data_directory(Some(id)).join("persistent_reply_store.sqlite") } + fn default_database_path(id: &str) -> PathBuf { T::default_data_directory(Some(id)).join(DB_FILE_NAME) } @@ -513,6 +576,37 @@ pub struct DebugConfig { /// Controls whether the sent sphinx packet use a NON-DEFAULT bigger size. pub use_extended_packet_size: Option, + + /// Defines the minimum number of reply surbs the client wants to keep in its storage at all times. + /// It can only allow to go below that value if its to request additional reply surbs. + pub minimum_reply_surb_storage_threshold: usize, + + /// Defines the maximum number of reply surbs the client wants to keep in its storage at any times. + pub maximum_reply_surb_storage_threshold: usize, + + /// Defines the minimum number of reply surbs the client would request. + pub minimum_reply_surb_request_size: u32, + + /// Defines the maximum number of reply surbs the client would request. + pub maximum_reply_surb_request_size: u32, + + /// Defines the maximum number of reply surbs a remote party is allowed to request from this client at once. + pub maximum_allowed_reply_surb_request_size: u32, + + /// Defines maximum amount of time the client is going to wait for reply surbs before explicitly asking + /// for more even though in theory they wouldn't need to. + #[serde(with = "humantime_serde")] + pub maximum_reply_surb_waiting_period: Duration, + + /// Defines maximum amount of time given reply surb is going to be valid for. + /// This is going to be superseded by key rotation once implemented. + #[serde(with = "humantime_serde")] + pub maximum_reply_surb_age: Duration, + + /// Defines maximum amount of time given reply key is going to be valid for. + /// This is going to be superseded by key rotation once implemented. + #[serde(with = "humantime_serde")] + pub maximum_reply_key_age: Duration, } #[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)] @@ -538,6 +632,14 @@ impl Default for DebugConfig { disable_loop_cover_traffic_stream: false, disable_main_poisson_packet_distribution: false, use_extended_packet_size: None, + minimum_reply_surb_storage_threshold: DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD, + maximum_reply_surb_storage_threshold: DEFAULT_MAXIMUM_REPLY_SURB_STORAGE_THRESHOLD, + minimum_reply_surb_request_size: DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE, + maximum_reply_surb_request_size: DEFAULT_MAXIMUM_REPLY_SURB_REQUEST_SIZE, + maximum_allowed_reply_surb_request_size: DEFAULT_MAXIMUM_ALLOWED_SURB_REQUEST_SIZE, + maximum_reply_surb_waiting_period: DEFAULT_MAXIMUM_REPLY_SURB_WAITING_PERIOD, + maximum_reply_surb_age: DEFAULT_MAXIMUM_REPLY_SURB_AGE, + maximum_reply_key_age: DEFAULT_MAXIMUM_REPLY_KEY_AGE, } } } diff --git a/clients/client-core/src/error.rs b/clients/client-core/src/error.rs index 37538d9e04..3b179567d1 100644 --- a/clients/client-core/src/error.rs +++ b/clients/client-core/src/error.rs @@ -1,47 +1,56 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -#[cfg(feature = "reply-surb")] -use crate::client::reply_key_storage::ReplyKeyStorageError; +use crate::client::replies::reply_storage::ReplyStorageBackend; use crypto::asymmetric::identity::Ed25519RecoveryError; use gateway_client::error::GatewayClientError; +use topology::NymTopologyError; use validator_client::ValidatorClientError; #[derive(thiserror::Error, Debug)] -pub enum ClientCoreError { +pub enum ClientCoreError { #[error("I/O error: {0}")] IoError(#[from] std::io::Error), + #[error("Gateway client error: {0}")] GatewayClientError(#[from] GatewayClientError), + #[error("Ed25519 error: {0}")] Ed25519RecoveryError(#[from] Ed25519RecoveryError), + #[error("Validator client error: {0}")] ValidatorClientError(#[from] ValidatorClientError), - #[cfg(feature = "reply-surb")] - #[error("Reply key storage error: {0}")] - ReplyKeyStorageError(#[from] ReplyKeyStorageError), - #[error("No gateway with id: {0}")] NoGatewayWithId(String), + #[error("No gateways on network")] NoGatewaysOnNetwork, + #[error("Failed to setup gateway")] FailedToSetupGateway, + #[error("List of validator apis is empty")] ListOfValidatorApisIsEmpty, + #[error("Could not load existing gateway configuration: {0}")] CouldNotLoadExistingGatewayConfiguration(std::io::Error), + #[error("The current network topology seem to be insufficient to route any packets through")] - InsufficientNetworkTopology, + InsufficientNetworkTopology(#[from] NymTopologyError), + + #[error("experienced a failure with our reply surb persistent storage: {source}")] + SurbStorageError { source: B::StorageError }, #[error("The gateway id is invalid - {0}")] UnableToCreatePublicKeyFromGatewayId(Ed25519RecoveryError), #[error("The identity of the gateway is unknwown - did you run init?")] GatewayIdUnknown, + #[error("The owner of the gateway is unknown - did you run init?")] GatewayOwnerUnknown, + #[error("The address of the gateway is unknown - did you run init?")] GatwayAddressUnknown, diff --git a/clients/client-core/src/init/helpers.rs b/clients/client-core/src/init/helpers.rs index c838f8c6db..7947d614a1 100644 --- a/clients/client-core/src/init/helpers.rs +++ b/clients/client-core/src/init/helpers.rs @@ -1,25 +1,29 @@ -use std::{sync::Arc, time::Duration}; - -use rand::{rngs::OsRng, seq::SliceRandom, thread_rng}; -use tap::TapFallible; -use url::Url; - -use config::NymConfig; -use crypto::asymmetric::identity; -use gateway_client::GatewayClient; -use gateway_requests::registration::handshake::SharedKeys; -use topology::{filter::VersionFilterable, gateway}; +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 +use crate::client::replies::reply_storage::ReplyStorageBackend; use crate::{ client::key_manager::KeyManager, config::{persistence::key_pathfinder::ClientKeyPathfinder, Config}, error::ClientCoreError, }; +use config::NymConfig; +use crypto::asymmetric::identity; +use gateway_client::GatewayClient; +use gateway_requests::registration::handshake::SharedKeys; +use rand::{rngs::OsRng, seq::SliceRandom, thread_rng}; +use std::{sync::Arc, time::Duration}; +use tap::TapFallible; +use topology::{filter::VersionFilterable, gateway}; +use url::Url; -pub(super) async fn query_gateway_details( +pub(super) async fn query_gateway_details( validator_servers: Vec, chosen_gateway_id: Option, -) -> Result { +) -> Result> +where + B: ReplyStorageBackend, +{ let validator_api = validator_servers .choose(&mut thread_rng()) .ok_or(ClientCoreError::ListOfValidatorApisIsEmpty)?; @@ -51,10 +55,13 @@ pub(super) async fn query_gateway_details( } } -async fn register_with_gateway( +async fn register_with_gateway( gateway: &gateway::Node, our_identity: Arc, -) -> Result, ClientCoreError> { +) -> Result, ClientCoreError> +where + B: ReplyStorageBackend, +{ let timeout = Duration::from_millis(1500); let mut gateway_client = GatewayClient::new_init( gateway.clients_address(), @@ -74,12 +81,13 @@ async fn register_with_gateway( Ok(shared_keys) } -pub(super) async fn register_with_gateway_and_store_keys( +pub(super) async fn register_with_gateway_and_store_keys( gateway_details: gateway::Node, config: &Config, -) -> Result<(), ClientCoreError> +) -> Result<(), ClientCoreError> where T: NymConfig, + B: ReplyStorageBackend, { let mut rng = OsRng; let mut key_manager = KeyManager::new(&mut rng); diff --git a/clients/client-core/src/init/mod.rs b/clients/client-core/src/init/mod.rs index 705cbf4eca..cdf210a27e 100644 --- a/clients/client-core/src/init/mod.rs +++ b/clients/client-core/src/init/mod.rs @@ -12,6 +12,7 @@ use tap::TapFallible; use config::NymConfig; use crypto::asymmetric::{encryption, identity}; +use crate::client::replies::reply_storage::ReplyStorageBackend; use crate::{ config::{ persistence::key_pathfinder::ClientKeyPathfinder, ClientCoreConfigTrait, Config, @@ -62,28 +63,37 @@ impl Display for InitResults { /// Convenience function for setting up the gateway for a client. Depending on the arguments given /// it will do the sensible thing. -pub async fn setup_gateway( +pub async fn setup_gateway( register_gateway: bool, user_chosen_gateway_id: Option, config: &Config, -) -> Result { +) -> Result> +where + B: ReplyStorageBackend, + C: NymConfig + ClientCoreConfigTrait, + T: NymConfig, +{ let id = config.get_id(); if register_gateway { register_with_gateway(user_chosen_gateway_id, config).await } else if let Some(user_chosen_gateway_id) = user_chosen_gateway_id { config_gateway_with_existing_keys(user_chosen_gateway_id, config).await } else { - reuse_existing_gateway_config::(&id) + reuse_existing_gateway_config::(&id) } } /// Get the gateway details by querying the validator-api. Either pick one at random or use /// the chosen one if it's among the available ones. /// Saves keys to disk, specified by the paths in `config`. -pub async fn register_with_gateway( +pub async fn register_with_gateway( user_chosen_gateway_id: Option, config: &Config, -) -> Result { +) -> Result> +where + B: ReplyStorageBackend, + T: NymConfig, +{ println!("Configuring gateway"); let gateway = query_gateway_details(config.get_validator_api_endpoints(), user_chosen_gateway_id).await?; @@ -101,10 +111,14 @@ pub async fn register_with_gateway( /// create any keys. /// This assumes that the user knows what they are doing, and that the existing keys are valid for /// the gateway being used -pub async fn config_gateway_with_existing_keys( +pub async fn config_gateway_with_existing_keys( user_chosen_gateway_id: String, config: &Config, -) -> Result { +) -> Result> +where + B: ReplyStorageBackend, + T: NymConfig, +{ println!("Using gateway provided by user, keeping existing keys"); let gateway = query_gateway_details( config.get_validator_api_endpoints(), @@ -116,9 +130,13 @@ pub async fn config_gateway_with_existing_keys( } /// Read and reuse the existing gateway configuration from a file that was generate earlier. -pub fn reuse_existing_gateway_config( +pub fn reuse_existing_gateway_config( id: &str, -) -> Result { +) -> Result> +where + B: ReplyStorageBackend, + T: NymConfig + ClientCoreConfigTrait, +{ println!("Not registering gateway, will reuse existing config and keys"); T::load_from_file(Some(id)) .map(|existing_config| existing_config.get_gateway_endpoint().clone()) @@ -135,15 +153,19 @@ pub fn reuse_existing_gateway_config( } /// Get the client address by loading the keys from stored files. -pub fn get_client_address_from_stored_keys( +pub fn get_client_address_from_stored_keys( config: &Config, -) -> Result +) -> Result> where T: config::NymConfig, + B: ReplyStorageBackend, { - fn load_identity_keys( + fn load_identity_keys( pathfinder: &ClientKeyPathfinder, - ) -> Result { + ) -> Result> + where + B: ReplyStorageBackend, + { let identity_keypair: identity::KeyPair = pemstore::load_keypair(&pemstore::KeyPairPath::new( pathfinder.private_identity_key().to_owned(), @@ -153,9 +175,12 @@ where Ok(identity_keypair) } - fn load_sphinx_keys( + fn load_sphinx_keys( pathfinder: &ClientKeyPathfinder, - ) -> Result { + ) -> Result> + where + B: ReplyStorageBackend, + { let sphinx_keypair: encryption::KeyPair = pemstore::load_keypair(&pemstore::KeyPairPath::new( pathfinder.private_encryption_key().to_owned(), diff --git a/clients/native/Cargo.toml b/clients/native/Cargo.toml index 1b19bf32ad..97e2a8d504 100644 --- a/clients/native/Cargo.toml +++ b/clients/native/Cargo.toml @@ -27,14 +27,13 @@ pretty_env_logger = "0.4" # for formatting log messages rand = { version = "0.7.3", features = ["wasm-bindgen"] } # rng-related traits + some rng implementation to use serde = { version = "1.0.104", features = ["derive"] } # for config serialization/deserialization serde_json = "1.0" -sled = "0.34" # for storage of replySURB decryption keys -tap = "1.0.1" thiserror = "1.0.34" +tap = "1.0.1" tokio = { version = "1.21.2", features = ["rt-multi-thread", "net", "signal"] } # async runtime tokio-tungstenite = "0.14" # websocket ## internal -client-core = { path = "../client-core" } +client-core = { path = "../client-core", features = ["fs-surb-storage"] } client-connections = { path = "../../common/client-connections" } coconut-interface = { path = "../../common/coconut-interface", optional = true } config = { path = "../../common/config" } diff --git a/clients/native/examples/websocket_binarysend.rs b/clients/native/examples/websocket_binarysend.rs index f103815af2..2c22f0d03b 100644 --- a/clients/native/examples/websocket_binarysend.rs +++ b/clients/native/examples/websocket_binarysend.rs @@ -25,58 +25,59 @@ async fn get_self_address(ws_stream: &mut WebSocketStream recipient, + ServerResponse::SelfAddress(recipient) => *recipient, _ => panic!("received an unexpected response!"), } } async fn send_file_with_reply() { - let uri = "ws://localhost:1977"; - let (mut ws_stream, _) = connect_async(uri).await.unwrap(); - - let recipient = get_self_address(&mut ws_stream).await; - println!("our full address is: {}", recipient); - - let read_data = std::fs::read("examples/dummy_file").unwrap(); - - let send_request = ClientRequest::Send { - recipient, - message: read_data, - with_reply_surb: true, - connection_id: Some(0), - }; - - println!("sending content of 'dummy_file' over the mix network..."); - let response = send_message_and_get_response(&mut ws_stream, send_request.serialize()).await; - - let received = match response { - ServerResponse::Received(received) => received, - _ => panic!("received an unexpected response!"), - }; - - println!("writing the file back to the disk!"); - std::fs::write("examples/received_file_withreply", received.message).unwrap(); - - let reply_message = b"hello from reply SURB! - thanks for sending me the file!".to_vec(); - let reply_request = ClientRequest::Reply { - message: reply_message.clone(), - reply_surb: received.reply_surb.unwrap(), - }; - - println!( - "sending {:?} (using reply SURB!) over the mix network...", - String::from_utf8(reply_message).unwrap() - ); - let response = send_message_and_get_response(&mut ws_stream, reply_request.serialize()).await; - let received = match response { - ServerResponse::Received(received) => received, - _ => panic!("received an unexpected response!"), - }; - - println!( - "received {:#?} from the mix network!", - String::from_utf8(received.message).unwrap() - ); + todo!("reimplement surb usage here : )") + // let uri = "ws://localhost:1977"; + // let (mut ws_stream, _) = connect_async(uri).await.unwrap(); + // + // let recipient = get_self_address(&mut ws_stream).await; + // println!("our full address is: {}", recipient); + // + // let read_data = std::fs::read("examples/dummy_file").unwrap(); + // + // let send_request = ClientRequest::Send { + // recipient, + // message: read_data, + // with_reply_surb: true, + // connection_id: Some(0), + // }; + // + // println!("sending content of 'dummy_file' over the mix network..."); + // let response = send_message_and_get_response(&mut ws_stream, send_request.serialize()).await; + // + // let received = match response { + // ServerResponse::Received(received) => received, + // _ => panic!("received an unexpected response!"), + // }; + // + // println!("writing the file back to the disk!"); + // std::fs::write("examples/received_file_withreply", received.message).unwrap(); + // + // let reply_message = b"hello from reply SURB! - thanks for sending me the file!".to_vec(); + // let reply_request = ClientRequest::Reply { + // message: reply_message.clone(), + // reply_surb: received.reply_surb.unwrap(), + // }; + // + // println!( + // "sending {:?} (using reply SURB!) over the mix network...", + // String::from_utf8(reply_message).unwrap() + // ); + // let response = send_message_and_get_response(&mut ws_stream, reply_request.serialize()).await; + // let received = match response { + // ServerResponse::Received(received) => received, + // _ => panic!("received an unexpected response!"), + // }; + // + // println!( + // "received {:#?} from the mix network!", + // String::from_utf8(received.message).unwrap() + // ); } async fn send_file_without_reply() { @@ -91,7 +92,6 @@ async fn send_file_without_reply() { let send_request = ClientRequest::Send { recipient, message: read_data, - with_reply_surb: false, connection_id: Some(0), }; diff --git a/clients/native/src/client/config/mod.rs b/clients/native/src/client/config/mod.rs index bb2b7d7a15..67902138ce 100644 --- a/clients/native/src/client/config/mod.rs +++ b/clients/native/src/client/config/mod.rs @@ -3,7 +3,7 @@ use crate::client::config::template::config_template; pub use client_core::config::MISSING_VALUE; -use client_core::config::{ClientCoreConfigTrait, Config as BaseConfig}; +use client_core::config::{ClientCoreConfigTrait, Config as BaseConfig, DebugConfig}; use config::defaults::DEFAULT_WEBSOCKET_LISTENING_PORT; use config::NymConfig; use serde::{Deserialize, Serialize}; @@ -28,7 +28,7 @@ impl SocketType { } } - pub fn is_websocket(self) -> bool { + pub fn is_websocket(&self) -> bool { matches!(self, SocketType::WebSocket) } } @@ -110,6 +110,10 @@ impl Config { &mut self.base } + pub fn get_debug_settings(&self) -> &DebugConfig { + self.get_base().get_debug_config() + } + pub fn get_socket_type(&self) -> SocketType { self.socket.socket_type } diff --git a/clients/native/src/client/config/template.rs b/clients/native/src/client/config/template.rs index c327d286ff..31ca091282 100644 --- a/clients/native/src/client/config/template.rs +++ b/clients/native/src/client/config/template.rs @@ -49,13 +49,12 @@ private_encryption_key_file = '{{ client.private_encryption_key_file }}' # Path to file containing public encryption key. public_encryption_key_file = '{{ client.public_encryption_key_file }}' -# Full path to file containing reply encryption keys of all reply-SURBs we have ever -# sent but not received back. -reply_encryption_key_store_path = '{{ client.reply_encryption_key_store_path }}' - # Path to the database containing bandwidth credentials database_path = '{{ client.database_path }}' +# Path to the persistent store for received reply surbs, unused encryption keys and used sender tags. +reply_surb_database_path = '{{ client.reply_surb_database_path }}' + ##### additional client config options ##### # A gateway specific, optional, base58 stringified shared key used for diff --git a/clients/native/src/client/mod.rs b/clients/native/src/client/mod.rs index b997c47fb7..cabe049c45 100644 --- a/clients/native/src/client/mod.rs +++ b/clients/native/src/client/mod.rs @@ -1,11 +1,13 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use crate::client::config::Config; use crate::error::ClientError; use crate::websocket; use client_connections::TransmissionLane; -use client_core::client::base_client::{BaseClientBuilder, ClientInput, ClientOutput}; +use client_core::client::base_client::{ + non_wasm_helpers, BaseClientBuilder, ClientInput, ClientOutput, +}; use client_core::client::inbound_messages::InputMessage; use client_core::client::key_manager::KeyManager; use client_core::client::received_buffer::{ReceivedBufferMessage, ReconstructedMessagesReceiver}; @@ -14,7 +16,7 @@ use futures::channel::mpsc; use gateway_client::bandwidth::BandwidthController; use log::*; use nymsphinx::addressing::clients::Recipient; -use nymsphinx::anonymous_replies::ReplySurb; +use nymsphinx::anonymous_replies::requests::AnonymousSenderTag; use nymsphinx::receiver::ReconstructedMessage; use task::{wait_for_signal, ShutdownNotifier}; @@ -107,7 +109,7 @@ impl SocketClient { /// blocking version of `start_socket` method. Will run forever (or until SIGINT is sent) pub async fn run_socket_forever(self) -> Result<(), ClientError> { - let shutdown = self.start_socket().await?; + let mut shutdown = self.start_socket().await?; wait_for_signal().await; println!( @@ -120,8 +122,8 @@ impl SocketClient { // Some of these components have shutdown signalling implemented as part of socks5 work, // but since it's not fully implemented (yet) for all the components of the native client, // we don't try to wait and instead just stop immediately. - //log::info!("Waiting for tasks to finish... (Press ctrl-c to force)"); - //shutdown.wait_for_shutdown().await; + log::info!("Waiting for tasks to finish... (Press ctrl-c to force)"); + shutdown.wait_for_shutdown().await; log::info!("Stopping nym-client"); Ok(()) @@ -136,6 +138,11 @@ impl SocketClient { self.config.get_base(), self.key_manager, Some(Self::create_bandwidth_controller(&self.config).await), + non_wasm_helpers::setup_fs_reply_surb_backend( + self.config.get_base().get_reply_surb_database_path(), + self.config.get_debug_settings(), + ) + .await?, ); let self_address = base_builder.as_mix_recipient(); @@ -160,6 +167,11 @@ impl SocketClient { self.config.get_base(), self.key_manager, Some(Self::create_bandwidth_controller(&self.config).await), + non_wasm_helpers::setup_fs_reply_surb_backend( + self.config.get_base().get_reply_surb_database_path(), + self.config.get_debug_settings(), + ) + .await?, ); let mut started_client = base_client.start_base().await?; @@ -197,14 +209,9 @@ impl DirectClient { /// EXPERIMENTAL DIRECT RUST API /// It's untested and there are absolutely no guarantees about it (but seems to have worked /// well enough in local tests) - pub async fn send_message( - &mut self, - recipient: Recipient, - message: Vec, - with_reply_surb: bool, - ) { + pub async fn send_regular_message(&mut self, recipient: Recipient, message: Vec) { let lane = TransmissionLane::General; - let input_msg = InputMessage::new_fresh(recipient, message, with_reply_surb, lane); + let input_msg = InputMessage::new_regular(recipient, message, lane); self.client_input .input_sender @@ -216,8 +223,28 @@ impl DirectClient { /// EXPERIMENTAL DIRECT RUST API /// It's untested and there are absolutely no guarantees about it (but seems to have worked /// well enough in local tests) - pub async fn send_reply(&mut self, reply_surb: ReplySurb, message: Vec) { - let input_msg = InputMessage::new_reply(reply_surb, message); + pub async fn send_anonymous_message( + &mut self, + recipient: Recipient, + message: Vec, + reply_surbs: u32, + ) { + let lane = TransmissionLane::General; + let input_msg = InputMessage::new_anonymous(recipient, message, reply_surbs, lane); + + self.client_input + .input_sender + .send(input_msg) + .await + .expect("InputMessageReceiver has stopped receiving!"); + } + + /// EXPERIMENTAL DIRECT RUST API + /// It's untested and there are absolutely no guarantees about it (but seems to have worked + /// well enough in local tests) + pub async fn send_reply(&mut self, recipient_tag: AnonymousSenderTag, message: Vec) { + let lane = TransmissionLane::General; + let input_msg = InputMessage::new_reply(recipient_tag, message, lane); self.client_input .input_sender diff --git a/clients/native/src/commands/init.rs b/clients/native/src/commands/init.rs index 050e680f8e..3caf3a5d0d 100644 --- a/clients/native/src/commands/init.rs +++ b/clients/native/src/commands/init.rs @@ -1,19 +1,17 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use std::fmt::Display; - -use clap::Args; -use config::NymConfig; -use nymsphinx::addressing::clients::Recipient; -use serde::Serialize; -use tap::TapFallible; - use crate::{ client::config::Config, commands::{override_config, OverrideConfig}, error::ClientError, }; +use clap::Args; +use config::NymConfig; +use nymsphinx::addressing::clients::Recipient; +use serde::Serialize; +use std::fmt::Display; +use tap::TapFallible; #[derive(Args, Clone)] pub(crate) struct Init { @@ -136,7 +134,7 @@ pub(crate) async fn execute(args: &Init) -> Result<(), ClientError> { // Setup gateway by either registering a new one, or creating a new config from the selected // one but with keys kept, or reusing the gateway configuration. - let gateway = client_core::init::setup_gateway::( + let gateway = client_core::init::setup_gateway::<_, Config, _>( register_gateway, user_chosen_gateway_id, config.get_base(), diff --git a/clients/native/src/error.rs b/clients/native/src/error.rs index 5ca3319cb7..050e79ebc5 100644 --- a/clients/native/src/error.rs +++ b/clients/native/src/error.rs @@ -1,14 +1,17 @@ +use client_core::client::replies::reply_storage::fs_backend; use client_core::error::ClientCoreError; #[derive(thiserror::Error, Debug)] pub enum ClientError { #[error("I/O error: {0}")] IoError(#[from] std::io::Error), + #[error("client-core error: {0}")] - ClientCoreError(#[from] ClientCoreError), + ClientCoreError(#[from] ClientCoreError), #[error("Failed to load config for: {0}")] FailedToLoadConfig(String), + #[error("Failed local version check, client and config mismatch")] FailedLocalVersionCheck, diff --git a/clients/native/src/websocket/handler.rs b/clients/native/src/websocket/handler.rs index 6dc0d398ad..7d8d16e97f 100644 --- a/clients/native/src/websocket/handler.rs +++ b/clients/native/src/websocket/handler.rs @@ -14,7 +14,7 @@ use futures::channel::mpsc; use futures::{SinkExt, StreamExt}; use log::*; use nymsphinx::addressing::clients::Recipient; -use nymsphinx::anonymous_replies::ReplySurb; +use nymsphinx::anonymous_replies::requests::AnonymousSenderTag; use nymsphinx::receiver::ReconstructedMessage; use tokio::net::TcpStream; use tokio_tungstenite::{ @@ -62,9 +62,13 @@ impl Clone for Handler { impl Drop for Handler { fn drop(&mut self) { - self.buffer_requester + if self + .buffer_requester .unbounded_send(ReceivedBufferMessage::ReceiverDisconnect) - .expect("the buffer request failed!") + .is_err() + { + error!("we failed to disconnect the receiver from the buffer! presumably the shutdown procedure has been initiated!") + } } } @@ -89,18 +93,22 @@ impl Handler { async fn handle_send( &mut self, - recipient: &Recipient, + recipient: Recipient, message: Vec, - with_reply_surb: bool, connection_id: Option, ) -> Option { + info!( + "Attempting to send {:.2} kiB message to {recipient} on connection_id {connection_id:?}", + message.len() as f64 / 1024.0 + ); + // We map the absence of a connection id as going into the general lane. let lane = connection_id.map_or(TransmissionLane::General, |id| { TransmissionLane::ConnectionId(id) }); // the ack control is now responsible for chunking, etc. - let input_msg = InputMessage::new_fresh(*recipient, message, with_reply_surb, lane); + let input_msg = InputMessage::new_regular(recipient, message, lane); self.msg_input .send(input_msg) .await @@ -109,53 +117,119 @@ impl Handler { // Only reply back with a `LaneQueueLength` if the sender providided a connection id let connection_id = match lane { TransmissionLane::General - | TransmissionLane::Reply + | TransmissionLane::ReplySurbRequest | TransmissionLane::Retransmission - | TransmissionLane::Control => return None, + | TransmissionLane::AdditionalReplySurbs => return None, TransmissionLane::ConnectionId(id) => id, }; // on receiving a send, we reply back the current lane queue length for that connection id. // Note that this does _NOT_ take into account the packets that have been received but not // yet reach `OutQueueControl`, so it might be a tad low. - let Ok(lane_queue_lengths) = self.lane_queue_lengths.lock() else { - log::warn!( - "Failed to get the lane queue length lock, \ - not responding back with the current queue length" - ); - return None; - }; - - let queue_length = lane_queue_lengths.get(&lane).unwrap_or(0); - Some(ServerResponse::LaneQueueLength(connection_id, queue_length)) - } - - async fn handle_reply( - &mut self, - reply_surb: ReplySurb, - message: Vec, - ) -> Option { - if message.len() > ReplySurb::max_msg_len(Default::default()) { - return Some( - ServerResponse::new_error( - format!( - "too long message to put inside a reply SURB. Received: {} bytes and maximum is {} bytes", - message.len(), ReplySurb::max_msg_len(Default::default())) - ) - ); + if let Ok(lane_queue_lengths) = self.lane_queue_lengths.lock() { + let queue_length = lane_queue_lengths.get(&lane).unwrap_or(0); + return Some(ServerResponse::LaneQueueLength { + lane: connection_id, + queue_length, + }); } - let input_msg = InputMessage::new_reply(reply_surb, message); + log::warn!("Failed to get the lane queue length lock, not responding back with the current queue length"); + None + } + + async fn handle_send_anonymous( + &mut self, + recipient: Recipient, + message: Vec, + reply_surbs: u32, + connection_id: Option, + ) -> Option { + info!( + "Attempting to anonymously send {:.2} kiB message to {recipient} on connection_id {connection_id:?} while attaching {reply_surbs} replySURBs.", + message.len() as f64 / 1024.0 + ); + + // We map the absence of a connection id as going into the general lane. + let lane = connection_id.map_or(TransmissionLane::General, |id| { + TransmissionLane::ConnectionId(id) + }); + + let input_msg = InputMessage::new_anonymous(recipient, message, reply_surbs, lane); self.msg_input .send(input_msg) .await .expect("InputMessageReceiver has stopped receiving!"); + // Only reply back with a `LaneQueueLength` if the sender providided a connection id + let connection_id = match lane { + TransmissionLane::General + | TransmissionLane::ReplySurbRequest + | TransmissionLane::Retransmission + | TransmissionLane::AdditionalReplySurbs => return None, + TransmissionLane::ConnectionId(id) => id, + }; + + // on receiving a send, we reply back the current lane queue length for that connection id. + // Note that this does _NOT_ take into account the packets that have been received but not + // yet reach `OutQueueControl`, so it might be a tad low. + if let Ok(lane_queue_lengths) = self.lane_queue_lengths.lock() { + let queue_length = lane_queue_lengths.get(&lane).unwrap_or(0); + return Some(ServerResponse::LaneQueueLength { + lane: connection_id, + queue_length, + }); + } + + log::warn!("Failed to get the lane queue length lock, not responding back with the current queue length"); + None + } + + async fn handle_reply( + &mut self, + recipient_tag: AnonymousSenderTag, + message: Vec, + connection_id: Option, + ) -> Option { + info!("Attempting to send {:.2} kiB reply message to {recipient_tag} on connection_id {connection_id:?}", message.len() as f64 / 1024.0); + + // We map the absence of a connection id as going into the general lane. + let lane = connection_id.map_or(TransmissionLane::General, |id| { + TransmissionLane::ConnectionId(id) + }); + + let input_msg = InputMessage::new_reply(recipient_tag, message, lane); + self.msg_input + .send(input_msg) + .await + .expect("InputMessageReceiver has stopped receiving!"); + + // Only reply back with a `LaneQueueLength` if the sender providided a connection id + let connection_id = match lane { + TransmissionLane::General + | TransmissionLane::ReplySurbRequest + | TransmissionLane::Retransmission + | TransmissionLane::AdditionalReplySurbs => return None, + TransmissionLane::ConnectionId(id) => id, + }; + + // on receiving a send, we reply back the current lane queue length for that connection id. + // Note that this does _NOT_ take into account the packets that have been received but not + // yet reach `OutQueueControl`, so it might be a tad low. + if let Ok(lane_queue_lengths) = self.lane_queue_lengths.lock() { + let queue_length = lane_queue_lengths.get(&lane).unwrap_or(0); + return Some(ServerResponse::LaneQueueLength { + lane: connection_id, + queue_length, + }); + } + + log::warn!("Failed to get the lane queue length lock, not responding back with the current queue length"); None } fn handle_self_address(&self) -> ServerResponse { - ServerResponse::SelfAddress(self.self_full_address) + ServerResponse::SelfAddress(Box::new(self.self_full_address)) } fn handle_closed_connection(&self, connection_id: u64) -> Option { @@ -175,7 +249,10 @@ impl Handler { let lane = TransmissionLane::ConnectionId(connection_id); let queue_length = lane_queue_lengths.get(&lane).unwrap_or(0); - Some(ServerResponse::LaneQueueLength(connection_id, queue_length)) + Some(ServerResponse::LaneQueueLength { + lane: connection_id, + queue_length, + }) } async fn handle_request(&mut self, request: ClientRequest) -> Option { @@ -183,16 +260,25 @@ impl Handler { ClientRequest::Send { recipient, message, - with_reply_surb, + connection_id, + } => self.handle_send(recipient, message, connection_id).await, + + ClientRequest::SendAnonymous { + recipient, + message, + reply_surbs, connection_id, } => { - self.handle_send(&recipient, message, with_reply_surb, connection_id) + self.handle_send_anonymous(recipient, message, reply_surbs, connection_id) .await } + ClientRequest::Reply { message, - reply_surb, - } => self.handle_reply(reply_surb, message).await, + sender_tag, + connection_id, + } => self.handle_reply(sender_tag, message, connection_id).await, + ClientRequest::SelfAddress => Some(self.handle_self_address()), ClientRequest::ClosedConnection(id) => self.handle_closed_connection(id), ClientRequest::GetLaneQueueLength(id) => self.handle_get_lane_queue_length(id), @@ -299,8 +385,7 @@ impl Handler { if let Some(response) = self.handle_ws_request(socket_msg).await { if let Err(err) = self.send_websocket_response(response).await { warn!( - "Failed to send message over websocket: {}. Assuming the connection is dead.", - err + "Failed to send message over websocket: {err}. Assuming the connection is dead.", ); break; } @@ -308,9 +393,10 @@ impl Handler { } // or a reconstructed mix message that we need to push back to the client mix_messages = msg_receiver.next() => { - let mix_messages = mix_messages.expect( - "mix messages sender was unexpectedly closed! this shouldn't have ever happened!", - ); + let Some(mix_messages) = mix_messages else { + error!("mix messages sender was unexpectedly closed! this shouldn't have ever happened! (unless we're shutting down - TODO: implement proper graceful shutdown handler)"); + return + }; if let Err(e) = self.push_websocket_received_plaintexts(mix_messages).await { warn!("failed to send sphinx packets back to the client - {:?}, assuming the connection is dead", e); break; diff --git a/clients/native/src/websocket/listener.rs b/clients/native/src/websocket/listener.rs index bdaa27d4fc..c7825fb345 100644 --- a/clients/native/src/websocket/listener.rs +++ b/clients/native/src/websocket/listener.rs @@ -54,9 +54,8 @@ impl Listener { Ok((mut socket, remote_addr)) => { debug!("Received connection from {:?}", remote_addr); if self.state.is_connected() { - warn!("tried to duplicate!"); + warn!("Tried to open a duplicate websocket connection. The request came from {}", remote_addr); // if we've already got a connection, don't allow another one - debug!("but there was already a connection present!"); // while we only ever want to accept a single connection, we don't want // to leave clients hanging (and also allow for reconnection if it somehow // was dropped) diff --git a/clients/native/websocket-requests/src/error.rs b/clients/native/websocket-requests/src/error.rs index f9fdd029cf..2d9035c19d 100644 --- a/clients/native/websocket-requests/src/error.rs +++ b/clients/native/websocket-requests/src/error.rs @@ -24,8 +24,11 @@ impl fmt::Debug for Error { } impl Error { - pub fn new(kind: ErrorKind, message: String) -> Self { - Error { kind, message } + pub fn new>(kind: ErrorKind, message: S) -> Self { + Error { + kind, + message: message.into(), + } } } @@ -62,6 +65,31 @@ pub enum ErrorKind { Other = 0xFF, } +impl TryFrom for ErrorKind { + type Error = Error; + + fn try_from(value: u8) -> Result { + match value { + _ if value == (ErrorKind::EmptyRequest as u8) => Ok(ErrorKind::EmptyRequest), + _ if value == (ErrorKind::TooShortRequest as u8) => Ok(ErrorKind::TooShortRequest), + _ if value == (ErrorKind::UnknownRequest as u8) => Ok(ErrorKind::UnknownRequest), + _ if value == (ErrorKind::MalformedRequest as u8) => Ok(ErrorKind::MalformedRequest), + + _ if value == (ErrorKind::EmptyResponse as u8) => Ok(ErrorKind::EmptyResponse), + _ if value == (ErrorKind::TooShortResponse as u8) => Ok(ErrorKind::TooShortResponse), + _ if value == (ErrorKind::UnknownResponse as u8) => Ok(ErrorKind::UnknownResponse), + _ if value == (ErrorKind::MalformedResponse as u8) => Ok(ErrorKind::MalformedResponse), + + _ if value == (ErrorKind::Other as u8) => Ok(ErrorKind::Other), + + n => Err(Error::new( + ErrorKind::MalformedResponse, + format!("invalid error code {}", n), + )), + } + } +} + impl ErrorKind { pub(crate) fn as_str(&self) -> &'static str { match *self { diff --git a/clients/native/websocket-requests/src/requests.rs b/clients/native/websocket-requests/src/requests.rs index 315399ae3d..f50364a3cf 100644 --- a/clients/native/websocket-requests/src/requests.rs +++ b/clients/native/websocket-requests/src/requests.rs @@ -1,4 +1,4 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 // all variable size data is always prefixed with u64 length @@ -7,69 +7,115 @@ use crate::error::{self, ErrorKind}; use crate::text::ClientRequestText; use nymsphinx::addressing::clients::Recipient; -use nymsphinx::anonymous_replies::ReplySurb; +use nymsphinx::anonymous_replies::requests::{AnonymousSenderTag, SENDER_TAG_SIZE}; use std::convert::{TryFrom, TryInto}; use std::mem::size_of; -/// Value tag representing [`Send`] variant of the [`ClientRequest`] -pub const SEND_REQUEST_TAG: u8 = 0x00; +#[repr(u8)] +enum ClientRequestTag { + /// Value tag representing [`Send`] variant of the [`ClientRequest`] + Send = 0x00, -/// Value tag representing [`Reply`] variant of the [`ClientRequest`] -pub const REPLY_REQUEST_TAG: u8 = 0x01; + /// Value tag representing [`SendAnonymous`] variant of the [`ClientRequest`] + SendAnonymous = 0x01, -/// Value tag representing [`SelfAddress`] variant of the [`ClientRequest`] -pub const SELF_ADDRESS_REQUEST_TAG: u8 = 0x02; + /// Value tag representing [`Reply`] variant of the [`ClientRequest`] + Reply = 0x02, -/// Value tag representing [`ClosedConnection`] variant of the [`ClientRequest`] -pub const CLOSED_CONNECTION_REQUEST_TAG: u8 = 0x03; + /// Value tag representing [`SelfAddress`] variant of the [`ClientRequest`] + SelfAddress = 0x03, -/// Value tag representing [`GetLaneQueueLength`] variant of the [`ClientRequest`] -pub const GET_LANE_QUEUE_LENGHT_TAG: u8 = 0x04; + /// Value tag representing [`ClosedConnection`] variant of the [`ClientRequest`] + ClosedConnection = 0x04, + + /// Value tag representing [`GetLaneQueueLength`] variant of the [`ClientRequest`] + GetLaneQueueLength = 0x05, +} + +impl TryFrom for ClientRequestTag { + type Error = error::Error; + + fn try_from(value: u8) -> Result { + match value { + _ if value == (Self::Send as u8) => Ok(Self::Send), + _ if value == (Self::SendAnonymous as u8) => Ok(Self::SendAnonymous), + _ if value == (Self::Reply as u8) => Ok(Self::Reply), + _ if value == (Self::SelfAddress as u8) => Ok(Self::SelfAddress), + _ if value == (Self::ClosedConnection as u8) => Ok(Self::ClosedConnection), + _ if value == (Self::GetLaneQueueLength as u8) => Ok(Self::GetLaneQueueLength), + n => Err(error::Error::new( + ErrorKind::UnknownRequest, + format!("{n} does not correspond to any valid request tag"), + )), + } + } +} #[allow(non_snake_case)] #[derive(Debug)] pub enum ClientRequest { + /// The simplest message variant where no additional information is attached. + /// You're simply sending your `data` to specified `recipient` without any tagging. + /// + /// Ends up with `NymMessage::Plain` variant Send { recipient: Recipient, message: Vec, - // Perhaps we could change it to a number to indicate how many reply_SURBs we want to include? - with_reply_surb: bool, connection_id: Option, }, - Reply { + + /// Create a message used for a duplex anonymous communication where the recipient + /// will never learn of our true identity. This is achieved by carefully sending `reply_surbs`. + /// + /// Note that if reply_surbs is set to zero then + /// this variant requires the client having sent some reply_surbs in the past + /// (and thus the recipient also knowing our sender tag). + /// + /// Ends up with `NymMessage::Repliable` variant + SendAnonymous { + recipient: Recipient, message: Vec, - reply_surb: ReplySurb, + reply_surbs: u32, + connection_id: Option, }, + + /// Attempt to use our internally received and stored `ReplySurb` to send the message back + /// to specified recipient whilst not knowing its full identity (or even gateway). + /// + /// Ends up with `NymMessage::Reply` variant + Reply { + sender_tag: AnonymousSenderTag, + message: Vec, + connection_id: Option, + }, + SelfAddress, + ClosedConnection(u64), + GetLaneQueueLength(u64), } // we could have been parsing it directly TryFrom, but we want to retain // information about whether it came from binary or text to send appropriate response back impl ClientRequest { - // SEND_REQUEST_TAG || with_surb || recipient || conn_id || data_len || data - fn serialize_send( - recipient: Recipient, - data: Vec, - with_reply_surb: bool, - connection_id: Option, - ) -> Vec { + // SEND_REQUEST_TAG || recipient || conn_id || data_len || data + fn serialize_send(recipient: Recipient, data: Vec, connection_id: Option) -> Vec { let data_len_bytes = (data.len() as u64).to_be_bytes(); let conn_id_bytes = connection_id.unwrap_or(0).to_be_bytes(); - std::iter::once(SEND_REQUEST_TAG) - .chain(std::iter::once(with_reply_surb as u8)) - .chain(recipient.to_bytes().iter().cloned()) // will not be length prefixed because the length is constant - .chain(conn_id_bytes.iter().cloned()) - .chain(data_len_bytes.iter().cloned()) + + std::iter::once(ClientRequestTag::Send as u8) + .chain(recipient.to_bytes().into_iter()) // will not be length prefixed because the length is constant + .chain(conn_id_bytes.into_iter()) + .chain(data_len_bytes.into_iter()) .chain(data.into_iter()) .collect() } - // SEND_REQUEST_TAG || with_reply || recipient || conn_id || data_len || data + // SEND_REQUEST_TAG || recipient || conn_id || data_len || data fn deserialize_send(b: &[u8]) -> Result { - // we need to have at least 1 (tag) + 1 (reply flag) + Recipient::LEN + 2*sizeof bytes - if b.len() < 2 + Recipient::LEN + 2 * size_of::() { + // we need to have at least 1 (tag) + Recipient::LEN + 2*sizeof bytes + if b.len() < 1 + Recipient::LEN + 2 * size_of::() { return Err(error::Error::new( ErrorKind::TooShortRequest, "not enough data provided to recover 'send'".to_string(), @@ -77,21 +123,10 @@ impl ClientRequest { } // this MUST match because it was called by 'deserialize' - debug_assert_eq!(b[0], SEND_REQUEST_TAG); - - let with_reply_surb = match b[1] { - 0 => false, - 1 => true, - n => { - return Err(error::Error::new( - ErrorKind::MalformedRequest, - format!("invalid reply surb flag {}", n), - )) - } - }; + debug_assert_eq!(b[0], ClientRequestTag::Send as u8); let mut recipient_bytes = [0u8; Recipient::LEN]; - recipient_bytes.copy_from_slice(&b[2..2 + Recipient::LEN]); + recipient_bytes.copy_from_slice(&b[1..1 + Recipient::LEN]); let recipient = match Recipient::try_from_bytes(recipient_bytes) { Ok(recipient) => recipient, Err(err) => { @@ -104,7 +139,7 @@ impl ClientRequest { let mut connection_id_bytes = [0u8; size_of::()]; connection_id_bytes - .copy_from_slice(&b[2 + Recipient::LEN..2 + Recipient::LEN + size_of::()]); + .copy_from_slice(&b[1 + Recipient::LEN..1 + Recipient::LEN + size_of::()]); let connection_id = u64::from_be_bytes(connection_id_bytes); let connection_id = if connection_id == 0 { None @@ -113,9 +148,9 @@ impl ClientRequest { }; let data_len_bytes = - &b[2 + Recipient::LEN + size_of::()..2 + Recipient::LEN + 2 * size_of::()]; + &b[1 + Recipient::LEN + size_of::()..1 + Recipient::LEN + 2 * size_of::()]; let data_len = u64::from_be_bytes(data_len_bytes.try_into().unwrap()); - let data = &b[2 + Recipient::LEN + 2 * size_of::()..]; + let data = &b[1 + Recipient::LEN + 2 * size_of::()..]; if data.len() as u64 != data_len { return Err(error::Error::new( ErrorKind::MalformedRequest, @@ -128,33 +163,111 @@ impl ClientRequest { } Ok(ClientRequest::Send { - with_reply_surb, recipient, message: data.to_vec(), connection_id, }) } - // REPLY_REQUEST_TAG || surb_len || surb || message_len || message - fn serialize_reply(message: Vec, reply_surb: &ReplySurb) -> Vec { - let reply_surb_bytes = reply_surb.to_bytes(); - let surb_len_bytes = (reply_surb_bytes.len() as u64).to_be_bytes(); - let message_len_bytes = (message.len() as u64).to_be_bytes(); + // SEND_ANONYMOUS_REQUEST_TAG || reply_surbs || recipient || conn_id || data_len || data + fn serialize_send_anonymous( + recipient: Recipient, + data: Vec, + reply_surbs: u32, + connection_id: Option, + ) -> Vec { + let data_len_bytes = (data.len() as u64).to_be_bytes(); + let conn_id_bytes = connection_id.unwrap_or(0).to_be_bytes(); - std::iter::once(REPLY_REQUEST_TAG) - .chain(surb_len_bytes.iter().cloned()) - .chain(reply_surb_bytes.into_iter()) - .chain(message_len_bytes.iter().cloned()) + std::iter::once(ClientRequestTag::SendAnonymous as u8) + .chain(reply_surbs.to_be_bytes().into_iter()) + .chain(recipient.to_bytes().into_iter()) // will not be length prefixed because the length is constant + .chain(conn_id_bytes.into_iter()) + .chain(data_len_bytes.into_iter()) + .chain(data.into_iter()) + .collect() + } + + // SEND_ANONYMOUS_REQUEST_TAG || reply_surbs || recipient || data_len || data + fn deserialize_send_anonymous(b: &[u8]) -> Result { + // we need to have at least 1 (tag) + sizeof (num surbs) + Recipient::LEN + 2 *sizeof bytes + if b.len() < 1 + size_of::() + Recipient::LEN + 2 * size_of::() { + return Err(error::Error::new( + ErrorKind::TooShortRequest, + "not enough data provided to recover 'send_anonymous'".to_string(), + )); + } + + // this MUST match because it was called by 'deserialize' + debug_assert_eq!(b[0], ClientRequestTag::SendAnonymous as u8); + + let reply_surbs = u32::from_be_bytes([b[1], b[2], b[3], b[4]]); + + let mut recipient_bytes = [0u8; Recipient::LEN]; + recipient_bytes.copy_from_slice(&b[5..5 + Recipient::LEN]); + let recipient = match Recipient::try_from_bytes(recipient_bytes) { + Ok(recipient) => recipient, + Err(err) => { + return Err(error::Error::new( + ErrorKind::MalformedRequest, + format!("malformed recipient: {:?}", err), + )) + } + }; + + let mut connection_id_bytes = [0u8; size_of::()]; + connection_id_bytes + .copy_from_slice(&b[5 + Recipient::LEN..5 + Recipient::LEN + size_of::()]); + let connection_id = u64::from_be_bytes(connection_id_bytes); + let connection_id = if connection_id == 0 { + None + } else { + Some(connection_id) + }; + + let data_len_bytes = + &b[5 + Recipient::LEN + size_of::()..5 + Recipient::LEN + 2 * size_of::()]; + let data_len = u64::from_be_bytes(data_len_bytes.try_into().unwrap()); + let data = &b[5 + Recipient::LEN + 2 * size_of::()..]; + if data.len() as u64 != data_len { + return Err(error::Error::new( + ErrorKind::MalformedRequest, + format!( + "data len has inconsistent length. specified: {} got: {}", + data_len, + data.len() + ), + )); + } + + Ok(ClientRequest::SendAnonymous { + reply_surbs, + recipient, + message: data.to_vec(), + connection_id, + }) + } + + // REPLY_REQUEST_TAG || SENDER_TAG || conn_id || message_len || message + fn serialize_reply( + message: Vec, + sender_tag: AnonymousSenderTag, + connection_id: Option, + ) -> Vec { + let message_len_bytes = (message.len() as u64).to_be_bytes(); + let conn_id_bytes = connection_id.unwrap_or(0).to_be_bytes(); + + std::iter::once(ClientRequestTag::Reply as u8) + .chain(sender_tag.to_bytes().into_iter()) + .chain(conn_id_bytes.into_iter()) + .chain(message_len_bytes.into_iter()) .chain(message.into_iter()) .collect() } - // REPLY_REQUEST_TAG || surb_len || surb || message_len || message + // REPLY_REQUEST_TAG || SENDER_TAG || conn_id || message_len || message fn deserialize_reply(b: &[u8]) -> Result { - // we need to have at the very least 2 * sizeof bytes (in case, for some peculiar reason - // message and reply surb were 0 len - the request would still be malformed, but would in theory - // be parse'able) - if b.len() < 1 + 2 * size_of::() { + if b.len() < 1 + SENDER_TAG_SIZE + 2 * size_of::() { return Err(error::Error::new( ErrorKind::TooShortRequest, "not enough data provided to recover 'reply'".to_string(), @@ -162,42 +275,28 @@ impl ClientRequest { } // this MUST match because it was called by 'deserialize' - debug_assert_eq!(b[0], REPLY_REQUEST_TAG); + debug_assert_eq!(b[0], ClientRequestTag::Reply as u8); - let reply_surb_len = - u64::from_be_bytes(b[1..1 + size_of::()].as_ref().try_into().unwrap()); + // the unwrap here is fine as we're definitely using exactly SENDER_TAG_SIZE bytes + let sender_tag = + AnonymousSenderTag::from_bytes(b[1..1 + SENDER_TAG_SIZE].try_into().unwrap()); - // make sure we won't go out of bounds here - if reply_surb_len > (b.len() - 1 + 2 * size_of::()) as u64 { - return Err(error::Error::new( - ErrorKind::MalformedRequest, - format!( - "not enough data to recover reply surb with specified length {}", - reply_surb_len - ), - )); - } - - let surb_bound = 1 + size_of::() + reply_surb_len as usize; - - let reply_surb_bytes = &b[1 + size_of::()..surb_bound]; - let reply_surb = match ReplySurb::from_bytes(reply_surb_bytes) { - Ok(reply_surb) => reply_surb, - Err(err) => { - return Err(error::Error::new( - ErrorKind::MalformedRequest, - format!("malformed reply surb: {:?}", err), - )) - } + let mut connection_id_bytes = [0u8; size_of::()]; + connection_id_bytes + .copy_from_slice(&b[1 + SENDER_TAG_SIZE..1 + SENDER_TAG_SIZE + size_of::()]); + let connection_id = u64::from_be_bytes(connection_id_bytes); + let connection_id = if connection_id == 0 { + None + } else { + Some(connection_id) }; let message_len = u64::from_be_bytes( - b[surb_bound..surb_bound + size_of::()] - .as_ref() + b[1 + SENDER_TAG_SIZE + size_of::()..1 + SENDER_TAG_SIZE + 2 * size_of::()] .try_into() .unwrap(), ); - let message = &b[surb_bound + size_of::()..]; + let message = &b[1 + SENDER_TAG_SIZE + 2 * size_of::()..]; if message.len() as u64 != message_len { return Err(error::Error::new( ErrorKind::MalformedRequest, @@ -208,33 +307,32 @@ impl ClientRequest { ), )); } - // TODO: should this blow HERE, i.e. during deserialization that the data you're trying - // to send via reply is too long? Ok(ClientRequest::Reply { - reply_surb, message: message.to_vec(), + sender_tag, + connection_id, }) } // SELF_ADDRESS_REQUEST_TAG fn serialize_self_address() -> Vec { - std::iter::once(SELF_ADDRESS_REQUEST_TAG).collect() + vec![ClientRequestTag::SelfAddress as u8] } // SELF_ADDRESS_REQUEST_TAG - fn deserialize_self_address(b: &[u8]) -> Self { + fn deserialize_self_address(b: &[u8]) -> Result { // this MUST match because it was called by 'deserialize' - debug_assert_eq!(b[0], SELF_ADDRESS_REQUEST_TAG); + debug_assert_eq!(b[0], ClientRequestTag::SelfAddress as u8); - ClientRequest::SelfAddress + Ok(ClientRequest::SelfAddress) } // CLOSED_CONNECTION_REQUEST_TAG fn serialize_closed_connection(connection_id: u64) -> Vec { let conn_id_bytes = connection_id.to_be_bytes(); - std::iter::once(CLOSED_CONNECTION_REQUEST_TAG) - .chain(conn_id_bytes.iter().copied()) + std::iter::once(ClientRequestTag::ClosedConnection as u8) + .chain(conn_id_bytes.into_iter()) .collect() } @@ -243,12 +341,12 @@ impl ClientRequest { if b.len() != 1 + size_of::() { return Err(error::Error::new( ErrorKind::MalformedRequest, - "the received closed connection has invalid length".to_string(), + "The received closed connection has invalid length", )); } // this MUST match because it was called by 'deserialize' - debug_assert_eq!(b[0], CLOSED_CONNECTION_REQUEST_TAG); + debug_assert_eq!(b[0], ClientRequestTag::ClosedConnection as u8); let mut connection_id_bytes = [0u8; size_of::()]; connection_id_bytes.copy_from_slice(&b[1..=size_of::()]); @@ -260,8 +358,8 @@ impl ClientRequest { // GET_LANE_QUEUE_LENGHT_TAG fn serialize_get_lane_queue_lengths(connection_id: u64) -> Vec { let conn_id_bytes = connection_id.to_be_bytes(); - std::iter::once(GET_LANE_QUEUE_LENGHT_TAG) - .chain(conn_id_bytes.iter().copied()) + std::iter::once(ClientRequestTag::GetLaneQueueLength as u8) + .chain(conn_id_bytes.into_iter()) .collect() } @@ -270,12 +368,12 @@ impl ClientRequest { if b.len() != 1 + size_of::() { return Err(error::Error::new( ErrorKind::MalformedRequest, - "the received get lane queue length has invalid length".to_string(), + "The received get lane queue lengths has invalid length", )); } // this MUST match because it was called by 'deserialize' - debug_assert_eq!(b[0], GET_LANE_QUEUE_LENGHT_TAG); + debug_assert_eq!(b[0], ClientRequestTag::GetLaneQueueLength as u8); let mut connection_id_bytes = [0u8; size_of::()]; connection_id_bytes.copy_from_slice(&b[1..=size_of::()]); @@ -289,14 +387,21 @@ impl ClientRequest { ClientRequest::Send { recipient, message, - with_reply_surb, connection_id, - } => Self::serialize_send(recipient, message, with_reply_surb, connection_id), + } => Self::serialize_send(recipient, message, connection_id), + + ClientRequest::SendAnonymous { + recipient, + message, + reply_surbs, + connection_id, + } => Self::serialize_send_anonymous(recipient, message, reply_surbs, connection_id), ClientRequest::Reply { message, - reply_surb, - } => Self::serialize_reply(message, &reply_surb), + sender_tag, + connection_id, + } => Self::serialize_reply(message, sender_tag, connection_id), ClientRequest::SelfAddress => Self::serialize_self_address(), @@ -316,28 +421,16 @@ impl ClientRequest { )); } - if b.len() < size_of::() { - return Err(error::Error::new( - ErrorKind::TooShortRequest, - format!( - "not enough data provided to recover request tag. Provided only {} bytes", - b.len() - ), - )); - } - let request_tag = b[0]; + let request_tag = ClientRequestTag::try_from(b[0])?; // determine what kind of request that is and try to deserialize it match request_tag { - SEND_REQUEST_TAG => Self::deserialize_send(b), - REPLY_REQUEST_TAG => Self::deserialize_reply(b), - SELF_ADDRESS_REQUEST_TAG => Ok(Self::deserialize_self_address(b)), - CLOSED_CONNECTION_REQUEST_TAG => Self::deserialize_closed_connection(b), - GET_LANE_QUEUE_LENGHT_TAG => Self::deserialize_get_lane_queue_length(b), - n => Err(error::Error::new( - ErrorKind::UnknownRequest, - format!("type {n}"), - )), + ClientRequestTag::Send => Self::deserialize_send(b), + ClientRequestTag::SendAnonymous => Self::deserialize_send_anonymous(b), + ClientRequestTag::Reply => Self::deserialize_reply(b), + ClientRequestTag::SelfAddress => Self::deserialize_self_address(b), + ClientRequestTag::ClosedConnection => Self::deserialize_closed_connection(b), + ClientRequestTag::GetLaneQueueLength => Self::deserialize_get_lane_queue_length(b), } } @@ -365,50 +458,52 @@ mod tests { let recipient = Recipient::try_from_base58_string("CytBseW6yFXUMzz4SGAKdNLGR7q3sJLLYxyBGvutNEQV.4QXYyEVc5fUDjmmi8PrHN9tdUFV4PCvSJE1278cHyvoe@4sBbL1ngf1vtNqykydQKTFh26sQCw888GpUqvPvyNB4f").unwrap(); let recipient_string = recipient.to_string(); - let send_request_no_surb = ClientRequest::Send { + let send_request = ClientRequest::Send { recipient, message: b"foomp".to_vec(), - with_reply_surb: false, connection_id: Some(42), }; - let bytes = send_request_no_surb.serialize(); + let bytes = send_request.serialize(); let recovered = ClientRequest::deserialize(&bytes).unwrap(); match recovered { ClientRequest::Send { recipient, message, - with_reply_surb, connection_id, } => { assert_eq!(recipient.to_string(), recipient_string); assert_eq!(message, b"foomp".to_vec()); - assert!(!with_reply_surb); assert_eq!(connection_id, Some(42)) } _ => unreachable!(), } + } - let send_request_surb = ClientRequest::Send { - recipient, + #[test] + fn send_anonymous_request_serialization_works() { + let original_recipient = Recipient::try_from_base58_string("CytBseW6yFXUMzz4SGAKdNLGR7q3sJLLYxyBGvutNEQV.4QXYyEVc5fUDjmmi8PrHN9tdUFV4PCvSJE1278cHyvoe@4sBbL1ngf1vtNqykydQKTFh26sQCw888GpUqvPvyNB4f").unwrap(); + + let send_anonymous_request = ClientRequest::SendAnonymous { + recipient: original_recipient, message: b"foomp".to_vec(), - with_reply_surb: true, - connection_id: None, + reply_surbs: 666, + connection_id: Some(42), }; - let bytes = send_request_surb.serialize(); + let bytes = send_anonymous_request.serialize(); let recovered = ClientRequest::deserialize(&bytes).unwrap(); match recovered { - ClientRequest::Send { + ClientRequest::SendAnonymous { recipient, message, - with_reply_surb, + reply_surbs, connection_id, } => { - assert_eq!(recipient.to_string(), recipient_string); + assert_eq!(recipient, original_recipient); assert_eq!(message, b"foomp".to_vec()); - assert!(with_reply_surb); - assert_eq!(connection_id, None) + assert_eq!(connection_id, Some(42)); + assert_eq!(reply_surbs, 666) } _ => unreachable!(), } @@ -416,22 +511,23 @@ mod tests { #[test] fn reply_request_serialization_works() { - let reply_surb_string = "CjfVbHbfAjbC3W1BvNHGXmM8KNAnDNYGaHMLqVDxRYeo352csAihstup9bvqXam4dTWgfHak6KYwL9STaxWJ47E8XFZbSEvs7hEsfCkxr6K9WJuSBPK84GDDEvad8ZAuMCoaXsAd5S2Lj9a5eYyzG4SL1jHzhSMni55LyJwumxo1ZTGZNXggxw1RREosvyzNrW9Rsi3owyPqLCwXpiei2tHZty8w8midVvg8vDa7ZEJD842CLv8D4ohynSG7gDpqTrhkRaqYAuz7dzqNbMXLJRM7v823Jn16fA1L7YQxmcaUdUigyRSgTdb4i9ebiLGSyJ1iDe6Acz613PQZh6Ua3bZ2zVKq3dSycpDm9ngarRK4zJrAaUxRkdih8YzW3BY4nL9eqkfKA4N1TWCLaRU7zpSaf8yMEwrAZReU3d5zLV8c5KBfa2w8R5anhQeBojduZEGEad8kkHuKU52Zg93FeWHvH1qgZaEJMHH4nN7gKXz9mvWDhYwyF4vt3Uy2NhCHC3N5pL1gMme27YcoPcTEia1fxKZtnt6rtEozzTrAgCJGswigkFbkafiV5QaJwLKTUxtzhkZ57eEuLPte9UvJHzhhXUQ2CV7R2BUkJjYZy3Zsx6YYvdYWiAFFkWUwNEGA4QpShUHciBfsQVHQ7pN41YcyYUhbywQDFnTVgEmdUZ1XCBi3gyK5U3tDQmFzP1u9m3mWrUA8qB9mRDE7ptNDm5c3c1458L6uXLUth7sdMaa1Was5LCmCdmNDtvNpCDAEt1in6q6mrZFR85aCSU9b1baNGwZoCqPpPvydkVe63gXWoi8ebvdyxARrqACFrSB3ZdY3uJBw8CTMNkKK6MvcefMkSVVsbLd36TQAtYSCqrpiMc5dQuKcEu5QfciwvWYXYx8WFNAgKwP2mv49KCTvfozNDUCbjzDwSx92Zv5zjG8HbFpB13bY9UZGeyTPvv7gGxCzjGjJGbW6FRAheRQaaje5fUgCNM95Tv7wBmAMRHHFgWafeK1sdFH7dtCX9u898HucGTaboSKLsVh8J78gbbkHErwjMh7y9YRkceq5TTYS5da4kHnyNKYWSbxgZrmFg44XGKoeYcqoHB3XTZrdsf7F5fFeNwnihkmADvhAcaxXUmVqq4rQFZH84a1iC3WBWXYcqiZH2L7ujGWV7mMDT4HBEerDYjc8rNY4xGTPfivCrBCJW1i14aqW8xRdsdgTM88eTksvC3WPJLJ7iMzfKXeL7fMW1Ek6QGyQtLBW98vEESpdcDg6DeZ5rMz6VqjTGGqcCaFGfHoqtfxMDaBAEsyQ8h7XDX6dg1wq9wH6j4Tw7Tj1MEv1b8uj5NJkozZdzVdYA2QyE2Dp8vuurQG6uVdTDNww2d88RBQ8sVgjxN8gR45y4woJLhFAaNTAtrY6wDTxyXST13ni6oyqdYxjFVk9Am4v3DzH7Y2K8iRVSHfTk4FRbPULyaeK6wt2anvMJH1XdvVRgc14h67MnBxMgMD1UFk8AErN7CDj26fppe3c5G6KozJe4cSqQUGbBjVzBnrHCruqrfZBn5hNZHTV37bQiomqhRQXohxhuKEnNrGbAe1xNvJr9X"; - let reply_surb = ReplySurb::from_base58_string(reply_surb_string).unwrap(); let reply_request = ClientRequest::Reply { + sender_tag: [8u8; SENDER_TAG_SIZE].into(), message: b"foomp".to_vec(), - reply_surb, + connection_id: Some(42), }; let bytes = reply_request.serialize(); let recovered = ClientRequest::deserialize(&bytes).unwrap(); match recovered { ClientRequest::Reply { - reply_surb, + sender_tag, message, + connection_id, } => { - assert_eq!(reply_surb.to_base58_string(), reply_surb_string); + assert_eq!(sender_tag, [8u8; SENDER_TAG_SIZE].into()); assert_eq!(message, b"foomp".to_vec()); + assert_eq!(connection_id, Some(42)); } _ => unreachable!(), } @@ -458,4 +554,15 @@ mod tests { _ => unreachable!(), } } + + #[test] + fn get_lane_queue_length_request_serialization_works() { + let close_connection_request = ClientRequest::GetLaneQueueLength(42); + let bytes = close_connection_request.serialize(); + let recovered = ClientRequest::deserialize(&bytes).unwrap(); + match recovered { + ClientRequest::GetLaneQueueLength(id) => assert_eq!(id, 42), + _ => unreachable!(), + } + } } diff --git a/clients/native/websocket-requests/src/responses.rs b/clients/native/websocket-requests/src/responses.rs index 7a32645957..cbefe54242 100644 --- a/clients/native/websocket-requests/src/responses.rs +++ b/clients/native/websocket-requests/src/responses.rs @@ -1,36 +1,54 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 // all variable size data is always prefixed with u64 length // tags are u8 -#![allow(unknown_lints)] // due to using `clippy::branches_sharing_code` which does not exist on `stable` just yet - use crate::error::{self, ErrorKind}; use crate::text::ServerResponseText; use nymsphinx::addressing::clients::Recipient; -use nymsphinx::anonymous_replies::ReplySurb; +use nymsphinx::anonymous_replies::requests::{AnonymousSenderTag, SENDER_TAG_SIZE}; use nymsphinx::receiver::ReconstructedMessage; use std::convert::TryInto; use std::mem::size_of; -/// Value tag representing [`Error`] variant of the [`ServerResponse`] -pub const ERROR_RESPONSE_TAG: u8 = 0x00; +#[repr(u8)] +enum ServerResponseTag { + /// Value tag representing [`Error`] variant of the [`ServerResponse`] + Error = 0x00, -/// Value tag representing [`Received`] variant of the [`ServerResponse`] -pub const RECEIVED_RESPONSE_TAG: u8 = 0x01; + /// Value tag representing [`Received`] variant of the [`ServerResponse`] + Received = 0x01, -/// Value tag representing [`SelfAddress`] variant of the [`ServerResponse`] -pub const SELF_ADDRESS_RESPONSE_TAG: u8 = 0x02; + /// Value tag representing [`SelfAddress`] variant of the [`ServerResponse`] + SelfAddress = 0x02, -/// Value tag representing [`LaneQueueLength`] variant of the [`ServerResponse`] -pub const LANE_QUEUE_LENGTH_RESPONSE_TAG: u8 = 0x03; + /// Value tag representing [`LaneQueueLength`] variant of the [`ServerResponse`] + LaneQueueLength = 0x03, +} + +impl TryFrom for ServerResponseTag { + type Error = error::Error; + + fn try_from(value: u8) -> Result { + match value { + _ if value == (Self::Error as u8) => Ok(Self::Error), + _ if value == (Self::Received as u8) => Ok(Self::Received), + _ if value == (Self::SelfAddress as u8) => Ok(Self::SelfAddress), + _ if value == (Self::LaneQueueLength as u8) => Ok(Self::LaneQueueLength), + n => Err(error::Error::new( + ErrorKind::UnknownResponse, + format!("{n} does not correspond to any valid response tag"), + )), + } + } +} #[derive(Debug)] pub enum ServerResponse { Received(ReconstructedMessage), - SelfAddress(Recipient), - LaneQueueLength(u64, usize), + SelfAddress(Box), + LaneQueueLength { lane: u64, queue_length: usize }, Error(error::Error), } @@ -42,24 +60,19 @@ impl ServerResponse { }) } - // RECEIVED_RESPONSE_TAG || with_reply || (surb_len || surb) || msg_len || msg + // RECEIVED_RESPONSE_TAG || 1 | 0 indicating sender_tag || Option || msg_len || msg fn serialize_received(reconstructed_message: ReconstructedMessage) -> Vec { let message_len_bytes = (reconstructed_message.message.len() as u64).to_be_bytes(); - if let Some(reply_surb) = reconstructed_message.reply_surb { - let reply_surb_bytes = reply_surb.to_bytes(); - let surb_len_bytes = (reply_surb_bytes.len() as u64).to_be_bytes(); - // with_reply || surb_len || surb || msg_len || msg - std::iter::once(RECEIVED_RESPONSE_TAG) + if let Some(sender_tag) = reconstructed_message.sender_tag { + std::iter::once(ServerResponseTag::Received as u8) .chain(std::iter::once(true as u8)) - .chain(surb_len_bytes.iter().cloned()) - .chain(reply_surb_bytes.iter().cloned()) + .chain(sender_tag.to_bytes().into_iter()) .chain(message_len_bytes.iter().cloned()) .chain(reconstructed_message.message.into_iter()) .collect() } else { - // without_reply || msg_len || msg - std::iter::once(RECEIVED_RESPONSE_TAG) + std::iter::once(ServerResponseTag::Received as u8) .chain(std::iter::once(false as u8)) .chain(message_len_bytes.iter().cloned()) .chain(reconstructed_message.message.into_iter()) @@ -67,10 +80,9 @@ impl ServerResponse { } } - // RECEIVED_RESPONSE_TAG || with_reply || (surb_len || surb) || msg_len || msg + // RECEIVED_RESPONSE_TAG || 1 | 0 indicating sender_tag || Option || msg_len || msg fn deserialize_received(b: &[u8]) -> Result { // this MUST match because it was called by 'deserialize' - debug_assert_eq!(b[0], RECEIVED_RESPONSE_TAG); // we must be able to read at the very least if it has a reply_surb and length of some field if b.len() < 2 + size_of::() { @@ -79,101 +91,70 @@ impl ServerResponse { "not enough data provided to recover 'received'".to_string(), )); } + debug_assert_eq!(b[0], ServerResponseTag::Received as u8); - let with_reply_surb = match b[1] { + let has_sender_tag = match b[1] { 0 => false, 1 => true, n => { return Err(error::Error::new( ErrorKind::MalformedResponse, - format!("invalid reply flag {}", n), + format!("invalid sender tag flag {n}"), )) } }; - // this is a false positive as even though the code is the same, it refers to different things - #[allow(clippy::branches_sharing_code)] - if with_reply_surb { - let reply_surb_len = - u64::from_be_bytes(b[2..2 + size_of::()].as_ref().try_into().unwrap()); - - // make sure we won't go out of bounds here - if reply_surb_len > (b.len() - 2 + 2 * size_of::()) as u64 { + let mut i = 2; + let sender_tag = if has_sender_tag { + if b[2..].len() < SENDER_TAG_SIZE { return Err(error::Error::new( - ErrorKind::MalformedResponse, - "not enough bytes to read reply_surb bytes!".to_string(), + ErrorKind::TooShortResponse, + "not enough data provided to recover 'received'".to_string(), )); } - - let surb_bound = 2 + size_of::() + reply_surb_len as usize; - - let reply_surb_bytes = &b[2 + size_of::()..surb_bound]; - let reply_surb = match ReplySurb::from_bytes(reply_surb_bytes) { - Ok(reply_surb) => reply_surb, - Err(err) => { - return Err(error::Error::new( - ErrorKind::MalformedResponse, - format!("malformed reply SURB: {:?}", err), - )) - } - }; - - let message_len = u64::from_be_bytes( - b[surb_bound..surb_bound + size_of::()] - .as_ref() - .try_into() - .unwrap(), - ); - let message = &b[surb_bound + size_of::()..]; - if message.len() as u64 != message_len { - return Err(error::Error::new( - ErrorKind::MalformedResponse, - format!( - "message len has inconsistent length. specified: {} got: {}", - message_len, - message.len() - ), - )); - } - - Ok(ServerResponse::Received(ReconstructedMessage { - message: message.to_vec(), - reply_surb: Some(reply_surb), - })) + i += SENDER_TAG_SIZE; + Some(AnonymousSenderTag::from_bytes( + b[2..2 + SENDER_TAG_SIZE].try_into().unwrap(), + )) } else { - let message_len = - u64::from_be_bytes(b[2..2 + size_of::()].as_ref().try_into().unwrap()); - let message = &b[2 + size_of::()..]; - if message.len() as u64 != message_len { - return Err(error::Error::new( - ErrorKind::MalformedResponse, - format!( - "message len has inconsistent length. specified: {} got: {}", - message_len, - message.len() - ), - )); - } + None + }; - Ok(ServerResponse::Received(ReconstructedMessage { - message: message.to_vec(), - reply_surb: None, - })) + if b[i..].len() < size_of::() { + return Err(error::Error::new( + ErrorKind::TooShortResponse, + "not enough data provided to recover 'received'".to_string(), + )); } + + let message_len = u64::from_be_bytes(b[i..i + size_of::()].try_into().unwrap()); + let message = &b[i + size_of::()..]; + if message.len() as u64 != message_len { + return Err(error::Error::new( + ErrorKind::MalformedResponse, + format!( + "message len has inconsistent length. specified: {} got: {}", + message_len, + message.len() + ), + )); + } + + Ok(ServerResponse::Received(ReconstructedMessage { + message: message.to_vec(), + sender_tag, + })) } // SELF_ADDRESS_RESPONSE_TAG || self_address fn serialize_self_address(address: Recipient) -> Vec { - std::iter::once(SELF_ADDRESS_RESPONSE_TAG) - .chain(address.to_bytes().iter().cloned()) + std::iter::once(ServerResponseTag::SelfAddress as u8) + .chain(address.to_bytes().into_iter()) .collect() } // SELF_ADDRESS_RESPONSE_TAG || self_address fn deserialize_self_address(b: &[u8]) -> Result { - // this MUST match because it was called by 'deserialize' - debug_assert_eq!(b[0], SELF_ADDRESS_RESPONSE_TAG); - if b.len() != 1 + Recipient::LEN { return Err(error::Error::new( ErrorKind::TooShortResponse, @@ -181,6 +162,9 @@ impl ServerResponse { )); } + // this MUST match because it was called by 'deserialize' + debug_assert_eq!(b[0], ServerResponseTag::SelfAddress as u8); + let mut recipient_bytes = [0u8; Recipient::LEN]; recipient_bytes.copy_from_slice(&b[1..1 + Recipient::LEN]); @@ -194,12 +178,12 @@ impl ServerResponse { } }; - Ok(ServerResponse::SelfAddress(recipient)) + Ok(ServerResponse::SelfAddress(Box::new(recipient))) } // LANE_QUEUE_LENGTH_RESPONSE_TAG || lane || queue_length fn serialize_lane_queue_length(lane: u64, queue_length: usize) -> Vec { - std::iter::once(LANE_QUEUE_LENGTH_RESPONSE_TAG) + std::iter::once(ServerResponseTag::LaneQueueLength as u8) .chain(lane.to_be_bytes().iter().cloned()) .chain(queue_length.to_be_bytes().iter().cloned()) .collect() @@ -208,7 +192,7 @@ impl ServerResponse { // LANE_QUEUE_LENGTH_RESPONSE_TAG || lane || queue_length fn deserialize_lane_queue_length(b: &[u8]) -> Result { // this MUST match because it was called by 'deserialize' - debug_assert_eq!(b[0], LANE_QUEUE_LENGTH_RESPONSE_TAG); + debug_assert_eq!(b[0], ServerResponseTag::LaneQueueLength as u8); let mut lane_bytes = [0u8; size_of::()]; lane_bytes.copy_from_slice(&b[1..=size_of::()]); @@ -219,15 +203,15 @@ impl ServerResponse { .copy_from_slice(&b[1 + size_of::()..1 + size_of::() + size_of::()]); let queue_length = usize::from_be_bytes(queue_length_bytes); - Ok(ServerResponse::LaneQueueLength(lane, queue_length)) + Ok(ServerResponse::LaneQueueLength { lane, queue_length }) } // ERROR_RESPONSE_TAG || err_code || msg_len || msg fn serialize_error(error: error::Error) -> Vec { let message_len_bytes = (error.message.len() as u64).to_be_bytes(); - std::iter::once(ERROR_RESPONSE_TAG) + std::iter::once(ServerResponseTag::Error as u8) .chain(std::iter::once(error.kind as u8)) - .chain(message_len_bytes.iter().cloned()) + .chain(message_len_bytes.into_iter()) .chain(error.message.into_bytes().into_iter()) .collect() } @@ -235,7 +219,7 @@ impl ServerResponse { // ERROR_RESPONSE_TAG || err_code || msg_len || msg fn deserialize_error(b: &[u8]) -> Result { // this MUST match because it was called by 'deserialize' - debug_assert_eq!(b[0], ERROR_RESPONSE_TAG); + debug_assert_eq!(b[0], ServerResponseTag::Error as u8); if b.len() < size_of::() + size_of::() { return Err(error::Error::new( @@ -244,26 +228,7 @@ impl ServerResponse { )); } - let error_kind = match b[1] { - _ if b[1] == (ErrorKind::EmptyRequest as u8) => ErrorKind::EmptyRequest, - _ if b[1] == (ErrorKind::TooShortRequest as u8) => ErrorKind::TooShortRequest, - _ if b[1] == (ErrorKind::UnknownRequest as u8) => ErrorKind::UnknownRequest, - _ if b[1] == (ErrorKind::MalformedRequest as u8) => ErrorKind::MalformedRequest, - - _ if b[1] == (ErrorKind::EmptyResponse as u8) => ErrorKind::EmptyResponse, - _ if b[1] == (ErrorKind::TooShortResponse as u8) => ErrorKind::TooShortResponse, - _ if b[1] == (ErrorKind::UnknownResponse as u8) => ErrorKind::UnknownResponse, - _ if b[1] == (ErrorKind::MalformedResponse as u8) => ErrorKind::MalformedResponse, - - _ if b[1] == (ErrorKind::Other as u8) => ErrorKind::Other, - - n => { - return Err(error::Error::new( - ErrorKind::MalformedResponse, - format!("invalid error code {}", n), - )) - } - }; + let error_kind = ErrorKind::try_from(b[1])?; let message_len = u64::from_be_bytes(b[2..2 + size_of::()].as_ref().try_into().unwrap()); @@ -300,8 +265,8 @@ impl ServerResponse { ServerResponse::Received(reconstructed_message) => { Self::serialize_received(reconstructed_message) } - ServerResponse::SelfAddress(address) => Self::serialize_self_address(address), - ServerResponse::LaneQueueLength(lane, queue_length) => { + ServerResponse::SelfAddress(address) => Self::serialize_self_address(*address), + ServerResponse::LaneQueueLength { lane, queue_length } => { Self::serialize_lane_queue_length(lane, queue_length) } ServerResponse::Error(err) => Self::serialize_error(err), @@ -328,18 +293,14 @@ impl ServerResponse { )); } - let response_tag = b[0]; + let response_tag = ServerResponseTag::try_from(b[0])?; // determine what kind of response that is and try to deserialize it match response_tag { - RECEIVED_RESPONSE_TAG => Self::deserialize_received(b), - SELF_ADDRESS_RESPONSE_TAG => Self::deserialize_self_address(b), - LANE_QUEUE_LENGTH_RESPONSE_TAG => Self::deserialize_lane_queue_length(b), - ERROR_RESPONSE_TAG => Self::deserialize_error(b), - n => Err(error::Error::new( - ErrorKind::UnknownResponse, - format!("type {}", n), - )), + ServerResponseTag::Received => Self::deserialize_received(b), + ServerResponseTag::SelfAddress => Self::deserialize_self_address(b), + ServerResponseTag::LaneQueueLength => Self::deserialize_lane_queue_length(b), + ServerResponseTag::Error => Self::deserialize_error(b), } } @@ -361,35 +322,33 @@ mod tests { #[test] fn received_response_serialization_works() { - let reply_surb_string = "CjfVbHbfAjbC3W1BvNHGXmM8KNAnDNYGaHMLqVDxRYeo352csAihstup9bvqXam4dTWgfHak6KYwL9STaxWJ47E8XFZbSEvs7hEsfCkxr6K9WJuSBPK84GDDEvad8ZAuMCoaXsAd5S2Lj9a5eYyzG4SL1jHzhSMni55LyJwumxo1ZTGZNXggxw1RREosvyzNrW9Rsi3owyPqLCwXpiei2tHZty8w8midVvg8vDa7ZEJD842CLv8D4ohynSG7gDpqTrhkRaqYAuz7dzqNbMXLJRM7v823Jn16fA1L7YQxmcaUdUigyRSgTdb4i9ebiLGSyJ1iDe6Acz613PQZh6Ua3bZ2zVKq3dSycpDm9ngarRK4zJrAaUxRkdih8YzW3BY4nL9eqkfKA4N1TWCLaRU7zpSaf8yMEwrAZReU3d5zLV8c5KBfa2w8R5anhQeBojduZEGEad8kkHuKU52Zg93FeWHvH1qgZaEJMHH4nN7gKXz9mvWDhYwyF4vt3Uy2NhCHC3N5pL1gMme27YcoPcTEia1fxKZtnt6rtEozzTrAgCJGswigkFbkafiV5QaJwLKTUxtzhkZ57eEuLPte9UvJHzhhXUQ2CV7R2BUkJjYZy3Zsx6YYvdYWiAFFkWUwNEGA4QpShUHciBfsQVHQ7pN41YcyYUhbywQDFnTVgEmdUZ1XCBi3gyK5U3tDQmFzP1u9m3mWrUA8qB9mRDE7ptNDm5c3c1458L6uXLUth7sdMaa1Was5LCmCdmNDtvNpCDAEt1in6q6mrZFR85aCSU9b1baNGwZoCqPpPvydkVe63gXWoi8ebvdyxARrqACFrSB3ZdY3uJBw8CTMNkKK6MvcefMkSVVsbLd36TQAtYSCqrpiMc5dQuKcEu5QfciwvWYXYx8WFNAgKwP2mv49KCTvfozNDUCbjzDwSx92Zv5zjG8HbFpB13bY9UZGeyTPvv7gGxCzjGjJGbW6FRAheRQaaje5fUgCNM95Tv7wBmAMRHHFgWafeK1sdFH7dtCX9u898HucGTaboSKLsVh8J78gbbkHErwjMh7y9YRkceq5TTYS5da4kHnyNKYWSbxgZrmFg44XGKoeYcqoHB3XTZrdsf7F5fFeNwnihkmADvhAcaxXUmVqq4rQFZH84a1iC3WBWXYcqiZH2L7ujGWV7mMDT4HBEerDYjc8rNY4xGTPfivCrBCJW1i14aqW8xRdsdgTM88eTksvC3WPJLJ7iMzfKXeL7fMW1Ek6QGyQtLBW98vEESpdcDg6DeZ5rMz6VqjTGGqcCaFGfHoqtfxMDaBAEsyQ8h7XDX6dg1wq9wH6j4Tw7Tj1MEv1b8uj5NJkozZdzVdYA2QyE2Dp8vuurQG6uVdTDNww2d88RBQ8sVgjxN8gR45y4woJLhFAaNTAtrY6wDTxyXST13ni6oyqdYxjFVk9Am4v3DzH7Y2K8iRVSHfTk4FRbPULyaeK6wt2anvMJH1XdvVRgc14h67MnBxMgMD1UFk8AErN7CDj26fppe3c5G6KozJe4cSqQUGbBjVzBnrHCruqrfZBn5hNZHTV37bQiomqhRQXohxhuKEnNrGbAe1xNvJr9X"; - - let received_with_surb = ServerResponse::Received(ReconstructedMessage { + let received_with_sender_tag = ServerResponse::Received(ReconstructedMessage { message: b"foomp".to_vec(), - reply_surb: Some(ReplySurb::from_base58_string(reply_surb_string).unwrap()), + sender_tag: Some([42u8; SENDER_TAG_SIZE].into()), }); - let bytes = received_with_surb.serialize(); + let bytes = received_with_sender_tag.serialize(); let recovered = ServerResponse::deserialize(&bytes).unwrap(); match recovered { ServerResponse::Received(reconstructed) => { assert_eq!(reconstructed.message, b"foomp".to_vec()); assert_eq!( - reconstructed.reply_surb.unwrap().to_base58_string(), - reply_surb_string + reconstructed.sender_tag, + Some([42u8; SENDER_TAG_SIZE].into()) ) } _ => unreachable!(), } - let received_without_surb = ServerResponse::Received(ReconstructedMessage { + let received_without_sender_tag = ServerResponse::Received(ReconstructedMessage { message: b"foomp".to_vec(), - reply_surb: None, + sender_tag: None, }); - let bytes = received_without_surb.serialize(); + let bytes = received_without_sender_tag.serialize(); let recovered = ServerResponse::deserialize(&bytes).unwrap(); match recovered { ServerResponse::Received(reconstructed) => { assert_eq!(reconstructed.message, b"foomp".to_vec()); - assert!(reconstructed.reply_surb.is_none()) + assert!(reconstructed.sender_tag.is_none()) } _ => unreachable!(), } @@ -400,7 +359,7 @@ mod tests { let recipient = Recipient::try_from_base58_string("CytBseW6yFXUMzz4SGAKdNLGR7q3sJLLYxyBGvutNEQV.4QXYyEVc5fUDjmmi8PrHN9tdUFV4PCvSJE1278cHyvoe@4sBbL1ngf1vtNqykydQKTFh26sQCw888GpUqvPvyNB4f").unwrap(); let recipient_string = recipient.to_string(); - let self_address_response = ServerResponse::SelfAddress(recipient); + let self_address_response = ServerResponse::SelfAddress(Box::new(recipient)); let bytes = self_address_response.serialize(); let recovered = ServerResponse::deserialize(&bytes).unwrap(); match recovered { @@ -413,11 +372,14 @@ mod tests { #[test] fn lane_queue_length_response_serialization_works() { - let lane_queue_length_response = ServerResponse::LaneQueueLength(13, 42); + let lane_queue_length_response = ServerResponse::LaneQueueLength { + lane: 13, + queue_length: 42, + }; let bytes = lane_queue_length_response.serialize(); let recovered = ServerResponse::deserialize(&bytes).unwrap(); match recovered { - ServerResponse::LaneQueueLength(lane, queue_length) => { + ServerResponse::LaneQueueLength { lane, queue_length } => { assert_eq!(lane, 13); assert_eq!(queue_length, 42) } diff --git a/clients/native/websocket-requests/src/text.rs b/clients/native/websocket-requests/src/text.rs index 1083ecd9a8..68091dbecf 100644 --- a/clients/native/websocket-requests/src/text.rs +++ b/clients/native/websocket-requests/src/text.rs @@ -1,11 +1,11 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use crate::error::ErrorKind; use crate::requests::ClientRequest; use crate::responses::ServerResponse; use nymsphinx::addressing::clients::Recipient; -use nymsphinx::anonymous_replies::ReplySurb; +use nymsphinx::anonymous_replies::requests::AnonymousSenderTag; use serde::{Deserialize, Serialize}; use std::convert::{TryFrom, TryInto}; @@ -19,15 +19,22 @@ pub(super) enum ClientRequestText { Send { message: String, recipient: String, - with_reply_surb: bool, + connection_id: Option, + }, + #[serde(rename_all = "camelCase")] + SendAnonymous { + recipient: String, + message: String, + reply_surbs: u32, + connection_id: Option, + }, + #[serde(rename_all = "camelCase")] + Reply { + sender_tag: String, + message: String, connection_id: Option, }, SelfAddress, - #[serde(rename_all = "camelCase")] - Reply { - message: String, - reply_surb: String, - }, } impl TryFrom for ClientRequestText { @@ -46,7 +53,6 @@ impl TryInto for ClientRequestText { ClientRequestText::Send { message, recipient, - with_reply_surb, connection_id, } => { let message_bytes = message.into_bytes(); @@ -57,23 +63,42 @@ impl TryInto for ClientRequestText { Ok(ClientRequest::Send { message: message_bytes, recipient, - with_reply_surb, + connection_id, + }) + } + ClientRequestText::SendAnonymous { + recipient, + message, + reply_surbs, + connection_id, + } => { + let message_bytes = message.into_bytes(); + let recipient = Recipient::try_from_base58_string(recipient).map_err(|err| { + Self::Error::new(ErrorKind::MalformedRequest, err.to_string()) + })?; + Ok(ClientRequest::SendAnonymous { + recipient, + message: message_bytes, + reply_surbs, connection_id, }) } ClientRequestText::SelfAddress => Ok(ClientRequest::SelfAddress), ClientRequestText::Reply { + sender_tag, message, - reply_surb, + connection_id, } => { let message_bytes = message.into_bytes(); - let reply_surb = ReplySurb::from_base58_string(reply_surb).map_err(|err| { - Self::Error::new(ErrorKind::MalformedRequest, err.to_string()) - })?; + let sender_tag = + AnonymousSenderTag::try_from_base58_string(sender_tag).map_err(|err| { + Self::Error::new(ErrorKind::MalformedRequest, err.to_string()) + })?; Ok(ClientRequest::Reply { + sender_tag, message: message_bytes, - reply_surb, + connection_id, }) } } @@ -89,7 +114,7 @@ pub(super) enum ServerResponseText { #[serde(rename_all = "camelCase")] Received { message: String, - reply_surb: Option, + sender_tag: Option, }, SelfAddress { address: String, @@ -131,15 +156,13 @@ impl From for ServerResponseText { // TODO: ask DH what is more appropriate, lossy utf8 conversion or returning error and then // pure binary later message: String::from_utf8_lossy(&reconstructed.message).into_owned(), - reply_surb: reconstructed - .reply_surb - .map(|reply_surb| reply_surb.to_base58_string()), + sender_tag: reconstructed.sender_tag.map(|tag| tag.to_base58_string()), } } ServerResponse::SelfAddress(recipient) => ServerResponseText::SelfAddress { address: recipient.to_string(), }, - ServerResponse::LaneQueueLength(lane, queue_length) => { + ServerResponse::LaneQueueLength { lane, queue_length } => { ServerResponseText::LaneQueueLength { lane, queue_length } } ServerResponse::Error(err) => ServerResponseText::Error { diff --git a/clients/socks5/Cargo.toml b/clients/socks5/Cargo.toml index 42c477efec..4a4e8edaff 100644 --- a/clients/socks5/Cargo.toml +++ b/clients/socks5/Cargo.toml @@ -26,7 +26,7 @@ tokio = { version = "1.21.2", features = ["rt-multi-thread", "net", "signal"] } url = "2.2" # internal -client-core = { path = "../client-core" } +client-core = { path = "../client-core", features = ["fs-surb-storage"] } client-connections = { path = "../../common/client-connections" } coconut-interface = { path = "../../common/coconut-interface", optional = true } config = { path = "../../common/config" } diff --git a/clients/socks5/src/client/config/mod.rs b/clients/socks5/src/client/config/mod.rs index 0bbab949ef..97372e4c86 100644 --- a/clients/socks5/src/client/config/mod.rs +++ b/clients/socks5/src/client/config/mod.rs @@ -3,7 +3,7 @@ use crate::client::config::template::config_template; pub use client_core::config::MISSING_VALUE; -use client_core::config::{ClientCoreConfigTrait, Config as BaseConfig}; +use client_core::config::{ClientCoreConfigTrait, Config as BaseConfig, DebugConfig}; use config::defaults::DEFAULT_SOCKS5_LISTENING_PORT; use config::NymConfig; use nymsphinx::addressing::clients::Recipient; @@ -12,6 +12,9 @@ use std::path::PathBuf; mod template; +const DEFAULT_CONNECTION_START_SURBS: u32 = 20; +const DEFAULT_PER_REQUEST_SURBS: u32 = 3; + #[derive(Debug, Default, Deserialize, PartialEq, Serialize)] #[serde(deny_unknown_fields)] pub struct Config { @@ -19,6 +22,9 @@ pub struct Config { base: BaseConfig, socks5: Socks5, + + #[serde(default)] + socks5_debug: Socks5Debug, } impl NymConfig for Config { @@ -63,6 +69,7 @@ impl Config { Config { base: BaseConfig::new(id), socks5: Socks5::new(provider_mix_address), + socks5_debug: Socks5Debug::default(), } } @@ -78,7 +85,24 @@ impl Config { self } + pub fn with_anonymous_replies(mut self, anonymous_replies: bool) -> Self { + self.socks5.send_anonymously = anonymous_replies; + self + } + // getters + pub fn get_base(&self) -> &BaseConfig { + &self.base + } + + pub fn get_base_mut(&mut self) -> &mut BaseConfig { + &mut self.base + } + + pub fn get_debug_settings(&self) -> &DebugConfig { + self.get_base().get_debug_config() + } + pub fn get_config_file_save_location(&self) -> PathBuf { self.config_directory().join(Self::config_file_name()) } @@ -88,17 +112,21 @@ impl Config { .expect("malformed provider address") } - pub fn get_base(&self) -> &BaseConfig { - &self.base - } - - pub fn get_base_mut(&mut self) -> &mut BaseConfig { - &mut self.base + pub fn get_send_anonymously(&self) -> bool { + self.socks5.send_anonymously } pub fn get_listening_port(&self) -> u16 { self.socks5.listening_port } + + pub fn get_connection_start_surbs(&self) -> u32 { + self.socks5_debug.connection_start_surbs + } + + pub fn get_per_request_surbs(&self) -> u32 { + self.socks5_debug.per_request_surbs + } } #[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] @@ -109,6 +137,13 @@ pub struct Socks5 { /// The mix address of the provider to which all requests are going to be sent. provider_mix_address: String, + + /// Specifies whether this client is going to use an anonymous sender tag for communication with the service provider. + /// While this is going to hide its actual address information, it will make the actual communication + /// slower and consume nearly double the bandwidth as it will require sending reply SURBs. + /// + /// Note that some service providers might not support this. + send_anonymously: bool, } impl Socks5 { @@ -116,6 +151,7 @@ impl Socks5 { Socks5 { listening_port: DEFAULT_SOCKS5_LISTENING_PORT, provider_mix_address: provider_mix_address.into(), + send_anonymously: false, } } } @@ -125,6 +161,26 @@ impl Default for Socks5 { Socks5 { listening_port: DEFAULT_SOCKS5_LISTENING_PORT, provider_mix_address: "".into(), + send_anonymously: false, + } + } +} + +#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct Socks5Debug { + /// Number of reply SURBs attached to each `Request::Connect` message. + connection_start_surbs: u32, + + /// Number of reply SURBs attached to each `Request::Send` message. + per_request_surbs: u32, +} + +impl Default for Socks5Debug { + fn default() -> Self { + Socks5Debug { + connection_start_surbs: DEFAULT_CONNECTION_START_SURBS, + per_request_surbs: DEFAULT_PER_REQUEST_SURBS, } } } diff --git a/clients/socks5/src/client/config/template.rs b/clients/socks5/src/client/config/template.rs index 11d3185f56..527da38274 100644 --- a/clients/socks5/src/client/config/template.rs +++ b/clients/socks5/src/client/config/template.rs @@ -49,13 +49,12 @@ private_encryption_key_file = '{{ client.private_encryption_key_file }}' # Path to file containing public encryption key. public_encryption_key_file = '{{ client.public_encryption_key_file }}' -# Full path to file containing reply encryption keys of all reply-SURBs we have ever -# sent but not received back. -reply_encryption_key_store_path = '{{ client.reply_encryption_key_store_path }}' - # Path to the database containing bandwidth credentials database_path = '{{ client.database_path }}' +# Path to the persistent store for received reply surbs, unused encryption keys and used sender tags. +reply_surb_database_path = '{{ client.reply_surb_database_path }}' + ##### additional client config options ##### # A gateway specific, optional, base58 stringified shared key used for @@ -92,6 +91,12 @@ provider_mix_address = '{{ socks5.provider_mix_address }}' # The port on which the client will be listening for incoming requests listening_port = {{ socks5.listening_port }} +# Specifies whether this client is going to use an anonymous sender tag for communication with the service provider. +# While this is going to hide its actual address information, it will make the actual communication +# slower and consume nearly double the bandwidth as it will require sending reply SURBs. +# +# Note that some service providers might not support this. +send_anonymously = {{ socks5.send_anonymously }} ##### logging configuration options ##### @@ -104,6 +109,9 @@ listening_port = {{ socks5.listening_port }} # The following options should not be modified unless you know EXACTLY what you are doing # as if set incorrectly, they may impact your anonymity. +# [socks5_debug] + + [debug] average_packet_delay = '{{ debug.average_packet_delay }}' diff --git a/clients/socks5/src/client/mod.rs b/clients/socks5/src/client/mod.rs index 4103dd2788..2b4bff7852 100644 --- a/clients/socks5/src/client/mod.rs +++ b/clients/socks5/src/client/mod.rs @@ -3,11 +3,14 @@ use crate::client::config::Config; use crate::error::Socks5ClientError; +use crate::socks; use crate::socks::{ authentication::{AuthenticationMethods, Authenticator, User}, server::SphinxSocksServer, }; -use client_core::client::base_client::{BaseClientBuilder, ClientInput, ClientOutput}; +use client_core::client::base_client::{ + non_wasm_helpers, BaseClientBuilder, ClientInput, ClientOutput, +}; use client_core::client::key_manager::KeyManager; use client_core::config::persistence::key_pathfinder::ClientKeyPathfinder; use futures::channel::mpsc; @@ -114,6 +117,11 @@ impl NymClient { config.get_provider_mix_address(), self_address, shared_lane_queue_lengths, + socks::client::Config::new( + config.get_send_anonymously(), + config.get_connection_start_surbs(), + config.get_per_request_surbs(), + ), shutdown.clone(), ); task::spawn_with_report_error( @@ -158,7 +166,6 @@ impl NymClient { // Listen to status messages from task, that we forward back to the caller shutdown.start_status_listener(sender); - // Listen for conditions to stop let res = tokio::select! { biased; message = receiver.next() => { @@ -198,6 +205,11 @@ impl NymClient { self.config.get_base(), self.key_manager, Some(Self::create_bandwidth_controller(&self.config).await), + non_wasm_helpers::setup_fs_reply_surb_backend( + self.config.get_base().get_reply_surb_database_path(), + self.config.get_debug_settings(), + ) + .await?, ); let self_address = base_builder.as_mix_recipient(); diff --git a/clients/socks5/src/commands/init.rs b/clients/socks5/src/commands/init.rs index 1e8b5c47f0..70e8935ca3 100644 --- a/clients/socks5/src/commands/init.rs +++ b/clients/socks5/src/commands/init.rs @@ -1,19 +1,17 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use std::fmt::Display; - -use clap::Args; -use config::NymConfig; -use nymsphinx::addressing::clients::Recipient; -use serde::Serialize; -use tap::TapFallible; - use crate::{ client::config::Config, commands::{override_config, OverrideConfig}, error::Socks5ClientError, }; +use clap::Args; +use config::NymConfig; +use nymsphinx::addressing::clients::Recipient; +use serde::Serialize; +use std::fmt::Display; +use tap::TapFallible; #[derive(Args, Clone)] pub(crate) struct Init { @@ -25,6 +23,14 @@ pub(crate) struct Init { #[clap(long)] provider: String, + /// Specifies whether this client is going to use an anonymous sender tag for communication with the service provider. + /// While this is going to hide its actual address information, it will make the actual communication + /// slower and consume nearly double the bandwidth as it will require sending reply SURBs. + /// + /// Note that some service providers might not support this. + #[clap(long)] + use_anonymous_sender_tag: bool, + /// Id of the gateway we are going to connect to. #[clap(long)] gateway: Option, @@ -72,6 +78,7 @@ impl From for OverrideConfig { nymd_validators: init_config.nymd_validators, api_validators: init_config.api_validators, port: init_config.port, + use_anonymous_sender_tag: init_config.use_anonymous_sender_tag, fastmode: init_config.fastmode, no_cover: init_config.no_cover, #[cfg(feature = "coconut")] @@ -138,7 +145,7 @@ pub(crate) async fn execute(args: &Init) -> Result<(), Socks5ClientError> { // Setup gateway by either registering a new one, or creating a new config from the selected // one but with keys kept, or reusing the gateway configuration. - let gateway = client_core::init::setup_gateway::( + let gateway = client_core::init::setup_gateway::<_, Config, _>( register_gateway, user_chosen_gateway_id, config.get_base(), diff --git a/clients/socks5/src/commands/mod.rs b/clients/socks5/src/commands/mod.rs index f1da5a6fda..5f5bfda1de 100644 --- a/clients/socks5/src/commands/mod.rs +++ b/clients/socks5/src/commands/mod.rs @@ -82,6 +82,7 @@ pub(crate) struct OverrideConfig { nymd_validators: Option, api_validators: Option, port: Option, + use_anonymous_sender_tag: bool, fastmode: bool, no_cover: bool, @@ -122,6 +123,10 @@ pub(crate) fn override_config(mut config: Config, args: OverrideConfig) -> Confi .set_custom_validator_apis(parse_validators(&raw_validators)); } + if args.use_anonymous_sender_tag { + config = config.with_anonymous_replies(true) + } + if let Some(port) = args.port { config = config.with_port(port); } diff --git a/clients/socks5/src/commands/run.rs b/clients/socks5/src/commands/run.rs index c1886fc003..612ecc02c2 100644 --- a/clients/socks5/src/commands/run.rs +++ b/clients/socks5/src/commands/run.rs @@ -22,6 +22,14 @@ pub(crate) struct Run { #[clap(long)] config: Option, + /// Specifies whether this client is going to use an anonymous sender tag for communication with the service provider. + /// While this is going to hide its actual address information, it will make the actual communication + /// slower and consume nearly double the bandwidth as it will require sending reply SURBs. + /// + /// Note that some service providers might not support this. + #[clap(long)] + use_anonymous_sender_tag: bool, + /// Address of the socks5 provider to send messages to. #[clap(long)] provider: Option, @@ -65,6 +73,7 @@ impl From for OverrideConfig { nymd_validators: run_config.nymd_validators, api_validators: run_config.api_validators, port: run_config.port, + use_anonymous_sender_tag: run_config.use_anonymous_sender_tag, fastmode: run_config.fastmode, no_cover: run_config.no_cover, #[cfg(feature = "coconut")] diff --git a/clients/socks5/src/error.rs b/clients/socks5/src/error.rs index 2ff6ffbfc2..23cd715cf5 100644 --- a/clients/socks5/src/error.rs +++ b/clients/socks5/src/error.rs @@ -1,21 +1,24 @@ -use client_core::error::ClientCoreError; - use crate::socks::types::SocksProxyError; +use client_core::client::replies::reply_storage::fs_backend; +use client_core::error::ClientCoreError; #[derive(thiserror::Error, Debug)] pub enum Socks5ClientError { #[error("I/O error: {0}")] IoError(#[from] std::io::Error), + #[error("client-core error: {0}")] - ClientCoreError(#[from] ClientCoreError), + ClientCoreError(#[from] ClientCoreError), #[error("SOCKS proxy error")] SocksProxyError(SocksProxyError), #[error("Failed to load config for: {0}")] FailedToLoadConfig(String), + #[error("Failed local version check, client and config mismatch")] FailedLocalVersionCheck, + #[error("Fail to bind address")] FailToBindAddress, } diff --git a/clients/socks5/src/socks/client.rs b/clients/socks5/src/socks/client.rs index acb0a989ad..3b35a4caf9 100644 --- a/clients/socks5/src/socks/client.rs +++ b/clients/socks5/src/socks/client.rs @@ -126,11 +126,33 @@ impl AsyncWrite for StreamState { } } +#[derive(Debug, Copy, Clone)] +pub(crate) struct Config { + use_surbs_for_responses: bool, + connection_start_surbs: u32, + per_request_surbs: u32, +} + +impl Config { + pub(crate) fn new( + use_surbs_for_responses: bool, + connection_start_surbs: u32, + per_request_surbs: u32, + ) -> Self { + Self { + use_surbs_for_responses, + connection_start_surbs, + per_request_surbs, + } + } +} + /// A client connecting to the Socks proxy server, because /// it wants to make a Nym-protected outbound request. Typically, this is /// something like e.g. a wallet app running on your laptop connecting to /// `SphinxSocksServer`. pub(crate) struct SocksClient { + config: Config, controller_sender: ControllerSender, stream: StreamState, auth_nmethods: u8, @@ -160,6 +182,7 @@ impl Drop for SocksClient { impl SocksClient { #[allow(clippy::too_many_arguments)] pub fn new( + config: Config, stream: TcpStream, authenticator: Authenticator, input_sender: InputMessageSender, @@ -175,6 +198,7 @@ impl SocksClient { let connection_id = Self::generate_random(); SocksClient { + config, controller_sender, connection_id, stream: StreamState::Available(stream), @@ -268,14 +292,14 @@ impl SocksClient { self.handle_request().await } - async fn send_connect_to_mixnet(&mut self, remote_address: RemoteAddress) { - let req = Request::new_connect(self.connection_id, remote_address, self.self_address); + async fn send_anonymous_connect_to_mixnet(&mut self, remote_address: RemoteAddress) { + let req = Request::new_connect(self.connection_id, remote_address, None); let msg = Message::Request(req); - let input_message = InputMessage::new_fresh( + let input_message = InputMessage::new_anonymous( self.service_provider, msg.into_bytes(), - false, + self.config.connection_start_surbs, TransmissionLane::ConnectionId(self.connection_id), ); self.input_sender @@ -284,6 +308,30 @@ impl SocksClient { .expect("InputMessageReceiver has stopped receiving!"); } + async fn send_connect_to_mixnet_with_return_address(&mut self, remote_address: RemoteAddress) { + let req = Request::new_connect(self.connection_id, remote_address, Some(self.self_address)); + let msg = Message::Request(req); + + let input_message = InputMessage::new_regular( + self.service_provider, + msg.into_bytes(), + TransmissionLane::ConnectionId(self.connection_id), + ); + self.input_sender + .send(input_message) + .await + .expect("InputMessageReceiver has stopped receiving!"); + } + + async fn send_connect_to_mixnet(&mut self, remote_address: RemoteAddress) { + if self.config.use_surbs_for_responses { + self.send_anonymous_connect_to_mixnet(remote_address).await + } else { + self.send_connect_to_mixnet_with_return_address(remote_address) + .await + } + } + async fn run_proxy(&mut self, conn_receiver: ConnectionReceiver, remote_proxy_target: String) { self.send_connect_to_mixnet(remote_proxy_target.clone()) .await; @@ -300,6 +348,8 @@ impl SocksClient { let connection_id = self.connection_id; let input_sender = self.input_sender.clone(); + let anonymous = self.config.use_surbs_for_responses; + let per_request_surbs = self.config.per_request_surbs; let recipient = self.service_provider; let (stream, _) = ProxyRunner::new( @@ -316,7 +366,16 @@ impl SocksClient { let provider_request = Request::new_send(conn_id, read_data, socket_closed); let provider_message = Message::Request(provider_request); let lane = TransmissionLane::ConnectionId(conn_id); - InputMessage::new_fresh(recipient, provider_message.into_bytes(), false, lane) + if anonymous { + InputMessage::new_anonymous( + recipient, + provider_message.into_bytes(), + per_request_surbs, + lane, + ) + } else { + InputMessage::new_regular(recipient, provider_message.into_bytes(), lane) + } }) .await .into_inner(); diff --git a/clients/socks5/src/socks/mixnet_responses.rs b/clients/socks5/src/socks/mixnet_responses.rs index 430b4322da..7613a32019 100644 --- a/clients/socks5/src/socks/mixnet_responses.rs +++ b/clients/socks5/src/socks/mixnet_responses.rs @@ -54,8 +54,8 @@ impl MixnetResponseListener { async fn on_message(&self, reconstructed_message: ReconstructedMessage) { let raw_message = reconstructed_message.message; - if reconstructed_message.reply_surb.is_some() { - warn!("this message had a surb - we didn't do anything with it"); + if reconstructed_message.sender_tag.is_some() { + warn!("this message was sent anonymously - it couldn't have come from the service provider"); } let response = match Message::try_from_bytes(&raw_message) { diff --git a/clients/socks5/src/socks/mod.rs b/clients/socks5/src/socks/mod.rs index 2acdaa615b..16603839ff 100644 --- a/clients/socks5/src/socks/mod.rs +++ b/clients/socks5/src/socks/mod.rs @@ -5,7 +5,7 @@ use std::convert::TryFrom; use self::types::SocksProxyError; pub mod authentication; -mod client; +pub(crate) mod client; pub(crate) mod mixnet_responses; mod request; pub mod server; diff --git a/clients/socks5/src/socks/server.rs b/clients/socks5/src/socks/server.rs index e31c8d2b0b..0bba59ee0b 100644 --- a/clients/socks5/src/socks/server.rs +++ b/clients/socks5/src/socks/server.rs @@ -3,6 +3,7 @@ use crate::error::Socks5ClientError; use super::{ authentication::Authenticator, client::SocksClient, mixnet_responses::MixnetResponseListener, }; +use crate::socks::client; use client_connections::{ConnectionCommandSender, LaneQueueLengths}; use client_core::client::{ inbound_messages::InputMessageSender, received_buffer::ReceivedBufferRequestSender, @@ -21,6 +22,7 @@ pub struct SphinxSocksServer { listening_address: SocketAddr, service_provider: Recipient, self_address: Recipient, + client_config: client::Config, lane_queue_lengths: LaneQueueLengths, shutdown: ShutdownListener, } @@ -33,6 +35,7 @@ impl SphinxSocksServer { service_provider: Recipient, self_address: Recipient, lane_queue_lengths: LaneQueueLengths, + client_config: client::Config, shutdown: ShutdownListener, ) -> Self { // hardcode ip as we (presumably) ONLY want to listen locally. If we change it, we can @@ -44,6 +47,7 @@ impl SphinxSocksServer { listening_address: format!("{}:{}", ip, port).parse().unwrap(), service_provider, self_address, + client_config, lane_queue_lengths, shutdown, } @@ -86,6 +90,7 @@ impl SphinxSocksServer { tokio::select! { Ok((stream, _remote)) = listener.accept() => { let mut client = SocksClient::new( + self.client_config, stream, self.authenticator.clone(), input_sender.clone(), diff --git a/clients/webassembly/js-example/index.js b/clients/webassembly/js-example/index.js index 4a28435219..f0890bf12e 100644 --- a/clients/webassembly/js-example/index.js +++ b/clients/webassembly/js-example/index.js @@ -65,7 +65,6 @@ async function main() { * * Message and recipient are taken from the values in the user interface. * - * @param {Client} nymClient the nym client to use for message sending */ async function sendMessageTo() { const message = document.getElementById('message').value; @@ -96,10 +95,13 @@ function displaySend(message) { /** * Display received text messages in the browser. Colour them green. * - * @param {string} message + * @param {Uint8Array} raw */ -function displayReceived(message) { - const content = message; +function displayReceived(raw, sender_tag) { + const content = new TextDecoder().decode(raw); + if (sender_tag !== undefined) { + console.log("this message also contained some surbs from", sender_tag) + } let timestamp = new Date().toISOString().substr(11, 12); let receivedDiv = document.createElement('div'); @@ -116,7 +118,7 @@ function displayReceived(message) { /** * Display the nymClient's sender address in the user interface * - * @param {Client} nymClient + * @param {String} address */ function displaySenderAddress(address) { document.getElementById('sender').value = address; diff --git a/clients/webassembly/js-example/worker.js b/clients/webassembly/js-example/worker.js index 0cbf2fe4d6..da066d6ea2 100644 --- a/clients/webassembly/js-example/worker.js +++ b/clients/webassembly/js-example/worker.js @@ -17,38 +17,7 @@ importScripts('nym_client_wasm.js'); console.log('Initializing worker'); // wasm_bindgen creates a global variable (with the exports attached) that is in scope after `importScripts` -const { default_debug, get_gateway, NymClient, set_panic_hook, Config } = wasm_bindgen; - -class ClientWrapper { - constructor(config, onMessageHandler) { - this.rustClient = new NymClient(config); - this.rustClient.set_on_message(onMessageHandler); - this.rustClient.set_on_gateway_connect(this.onConnect); - } - - selfAddress = () => { - return this.rustClient.self_address(); - }; - - onConnect = () => { - console.log('Established (and authenticated) gateway connection!'); - }; - - start = async () => { - // this is current limitation of wasm in rust - for async methods you can't take self by reference... - // I'm trying to figure out if I can somehow hack my way around it, but for time being you have to re-assign - // the object (it's the same one) - this.rustClient = await this.rustClient.start(); - }; - - sendMessage = async (recipient, message) => { - this.rustClient = await this.rustClient.send_message(recipient, message); - }; - - sendBinaryMessage = async (recipient, message) => { - this.rustClient = await this.rustClient.send_binary_message(recipient, message); - }; -} +const { default_debug, NymClientBuilder, set_panic_hook, Config, GatewayEndpointConfig } = wasm_bindgen; let client = null; @@ -62,11 +31,12 @@ async function main() { set_panic_hook(); // validator server we will use to get topology from - const validator = 'https://validator.nymtech.net/api'; //"http://localhost:8081"; - const preferredGateway = 'E3mvZTHQCdBvhfr178Swx9g4QG3kkRUun7YnToLMcMbM'; - - const gatewayEndpoint = await get_gateway(validator, preferredGateway); - gatewayEndpoint.gateway_listener = "wss://gateway1.nymtech.net:443"; // this is needed if we want it to work on the web. However this gateway is a v1 gateway, we will need to change for v2 once we get there + const validator = 'https://qwerty-validator-api.qa.nymte.ch/api'; + + const gatewayId = 'EVupP2tRUeZo5Y6RpBHAbm8kSntpgNyZNL6yCr7BDEoG'; + const gatewayOwner = 'n1rmlew3euapuq7rs4s4j9apv00whrsazr764kl7'; + const gatewayListener = 'ws://176.58.120.72:9000'; + const gatewayEndpoint = new GatewayEndpointConfig(gatewayId, gatewayOwner, gatewayListener) // only really useful if you want to adjust some settings like traffic rate // (if not needed you can just pass a null) @@ -94,12 +64,17 @@ async function main() { }; console.log('Instantiating WASM client...'); - client = new ClientWrapper(config, onMessageHandler); + + let clientBuilder = new NymClientBuilder(config, onMessageHandler) console.log('Web worker creating WASM client...'); - await client.start(); + let local_client = await clientBuilder.start_client(); console.log('WASM client running!'); - - const selfAddress = client.rustClient.self_address(); + + const selfAddress = local_client.self_address(); + + // set the global (I guess we don't have to anymore?) + client = local_client; + console.log(`Client address is ${selfAddress}`); self.postMessage({ kind: 'Ready', @@ -114,7 +89,8 @@ async function main() { switch (event.data.kind) { case 'SendMessage': { const { message, recipient } = event.data.args; - await client.sendMessage(message, recipient); + let uint8Array = new TextEncoder().encode(message); + await client.send_regular_message(uint8Array, recipient); } } } diff --git a/clients/webassembly/src/client/config.rs b/clients/webassembly/src/client/config.rs index 66c6ceefe7..4740a02b2a 100644 --- a/clients/webassembly/src/client/config.rs +++ b/clients/webassembly/src/client/config.rs @@ -106,6 +106,34 @@ pub struct Debug { /// Controls whether the sent sphinx packet use the NON-DEFAULT bigger size. pub use_extended_packet_size: bool, + + /// Defines the minimum number of reply surbs the client wants to keep in its storage at all times. + /// It can only allow to go below that value if its to request additional reply surbs. + pub minimum_reply_surb_storage_threshold: usize, + + /// Defines the maximum number of reply surbs the client wants to keep in its storage at any times. + pub maximum_reply_surb_storage_threshold: usize, + + /// Defines the minimum number of reply surbs the client would request. + pub minimum_reply_surb_request_size: u32, + + /// Defines the maximum number of reply surbs the client would request. + pub maximum_reply_surb_request_size: u32, + + /// Defines the maximum number of reply surbs a remote party is allowed to request from this client at once. + pub maximum_allowed_reply_surb_request_size: u32, + + /// Defines maximum amount of time the client is going to wait for reply surbs before explicitly asking + /// for more even though in theory they wouldn't need to. + pub maximum_reply_surb_waiting_period_ms: u64, + + /// Defines maximum amount of time given reply surb is going to be valid for. + /// This is going to be superseded by key rotation once implemented. + pub maximum_reply_surb_age_ms: u64, + + /// Defines maximum amount of time given reply key is going to be valid for. + /// This is going to be superseded by key rotation once implemented. + pub maximum_reply_key_age_ms: u64, } impl From for ConfigDebug { @@ -135,6 +163,16 @@ impl From for ConfigDebug { disable_main_poisson_packet_distribution: debug .disable_main_poisson_packet_distribution, use_extended_packet_size, + minimum_reply_surb_storage_threshold: debug.minimum_reply_surb_storage_threshold, + maximum_reply_surb_storage_threshold: debug.maximum_reply_surb_storage_threshold, + minimum_reply_surb_request_size: debug.minimum_reply_surb_request_size, + maximum_reply_surb_request_size: debug.maximum_reply_surb_request_size, + maximum_allowed_reply_surb_request_size: debug.maximum_allowed_reply_surb_request_size, + maximum_reply_surb_waiting_period: Duration::from_millis( + debug.maximum_reply_surb_waiting_period_ms, + ), + maximum_reply_surb_age: Duration::from_millis(debug.maximum_reply_surb_age_ms), + maximum_reply_key_age: Duration::from_millis(debug.maximum_reply_key_age_ms), } } } @@ -157,6 +195,16 @@ impl From for Debug { disable_main_poisson_packet_distribution: debug .disable_main_poisson_packet_distribution, use_extended_packet_size: debug.use_extended_packet_size.is_some(), + minimum_reply_surb_storage_threshold: debug.minimum_reply_surb_storage_threshold, + maximum_reply_surb_storage_threshold: debug.maximum_reply_surb_storage_threshold, + minimum_reply_surb_request_size: debug.minimum_reply_surb_request_size, + maximum_reply_surb_request_size: debug.maximum_reply_surb_request_size, + maximum_allowed_reply_surb_request_size: debug.maximum_allowed_reply_surb_request_size, + maximum_reply_surb_waiting_period_ms: debug + .maximum_reply_surb_waiting_period + .as_millis() as u64, + maximum_reply_surb_age_ms: debug.maximum_reply_surb_age.as_millis() as u64, + maximum_reply_key_age_ms: debug.maximum_reply_key_age.as_millis() as u64, } } } diff --git a/clients/webassembly/src/client/helpers.rs b/clients/webassembly/src/client/helpers.rs new file mode 100644 index 0000000000..4349fd5f78 --- /dev/null +++ b/clients/webassembly/src/client/helpers.rs @@ -0,0 +1,30 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use client_core::client::base_client::ClientInput; +use client_core::client::inbound_messages::InputMessage; +use js_sys::Promise; +use std::sync::Arc; +use wasm_bindgen::JsValue; +use wasm_bindgen_futures::future_to_promise; + +// defining helper trait as we could directly call the method on the wrapper +pub(crate) trait InputSender { + fn send_message(&self, message: InputMessage) -> Promise; +} + +impl InputSender for Arc { + fn send_message(&self, message: InputMessage) -> Promise { + let this = Arc::clone(self); + future_to_promise(async move { + match this.input_sender.send(message).await { + Ok(_) => Ok(JsValue::null()), + Err(_) => { + let js_error = + js_sys::Error::new("InputMessageReceiver has stopped receiving!"); + Err(JsValue::from(js_error)) + } + } + }) + } +} diff --git a/clients/webassembly/src/client/mod.rs b/clients/webassembly/src/client/mod.rs index 68a40cf99b..9c3aefe8c6 100644 --- a/clients/webassembly/src/client/mod.rs +++ b/clients/webassembly/src/client/mod.rs @@ -2,59 +2,65 @@ // SPDX-License-Identifier: Apache-2.0 use self::config::Config; +use crate::client::helpers::InputSender; use crate::client::response_pusher::ResponsePusher; use client_connections::TransmissionLane; use client_core::client::base_client::{BaseClientBuilder, ClientInput, ClientOutput}; +use client_core::client::replies::reply_storage::browser_backend; use client_core::client::{inbound_messages::InputMessage, key_manager::KeyManager}; -use crypto::asymmetric::identity; +use gateway_client::bandwidth::BandwidthController; +use js_sys::Promise; use nymsphinx::addressing::clients::Recipient; +use nymsphinx::anonymous_replies::requests::AnonymousSenderTag; use rand::rngs::OsRng; +use std::sync::Arc; use task::ShutdownNotifier; use wasm_bindgen::prelude::*; +use wasm_bindgen_futures::future_to_promise; use wasm_utils::{console_error, console_log}; pub mod config; +mod helpers; mod response_pusher; #[wasm_bindgen] pub struct NymClient { - config: Config, - - /// KeyManager object containing smart pointers to all relevant keys used by the client. - // due to disgusting workaround I had to wrap the key_manager in an Option - // so that the interface wouldn't change (i.e. both `start` and `new` would still return a `NymClient`) - key_manager: Option, - self_address: Option, - - // TODO: this should be stored somewhere persistently - // received_keys: HashSet, - /// Channel used for transforming 'raw' messages into sphinx packets and sending them - /// through the mix network. - client_input: Option, - - // callbacks - on_message: Option, - on_binary_message: Option, - on_gateway_connect: Option, + self_address: String, + client_input: Arc, // even though we don't use graceful shutdowns, other components rely on existence of this struct // and if it's dropped, everything will start going offline - _shutdown: Option, + _shutdown: ShutdownNotifier, } #[wasm_bindgen] -impl NymClient { +pub struct NymClientBuilder { + config: Config, + + /// KeyManager object containing smart pointers to all relevant keys used by the client. + key_manager: KeyManager, + + reply_surb_storage_backend: browser_backend::Backend, + + on_message: js_sys::Function, + + // unimplemented: + bandwidth_controller: Option, + disabled_credentials: bool, +} + +#[wasm_bindgen] +impl NymClientBuilder { #[wasm_bindgen(constructor)] - pub fn new(config: Config) -> Self { - Self { + pub fn new(config: Config, on_message: js_sys::Function) -> Self { + //, key_manager: Option) { + NymClientBuilder { + reply_surb_storage_backend: Self::setup_reply_surb_storage_backend(&config), config, - key_manager: Some(Self::setup_key_manager()), - on_message: None, - on_binary_message: None, - on_gateway_connect: None, - client_input: None, - self_address: None, - _shutdown: None, + key_manager: Self::setup_key_manager(), + on_message, + bandwidth_controller: None, + disabled_credentials: true, } } @@ -69,117 +75,154 @@ impl NymClient { KeyManager::new(&mut rng) } - pub fn set_on_message(&mut self, on_message: js_sys::Function) { - self.on_message = Some(on_message); - } - - pub fn set_on_binary_message(&mut self, on_binary_message: js_sys::Function) { - self.on_binary_message = Some(on_binary_message); - } - - pub fn set_on_gateway_connect(&mut self, on_connect: js_sys::Function) { - self.on_gateway_connect = Some(on_connect) - } - - fn as_mix_recipient(&self) -> Recipient { - // another disgusting (and hopefully temporary) workaround - let key_manager_ref = self - .key_manager - .as_ref() - .expect("attempting to call 'as_mix_recipient' after 'start'"); - - Recipient::new( - *key_manager_ref.identity_keypair().public_key(), - *key_manager_ref.encryption_keypair().public_key(), - identity::PublicKey::from_base58_string(&self.config.gateway_endpoint.gateway_id) - .expect("no gateway has been selected"), + // don't get too excited about the name, under the hood it's just a big fat placeholder + // with no persistence + fn setup_reply_surb_storage_backend(config: &Config) -> browser_backend::Backend { + browser_backend::Backend::new( + config.debug.minimum_reply_surb_storage_threshold, + config.debug.maximum_reply_surb_storage_threshold, ) } + fn start_reconstructed_pusher(client_output: ClientOutput, on_message: js_sys::Function) { + ResponsePusher::new(client_output, on_message).start() + } + + pub async fn start_client(self) -> Promise { + future_to_promise(async move { + console_log!("Starting the wasm client"); + + let base_builder = BaseClientBuilder::new( + &self.config.gateway_endpoint, + &self.config.debug, + self.key_manager, + self.bandwidth_controller, + self.reply_surb_storage_backend, + self.disabled_credentials, + vec![self.config.validator_api_url.clone()], + ); + + let self_address = base_builder.as_mix_recipient().to_string(); + let mut started_client = match base_builder.start_base().await { + Ok(base_client) => base_client, + Err(err) => { + let error_msg = format!("failed to start the base client components - {err}"); + console_error!("{}", error_msg); + let js_error = js_sys::Error::new(&error_msg); + return Err(JsValue::from(js_error)); + } + }; + + let client_input = started_client.client_input.register_producer(); + let client_output = started_client.client_output.register_consumer(); + + Self::start_reconstructed_pusher(client_output, self.on_message); + + Ok(JsValue::from(NymClient { + self_address, + client_input: Arc::new(client_input), + _shutdown: started_client.shutdown_notifier, + })) + }) + } +} + +#[wasm_bindgen] +impl NymClient { pub fn self_address(&self) -> String { - if let Some(address) = &self.self_address { - address.clone() - } else { - self.as_mix_recipient().to_string() + self.self_address.clone() + } + + fn parse_recipient(recipient: &str) -> Result { + match Recipient::try_from_base58_string(recipient) { + Ok(recipient) => Ok(recipient), + Err(err) => { + let error_msg = format!("{recipient} is not a valid Nym network recipient - {err}"); + console_error!("{}", error_msg); + let js_error = js_sys::Error::new(&error_msg); + Err(JsValue::from(js_error)) + } } } - // Right now it's impossible to have async exported functions to take `&mut self` rather than mut self - // TODO: try Rc> approach? - pub async fn send_message(self, message: String, recipient: String) -> Self { - console_log!("Sending {} to {}", message, recipient); - - let message_bytes = message.into_bytes(); - self.send_binary_message(message_bytes, recipient).await + fn parse_sender_tag(tag: &str) -> Result { + match AnonymousSenderTag::try_from_base58_string(tag) { + Ok(tag) => Ok(tag), + Err(err) => { + let error_msg = format!("{tag} is not a valid Nym AnonymousSenderTag - {err}"); + console_error!("{}", error_msg); + let js_error = js_sys::Error::new(&error_msg); + Err(JsValue::from(js_error)) + } + } } - pub async fn send_binary_message(self, message: Vec, recipient: String) -> Self { - console_log!("Sending {} bytes to {}", message.len(), recipient); - - let recipient = Recipient::try_from_base58_string(recipient).unwrap(); - let lane = TransmissionLane::General; - - let input_msg = InputMessage::new_fresh(recipient, message, false, lane); - - self.client_input - .as_ref() - .expect("start method was not called before!") - .input_sender - .send(input_msg) - .await - .expect("InputMessageReceiver has stopped receiving!"); - - self - } - - fn start_reconstructed_pusher( - client_output: ClientOutput, - on_message: Option, - on_binary_message: Option, - ) { - ResponsePusher::new(client_output, on_message, on_binary_message).start() - } - - pub async fn start(mut self) -> NymClient { - console_log!("Starting the wasm client"); - - let base_builder = BaseClientBuilder::new( - &self.config.gateway_endpoint, - &self.config.debug, - self.key_manager.take().unwrap(), - None, - true, - vec![self.config.validator_api_url.clone()], + /// The simplest message variant where no additional information is attached. + /// You're simply sending your `data` to specified `recipient` without any tagging. + /// + /// Ends up with `NymMessage::Plain` variant + pub fn send_regular_message(&self, message: Vec, recipient: String) -> Promise { + console_log!( + "Attempting to send {:.2} kiB message to {recipient}", + message.len() as f64 / 1024.0 ); - self.self_address = Some(base_builder.as_mix_recipient().to_string()); - let mut started_client = match base_builder.start_base().await { - Ok(base_client) => base_client, - Err(err) => { - console_error!("failed to start base client components - {}", err); - // proper error handling is left here as an exercise for the reader (hi Mark : )) - panic!("failed to start base client components - {err}") - } + let recipient = match Self::parse_recipient(&recipient) { + Ok(recipient) => recipient, + Err(err) => return Promise::reject(&err), }; - match self.on_gateway_connect.as_ref() { - Some(callback) => { - callback - .call0(&JsValue::null()) - .expect("on connect callback failed!"); - } - None => console_log!("Gateway connection established - no callback specified"), + let lane = TransmissionLane::General; + + let input_msg = InputMessage::new_regular(recipient, message, lane); + self.client_input.send_message(input_msg) + } + + /// Creates a message used for a duplex anonymous communication where the recipient + /// will never learn of our true identity. This is achieved by carefully sending `reply_surbs`. + /// + /// Note that if reply_surbs is set to zero then + /// this variant requires the client having sent some reply_surbs in the past + /// (and thus the recipient also knowing our sender tag). + /// + /// Ends up with `NymMessage::Repliable` variant + pub fn send_anonymous_message( + &self, + message: Vec, + recipient: String, + reply_surbs: u32, + ) -> Promise { + console_log!( + "Attempting to anonymously send {:.2} kiB message to {recipient} while attaching {reply_surbs} replySURBs.", + message.len() as f64 / 1024.0 + ); + + let recipient = match Self::parse_recipient(&recipient) { + Ok(recipient) => recipient, + Err(err) => return Promise::reject(&err), }; + let lane = TransmissionLane::General; - // those should be moved to a completely different struct, but I don't want to break compatibility for now - let client_input = started_client.client_input.register_producer(); - let client_output = started_client.client_output.register_consumer(); + let input_msg = InputMessage::new_anonymous(recipient, message, reply_surbs, lane); + self.client_input.send_message(input_msg) + } - let on_message = self.on_message.take(); - let on_binary_message = self.on_binary_message.take(); - Self::start_reconstructed_pusher(client_output, on_message, on_binary_message); - self.client_input = Some(client_input); - self._shutdown = Some(started_client.shutdown_notifier); + /// Attempt to use our internally received and stored `ReplySurb` to send the message back + /// to specified recipient whilst not knowing its full identity (or even gateway). + /// + /// Ends up with `NymMessage::Reply` variant + pub fn send_reply(&self, message: Vec, recipient_tag: String) -> Promise { + console_log!( + "Attempting to send {:.2} kiB reply message to {recipient_tag}", + message.len() as f64 / 1024.0 + ); - self + let sender_tag = match Self::parse_sender_tag(&recipient_tag) { + Ok(recipient) => recipient, + Err(err) => return Promise::reject(&err), + }; + let lane = TransmissionLane::General; + + let input_msg = InputMessage::new_reply(sender_tag, message, lane); + self.client_input.send_message(input_msg) } } diff --git a/clients/webassembly/src/client/response_pusher.rs b/clients/webassembly/src/client/response_pusher.rs index c5717a9bc3..fbe04c66ed 100644 --- a/clients/webassembly/src/client/response_pusher.rs +++ b/clients/webassembly/src/client/response_pusher.rs @@ -5,27 +5,18 @@ use client_core::client::base_client::ClientOutput; use client_core::client::received_buffer::{ReceivedBufferMessage, ReconstructedMessagesReceiver}; use futures::channel::mpsc; use futures::StreamExt; +use js_sys::Uint8Array; use wasm_bindgen::JsValue; use wasm_bindgen_futures::spawn_local; -use wasm_utils::console_log; +use wasm_utils::console_error; pub(crate) struct ResponsePusher { reconstructed_receiver: ReconstructedMessagesReceiver, - on_message: Option, - on_binary_message: Option, + on_message: js_sys::Function, } impl ResponsePusher { - pub(crate) fn new( - client_output: ClientOutput, - on_message: Option, - on_binary_message: Option, - ) -> Self { - if on_message.is_none() && on_binary_message.is_none() { - // exercise for the reader : ) - panic!("neither 'on_message' nor 'on_binary_message' was set!") - } - + pub(crate) fn new(client_output: ClientOutput, on_message: js_sys::Function) -> Self { // register our output let (reconstructed_sender, reconstructed_receiver) = mpsc::unbounded(); @@ -40,7 +31,6 @@ impl ResponsePusher { ResponsePusher { reconstructed_receiver, on_message, - on_binary_message, } } @@ -49,23 +39,20 @@ impl ResponsePusher { let this = JsValue::null(); while let Some(reconstructed) = self.reconstructed_receiver.next().await { - for msg in reconstructed { - if let Some(ref callback_binary) = self.on_binary_message { - let arg1 = serde_wasm_bindgen::to_value(&msg.message).unwrap(); - callback_binary - .call1(&this, &arg1) - .expect("on binary message failed!"); - } - if let Some(ref callback) = self.on_message { - if msg.reply_surb.is_some() { - console_log!("the received message contained a reply-surb that we do not know how to handle (yet)") - } - let stringified = String::from_utf8_lossy(&msg.message).into_owned(); - let arg1 = serde_wasm_bindgen::to_value(&stringified).unwrap(); - callback.call1(&this, &arg1).expect("on message failed!"); - } + for reconstructed_msg in reconstructed { + let (msg, tag) = reconstructed_msg.into_inner(); + + let msg_slice: &[u8] = &msg; + let array = Uint8Array::from(msg_slice); + let arg1 = JsValue::from(array); + let arg2 = JsValue::from(tag); + self.on_message + .call2(&this, &arg1, &arg2) + .expect("on binary message failed!"); } } + + console_error!("we stopped receiving reconstructed messages!") }) } } diff --git a/common/client-connections/src/lib.rs b/common/client-connections/src/lib.rs index 515938ed54..f86270da63 100644 --- a/common/client-connections/src/lib.rs +++ b/common/client-connections/src/lib.rs @@ -10,9 +10,11 @@ pub type ConnectionId = u64; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub enum TransmissionLane { General, - Reply, + // we need to treat surb-related requests and responses at higher priority + // so that the rest of underlying communication could actually continue + ReplySurbRequest, + AdditionalReplySurbs, Retransmission, - Control, ConnectionId(ConnectionId), } diff --git a/common/client-libs/gateway-client/Cargo.toml b/common/client-libs/gateway-client/Cargo.toml index d1ea2abf1e..8f1de308d3 100644 --- a/common/client-libs/gateway-client/Cargo.toml +++ b/common/client-libs/gateway-client/Cargo.toml @@ -57,6 +57,7 @@ version = "0.4" [target."cfg(target_arch = \"wasm32\")".dependencies.wasm-utils] path = "../../wasm-utils" +features = ["websocket"] # only import it in wasm. Prefer proper tokio timer in non-wasm [target."cfg(target_arch = \"wasm32\")".dependencies.wasm-timer] diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index a731186424..e1c2654b80 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -410,7 +410,7 @@ impl GatewayClient { match gateway_protocol { None => { warn!("the gateway we're connected to has not specified its protocol version. It's probably running version < 1.1.X, but that's still fine for now. It will become a hard error in 1.2.0"); - // note: in 1.2.0 we will have to return a hard error here + // note: in +1.2.0 we will have to return a hard error here Ok(()) } Some(v) if v != PROTOCOL_VERSION => { diff --git a/common/client-libs/gateway-client/src/lib.rs b/common/client-libs/gateway-client/src/lib.rs index 8671a7363b..ac209f0920 100644 --- a/common/client-libs/gateway-client/src/lib.rs +++ b/common/client-libs/gateway-client/src/lib.rs @@ -16,7 +16,7 @@ pub mod client; pub mod error; pub mod packet_router; pub mod socket_state; -#[cfg(feature = "wasm")] +#[cfg(target_arch = "wasm32")] mod wasm_storage; /// Helper method for reading from websocket stream. Helps to flatten the structure. diff --git a/common/client-libs/validator-client/src/client.rs b/common/client-libs/validator-client/src/client.rs index 6a218f1fa2..b5746ea06c 100644 --- a/common/client-libs/validator-client/src/client.rs +++ b/common/client-libs/validator-client/src/client.rs @@ -1,20 +1,12 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 + use crate::{validator_api, ValidatorClientError}; use coconut_dkg_common::types::NodeIndex; -#[cfg(feature = "nymd-client")] -use coconut_dkg_common::{ - dealer::ContractDealing, types::DealerDetails, verification_key::ContractVKShare, -}; -#[cfg(feature = "nymd-client")] -use coconut_interface::Base58; use coconut_interface::VerificationKey; -use mixnet_contract_common::families::{Family, FamilyHead}; use mixnet_contract_common::mixnode::MixNodeDetails; +use mixnet_contract_common::MixId; use mixnet_contract_common::{GatewayBond, IdentityKeyRef}; -use mixnet_contract_common::{IdentityKey, MixId}; -#[cfg(feature = "nymd-client")] -use std::str::FromStr; use validator_api_requests::coconut::{ BlindSignRequestBody, BlindedSignatureResponse, VerifyCredentialBody, VerifyCredentialResponse, }; @@ -28,15 +20,24 @@ use crate::nymd::traits::{DkgQueryClient, MixnetQueryClient, MultisigQueryClient #[cfg(feature = "nymd-client")] use crate::nymd::{self, CosmWasmClient, NymdClient, QueryNymdClient, SigningNymdClient}; #[cfg(feature = "nymd-client")] +use coconut_dkg_common::{ + dealer::ContractDealing, types::DealerDetails, verification_key::ContractVKShare, +}; +#[cfg(feature = "nymd-client")] +use coconut_interface::Base58; +#[cfg(feature = "nymd-client")] use cw3::ProposalResponse; #[cfg(feature = "nymd-client")] use mixnet_contract_common::{ + families::{Family, FamilyHead}, mixnode::MixNodeBond, pending_events::{PendingEpochEvent, PendingIntervalEvent}, - Delegation, RewardedSetNodeStatus, UnbondedMixnode, + Delegation, IdentityKey, RewardedSetNodeStatus, UnbondedMixnode, }; #[cfg(feature = "nymd-client")] use network_defaults::NymNetworkDetails; +#[cfg(feature = "nymd-client")] +use std::str::FromStr; use url::Url; #[cfg(feature = "nymd-client")] use validator_api_requests::models::MixNodeBondAnnotated; diff --git a/common/mixnode-common/src/packet_processor/processor.rs b/common/mixnode-common/src/packet_processor/processor.rs index 918e001fec..aaadfe0171 100644 --- a/common/mixnode-common/src/packet_processor/processor.rs +++ b/common/mixnode-common/src/packet_processor/processor.rs @@ -161,7 +161,7 @@ impl SphinxPacketProcessor { ) -> Result { match packet { ProcessedPacket::ForwardHop(packet, address, delay) => { - self.process_forward_hop(packet, address, delay, packet_mode) + self.process_forward_hop(*packet, address, delay, packet_mode) } // right now there's no use for the surb_id included in the header - probably it should get removed from the // sphinx all together? diff --git a/common/nymsphinx/Cargo.toml b/common/nymsphinx/Cargo.toml index f0f24ac665..d9d81aecd4 100644 --- a/common/nymsphinx/Cargo.toml +++ b/common/nymsphinx/Cargo.toml @@ -9,6 +9,7 @@ edition = "2021" [dependencies] rand = { version = "0.7.3", features = ["wasm-bindgen"] } rand_distr = "0.3" +thiserror = "1.0.37" nymsphinx-acknowledgements = { path = "acknowledgements" } nymsphinx-addressing = { path = "addressing" } diff --git a/common/nymsphinx/acknowledgements/src/surb_ack.rs b/common/nymsphinx/acknowledgements/src/surb_ack.rs index 22bd4bc468..67e863d1f6 100644 --- a/common/nymsphinx/acknowledgements/src/surb_ack.rs +++ b/common/nymsphinx/acknowledgements/src/surb_ack.rs @@ -72,6 +72,10 @@ impl SurbAck { PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN } + pub fn expected_total_delay(&self) -> Delay { + self.expected_total_delay + } + pub fn prepare_for_sending(self) -> (Delay, Vec) { // SURB_FIRST_HOP || SURB_ACK let surb_bytes: Vec<_> = self diff --git a/common/nymsphinx/addressing/Cargo.toml b/common/nymsphinx/addressing/Cargo.toml index a67849b128..7a85486e4f 100644 --- a/common/nymsphinx/addressing/Cargo.toml +++ b/common/nymsphinx/addressing/Cargo.toml @@ -10,6 +10,7 @@ edition = "2021" crypto = { path = "../../crypto", features = ["asymmetric"] } # all addresses are expressed in terms on their crypto keys nymsphinx-types = { path = "../types" } # we need to be able to refer to some types defined inside sphinx crate serde = "1.0" # implementing serialization/deserialization for some types, like `Recipient` +thiserror = "1.0.37" [dev-dependencies] rand = "0.7" diff --git a/common/nymsphinx/addressing/src/clients.rs b/common/nymsphinx/addressing/src/clients.rs index 819f272efd..fd7235a9b7 100644 --- a/common/nymsphinx/addressing/src/clients.rs +++ b/common/nymsphinx/addressing/src/clients.rs @@ -10,6 +10,7 @@ use nymsphinx_types::Destination; use serde::de::{Error as SerdeError, Unexpected, Visitor}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::fmt::{self, Formatter}; +use thiserror::Error; // Not entirely sure whether this is the correct place for those, but let's see how it's going // to work out @@ -19,46 +20,25 @@ const CLIENT_ENCRYPTION_KEY_SIZE: usize = encryption::PUBLIC_KEY_SIZE; pub type ClientIdentity = identity::PublicKey; const CLIENT_IDENTITY_SIZE: usize = identity::PUBLIC_KEY_LENGTH; -#[derive(Debug)] +pub type RecipientBytes = [u8; Recipient::LEN]; + +#[derive(Debug, Error)] pub enum RecipientFormattingError { - MalformedRecipientError, + #[error("recipient is malformed - {reason} ")] + MalformedRecipientError { reason: String }, + + #[error("recipient's identity key is malformed: {0}")] MalformedIdentityError(identity::Ed25519RecoveryError), - MalformedEncryptionKeyError(encryption::KeyRecoveryError), + + #[error("recipient's encryption key is malformed: {0}")] + MalformedEncryptionKeyError(#[from] encryption::KeyRecoveryError), + + #[error("recipient gateway's identity key is malformed: {0}")] MalformedGatewayError(identity::Ed25519RecoveryError), } -impl fmt::Display for RecipientFormattingError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result { - match self { - RecipientFormattingError::MalformedRecipientError => { - write!(f, "recipient is malformed") - } - RecipientFormattingError::MalformedIdentityError(id_err) => { - write!(f, "recipient's identity key is malformed: {}", id_err) - } - RecipientFormattingError::MalformedEncryptionKeyError(enc_err) => { - write!(f, "recipient's encryption key is malformed: {}", enc_err) - } - RecipientFormattingError::MalformedGatewayError(id_err) => write!( - f, - "recipient gateway's identity key is malformed: {}", - id_err - ), - } - } -} - -// since we have Debug and Display might as well slap Error on top of it too -impl std::error::Error for RecipientFormattingError {} - -impl From for RecipientFormattingError { - fn from(err: encryption::KeyRecoveryError) -> Self { - RecipientFormattingError::MalformedEncryptionKeyError(err) - } -} - // TODO: this should a different home... somewhere, but where? -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct Recipient { client_identity: ClientIdentity, client_encryption_key: ClientEncryptionKey, @@ -154,7 +134,7 @@ impl Recipient { &self.gateway } - pub fn to_bytes(self) -> [u8; Self::LEN] { + pub fn to_bytes(self) -> RecipientBytes { let mut out = [0u8; Self::LEN]; out[..CLIENT_IDENTITY_SIZE].copy_from_slice(&self.client_identity.to_bytes()); out[CLIENT_IDENTITY_SIZE..CLIENT_IDENTITY_SIZE + CLIENT_ENCRYPTION_KEY_SIZE] @@ -165,7 +145,7 @@ impl Recipient { out } - pub fn try_from_bytes(bytes: [u8; Self::LEN]) -> Result { + pub fn try_from_bytes(bytes: RecipientBytes) -> Result { let identity_bytes = &bytes[..CLIENT_IDENTITY_SIZE]; let enc_key_bytes = &bytes[CLIENT_IDENTITY_SIZE..CLIENT_IDENTITY_SIZE + CLIENT_ENCRYPTION_KEY_SIZE]; @@ -196,14 +176,20 @@ impl Recipient { let string_address = full_address.into(); let split: Vec<_> = string_address.split('@').collect(); if split.len() != 2 { - return Err(RecipientFormattingError::MalformedRecipientError); + return Err(RecipientFormattingError::MalformedRecipientError { + reason: "the string address does not contain exactly a single '@' character" + .to_string(), + }); } let client_half = split[0]; let gateway_half = split[1]; let split_client: Vec<_> = client_half.split('.').collect(); if split_client.len() != 2 { - return Err(RecipientFormattingError::MalformedRecipientError); + return Err(RecipientFormattingError::MalformedRecipientError { + reason: "the string address does not contain exactly a single '.' character" + .to_string(), + }); } let client_identity = match ClientIdentity::from_base58_string(split_client[0]) { diff --git a/common/nymsphinx/addressing/src/nodes.rs b/common/nymsphinx/addressing/src/nodes.rs index a01f7202bd..cf43625c5a 100644 --- a/common/nymsphinx/addressing/src/nodes.rs +++ b/common/nymsphinx/addressing/src/nodes.rs @@ -5,6 +5,7 @@ use crypto::asymmetric::identity; use nymsphinx_types::{NodeAddressBytes, NODE_ADDRESS_LENGTH}; use std::convert::{TryFrom, TryInto}; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; +use thiserror::Error; // Not entirely sure whether this is the correct place for those, but let's see how it's going // to work out @@ -20,10 +21,23 @@ pub const NODE_IDENTITY_SIZE: usize = identity::PUBLIC_KEY_LENGTH; /// In this case it's an ipv6 socket address (with version prefix) pub const MAX_NODE_ADDRESS_UNPADDED_LEN: usize = 19; -#[derive(Debug)] +#[derive(Debug, Error)] pub enum NymNodeRoutingAddressError { - InsufficientNumberOfBytesAvailableError, - InvalidIpVersion, + #[error("Attempted to deserialize NymNodeRoutingAddress without providing any bytes")] + NoBytesProvided, + + #[error("Provided insufficient amount of few bytes to deserialize a valid NymNodeRoutingAddress for IPv{protocol_version} variant. Received {received} and required {required}")] + TooFewBytesProvided { + protocol_version: u8, + received: usize, + required: usize, + }, + + #[error("{received} is not a valid version of the Internet Protocol (IP). Expected either '4' or '6'")] + InvalidIpVersion { received: u8 }, + + #[error("Could not serialize NymNodeRoutingAddress into NodeAddressBytes as that requires using at least {required} bytes and only {NODE_ADDRESS_LENGTH} are available")] + TooSmallBytesRepresentation { required: usize }, } /// Current representation of Node routing information used in Nym system. @@ -84,28 +98,39 @@ impl NymNodeRoutingAddress { /// Tries to recover `Self` from a bytes slice. /// Does not care if it's zero-padded or not. pub fn try_from_bytes(b: &[u8]) -> Result { - // the bare minimum to represent `Self` is 7 bytes (for the shorter V4 version) - if b.len() < 7 { - return Err(NymNodeRoutingAddressError::InsufficientNumberOfBytesAvailableError); + if b.is_empty() { + return Err(NymNodeRoutingAddressError::NoBytesProvided); } let ip_version = b[0]; - let port: u16 = u16::from_be_bytes([b[1], b[2]]); let ip = match ip_version { - 4 => IpAddr::V4(Ipv4Addr::new(b[3], b[4], b[5], b[6])), + 4 => { + if b.len() < 7 { + return Err(NymNodeRoutingAddressError::TooFewBytesProvided { + protocol_version: 4, + received: b.len(), + required: 7, + }); + } + IpAddr::V4(Ipv4Addr::new(b[3], b[4], b[5], b[6])) + } 6 => { if b.len() < 19 { - return Err( - NymNodeRoutingAddressError::InsufficientNumberOfBytesAvailableError, - ); + return Err(NymNodeRoutingAddressError::TooFewBytesProvided { + protocol_version: 6, + received: b.len(), + required: 19, + }); } let mut address_octets = [0u8; 16]; address_octets.copy_from_slice(&b[3..19]); IpAddr::V6(Ipv6Addr::from(address_octets)) } - _ => return Err(NymNodeRoutingAddressError::InvalidIpVersion), + v => return Err(NymNodeRoutingAddressError::InvalidIpVersion { received: v }), }; + let port: u16 = u16::from_be_bytes([b[1], b[2]]); + Ok(Self(SocketAddr::new(ip, port))) } @@ -148,7 +173,9 @@ impl TryInto for NymNodeRoutingAddress { fn try_into(self) -> Result { // first check if we have enough bytes to represent `self`: if self.bytes_min_len() > NODE_ADDRESS_LENGTH { - return Err(NymNodeRoutingAddressError::InsufficientNumberOfBytesAvailableError); + return Err(NymNodeRoutingAddressError::TooSmallBytesRepresentation { + required: self.bytes_min_len(), + }); } let padded_address = self.as_zero_padded_bytes(NODE_ADDRESS_LENGTH); diff --git a/common/nymsphinx/anonymous-replies/Cargo.toml b/common/nymsphinx/anonymous-replies/Cargo.toml index 246f6de509..5ddb069e19 100644 --- a/common/nymsphinx/anonymous-replies/Cargo.toml +++ b/common/nymsphinx/anonymous-replies/Cargo.toml @@ -7,12 +7,16 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -rand = {version = "0.7.3", features = ["wasm-bindgen"]} +rand = { version = "0.7.3", features = ["wasm-bindgen"] } bs58 = "0.4" serde = "1.0" +thiserror = "1" crypto = { path = "../../crypto" } nymsphinx-addressing = { path = "../addressing" } nymsphinx-params = { path = "../params" } nymsphinx-types = { path = "../types" } topology = { path = "../../topology" } + +[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-bindgen] +version = "0.2.83" \ No newline at end of file diff --git a/common/nymsphinx/anonymous-replies/src/encryption_key.rs b/common/nymsphinx/anonymous-replies/src/encryption_key.rs index b52b8cea60..7a6689f4a7 100644 --- a/common/nymsphinx/anonymous-replies/src/encryption_key.rs +++ b/common/nymsphinx/anonymous-replies/src/encryption_key.rs @@ -16,7 +16,7 @@ pub type EncryptionKeyDigest = pub type SurbEncryptionKeySize = ::KeySize; -#[derive(Clone, Debug)] +#[derive(Clone, Copy, Debug)] pub struct SurbEncryptionKey(CipherKey); #[derive(Debug)] diff --git a/common/nymsphinx/anonymous-replies/src/lib.rs b/common/nymsphinx/anonymous-replies/src/lib.rs index ce93c4099b..3e48d0ea1b 100644 --- a/common/nymsphinx/anonymous-replies/src/lib.rs +++ b/common/nymsphinx/anonymous-replies/src/lib.rs @@ -3,6 +3,7 @@ pub mod encryption_key; pub mod reply_surb; +pub mod requests; pub use encryption_key::{SurbEncryptionKey, SurbEncryptionKeySize}; pub use reply_surb::{ReplySurb, ReplySurbError}; diff --git a/common/nymsphinx/anonymous-replies/src/reply_surb.rs b/common/nymsphinx/anonymous-replies/src/reply_surb.rs index b8b8ec04cf..1fb29b2910 100644 --- a/common/nymsphinx/anonymous-replies/src/reply_surb.rs +++ b/common/nymsphinx/anonymous-replies/src/reply_surb.rs @@ -1,4 +1,4 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use crate::encryption_key::{SurbEncryptionKey, SurbEncryptionKeyError, SurbEncryptionKeySize}; @@ -14,44 +14,22 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::convert::TryFrom; use std::fmt::{self, Formatter}; use std::time; +use thiserror::Error; use topology::{NymTopology, NymTopologyError}; -#[derive(Debug)] +#[derive(Debug, Error)] pub enum ReplySurbError { + #[error("tried to use reply SURB with an unpadded message")] UnpaddedMessageError, - MalformedStringError(bs58::decode::Error), - RecoveryError(SphinxError), - InvalidEncryptionKeyData(SurbEncryptionKeyError), -} -impl fmt::Display for ReplySurbError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result { - match self { - ReplySurbError::UnpaddedMessageError => { - write!(f, "tried to use reply SURB with an unpadded message") - } - ReplySurbError::MalformedStringError(decode_err) => { - write!(f, "reply SURB is incorrectly formatted: {}", decode_err) - } - ReplySurbError::RecoveryError(sphinx_err) => { - write!(f, "failed to recover reply SURB from bytes: {}", sphinx_err) - } - ReplySurbError::InvalidEncryptionKeyData(surb_key_err) => write!( - f, - "failed to recover reply SURB encryption key from bytes: {}", - surb_key_err - ), - } - } -} + #[error("reply SURB is incorrectly formatted: {0}")] + MalformedStringError(#[from] bs58::decode::Error), -// since we have Debug and Display might as well slap Error on top of it too -impl std::error::Error for ReplySurbError {} + #[error("failed to recover reply SURB from bytes: {0}")] + RecoveryError(#[from] SphinxError), -impl From for ReplySurbError { - fn from(err: SurbEncryptionKeyError) -> Self { - ReplySurbError::InvalidEncryptionKeyData(err) - } + #[error("failed to recover reply SURB encryption key from bytes: {0}")] + InvalidEncryptionKeyData(#[from] SurbEncryptionKeyError), } #[derive(Debug)] @@ -157,6 +135,8 @@ impl ReplySurb { } pub fn from_bytes(bytes: &[u8]) -> Result { + // TODO: introduce bound checks to guard us against out of bound reads + let encryption_key = SurbEncryptionKey::try_from_bytes(&bytes[..SurbEncryptionKeySize::USIZE])?; @@ -189,21 +169,22 @@ impl ReplySurb { // - surb-ack // - key digest // - encrypted plaintext with padding to constant length - pub fn apply_surb( + pub fn apply_surb>( self, - message: &[u8], + message: M, packet_size: Option, ) -> Result<(SphinxPacket, NymNodeRoutingAddress), ReplySurbError> { let packet_size = packet_size.unwrap_or_default(); - if message.len() != packet_size.plaintext_size() { + let message_bytes = message.as_ref(); + if message_bytes.len() != packet_size.plaintext_size() { return Err(ReplySurbError::UnpaddedMessageError); } // this can realistically only fail on too long messages and we just checked for that let (packet, first_hop) = self .surb - .use_surb(message, packet_size.payload_size()) + .use_surb(message_bytes, packet_size.payload_size()) .expect("this error indicates inconsistent message length checking - it shouldn't have happened!"); let first_hop_address = NymNodeRoutingAddress::try_from(first_hop).unwrap(); diff --git a/common/nymsphinx/anonymous-replies/src/requests.rs b/common/nymsphinx/anonymous-replies/src/requests.rs new file mode 100644 index 0000000000..686f65aa79 --- /dev/null +++ b/common/nymsphinx/anonymous-replies/src/requests.rs @@ -0,0 +1,476 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::{ReplySurb, ReplySurbError}; +use nymsphinx_addressing::clients::{Recipient, RecipientFormattingError}; +use rand::{CryptoRng, RngCore}; +use std::fmt::{Display, Formatter}; +use std::mem; +use thiserror::Error; + +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; + +pub const SENDER_TAG_SIZE: usize = 16; + +#[derive(Debug, Error)] +pub enum InvalidAnonymousSenderTagRepresentation { + #[error("Failed to decode the base58-encoded string - {0}")] + MalformedString(#[from] bs58::decode::Error), + + #[error( + "Decoded AnonymousSenderTag has invalid length. Expected {expected}, but got {received}" + )] + InvalidLength { received: usize, expected: usize }, +} + +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] +pub struct AnonymousSenderTag([u8; SENDER_TAG_SIZE]); + +impl From<[u8; SENDER_TAG_SIZE]> for AnonymousSenderTag { + fn from(bytes: [u8; SENDER_TAG_SIZE]) -> Self { + AnonymousSenderTag(bytes) + } +} + +impl Display for AnonymousSenderTag { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.to_base58_string()) + } +} + +impl AnonymousSenderTag { + pub fn new_random(rng: &mut R) -> Self { + let mut bytes = [0u8; SENDER_TAG_SIZE]; + rng.fill_bytes(&mut bytes); + AnonymousSenderTag(bytes) + } + + pub fn to_bytes(&self) -> [u8; SENDER_TAG_SIZE] { + self.0 + } + + pub fn from_bytes(bytes: [u8; SENDER_TAG_SIZE]) -> Self { + AnonymousSenderTag(bytes) + } + + pub fn to_base58_string(self) -> String { + bs58::encode(self.to_bytes()).into_string() + } + + pub fn try_from_base58_string>( + val: I, + ) -> Result { + let bytes = bs58::decode(val).into_vec()?; + if bytes.len() != SENDER_TAG_SIZE { + return Err(InvalidAnonymousSenderTagRepresentation::InvalidLength { + received: bytes.len(), + expected: SENDER_TAG_SIZE, + }); + } + + // the unwrap here is fine as we just asserted the bytes are of exactly SENDER_TAG_SIZE length + let byte_array: [u8; SENDER_TAG_SIZE] = bytes.try_into().unwrap(); + Ok(AnonymousSenderTag::from_bytes(byte_array)) + } +} + +#[derive(Debug, Error)] +pub enum InvalidReplyRequestError { + #[error("Did not provide sufficient number of bytes to deserialize a valid request")] + RequestTooShortToDeserialize, + + #[error("{received} is not a valid content tag for a repliable message")] + InvalidRepliableContentTag { received: u8 }, + + #[error("{received} is not a valid content tag for a reply message")] + InvalidReplyContentTag { received: u8 }, + + #[error("failed to deserialize recipient information - {0}")] + MalformedRecipient(#[from] RecipientFormattingError), + + #[error("failed to deserialize replySURB - {0}")] + MalformedReplySurb(#[from] ReplySurbError), +} + +#[derive(Debug)] +pub struct RepliableMessage { + pub sender_tag: AnonymousSenderTag, + pub content: RepliableMessageContent, +} + +impl Display for RepliableMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match &self.content { + RepliableMessageContent::Data { + message, + reply_surbs, + } => write!( + f, + "repliable {:.2} kiB data message with {} reply surbs attached from {}", + message.len() as f64 / 1024.0, + reply_surbs.len(), + self.sender_tag, + ), + RepliableMessageContent::AdditionalSurbs { reply_surbs } => write!( + f, + "repliable additional surbs message ({} reply surbs attached) from {}", + reply_surbs.len(), + self.sender_tag, + ), + RepliableMessageContent::Heartbeat { + additional_reply_surbs, + } => { + write!( + f, + "repliable heartbeat message ({} reply surbs attached) from {}", + additional_reply_surbs.len(), + self.sender_tag, + ) + } + } + } +} + +impl RepliableMessage { + pub fn new_data( + data: Vec, + sender_tag: AnonymousSenderTag, + reply_surbs: Vec, + ) -> Self { + RepliableMessage { + sender_tag, + content: RepliableMessageContent::Data { + message: data, + reply_surbs, + }, + } + } + + pub fn new_additional_surbs( + sender_tag: AnonymousSenderTag, + reply_surbs: Vec, + ) -> Self { + RepliableMessage { + sender_tag, + content: RepliableMessageContent::AdditionalSurbs { reply_surbs }, + } + } + + pub fn into_bytes(self) -> Vec { + let content_tag = self.content.tag(); + + self.sender_tag + .to_bytes() + .into_iter() + .chain(std::iter::once(content_tag as u8)) + .chain(self.content.into_bytes()) + .collect() + } + + pub fn try_from_bytes( + bytes: &[u8], + num_mix_hops: u8, + ) -> Result { + if bytes.len() < SENDER_TAG_SIZE + 1 { + return Err(InvalidReplyRequestError::RequestTooShortToDeserialize); + } + let sender_tag = + AnonymousSenderTag::from_bytes(bytes[..SENDER_TAG_SIZE].try_into().unwrap()); + let content_tag = RepliableMessageContentTag::try_from(bytes[SENDER_TAG_SIZE])?; + + let content = RepliableMessageContent::try_from_bytes( + &bytes[SENDER_TAG_SIZE + 1..], + num_mix_hops, + content_tag, + )?; + + Ok(RepliableMessage { + sender_tag, + content, + }) + } +} + +// this recovery code is shared between all variants containing reply surbs +fn recover_reply_surbs( + bytes: &[u8], + num_mix_hops: u8, +) -> Result<(Vec, usize), InvalidReplyRequestError> { + let mut consumed = mem::size_of::(); + if bytes.len() < consumed { + return Err(InvalidReplyRequestError::RequestTooShortToDeserialize); + } + let num_surbs = u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]); + let surb_size = ReplySurb::serialized_len(num_mix_hops); + if bytes[consumed..].len() < num_surbs as usize * surb_size { + return Err(InvalidReplyRequestError::RequestTooShortToDeserialize); + } + + let mut reply_surbs = Vec::with_capacity(num_surbs as usize); + for _ in 0..num_surbs as usize { + let surb_bytes = &bytes[consumed..consumed + surb_size]; + let reply_surb = ReplySurb::from_bytes(surb_bytes)?; + reply_surbs.push(reply_surb); + + consumed += surb_size; + } + + Ok((reply_surbs, consumed)) +} + +#[repr(u8)] +enum RepliableMessageContentTag { + Data = 0, + AdditionalSurbs = 1, + Heartbeat = 2, +} + +impl TryFrom for RepliableMessageContentTag { + type Error = InvalidReplyRequestError; + + fn try_from(value: u8) -> Result { + match value { + _ if value == (RepliableMessageContentTag::Data as u8) => Ok(Self::Data), + _ if value == (RepliableMessageContentTag::AdditionalSurbs as u8) => { + Ok(Self::AdditionalSurbs) + } + _ if value == (RepliableMessageContentTag::Heartbeat as u8) => Ok(Self::Heartbeat), + val => Err(InvalidReplyRequestError::InvalidRepliableContentTag { received: val }), + } + } +} + +// sent by original sender that initialised the communication that knows address of the remote +#[derive(Debug)] +pub enum RepliableMessageContent { + Data { + message: Vec, + reply_surbs: Vec, + }, + AdditionalSurbs { + reply_surbs: Vec, + }, + Heartbeat { + additional_reply_surbs: Vec, + }, +} + +impl RepliableMessageContent { + pub fn into_bytes(self) -> Vec { + match self { + RepliableMessageContent::Data { + message, + reply_surbs, + } => { + let num_surbs = reply_surbs.len() as u32; + + num_surbs + .to_be_bytes() + .into_iter() + .chain(reply_surbs.into_iter().flat_map(|s| s.to_bytes())) + .chain(message.into_iter()) + .collect() + } + RepliableMessageContent::AdditionalSurbs { reply_surbs } => { + let num_surbs = reply_surbs.len() as u32; + + num_surbs + .to_be_bytes() + .into_iter() + .chain(reply_surbs.into_iter().flat_map(|s| s.to_bytes())) + .collect() + } + RepliableMessageContent::Heartbeat { + additional_reply_surbs, + } => { + let num_surbs = additional_reply_surbs.len() as u32; + + num_surbs + .to_be_bytes() + .into_iter() + .chain( + additional_reply_surbs + .into_iter() + .flat_map(|s| s.to_bytes()), + ) + .collect() + } + } + } + + fn try_from_bytes( + bytes: &[u8], + num_mix_hops: u8, + tag: RepliableMessageContentTag, + ) -> Result { + if bytes.is_empty() { + return Err(InvalidReplyRequestError::RequestTooShortToDeserialize); + } + + let (reply_surbs, n) = recover_reply_surbs(bytes, num_mix_hops)?; + + match tag { + RepliableMessageContentTag::Data => Ok(RepliableMessageContent::Data { + message: bytes[n..].to_vec(), + reply_surbs, + }), + RepliableMessageContentTag::AdditionalSurbs => { + Ok(RepliableMessageContent::AdditionalSurbs { reply_surbs }) + } + RepliableMessageContentTag::Heartbeat => Ok(RepliableMessageContent::Heartbeat { + additional_reply_surbs: reply_surbs, + }), + } + } + + fn tag(&self) -> RepliableMessageContentTag { + match self { + RepliableMessageContent::Data { .. } => RepliableMessageContentTag::Data, + RepliableMessageContent::AdditionalSurbs { .. } => { + RepliableMessageContentTag::AdditionalSurbs + } + RepliableMessageContent::Heartbeat { .. } => RepliableMessageContentTag::Heartbeat, + } + } +} + +// sent by the remote party who does **NOT** know the original sender's identity +#[derive(Debug)] +pub struct ReplyMessage { + pub content: ReplyMessageContent, +} + +impl Display for ReplyMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match &self.content { + ReplyMessageContent::Data { message } => write!( + f, + "{:.2} kiB reply data message", + message.len() as f64 / 1024.0 + ), + ReplyMessageContent::SurbRequest { recipient, amount } => write!( + f, + "request for {amount} additional reply SURBs from {recipient}", + ), + } + } +} + +impl ReplyMessage { + pub fn new_data_message(message: Vec) -> Self { + ReplyMessage { + content: ReplyMessageContent::Data { message }, + } + } + + pub fn new_surb_request_message(recipient: Recipient, amount: u32) -> Self { + ReplyMessage { + content: ReplyMessageContent::SurbRequest { + recipient: Box::new(recipient), + amount, + }, + } + } + + pub fn into_bytes(self) -> Vec { + let content_tag = self.content.tag(); + + std::iter::once(content_tag as u8) + .chain(self.content.into_bytes()) + .collect() + } + + pub fn try_from_bytes(bytes: &[u8]) -> Result { + if bytes.is_empty() { + return Err(InvalidReplyRequestError::RequestTooShortToDeserialize); + } + let tag = ReplyMessageContentTag::try_from(bytes[0])?; + let content = ReplyMessageContent::try_from_bytes(&bytes[1..], tag)?; + + Ok(ReplyMessage { content }) + } +} + +#[repr(u8)] +enum ReplyMessageContentTag { + Data = 0, + SurbRequest = 1, +} + +impl TryFrom for ReplyMessageContentTag { + type Error = InvalidReplyRequestError; + + fn try_from(value: u8) -> Result { + match value { + _ if value == (ReplyMessageContentTag::Data as u8) => Ok(Self::Data), + _ if value == (ReplyMessageContentTag::SurbRequest as u8) => Ok(Self::SurbRequest), + val => Err(InvalidReplyRequestError::InvalidReplyContentTag { received: val }), + } + } +} + +#[derive(Debug)] +pub enum ReplyMessageContent { + // TODO: later allow to request surbs whilst sending data + Data { + message: Vec, + }, + SurbRequest { + recipient: Box, + amount: u32, + }, +} + +impl ReplyMessageContent { + pub fn into_bytes(self) -> Vec { + match self { + ReplyMessageContent::Data { message } => message, + ReplyMessageContent::SurbRequest { recipient, amount } => recipient + .to_bytes() + .into_iter() + .chain(amount.to_be_bytes().into_iter()) + .collect(), + } + } + + fn try_from_bytes( + bytes: &[u8], + tag: ReplyMessageContentTag, + ) -> Result { + if bytes.is_empty() { + return Err(InvalidReplyRequestError::RequestTooShortToDeserialize); + } + + match tag { + ReplyMessageContentTag::Data => Ok(ReplyMessageContent::Data { + message: bytes.to_vec(), + }), + ReplyMessageContentTag::SurbRequest => { + if bytes.len() != Recipient::LEN + std::mem::size_of::() { + return Err(InvalidReplyRequestError::RequestTooShortToDeserialize); + } + let mut recipient_bytes = [0u8; Recipient::LEN]; + recipient_bytes.copy_from_slice(&bytes[..Recipient::LEN]); + + Ok(ReplyMessageContent::SurbRequest { + recipient: Box::new(Recipient::try_from_bytes(recipient_bytes)?), + amount: u32::from_be_bytes([ + bytes[Recipient::LEN], + bytes[Recipient::LEN + 1], + bytes[Recipient::LEN + 2], + bytes[Recipient::LEN + 3], + ]), + }) + } + } + } + + fn tag(&self) -> ReplyMessageContentTag { + match self { + ReplyMessageContent::Data { .. } => ReplyMessageContentTag::Data, + ReplyMessageContent::SurbRequest { .. } => ReplyMessageContentTag::SurbRequest, + } + } +} diff --git a/common/nymsphinx/chunking/Cargo.toml b/common/nymsphinx/chunking/Cargo.toml index 5f47ab5358..3d6bacab61 100644 --- a/common/nymsphinx/chunking/Cargo.toml +++ b/common/nymsphinx/chunking/Cargo.toml @@ -9,6 +9,7 @@ edition = "2021" [dependencies] log = "0.4.8" rand = { version = "0.7.3", features = ["wasm-bindgen"] } +thiserror = "1.0.37" nymsphinx-addressing = { path = "../addressing" } nymsphinx-params = { path = "../params" } diff --git a/common/nymsphinx/chunking/src/fragment.rs b/common/nymsphinx/chunking/src/fragment.rs index 58c1baa78a..3f102282dd 100644 --- a/common/nymsphinx/chunking/src/fragment.rs +++ b/common/nymsphinx/chunking/src/fragment.rs @@ -1,12 +1,10 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::set::generate_set_id; use crate::ChunkingError; use nymsphinx_params::{SerializedFragmentIdentifier, FRAG_ID_LEN}; -use rand::Rng; use std::convert::TryInto; -use std::fmt::{self, Formatter}; +use std::fmt::{self, Debug, Formatter}; // Personal reflection: In hindsight I've spent too much time on relatively too little // gain here, as even though I might have saved couple of bytes per packet, the gain @@ -60,7 +58,7 @@ pub const COVER_FRAG_ID: FragmentIdentifier = FragmentIdentifier { /// and u8 position of the `Fragment` in the set. // TODO: this should really be redesigned, especially how cover and reply messages are really // "abusing" this. They should work with it natively instead. -#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] +#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd)] pub struct FragmentIdentifier { set_id: i32, fragment_position: u8, @@ -77,20 +75,6 @@ impl fmt::Display for FragmentIdentifier { } impl FragmentIdentifier { - // I really dislike how 'hacky' this function seems - // refer to: https://github.com/nymtech/nym/issues/294 for further discussion - pub fn new_reply(rng: &mut R) -> Self { - FragmentIdentifier { - set_id: generate_set_id(rng), - fragment_position: 0, - } - } - - // and this one - pub fn is_reply(self) -> bool { - self.set_id > 0 && self.fragment_position == 0 - } - pub fn to_bytes(self) -> SerializedFragmentIdentifier { debug_assert_eq!(FRAG_ID_LEN, 5); @@ -110,7 +94,7 @@ impl FragmentIdentifier { let set_id = i32::from_be_bytes([b[0], b[1], b[2], b[3]]); // set_id == 0 is valid for COVER_FRAG_ID and replies if set_id < 0 { - return Err(ChunkingError::MalformedFragmentIdentifier); + return Err(ChunkingError::MalformedFragmentIdentifier { received: set_id }); } Ok(FragmentIdentifier { @@ -124,12 +108,22 @@ impl FragmentIdentifier { /// Each `Fragment` after being marshaled is guaranteed to fit into a single sphinx packet. /// The `Fragment` itself consists of part, or whole of, message to be sent as well as additional /// header used to reconstruct the message after being received. -#[derive(PartialEq, Clone, Debug)] +#[derive(PartialEq, Clone)] pub struct Fragment { header: FragmentHeader, payload: Vec, } +// manual implementation to hide detailed payload that we don't care about +impl Debug for Fragment { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.debug_struct("Fragment") + .field("header", &self.header) + .field("payload length", &self.payload.len()) + .finish() + } +} + impl Fragment { /// Tries to encapsulate provided payload slice and metadata into a `Fragment`. /// It can fail if payload would not fully fit in a single `Fragment` or some of the metadata @@ -153,24 +147,42 @@ impl Fragment { // check for whether payload has expected length, which depend on whether fragment is linked // and if it's the only one or the last one in the set (then lower bound is removed) + let max_linked_len = linked_fragment_payload_max_len(max_plaintext_size); + let max_unlinked_len = unlinked_fragment_payload_max_len(max_plaintext_size); + if previous_fragments_set_id.is_some() { if total_fragments > 1 { - if payload.len() != linked_fragment_payload_max_len(max_plaintext_size) { - return Err(ChunkingError::InvalidPayloadLengthError); + if payload.len() != max_linked_len { + return Err(ChunkingError::InvalidPayloadLengthError { + received: payload.len(), + expected: max_linked_len, + }); } - } else if payload.len() > linked_fragment_payload_max_len(max_plaintext_size) { - return Err(ChunkingError::InvalidPayloadLengthError); + } else if payload.len() > max_linked_len { + return Err(ChunkingError::TooLongPayloadLengthError { + received: payload.len(), + expected_at_most: max_linked_len, + }); } } else if next_fragments_set_id.is_some() { - if payload.len() != linked_fragment_payload_max_len(max_plaintext_size) { - return Err(ChunkingError::InvalidPayloadLengthError); + if payload.len() != max_linked_len { + return Err(ChunkingError::InvalidPayloadLengthError { + received: payload.len(), + expected: max_linked_len, + }); } } else if total_fragments != current_fragment { - if payload.len() != unlinked_fragment_payload_max_len(max_plaintext_size) { - return Err(ChunkingError::InvalidPayloadLengthError); + if payload.len() != max_unlinked_len { + return Err(ChunkingError::InvalidPayloadLengthError { + received: payload.len(), + expected: max_unlinked_len, + }); } - } else if payload.len() > unlinked_fragment_payload_max_len(max_plaintext_size) { - return Err(ChunkingError::InvalidPayloadLengthError); + } else if payload.len() > max_unlinked_len { + return Err(ChunkingError::TooLongPayloadLengthError { + received: payload.len(), + expected_at_most: max_unlinked_len, + }); } Ok(Fragment { @@ -347,7 +359,10 @@ impl FragmentHeader { fn try_from_bytes(b: &[u8]) -> Result<(Self, usize), ChunkingError> { // header needs to be at least 7 bytes long if b.len() < UNLINKED_FRAGMENTED_HEADER_LEN { - return Err(ChunkingError::TooShortFragmentData); + return Err(ChunkingError::TooShortFragmentHeader { + received: b.len(), + expected: UNLINKED_FRAGMENTED_HEADER_LEN, + }); } let frag_id = i32::from_be_bytes(b[0..4].try_into().unwrap()); // sanity check for the fragmentation flag @@ -370,7 +385,10 @@ impl FragmentHeader { let read_bytes = if b[6] != 0 { // there's linking ID supposedly attached, make sure we have enough bytes to parse if b.len() < LINKED_FRAGMENTED_HEADER_LEN { - return Err(ChunkingError::TooShortFragmentData); + return Err(ChunkingError::TooShortFragmentHeader { + received: b.len(), + expected: LINKED_FRAGMENTED_HEADER_LEN, + }); } let flagged_linked_id = i32::from_be_bytes(b[6..10].try_into().unwrap()); diff --git a/common/nymsphinx/chunking/src/lib.rs b/common/nymsphinx/chunking/src/lib.rs index 62a246955b..60316edb15 100644 --- a/common/nymsphinx/chunking/src/lib.rs +++ b/common/nymsphinx/chunking/src/lib.rs @@ -3,6 +3,7 @@ use crate::fragment::{linked_fragment_payload_max_len, unlinked_fragment_payload_max_len}; pub use set::split_into_sets; +use thiserror::Error; // Future consideration: currently in a lot of places, the payloads have randomised content // which is not a perfect testing strategy as it might not detect some edge cases I never would @@ -45,18 +46,26 @@ pub mod set; /// Both of those concepts as well as their structures, i.e. `Set` and `Fragment` /// are further explained in the respective files. -#[derive(PartialEq, Eq, Debug)] +#[derive(PartialEq, Eq, Debug, Error)] pub enum ChunkingError { - InvalidPayloadLengthError, - TooBigMessageToSplit, + #[error("Received payload is too long. Got {received}, expected {expected}")] + InvalidPayloadLengthError { received: usize, expected: usize }, + + #[error("Received payload is too long. Got {received}, expected at most {expected_at_most}")] + TooLongPayloadLengthError { + received: usize, + expected_at_most: usize, + }, + + // this should really be split into multiple variants to provide better error information + #[error("Provided header was malformed or contained self-contradicting fields")] MalformedHeaderError, - NoValidProvidersError, - NoValidRoutesAvailableError, - InvalidTopologyError, - TooShortFragmentData, - MalformedFragmentData, - UnexpectedFragmentCount, - MalformedFragmentIdentifier, + + #[error("Received too few bytes to deserialize fragment header. Got {received}, expected {expected}")] + TooShortFragmentHeader { received: usize, expected: usize }, + + #[error("Received fragment identifier ({received}) is not a valid value!")] + MalformedFragmentIdentifier { received: i32 }, } /// Returns number of fragments the message will be split to as well as number of available @@ -94,7 +103,7 @@ pub fn number_of_required_fragments( // we know for sure that all fragments in all but last set are definitely full // (last one has single 'linked' fragment) - let without_last = (n - 1) * (u8::max_value() as usize); + let without_last = (n - 1) * (u8::MAX as usize); let linked_fragments_without_last = (2 * n - 2) - 1; let unlinked_fragments_without_last = without_last - linked_fragments_without_last; diff --git a/common/nymsphinx/cover/Cargo.toml b/common/nymsphinx/cover/Cargo.toml index 6fd629ade7..064ebf1298 100644 --- a/common/nymsphinx/cover/Cargo.toml +++ b/common/nymsphinx/cover/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" [dependencies] rand = { version = "0.7.3", features = ["wasm-bindgen"] } +thiserror = "1.0.37" crypto = { path = "../../crypto" } nymsphinx-acknowledgements = { path = "../acknowledgements" } diff --git a/common/nymsphinx/cover/src/lib.rs b/common/nymsphinx/cover/src/lib.rs index aaaff5a9b5..2ce9454d5c 100644 --- a/common/nymsphinx/cover/src/lib.rs +++ b/common/nymsphinx/cover/src/lib.rs @@ -6,7 +6,7 @@ use crypto::symmetric::stream_cipher; use nymsphinx_acknowledgements::surb_ack::SurbAck; use nymsphinx_acknowledgements::AckKey; use nymsphinx_addressing::clients::Recipient; -use nymsphinx_addressing::nodes::{NymNodeRoutingAddress, NymNodeRoutingAddressError}; +use nymsphinx_addressing::nodes::NymNodeRoutingAddress; use nymsphinx_chunking::fragment::COVER_FRAG_ID; use nymsphinx_forwarding::packet::MixPacket; use nymsphinx_params::packet_sizes::PacketSize; @@ -18,35 +18,18 @@ use nymsphinx_types::{delays, Error as SphinxError}; use rand::{CryptoRng, RngCore}; use std::convert::TryFrom; use std::time; +use thiserror::Error; use topology::{NymTopology, NymTopologyError}; pub const LOOP_COVER_MESSAGE_PAYLOAD: &[u8] = b"The cake is a lie!"; -#[derive(Debug)] +#[derive(Debug, Error)] pub enum CoverMessageError { - NoValidProvidersError, - InvalidTopologyError, - SphinxError(SphinxError), - InvalidFirstMixAddress, -} + #[error("Could not construct cover message due to invalid topology - {0}")] + InvalidTopologyError(#[from] NymTopologyError), -impl From for CoverMessageError { - fn from(err: SphinxError) -> Self { - CoverMessageError::SphinxError(err) - } -} - -impl From for CoverMessageError { - fn from(_: NymNodeRoutingAddressError) -> Self { - use CoverMessageError::*; - InvalidFirstMixAddress - } -} - -impl From for CoverMessageError { - fn from(_: NymTopologyError) -> Self { - CoverMessageError::InvalidTopologyError - } + #[error("Could not construct a valid sphinx packet - {0}")] + SphinxError(#[from] SphinxError), } pub fn generate_loop_cover_surb_ack( diff --git a/common/nymsphinx/framing/src/codec.rs b/common/nymsphinx/framing/src/codec.rs index 53bd77c3b7..5794a88544 100644 --- a/common/nymsphinx/framing/src/codec.rs +++ b/common/nymsphinx/framing/src/codec.rs @@ -178,7 +178,7 @@ mod packet_encoding { ]; SphinxPacketBuilder::new() .with_payload_size(size.payload_size()) - .build_packet(b"foomp".to_vec(), &route, &destination, &delays) + .build_packet(b"foomp", &route, &destination, &delays) .unwrap() } diff --git a/common/nymsphinx/src/lib.rs b/common/nymsphinx/src/lib.rs index e3e7c51fac..bbc69c2682 100644 --- a/common/nymsphinx/src/lib.rs +++ b/common/nymsphinx/src/lib.rs @@ -1,6 +1,7 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +pub mod message; pub mod preparer; pub mod receiver; pub mod utils; @@ -16,3 +17,6 @@ pub use nymsphinx_forwarding as forwarding; pub use nymsphinx_framing as framing; pub use nymsphinx_params as params; pub use nymsphinx_types::*; + +// TEMP UNTIL FURTHER REFACTORING +pub use preparer::payload::NymsphinxPayloadBuilder; diff --git a/common/nymsphinx/src/message.rs b/common/nymsphinx/src/message.rs new file mode 100644 index 0000000000..f9b32daa35 --- /dev/null +++ b/common/nymsphinx/src/message.rs @@ -0,0 +1,238 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::chunking; +use crypto::asymmetric::encryption; +use crypto::Digest; +use nymsphinx_addressing::clients::Recipient; +use nymsphinx_addressing::nodes::MAX_NODE_ADDRESS_UNPADDED_LEN; +use nymsphinx_anonymous_replies::requests::{ + InvalidReplyRequestError, RepliableMessage, RepliableMessageContent, ReplyMessage, + ReplyMessageContent, +}; +use nymsphinx_chunking::fragment::Fragment; +use nymsphinx_params::{PacketSize, ReplySurbKeyDigestAlgorithm}; +use rand::Rng; +use std::fmt::{Display, Formatter}; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum NymMessageError { + #[error("{received} is not a valid type tag for a NymMessage")] + InvalidMessageType { received: u8 }, + + #[error(transparent)] + InvalidReplyRequest(#[from] InvalidReplyRequestError), + + #[error("The received message seems to have incorrect zero padding (no '1' byte found)")] + InvalidMessagePadding, + + #[error("Received empty message for deserialization")] + EmptyMessage, +} + +#[repr(u8)] +enum NymMessageType { + Plain = 0, + Repliable = 1, + Reply = 2, +} + +impl TryFrom for NymMessageType { + type Error = NymMessageError; + + fn try_from(value: u8) -> Result { + match value { + _ if value == (NymMessageType::Plain as u8) => Ok(Self::Plain), + _ if value == (NymMessageType::Repliable as u8) => Ok(Self::Repliable), + _ if value == (NymMessageType::Reply as u8) => Ok(Self::Reply), + val => Err(NymMessageError::InvalidMessageType { received: val }), + } + } +} + +pub type PlainMessage = Vec; + +#[derive(Debug)] +pub enum NymMessage { + Plain(PlainMessage), + Repliable(RepliableMessage), + Reply(ReplyMessage), +} + +impl Display for NymMessage { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + NymMessage::Plain(plain_message) => write!( + f, + "plain {:.2} kiB message", + plain_message.len() as f64 / 1024.0 + ), + NymMessage::Repliable(repliable_message) => repliable_message.fmt(f), + NymMessage::Reply(reply_message) => reply_message.fmt(f), + } + } +} + +impl NymMessage { + pub fn new_additional_surbs_request(recipient: Recipient, amount: u32) -> Self { + NymMessage::Reply(ReplyMessage { + content: ReplyMessageContent::SurbRequest { + recipient: Box::new(recipient), + amount, + }, + }) + } + + pub fn new_plain(msg: Vec) -> Self { + NymMessage::Plain(msg) + } + + pub fn new_repliable(msg: RepliableMessage) -> Self { + NymMessage::Repliable(msg) + } + + pub fn new_reply(msg: ReplyMessage) -> Self { + NymMessage::Reply(msg) + } + + pub fn is_reply_surb_request(&self) -> bool { + match self { + NymMessage::Reply(reply_msg) => { + matches!(reply_msg.content, ReplyMessageContent::SurbRequest { .. }) + } + _ => false, + } + } + + pub fn into_inner_data(self) -> Vec { + match self { + NymMessage::Plain(data) => data, + NymMessage::Repliable(repliable) => match repliable.content { + RepliableMessageContent::Data { message, .. } => message, + _ => Vec::new(), + }, + NymMessage::Reply(reply) => match reply.content { + ReplyMessageContent::Data { message } => message, + _ => Vec::new(), + }, + } + } + + fn typ(&self) -> NymMessageType { + match self { + NymMessage::Plain(_) => NymMessageType::Plain, + NymMessage::Repliable(_) => NymMessageType::Repliable, + NymMessage::Reply(_) => NymMessageType::Reply, + } + } + + fn inner_bytes(self) -> Vec { + match self { + NymMessage::Plain(msg) => msg, + NymMessage::Repliable(msg) => msg.into_bytes(), + NymMessage::Reply(msg) => msg.into_bytes(), + } + } + + // the message is in the format of: + // typ || msg + fn into_bytes(self) -> Vec { + let typ = self.typ(); + + std::iter::once(typ as u8) + .chain(self.inner_bytes()) + .collect() + } + + fn try_from_bytes(bytes: &[u8], num_mix_hops: u8) -> Result { + if bytes.is_empty() { + return Err(NymMessageError::EmptyMessage); + } + + let typ_tag = NymMessageType::try_from(bytes[0])?; + match typ_tag { + NymMessageType::Plain => Ok(NymMessage::Plain(bytes[1..].to_vec())), + NymMessageType::Repliable => Ok(NymMessage::Repliable( + RepliableMessage::try_from_bytes(&bytes[1..], num_mix_hops)?, + )), + NymMessageType::Reply => Ok(NymMessage::Reply(ReplyMessage::try_from_bytes( + &bytes[1..], + )?)), + } + } + + /// Length of plaintext (from the sphinx point of view) data that is available per sphinx + /// packet. + pub fn available_plaintext_per_packet(&self, packet_size: PacketSize) -> usize { + let ack_overhead = MAX_NODE_ADDRESS_UNPADDED_LEN + PacketSize::AckPacket.size(); + + let variant_overhead = match self { + // each plain or repliable packet attaches an ephemeral public key so that the recipient + // could perform diffie-hellman with its own keys followed by a kdf to re-derive + // the packet encryption key + NymMessage::Plain(_) | NymMessage::Repliable(_) => encryption::PUBLIC_KEY_SIZE, + // each reply attaches the digest of the encryption key so that the recipient could + // lookup correct key for decryption, + NymMessage::Reply(_) => ReplySurbKeyDigestAlgorithm::output_size(), + }; + + packet_size.plaintext_size() - ack_overhead - variant_overhead + } + + /// Pads the message so that after it gets chunked, it will occupy exactly N sphinx packets. + /// Produces new_message = message || 1 || 0000.... + pub fn pad_to_full_packet_lengths(self, plaintext_per_packet: usize) -> PaddedMessage { + let bytes = self.into_bytes(); + + // 1 is added as there will always have to be at least a single byte of padding (1) added + // to be able to later distinguish the actual padding from the underlying message + let (_, space_left) = + chunking::number_of_required_fragments(bytes.len() + 1, plaintext_per_packet); + + bytes + .into_iter() + .chain(std::iter::once(1u8)) + .chain(std::iter::repeat(0u8).take(space_left)) + .collect::>() + .into() + } +} + +pub struct PaddedMessage(Vec); + +impl PaddedMessage { + pub fn new_reconstructed(bytes: Vec) -> Self { + PaddedMessage(bytes) + } + + /// Splits the padded message into [`Fragment`] that when serialized are going to become + /// sphinx packet payloads. + pub fn split_into_fragments( + self, + rng: &mut R, + plaintext_per_packet: usize, + ) -> Vec { + chunking::split_into_sets(rng, &self.0, plaintext_per_packet) + .into_iter() + .flat_map(|fragment_set| fragment_set.into_iter()) + .collect() + } + + // reverse of NymMessage::pad_to_full_packet_lengths + pub fn remove_padding(self, num_mix_hops: u8) -> Result { + // we are looking for first occurrence of 1 in the tail and we get its index + if let Some(padding_end) = self.0.iter().rposition(|b| *b == 1) { + // and now we only take bytes until that point (but not including it) + NymMessage::try_from_bytes(&self.0[..padding_end], num_mix_hops) + } else { + Err(NymMessageError::InvalidMessagePadding) + } + } +} + +impl From> for PaddedMessage { + fn from(bytes: Vec) -> Self { + PaddedMessage(bytes) + } +} diff --git a/common/nymsphinx/src/preparer/mod.rs b/common/nymsphinx/src/preparer/mod.rs index d91a7c85a5..19f68e30bc 100644 --- a/common/nymsphinx/src/preparer/mod.rs +++ b/common/nymsphinx/src/preparer/mod.rs @@ -1,24 +1,17 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::chunking; -use crypto::asymmetric::encryption; -use crypto::shared_key::new_ephemeral_shared_key; -use crypto::symmetric::stream_cipher; -use crypto::Digest; +use crate::message::NymMessage; +use crate::NymsphinxPayloadBuilder; use nymsphinx_acknowledgements::surb_ack::SurbAck; use nymsphinx_acknowledgements::AckKey; use nymsphinx_addressing::clients::Recipient; -use nymsphinx_addressing::nodes::{NymNodeRoutingAddress, MAX_NODE_ADDRESS_UNPADDED_LEN}; -use nymsphinx_anonymous_replies::encryption_key::SurbEncryptionKey; +use nymsphinx_addressing::nodes::NymNodeRoutingAddress; use nymsphinx_anonymous_replies::reply_surb::ReplySurb; use nymsphinx_chunking::fragment::{Fragment, FragmentIdentifier}; use nymsphinx_forwarding::packet::MixPacket; use nymsphinx_params::packet_sizes::PacketSize; -use nymsphinx_params::{ - PacketEncryptionAlgorithm, PacketHkdfAlgorithm, ReplySurbEncryptionAlgorithm, - ReplySurbKeyDigestAlgorithm, DEFAULT_NUM_MIX_HOPS, -}; +use nymsphinx_params::DEFAULT_NUM_MIX_HOPS; use nymsphinx_types::builder::SphinxPacketBuilder; use nymsphinx_types::{delays, Delay}; use rand::{CryptoRng, Rng}; @@ -26,6 +19,8 @@ use std::convert::TryFrom; use std::time::Duration; use topology::{NymTopology, NymTopologyError}; +pub(crate) mod payload; + /// Represents fully packed and prepared [`Fragment`] that can be sent through the mix network. pub struct PreparedFragment { /// Indicates the total expected round-trip time, i.e. delay from the sending of this message @@ -36,27 +31,17 @@ pub struct PreparedFragment { /// address of the node to which the message should be sent, the actual 'chunk' of the message /// going through the mix network and also the 'mode' of the packet, i.e. VPN or Mix. pub mix_packet: MixPacket, -} -#[derive(Debug)] -pub enum PreparationError { - TopologyError(NymTopologyError), - TooLongReplyMessageError, -} - -impl From for PreparationError { - fn from(err: NymTopologyError) -> Self { - PreparationError::TopologyError(err) - } + /// Identifier to uniquely identify a fragment. + pub fragment_identifier: FragmentIdentifier, } /// Prepares the message that is to be sent through the mix network by attaching /// an optional reply-SURB, padding it to appropriate length, encrypting its content, /// and chunking into appropriate size [`Fragment`]s. -// #[cfg_attr(not(target_arch = "wasm32"), derive(Clone))] #[derive(Clone)] #[must_use] -pub struct MessagePreparer { +pub struct MessagePreparer { /// Instance of a cryptographically secure random number generator. rng: R, @@ -115,86 +100,70 @@ where self.sender_address = sender_address; } - /// Length of plaintext (from the sphinx point of view) data that is available per sphinx - /// packet. - fn available_plaintext_per_packet(&self) -> usize { - // we need to put first hop's destination alongside the actual ack data - // TODO: a possible optimization way down the line: currently we're always assuming that - // the addresses will have `MAX_NODE_ADDRESS_UNPADDED_LEN`, i.e. be ipv6. In most cases - // they're actually going to be ipv4 hence wasting few bytes every packet. - // To fully utilise all available space, I guess first we'd need to generate routes for ACKs - // and only then perform the chunking with `available_plaintext_size` being called per chunk. - // However this will probably introduce bunch of complexity - // for relatively not a lot of gain, so it shouldn't be done just yet. - let ack_overhead = MAX_NODE_ADDRESS_UNPADDED_LEN + PacketSize::AckPacket.size(); - let ephemeral_public_key_overhead = encryption::PUBLIC_KEY_SIZE; - - self.packet_size.plaintext_size() - ack_overhead - ephemeral_public_key_overhead - } - - /// Pads the message so that after it gets chunked, it will occupy exactly N sphinx packets. - /// Produces new_message = message || 1 || 0000.... - fn pad_message(&self, message: Vec) -> Vec { - // 1 is added as there will always have to be at least a single byte of padding (1) added - // to be able to later distinguish the actual padding from the underlying message - let (_, space_left) = chunking::number_of_required_fragments( - message.len() + 1, - self.available_plaintext_per_packet(), - ); - - message - .into_iter() - .chain(std::iter::once(1u8)) - .chain(std::iter::repeat(0u8).take(space_left)) - .collect() - } - - /// Attaches reply-SURB to the message alongside the reply key. - /// Results in: - /// new_message = 0 || message - /// OR - /// new_message = 1 || REPLY_KEY || REPLY_SURB || message - fn optionally_attach_reply_surb( + pub fn generate_reply_surbs( &mut self, - message: Vec, - should_attach: bool, + amount: usize, topology: &NymTopology, - ) -> Result<(Vec, Option), PreparationError> { - if should_attach { + ) -> Result, NymTopologyError> { + let mut reply_surbs = Vec::with_capacity(amount); + for _ in 0..amount { let reply_surb = ReplySurb::construct( &mut self.rng, &self.sender_address, self.average_packet_delay, topology, )?; - - let reply_key = reply_surb.encryption_key(); - // if there's a reply surb, the message takes form of `1 || REPLY_KEY || REPLY_SURB || MSG` - Ok(( - std::iter::once(true as u8) - .chain(reply_surb.to_bytes().iter().cloned()) - .chain(message.into_iter()) - .collect(), - Some(reply_key.clone()), - )) - } else { - // but if there's no reply surb, the message takes form of `0 || MSG` - Ok(( - std::iter::once(false as u8) - .chain(message.into_iter()) - .collect(), - None, - )) + reply_surbs.push(reply_surb) } + + Ok(reply_surbs) } - /// Splits the message into [`Fragment`] that are going to be put later put into sphinx packets. - fn split_message(&mut self, message: Vec) -> Vec { - let plaintext_per_packet = self.available_plaintext_per_packet(); - chunking::split_into_sets(&mut self.rng, &message, plaintext_per_packet) - .into_iter() - .flat_map(|fragment_set| fragment_set.into_iter()) - .collect() + /// The procedure is as follows: + /// For each fragment: + /// - compute SURB_ACK + /// - generate (x, g^x) + /// - obtain key k from the reply-surb which was computed as follows: + /// k = KDF(remote encryption key ^ x) this is equivalent to KDF( dh(remote, x) ) + /// - compute v_b = AES-128-CTR(k, serialized_fragment) + /// - compute vk_b = H(k) || v_b + /// - compute sphinx_plaintext = SURB_ACK || H(k) || v_b + /// - compute sphinx_packet by applying the reply surb on the sphinx_plaintext + pub fn prepare_reply_chunk_for_sending( + &mut self, + fragment: Fragment, + topology: &NymTopology, + ack_key: &AckKey, + reply_surb: ReplySurb, + ) -> Result { + // this is not going to be accurate by any means. but that's the best estimation we can do + let expected_forward_delay = Delay::new_from_millis( + (self.average_packet_delay.as_millis() * self.num_mix_hops as u128) as u64, + ); + + let fragment_identifier = fragment.fragment_identifier(); + + // create an ack + let surb_ack = self.generate_surb_ack(fragment_identifier, topology, ack_key)?; + let ack_delay = surb_ack.expected_total_delay(); + + let packet_payload = NymsphinxPayloadBuilder::new(fragment, surb_ack) + .build_reply(reply_surb.encryption_key()); + + // the unwrap here is fine as the failures can only originate from attempting to use invalid payload lenghts + // and we just very carefully constructed a (presumably) valid one + let (sphinx_packet, first_hop_address) = reply_surb + .apply_surb(packet_payload, Some(self.packet_size)) + .unwrap(); + + Ok(PreparedFragment { + // the round-trip delay is the sum of delays of all hops on the forward route as + // well as the total delay of the ack packet. + // we don't know the delays inside the reply surbs so we use best-effort estimation from our poisson distribution + total_delay: expected_forward_delay + ack_delay, + mix_packet: MixPacket::new(first_hop_address, sphinx_packet, Default::default()), + fragment_identifier, + }) } /// Tries to convert this [`Fragment`] into a [`SphinxPacket`] that can be sent through the Nym mix-network, @@ -221,46 +190,14 @@ where ack_key: &AckKey, packet_recipient: &Recipient, ) -> Result { + let fragment_identifier = fragment.fragment_identifier(); + // create an ack - let (ack_delay, surb_ack_bytes) = self - .generate_surb_ack(fragment.fragment_identifier(), topology, ack_key)? - .prepare_for_sending(); + let surb_ack = self.generate_surb_ack(fragment_identifier, topology, ack_key)?; + let ack_delay = surb_ack.expected_total_delay(); - // TODO: - // TODO: - // TODO: - // TODO: - // TODO: ASK @AP AND @DH WHETHER THOSE KEYS CAN/SHOULD ALSO BE REUSED IN VPN MODE!! - // TODO: - // TODO: - // TODO: - // TODO: - - // create keys for 'payload' encryption - let (ephemeral_keypair, shared_key) = - new_ephemeral_shared_key::( - &mut self.rng, - packet_recipient.encryption_key(), - ); - - // serialize fragment and encrypt its content - let mut chunk_data = fragment.into_bytes(); - - let zero_iv = stream_cipher::zero_iv::(); - stream_cipher::encrypt_in_place::( - &shared_key, - &zero_iv, - &mut chunk_data, - ); - - // combine it together as follows: - // SURB_ACK_FIRST_HOP || SURB_ACK_DATA || EPHEMERAL_KEY || CHUNK_DATA - // (note: surb_ack_bytes contains SURB_ACK_FIRST_HOP || SURB_ACK_DATA ) - let packet_payload: Vec<_> = surb_ack_bytes - .into_iter() - .chain(ephemeral_keypair.public_key().to_bytes().iter().cloned()) - .chain(chunk_data.into_iter()) - .collect(); + let packet_payload = NymsphinxPayloadBuilder::new(fragment, surb_ack) + .build_regular(&mut self.rng, packet_recipient.encryption_key()); // generate pseudorandom route for the packet let route = topology.random_route_to_gateway( @@ -290,6 +227,7 @@ where // note that the last hop of the packet is a gateway that does not do any delays total_delay: delays.iter().take(delays.len() - 1).sum::() + ack_delay, mix_packet: MixPacket::new(first_hop_address, sphinx_packet, Default::default()), + fragment_identifier, }) } @@ -310,113 +248,12 @@ where ) } - /// Attaches an optional reply-surb and correct padding to the underlying message - /// and splits it into [`Fragment`] that can be later packed into sphinx packets to be - /// sent through the mix network. - pub fn prepare_and_split_message( - &mut self, - message: Vec, - with_reply_surb: bool, - topology: &NymTopology, - ) -> Result<(Vec, Option), PreparationError> { - let (message, reply_key) = - self.optionally_attach_reply_surb(message, with_reply_surb, topology)?; + pub fn pad_and_split_message(&mut self, message: NymMessage) -> Vec { + let plaintext_per_packet = message.available_plaintext_per_packet(self.packet_size); - let message = self.pad_message(message); - - Ok((self.split_message(message), reply_key)) - } - - // TODO: perhaps the return type could somehow be combined with [`PreparedFragment`] ? - pub async fn prepare_reply_for_use( - &mut self, - message: Vec, - reply_surb: ReplySurb, - topology: &NymTopology, - ack_key: &AckKey, - ) -> Result<(MixPacket, FragmentIdentifier), PreparationError> { - // there's no chunking in reply-surbs so there's a hard limit on message, - // we also need to put the key digest into the message (same size as ephemeral key) - // and need 1 byte to indicate padding length (this is not the case for 'normal' messages - // as there the padding is added for the whole message) - // so before doing any processing, let's see if we have enough space for it all - let ack_overhead = MAX_NODE_ADDRESS_UNPADDED_LEN + PacketSize::AckPacket.size(); - if message.len() - > self.packet_size.plaintext_size() - - ack_overhead - - ReplySurbKeyDigestAlgorithm::output_size() - - 1 - { - return Err(PreparationError::TooLongReplyMessageError); - } - - let reply_id = FragmentIdentifier::new_reply(&mut self.rng); - - // create an ack - // even though it won't be used for retransmission, it must be present so that - // gateways could not distinguish reply packets from normal messages due to lack of said acks - // note: the ack delay is irrelevant since we do not know the delay of actual surb - let (_, surb_ack_bytes) = self - .generate_surb_ack(reply_id, topology, ack_key)? - .prepare_for_sending(); - - let zero_pad_len = self.packet_size.plaintext_size() - - message.len() - - ack_overhead - - ReplySurbKeyDigestAlgorithm::output_size() - - 1; - - // create reply message that will reach the recipient: - let mut reply_content: Vec<_> = message - .into_iter() - .chain(std::iter::once(1)) - .chain(std::iter::repeat(0).take(zero_pad_len)) - .collect(); - - // encrypt the reply message - let zero_iv = stream_cipher::zero_iv::(); - stream_cipher::encrypt_in_place::( - reply_surb.encryption_key().inner(), - &zero_iv, - &mut reply_content, - ); - - // combine it together as follows: - // SURB_ACK_FIRST_HOP || SURB_ACK_DATA || KEY_DIGEST || E (REPLY_MESSAGE || 1 || 0*) - // (note: surb_ack_bytes contains SURB_ACK_FIRST_HOP || SURB_ACK_DATA ) - let packet_payload: Vec<_> = surb_ack_bytes - .into_iter() - .chain(reply_surb.encryption_key().compute_digest().iter().copied()) - .chain(reply_content.into_iter()) - .collect(); - - // finally put it all inside a sphinx packet - // this can only fail if packet payload has incorrect size, but if it does, it means - // there's a bug in the above code - let (packet, first_hop) = reply_surb - .apply_surb(&packet_payload, Some(self.packet_size)) - .unwrap(); - - Ok(( - MixPacket::new(first_hop, packet, Default::default()), - reply_id, - )) - } - - #[allow(dead_code)] - #[cfg(test)] - pub(crate) fn test_fixture() -> MessagePreparer { - let rng = rand::rngs::OsRng; - let dummy_address = Recipient::try_from_base58_string("CytBseW6yFXUMzz4SGAKdNLGR7q3sJLLYxyBGvutNEQV.4QXYyEVc5fUDjmmi8PrHN9tdUFV4PCvSJE1278cHyvoe@4sBbL1ngf1vtNqykydQKTFh26sQCw888GpUqvPvyNB4f").unwrap(); - - MessagePreparer { - rng, - packet_size: Default::default(), - sender_address: dummy_address, - average_packet_delay: Default::default(), - average_ack_delay: Default::default(), - num_mix_hops: DEFAULT_NUM_MIX_HOPS, - } + message + .pad_to_full_packet_lengths(plaintext_per_packet) + .split_into_fragments(&mut self.rng, plaintext_per_packet) } } diff --git a/common/nymsphinx/src/preparer/payload.rs b/common/nymsphinx/src/preparer/payload.rs new file mode 100644 index 0000000000..94acde03c8 --- /dev/null +++ b/common/nymsphinx/src/preparer/payload.rs @@ -0,0 +1,97 @@ +// Copyright 2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crypto::aes::cipher::{KeyIvInit, StreamCipher}; +use crypto::asymmetric::encryption; +use crypto::shared_key::new_ephemeral_shared_key; +use crypto::symmetric::stream_cipher; +use crypto::symmetric::stream_cipher::CipherKey; +use nymsphinx_acknowledgements::surb_ack::SurbAck; +use nymsphinx_anonymous_replies::SurbEncryptionKey; +use nymsphinx_chunking::fragment::Fragment; +use nymsphinx_params::{ + PacketEncryptionAlgorithm, PacketHkdfAlgorithm, ReplySurbEncryptionAlgorithm, +}; +use rand::{CryptoRng, RngCore}; + +pub struct NymsphinxPayloadBuilder { + fragment: Fragment, + surb_ack: SurbAck, +} + +impl NymsphinxPayloadBuilder { + pub fn new(fragment: Fragment, surb_ack: SurbAck) -> Self { + NymsphinxPayloadBuilder { fragment, surb_ack } + } + + fn build( + self, + packet_encryption_key: &CipherKey, + variant_data: impl IntoIterator, + ) -> NymsphinxPayload + where + C: StreamCipher + KeyIvInit, + { + let (_, surb_ack_bytes) = self.surb_ack.prepare_for_sending(); + + let mut fragment_data = self.fragment.into_bytes(); + stream_cipher::encrypt_in_place::( + packet_encryption_key, + &stream_cipher::zero_iv::(), + &mut fragment_data, + ); + + // combines all the data as follows: + // SURB_ACK || VARIANT_SPECIFIC_DATA || CHUNK_DATA + // where variant-specific data is as follows: + // for replies it would be the digest of the encryption key used + // for 'regular' messages it would be the public component used in DH later used in the KDF + NymsphinxPayload( + surb_ack_bytes + .into_iter() + .chain(variant_data.into_iter()) + .chain(fragment_data.into_iter()) + .collect(), + ) + } + + pub fn build_reply(self, packet_encryption_key: &SurbEncryptionKey) -> NymsphinxPayload { + let key_digest = packet_encryption_key.compute_digest(); + self.build::( + packet_encryption_key.inner(), + key_digest.into_iter(), + ) + } + + pub fn build_regular( + self, + rng: &mut R, + recipient_encryption_key: &encryption::PublicKey, + ) -> NymsphinxPayload + where + R: RngCore + CryptoRng, + { + // create keys for 'payload' encryption + let (ephemeral_keypair, shared_key) = new_ephemeral_shared_key::< + PacketEncryptionAlgorithm, + PacketHkdfAlgorithm, + _, + >(rng, recipient_encryption_key); + + self.build::( + &shared_key, + ephemeral_keypair.public_key().to_bytes(), + ) + } +} + +// the actual byte data that will be put into the sphinx packet paylaod. +// no more transformations are going to happen to it +// TODO: use that fact for some better compile time assertions +pub struct NymsphinxPayload(Vec); + +impl AsRef<[u8]> for NymsphinxPayload { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} diff --git a/common/nymsphinx/src/receiver.rs b/common/nymsphinx/src/receiver.rs index 0b6a8e96dd..453f632f76 100644 --- a/common/nymsphinx/src/receiver.rs +++ b/common/nymsphinx/src/receiver.rs @@ -1,13 +1,22 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::message::{NymMessage, NymMessageError, PaddedMessage, PlainMessage}; +use crypto::aes::cipher::{KeyIvInit, StreamCipher}; use crypto::asymmetric::encryption; use crypto::shared_key::recompute_shared_key; use crypto::symmetric::stream_cipher; -use nymsphinx_anonymous_replies::reply_surb::{ReplySurb, ReplySurbError}; +use crypto::symmetric::stream_cipher::CipherKey; +use nymsphinx_anonymous_replies::requests::AnonymousSenderTag; +use nymsphinx_anonymous_replies::SurbEncryptionKey; use nymsphinx_chunking::fragment::Fragment; use nymsphinx_chunking::reconstruction::MessageReconstructor; -use nymsphinx_params::{PacketEncryptionAlgorithm, PacketHkdfAlgorithm, DEFAULT_NUM_MIX_HOPS}; +use nymsphinx_chunking::ChunkingError; +use nymsphinx_params::{ + PacketEncryptionAlgorithm, PacketHkdfAlgorithm, ReplySurbEncryptionAlgorithm, + DEFAULT_NUM_MIX_HOPS, +}; +use thiserror::Error; // TODO: should this live in this file? #[derive(Debug)] @@ -15,31 +24,53 @@ pub struct ReconstructedMessage { /// The actual plaintext message that was received. pub message: Vec, - /// Optional ReplySURB to allow for an anonymous reply to the sender. - pub reply_surb: Option, + /// Optional ephemeral sender tag indicating pseudo-identity of the party who sent us the message + /// (alongside any reply SURBs) + pub sender_tag: Option, } -#[derive(Debug)] +impl From for (Vec, Option) { + fn from(msg: ReconstructedMessage) -> Self { + (msg.message, msg.sender_tag) + } +} + +impl ReconstructedMessage { + pub fn new(message: Vec, sender_tag: AnonymousSenderTag) -> Self { + Self { + message, + sender_tag: Some(sender_tag), + } + } + + pub fn into_inner(self) -> (Vec, Option) { + self.into() + } +} + +impl From for ReconstructedMessage { + fn from(message: PlainMessage) -> Self { + ReconstructedMessage { + message, + sender_tag: None, + } + } +} + +#[derive(Debug, Error)] pub enum MessageRecoveryError { - InvalidSurbPrefixError, - MalformedSurbError(ReplySurbError), - InvalidRemoteEphemeralKey(encryption::KeyRecoveryError), - MalformedFragmentError, - InvalidMessagePaddingError, - MalformedReconstructedMessage(Vec), - TooShortMessageError, -} + #[error("Recovered remote x25519 public key is invalid - {0}")] + InvalidRemoteEphemeralKey(#[from] encryption::KeyRecoveryError), -impl From for MessageRecoveryError { - fn from(err: ReplySurbError) -> Self { - MessageRecoveryError::MalformedSurbError(err) - } -} + #[error("The reconstructed message was malformed - {source}")] + MalformedReconstructedMessage { + #[source] + source: NymMessageError, + used_sets: Vec, + }, -impl From for MessageRecoveryError { - fn from(err: encryption::KeyRecoveryError) -> Self { - MessageRecoveryError::InvalidRemoteEphemeralKey(err) - } + #[error("Failed to recover message fragment - {0}")] + FragmentRecoveryError(#[from] ChunkingError), } pub struct MessageReceiver { @@ -64,36 +95,34 @@ impl MessageReceiver { self } - /// Parses the message to strip and optionally recover reply SURB. - fn recover_reply_surb_from_message( - &self, - message: &mut Vec, - ) -> Result, MessageRecoveryError> { - match message[0] { - n if n == false as u8 => { - message.remove(0); - Ok(None) - } - n if n == true as u8 => { - let surb_len: usize = ReplySurb::serialized_len(self.num_mix_hops); - // note the extra +1 (due to 0/1 message prefix) - let surb_bytes = &message[1..1 + surb_len]; - let reply_surb = ReplySurb::from_bytes(surb_bytes)?; + fn decrypt_raw_message(&self, message: &mut [u8], key: &CipherKey) + where + C: StreamCipher + KeyIvInit, + { + let zero_iv = stream_cipher::zero_iv::(); + stream_cipher::decrypt_in_place::(key, &zero_iv, message) + } - *message = message.drain(1 + surb_len..).collect(); - Ok(Some(reply_surb)) - } - _ => Err(MessageRecoveryError::InvalidSurbPrefixError), - } + /// Given raw fragment data, **WITH KEY DIGEST PREFIX ALREADY REMOVED!!**, uses looked up + /// key to decrypt fragment data + pub fn recover_plaintext_from_reply( + &self, + reply_ciphertext: &mut [u8], + reply_key: SurbEncryptionKey, + ) { + self.decrypt_raw_message::( + reply_ciphertext, + reply_key.inner(), + ) } /// Given raw fragment data, recovers the remote ephemeral key, recomputes shared secret, /// uses it to decrypt fragment data - pub fn recover_plaintext( + pub fn recover_plaintext_from_regular_packet<'a>( &self, local_key: &encryption::PrivateKey, - mut raw_enc_frag: Vec, - ) -> Result, MessageRecoveryError> { + raw_enc_frag: &'a mut [u8], + ) -> Result<&'a mut [u8], MessageRecoveryError> { // 1. recover remote encryption key let remote_key_bytes = &raw_enc_frag[..encryption::PUBLIC_KEY_SIZE]; let remote_ephemeral_key = encryption::PublicKey::from_bytes(remote_key_bytes)?; @@ -105,33 +134,17 @@ impl MessageReceiver { ); // 3. decrypt fragment data - let fragment_bytes = &mut raw_enc_frag[encryption::PUBLIC_KEY_SIZE..]; + let fragment_ciphertext = &mut raw_enc_frag[encryption::PUBLIC_KEY_SIZE..]; - let zero_iv = stream_cipher::zero_iv::(); - Ok(stream_cipher::decrypt::( - &encryption_key, - &zero_iv, - fragment_bytes, - )) + self.decrypt_raw_message::(fragment_ciphertext, &encryption_key); + let fragment_data = fragment_ciphertext; + + Ok(fragment_data) } /// Given fragment data recovers [`Fragment`] itself. pub fn recover_fragment(&self, frag_data: &[u8]) -> Result { - Fragment::try_from_bytes(frag_data) - .map_err(|_| MessageRecoveryError::MalformedFragmentError) - } - - /// Removes the zero padding from the message that was initially included to ensure same length - /// sphinx payloads. - pub fn remove_padding(message: &mut Vec) -> Result<(), MessageRecoveryError> { - // we are looking for first occurrence of 1 in the tail and we get its index - if let Some(i) = message.iter().rposition(|b| *b == 1) { - // and now we only take bytes until that point (but not including it) - *message = message.drain(..i).collect(); - Ok(()) - } else { - Err(MessageRecoveryError::InvalidMessagePaddingError) - } + Ok(Fragment::try_from_bytes(frag_data)?) } /// Inserts given [`Fragment`] into the reconstructor. @@ -144,30 +157,15 @@ impl MessageReceiver { pub fn insert_new_fragment( &mut self, fragment: Fragment, - ) -> Result)>, MessageRecoveryError> { - if let Some((mut message, used_sets)) = self.reconstructor.insert_new_fragment(fragment) { - // Split message into plaintext and reply-SURB - let reply_surb = match self.recover_reply_surb_from_message(&mut message) { - Ok(reply_surb) => reply_surb, - Err(_) => { - return Err(MessageRecoveryError::MalformedReconstructedMessage( - used_sets, - )); - } - }; - - // Finally, remove the zero padding from the message - Self::remove_padding(&mut message).map_err(|_| { - MessageRecoveryError::MalformedReconstructedMessage(used_sets.clone()) - })?; - - Ok(Some(( - ReconstructedMessage { - message, - reply_surb, - }, - used_sets, - ))) + ) -> Result)>, MessageRecoveryError> { + if let Some((message, used_sets)) = self.reconstructor.insert_new_fragment(fragment) { + match PaddedMessage::new_reconstructed(message).remove_padding(self.num_mix_hops) { + Ok(message) => Ok(Some((message, used_sets))), + Err(err) => Err(MessageRecoveryError::MalformedReconstructedMessage { + source: err, + used_sets, + }), + } } else { Ok(None) } @@ -188,16 +186,14 @@ mod message_receiver { use super::*; use crypto::asymmetric::identity; use mixnet_contract_common::Layer; - use nymsphinx_addressing::clients::Recipient; - use rand::rngs::OsRng; use std::collections::HashMap; - use std::time::Duration; use topology::{gateway, mix, NymTopology}; // TODO: is it somehow maybe possible to move it to `topology` and have if conditionally // available to other modules? /// Returns a hardcoded, valid instance of [`NymTopology`] that is to be used in /// tests requiring instance of topology. + #[allow(dead_code)] fn topology_fixture() -> NymTopology { let mut mixes = HashMap::new(); mixes.insert( @@ -282,41 +278,4 @@ mod message_receiver { }], ) } - - #[test] - fn correctly_splits_message_into_plaintext_and_surb() { - let message_receiver: MessageReceiver = Default::default(); - - // the actual 'correctness' of the underlying message doesn't matter for this test - let message = vec![42; 100]; - let dummy_recipient = Recipient::try_from_base58_string("CytBseW6yFXUMzz4SGAKdNLGR7q3sJLLYxyBGvutNEQV.4QXYyEVc5fUDjmmi8PrHN9tdUFV4PCvSJE1278cHyvoe@FioFa8nMmPpQnYi7JyojoTuwGLeyNS8BF4ChPr29zUML").unwrap(); - let average_delay = Duration::from_millis(500); - let topology = topology_fixture(); - - let reply_surb = - ReplySurb::construct(&mut OsRng, &dummy_recipient, average_delay, &topology).unwrap(); - - let reply_surb_bytes = reply_surb.to_bytes(); - - // this is not exactly what is 'received' but rather after "some" processing, however, - // this is the expected argument to the function - let mut received_without_surb: Vec<_> = - std::iter::once(0).chain(message.iter().cloned()).collect(); - - let reply_surb = message_receiver - .recover_reply_surb_from_message(&mut received_without_surb) - .unwrap(); - assert_eq!(received_without_surb, message); - assert!(reply_surb.is_none()); - - let mut received_with_surb: Vec<_> = std::iter::once(1) - .chain(reply_surb_bytes.iter().cloned()) - .chain(message.iter().cloned()) - .collect(); - let reply_surb = message_receiver - .recover_reply_surb_from_message(&mut received_with_surb) - .unwrap(); - assert_eq!(received_with_surb, message); - assert_eq!(reply_surb_bytes, reply_surb.unwrap().to_bytes()); - } } diff --git a/common/nymsphinx/types/Cargo.toml b/common/nymsphinx/types/Cargo.toml index 34a916bbf5..353de2b1b2 100644 --- a/common/nymsphinx/types/Cargo.toml +++ b/common/nymsphinx/types/Cargo.toml @@ -7,5 +7,5 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -sphinx = { git = "https://github.com/nymtech/sphinx", rev="c494250f2a78bed33a618d470792418eee932859" } +sphinx = { git = "https://github.com/nymtech/sphinx", rev="e05a1992522ed0afd3c6fcac160313ffc9bb306a" } #sphinx = { path = "../../../../sphinx"} diff --git a/common/socks5/requests/src/request.rs b/common/socks5/requests/src/request.rs index f6921e362a..3148f6cd84 100644 --- a/common/socks5/requests/src/request.rs +++ b/common/socks5/requests/src/request.rs @@ -15,6 +15,18 @@ pub enum RequestFlag { Send = 1, } +impl TryFrom for RequestFlag { + type Error = RequestError; + + fn try_from(value: u8) -> Result { + match value { + _ if value == (RequestFlag::Connect as u8) => Ok(Self::Connect), + _ if value == (RequestFlag::Send as u8) => Ok(Self::Send), + _ => Err(RequestError::UnknownRequestFlag), + } + } +} + #[derive(Debug, Error)] pub enum RequestError { #[error("not enough bytes to recover the length of the address")] @@ -45,23 +57,12 @@ impl RequestError { } } -impl TryFrom for RequestFlag { - type Error = RequestError; - - fn try_from(value: u8) -> Result { - match value { - _ if value == (RequestFlag::Connect as u8) => Ok(Self::Connect), - _ if value == (RequestFlag::Send as u8) => Ok(Self::Send), - _ => Err(RequestError::UnknownRequestFlag), - } - } -} - #[derive(Debug)] pub struct ConnectRequest { + // TODO: is connection_id redundant now? pub conn_id: ConnectionId, pub remote_addr: RemoteAddress, - pub return_address: Recipient, + pub return_address: Option, } /// A request from a SOCKS5 client that a Nym Socks5 service provider should @@ -82,7 +83,7 @@ impl Request { pub fn new_connect( conn_id: ConnectionId, remote_addr: RemoteAddress, - return_address: Recipient, + return_address: Option, ) -> Request { Request::Connect(Box::new(ConnectRequest { conn_id, @@ -99,12 +100,13 @@ impl Request { /// Deserialize the request type, connection id, destination address and port, /// and the request body from bytes. /// - /// Serialized bytes looks like this: - /// - /// -------------------------------------------------------------------------------------- - /// request_flag | connection_id | address_length | remote_address_bytes | request_data | - /// 1 | 8 | 2 | address_length | ... | - /// -------------------------------------------------------------------------------------- + // TODO: this was already inaccurate + // /// Serialized bytes looks like this: + // /// + // /// -------------------------------------------------------------------------------------- + // /// request_flag | connection_id | address_length | remote_address_bytes | request_data | + // /// 1 | 8 | 2 | address_length | ... | + // /// -------------------------------------------------------------------------------------- /// /// The request_flag tells us whether this is a new connection request (`new_connect`), /// an already-established connection we should send up (`new_send`), or @@ -144,14 +146,20 @@ impl Request { // just a temporary reference to mid-slice for ease of use let recipient_data_bytes = &connect_request_bytes[address_end..]; - if recipient_data_bytes.len() != Recipient::LEN { - return Err(RequestError::ReturnAddressTooShort); - } + let return_address = if recipient_data_bytes.is_empty() { + None + } else { + if recipient_data_bytes.len() != Recipient::LEN { + return Err(RequestError::ReturnAddressTooShort); + } - let mut return_bytes = [0u8; Recipient::LEN]; - return_bytes.copy_from_slice(&recipient_data_bytes[..Recipient::LEN]); - let return_address = Recipient::try_from_bytes(return_bytes) - .map_err(RequestError::MalformedReturnAddress)?; + let mut return_bytes = [0u8; Recipient::LEN]; + return_bytes.copy_from_slice(&recipient_data_bytes[..Recipient::LEN]); + Some( + Recipient::try_from_bytes(return_bytes) + .map_err(RequestError::MalformedReturnAddress)?, + ) + }; Ok(Request::new_connect( connection_id, @@ -161,7 +169,7 @@ impl Request { } RequestFlag::Send => { let local_closed = b[9] != 0; - let data = b[10..].as_ref().to_vec(); + let data = b[10..].to_vec(); Ok(Request::Send(connection_id, data, local_closed)) } @@ -178,15 +186,19 @@ impl Request { let remote_address_bytes = req.remote_addr.into_bytes(); let remote_address_bytes_len = remote_address_bytes.len() as u16; - std::iter::once(RequestFlag::Connect as u8) - .chain(req.conn_id.to_be_bytes().iter().cloned()) - .chain(remote_address_bytes_len.to_be_bytes().iter().cloned()) - .chain(remote_address_bytes.into_iter()) - .chain(req.return_address.to_bytes().iter().cloned()) - .collect() + let iter = std::iter::once(RequestFlag::Connect as u8) + .chain(req.conn_id.to_be_bytes().into_iter()) + .chain(remote_address_bytes_len.to_be_bytes().into_iter()) + .chain(remote_address_bytes.into_iter()); + + if let Some(return_address) = req.return_address { + iter.chain(return_address.to_bytes().into_iter()).collect() + } else { + iter.collect() + } } Request::Send(conn_id, data, local_closed) => std::iter::once(RequestFlag::Send as u8) - .chain(conn_id.to_be_bytes().iter().cloned()) + .chain(conn_id.to_be_bytes().into_iter()) .chain(std::iter::once(local_closed as u8)) .chain(data.into_iter()) .collect(), @@ -324,7 +336,7 @@ mod request_deserialization_tests { let request_bytes: Vec<_> = request_bytes_prefix .iter() .cloned() - .chain(recipient_bytes.iter().cloned()) + .chain(recipient_bytes.into_iter()) .collect(); assert!(Request::try_from_bytes(&request_bytes) .unwrap_err() @@ -361,7 +373,7 @@ mod request_deserialization_tests { let request_bytes: Vec<_> = request_bytes .into_iter() - .chain(recipient_bytes.iter().cloned()) + .chain(recipient_bytes.into_iter()) .collect(); let request = Request::try_from_bytes(&request_bytes).unwrap(); @@ -370,7 +382,7 @@ mod request_deserialization_tests { assert_eq!("foo.com".to_string(), req.remote_addr); assert_eq!(u64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]), req.conn_id); assert_eq!( - req.return_address.to_bytes().to_vec(), + req.return_address.unwrap().to_bytes().to_vec(), recipient.to_bytes().to_vec() ); } @@ -408,7 +420,7 @@ mod request_deserialization_tests { let request_bytes: Vec<_> = request_bytes .into_iter() - .chain(recipient_bytes.iter().cloned()) + .chain(recipient_bytes.into_iter()) .collect(); let request = Request::try_from_bytes(&request_bytes).unwrap(); @@ -417,7 +429,7 @@ mod request_deserialization_tests { assert_eq!("foo.com".to_string(), req.remote_addr); assert_eq!(u64::from_be_bytes([1, 2, 3, 4, 5, 6, 7, 8]), req.conn_id); assert_eq!( - req.return_address.to_bytes().to_vec(), + req.return_address.unwrap().to_bytes().to_vec(), recipient.to_bytes().to_vec() ); } diff --git a/common/topology/Cargo.toml b/common/topology/Cargo.toml index f2a8a899fd..2996aeb639 100644 --- a/common/topology/Cargo.toml +++ b/common/topology/Cargo.toml @@ -10,6 +10,7 @@ edition = "2021" bs58 = "0.4" log = "0.4" rand = { version = "0.7.3", features = ["wasm-bindgen"] } +thiserror = "1.0.37" ## internal crypto = { path = "../crypto" } diff --git a/common/topology/src/lib.rs b/common/topology/src/lib.rs index 2e9cde725b..ff3ba55c83 100644 --- a/common/topology/src/lib.rs +++ b/common/topology/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use crate::filter::VersionFilterable; @@ -14,19 +14,31 @@ use std::fmt::{self, Display, Formatter}; use std::io; use std::net::{IpAddr, SocketAddr, ToSocketAddrs}; use std::str::FromStr; +use thiserror::Error; pub mod filter; pub mod gateway; pub mod mix; -#[derive(Debug)] +#[derive(Debug, Clone, Error)] pub enum NymTopologyError { - InvalidMixLayerError, - MissingLayerError(Vec), - NonExistentGatewayError, + #[error("The provided network topology is empty - there are no mixnodes and no gateways on it - the network request(s) probably failed")] + EmptyNetworkTopology, - InvalidNumberOfHopsError, - NoMixesOnLayerAvailable(MixLayer), + #[error("The provided network topology has no gateways available")] + NoGatewaysAvailable, + + #[error("The provided network topology has no mixnodes available")] + NoMixnodesAvailable, + + #[error("Gateway with identity key {identity_key} doesn't exist")] + NonExistentGatewayError { identity_key: String }, + + #[error("Wanted to create a mix route with {requested} hops, while only {available} layers are available")] + InvalidNumberOfHopsError { available: usize, requested: usize }, + + #[error("No mixnodes available on layer {layer}")] + EmptyMixLayer { layer: MixLayer }, } #[derive(Debug, Clone)] @@ -134,7 +146,10 @@ impl NymTopology { use rand::seq::SliceRandom; if self.mixes.len() < num_mix_hops as usize { - return Err(NymTopologyError::InvalidNumberOfHopsError); + return Err(NymTopologyError::InvalidNumberOfHopsError { + available: self.mixes.len(), + requested: num_mix_hops as usize, + }); } let mut route = Vec::with_capacity(num_mix_hops as usize); @@ -144,13 +159,13 @@ impl NymTopology { let layer_mixes = self .mixes .get(&layer) - .ok_or(NymTopologyError::NoMixesOnLayerAvailable(layer))?; + .ok_or(NymTopologyError::EmptyMixLayer { layer })?; // choose a random mix from the above list // this can return a 'None' only if slice is empty let random_mix = layer_mixes .choose(rng) - .ok_or(NymTopologyError::NoMixesOnLayerAvailable(layer))?; + .ok_or(NymTopologyError::EmptyMixLayer { layer })?; route.push(random_mix.into()); } @@ -169,9 +184,11 @@ impl NymTopology { // I don't think there's a need for this RNG to be crypto-secure R: Rng + ?Sized, { - let gateway = self - .get_gateway(gateway_identity) - .ok_or(NymTopologyError::NonExistentGatewayError)?; + let gateway = self.get_gateway(gateway_identity).ok_or( + NymTopologyError::NonExistentGatewayError { + identity_key: gateway_identity.to_base58_string(), + }, + )?; Ok(self .random_mix_route(rng, num_mix_hops)? @@ -186,29 +203,39 @@ impl NymTopology { } /// Checks if a mixnet path can be constructed using the specified number of hops - pub fn can_construct_path_through(&self, num_mix_hops: u8) -> bool { - // if there are no gateways present, we can't do anything - if self.gateways.is_empty() { - return false; + pub fn ensure_can_construct_path_through( + &self, + num_mix_hops: u8, + ) -> Result<(), NymTopologyError> { + let mixnodes = self.mixes(); + // 1. is it completely empty? + if mixnodes.is_empty() && self.gateways().is_empty() { + return Err(NymTopologyError::EmptyNetworkTopology); } - // early termination - if self.mixes.is_empty() { - return false; + // 2. does it have any mixnode at all? + if mixnodes.is_empty() { + return Err(NymTopologyError::NoMixnodesAvailable); } - // make sure there's at least one mix per layer - for i in 1..=num_mix_hops { - match self.mixes.get(&i) { - None => return false, - Some(layer_entry) => { - if layer_entry.is_empty() { - return false; + // 3. does it have any gateways at all? + if self.gateways().is_empty() { + return Err(NymTopologyError::NoGatewaysAvailable); + } + + // 4. does it have a mixnode on each layer? + for layer in 1..=num_mix_hops { + match mixnodes.get(&layer) { + None => return Err(NymTopologyError::EmptyMixLayer { layer }), + Some(layer_nodes) => { + if layer_nodes.is_empty() { + return Err(NymTopologyError::EmptyMixLayer { layer }); } } } } - true + + Ok(()) } #[must_use] diff --git a/common/wasm-utils/Cargo.toml b/common/wasm-utils/Cargo.toml index 75021ddad9..be39421ce2 100644 --- a/common/wasm-utils/Cargo.toml +++ b/common/wasm-utils/Cargo.toml @@ -16,6 +16,7 @@ wasm-bindgen-futures = "0.4" [dependencies.tungstenite] version = "0.13" default-features = false +optional = true [dependencies.web-sys] version = "0.3" @@ -30,3 +31,9 @@ features = [ "WebSocket", "Window", ] +optional = true + +[features] +default = ["sleep"] +websocket = ["tungstenite", "web-sys"] +sleep = ["web-sys"] \ No newline at end of file diff --git a/common/wasm-utils/src/lib.rs b/common/wasm-utils/src/lib.rs index 94b8faae05..8e0205c6de 100644 --- a/common/wasm-utils/src/lib.rs +++ b/common/wasm-utils/src/lib.rs @@ -5,8 +5,8 @@ use js_sys::Promise; use wasm_bindgen::prelude::*; use wasm_bindgen::JsValue; use wasm_bindgen_futures::JsFuture; -use web_sys::window; +#[cfg(feature = "websocket")] pub mod websocket; // will cause messages to be written as if console.log("...") was called @@ -39,9 +39,10 @@ extern "C" { pub fn error(s: &str); } +#[cfg(feature = "sleep")] pub async fn sleep(ms: i32) -> Result<(), JsValue> { let promise = Promise::new(&mut |yes, _| { - let win = window().expect("no window available!"); + let win = web_sys::window().expect("no window available!"); win.set_timeout_with_callback_and_timeout_and_arguments_0(&yes, ms) .unwrap(); }); diff --git a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs index 7a23c13655..9e13fd2e69 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs @@ -350,7 +350,7 @@ where match client_protocol { None => { warn!("the client we're connected to has not specified its protocol version. It's probably running version < 1.1.X, but that's still fine for now. It will become a hard error in 1.2.0"); - // note: in 1.2.0 we will have to return a hard error here + // note: in +1.2.0 we will have to return a hard error here Ok(()) } Some(v) if v != PROTOCOL_VERSION => { diff --git a/mixnode/src/node/packet_delayforwarder.rs b/mixnode/src/node/packet_delayforwarder.rs index 9be8175bed..81e0303afd 100644 --- a/mixnode/src/node/packet_delayforwarder.rs +++ b/mixnode/src/node/packet_delayforwarder.rs @@ -194,7 +194,7 @@ mod tests { ]; SphinxPacketBuilder::new() .with_payload_size(size.payload_size()) - .build_packet(b"foomp".to_vec(), &route, &destination, &delays) + .build_packet(b"foomp", &route, &destination, &delays) .unwrap() } diff --git a/nym-connect/Cargo.lock b/nym-connect/Cargo.lock index 1c6bd7ed3e..711edb17af 100644 --- a/nym-connect/Cargo.lock +++ b/nym-connect/Cargo.lock @@ -123,9 +123,9 @@ checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" [[package]] name = "async-trait" -version = "0.1.57" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f" +checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" dependencies = [ "proc-macro2", "quote", @@ -165,6 +165,15 @@ dependencies = [ "num-traits", ] +[[package]] +name = "atoi" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" +dependencies = [ + "num-traits", +] + [[package]] name = "attohttpc" version = "0.22.0" @@ -632,9 +641,11 @@ dependencies = [ name = "client-core" version = "1.1.2" dependencies = [ + "async-trait", "client-connections", "config", "crypto", + "dashmap", "dirs", "futures", "gateway-client", @@ -648,10 +659,11 @@ dependencies = [ "rand 0.7.3", "serde", "serde_json", - "sled", + "sqlx 0.6.2", "tap", "task", "thiserror", + "time 0.3.17", "tokio", "tokio-stream", "topology", @@ -660,6 +672,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "wasm-timer", + "wasm-utils", ] [[package]] @@ -940,7 +953,16 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49fc9a695bca7f35f5f4c15cddc84415f66a74ea78eef08e90c5024f2b540e23" dependencies = [ - "crc-catalog", + "crc-catalog 1.1.1", +] + +[[package]] +name = "crc" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53757d12b596c16c78b83458d732a5d1a17ab3f53f2f7412f6fb57cc8a140ab3" +dependencies = [ + "crc-catalog 2.1.0", ] [[package]] @@ -949,6 +971,12 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403" +[[package]] +name = "crc-catalog" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d0165d2900ae6778e36e80bbc4da3b5eefccee9ba939761f9c2882a5d9af3ff" + [[package]] name = "crc32fast" version = "1.3.2" @@ -964,7 +992,7 @@ version = "0.1.0" dependencies = [ "async-trait", "log", - "sqlx", + "sqlx 0.5.13", "thiserror", "tokio", ] @@ -991,20 +1019,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "crossbeam-epoch" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1" -dependencies = [ - "autocfg 1.1.0", - "cfg-if", - "crossbeam-utils", - "memoffset", - "once_cell", - "scopeguard", -] - [[package]] name = "crossbeam-queue" version = "0.3.6" @@ -1127,7 +1141,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1a816186fa68d9e426e3cb4ae4dff1fcd8e4a2c34b781bf7a822574a0d0aac8" dependencies = [ - "sct", + "sct 0.6.1", ] [[package]] @@ -1287,6 +1301,19 @@ dependencies = [ "syn", ] +[[package]] +name = "dashmap" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" +dependencies = [ + "cfg-if", + "hashbrown 0.12.3", + "lock_api", + "once_cell", + "parking_lot_core 0.9.3", +] + [[package]] name = "deflate" version = "0.7.20" @@ -1422,6 +1449,12 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" +[[package]] +name = "dotenvy" +version = "0.15.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03d8c417d7a8cb362e0c37e5d815f5eb7c37f79ff93707329d5a194e42e54ca0" + [[package]] name = "dtoa" version = "0.4.8" @@ -1717,16 +1750,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" -[[package]] -name = "fs2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -2303,6 +2326,9 @@ name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] [[package]] name = "hashlink" @@ -2313,6 +2339,15 @@ dependencies = [ "hashbrown 0.11.2", ] +[[package]] +name = "hashlink" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa" +dependencies = [ + "hashbrown 0.12.3", +] + [[package]] name = "headers" version = "0.3.8" @@ -2532,9 +2567,9 @@ dependencies = [ "hyper-rustls", "rustls-native-certs", "tokio", - "tokio-rustls", + "tokio-rustls 0.22.0", "tower-service", - "webpki", + "webpki 0.21.4", ] [[package]] @@ -2547,12 +2582,12 @@ dependencies = [ "futures-util", "hyper", "log", - "rustls", + "rustls 0.19.1", "rustls-native-certs", "tokio", - "tokio-rustls", - "webpki", - "webpki-roots", + "tokio-rustls 0.22.0", + "webpki 0.21.4", + "webpki-roots 0.21.1", ] [[package]] @@ -2786,9 +2821,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.55" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" dependencies = [ "wasm-bindgen", ] @@ -3110,7 +3145,7 @@ dependencies = [ "serde_json", "serde_repr", "thiserror", - "time 0.3.14", + "time 0.3.17", ] [[package]] @@ -3303,15 +3338,6 @@ dependencies = [ "syn", ] -[[package]] -name = "num_threads" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" -dependencies = [ - "libc", -] - [[package]] name = "nym-connect" version = "1.1.2" @@ -3421,6 +3447,7 @@ dependencies = [ "nymsphinx-types", "rand 0.7.3", "rand_distr", + "thiserror", "tokio", "topology", ] @@ -3445,6 +3472,7 @@ dependencies = [ "crypto", "nymsphinx-types", "serde", + "thiserror", ] [[package]] @@ -3458,7 +3486,9 @@ dependencies = [ "nymsphinx-types", "rand 0.7.3", "serde", + "thiserror", "topology", + "wasm-bindgen", ] [[package]] @@ -3470,6 +3500,7 @@ dependencies = [ "nymsphinx-params", "nymsphinx-types", "rand 0.7.3", + "thiserror", ] [[package]] @@ -3484,6 +3515,7 @@ dependencies = [ "nymsphinx-params", "nymsphinx-types", "rand 0.7.3", + "thiserror", "topology", ] @@ -4010,7 +4042,7 @@ dependencies = [ "indexmap", "line-wrap", "serde", - "time 0.3.14", + "time 0.3.17", "xml-rs", ] @@ -4580,8 +4612,20 @@ dependencies = [ "base64", "log", "ring", - "sct", - "webpki", + "sct 0.6.1", + "webpki 0.21.4", +] + +[[package]] +name = "rustls" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c" +dependencies = [ + "log", + "ring", + "sct 0.7.0", + "webpki 0.22.0", ] [[package]] @@ -4591,11 +4635,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a07b7c1885bd8ed3831c289b7870b13ef46fe0e856d288c30d9cc17d75a2092" dependencies = [ "openssl-probe", - "rustls", + "rustls 0.19.1", "schannel", "security-framework", ] +[[package]] +name = "rustls-pemfile" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0864aeff53f8c05aa08d86e5ef839d3dfcf07aeba2db32f12db0ef716e87bd55" +dependencies = [ + "base64", +] + [[package]] name = "rustversion" version = "1.0.9" @@ -4680,6 +4733,16 @@ dependencies = [ "untrusted", ] +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "sec1" version = "0.2.1" @@ -5003,22 +5066,6 @@ dependencies = [ "autocfg 1.1.0", ] -[[package]] -name = "sled" -version = "0.34.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f96b4737c2ce5987354855aed3797279def4ebf734436c6aa4552cf8e169935" -dependencies = [ - "crc32fast", - "crossbeam-epoch", - "crossbeam-utils", - "fs2", - "fxhash", - "libc", - "log", - "parking_lot 0.11.2", -] - [[package]] name = "smallvec" version = "0.6.14" @@ -5083,7 +5130,7 @@ dependencies = [ [[package]] name = "sphinx" version = "0.1.0" -source = "git+https://github.com/nymtech/sphinx?rev=c494250f2a78bed33a618d470792418eee932859#c494250f2a78bed33a618d470792418eee932859" +source = "git+https://github.com/nymtech/sphinx?rev=e05a1992522ed0afd3c6fcac160313ffc9bb306a#e05a1992522ed0afd3c6fcac160313ffc9bb306a" dependencies = [ "aes 0.7.5", "arrayref", @@ -5139,14 +5186,35 @@ dependencies = [ "unicode_categories", ] +[[package]] +name = "sqlformat" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87e292b4291f154971a43c3774364e2cbcaec599d3f5bf6fa9d122885dbc38a" +dependencies = [ + "itertools", + "nom", + "unicode_categories", +] + [[package]] name = "sqlx" version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "551873805652ba0d912fec5bbb0f8b4cdd96baf8e2ebf5970e5671092966019b" dependencies = [ - "sqlx-core", - "sqlx-macros", + "sqlx-core 0.5.13", + "sqlx-macros 0.5.13", +] + +[[package]] +name = "sqlx" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9249290c05928352f71c077cc44a464d880c63f26f7534728cca008e135c0428" +dependencies = [ + "sqlx-core 0.6.2", + "sqlx-macros 0.6.2", ] [[package]] @@ -5156,11 +5224,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48c61941ccf5ddcada342cd59e3e5173b007c509e1e8e990dafc830294d9dc5" dependencies = [ "ahash", - "atoi", + "atoi 0.4.0", "bitflags", "byteorder", "bytes", - "crc", + "crc 2.1.0", "crossbeam-queue", "either", "event-listener", @@ -5170,7 +5238,7 @@ dependencies = [ "futures-executor", "futures-intrusive", "futures-util", - "hashlink", + "hashlink 0.7.0", "hex", "indexmap", "itoa 1.0.3", @@ -5181,17 +5249,63 @@ dependencies = [ "once_cell", "paste", "percent-encoding", - "rustls", + "rustls 0.19.1", "sha2 0.10.6", "smallvec 1.9.0", - "sqlformat", - "sqlx-rt", + "sqlformat 0.1.8", + "sqlx-rt 0.5.13", "stringprep", "thiserror", "tokio-stream", "url", - "webpki", - "webpki-roots", + "webpki 0.21.4", + "webpki-roots 0.21.1", +] + +[[package]] +name = "sqlx-core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbc16ddba161afc99e14d1713a453747a2b07fc097d2009f4c300ec99286105" +dependencies = [ + "ahash", + "atoi 1.0.0", + "bitflags", + "byteorder", + "bytes", + "crc 3.0.0", + "crossbeam-queue", + "dotenvy", + "either", + "event-listener", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "hashlink 0.8.1", + "hex", + "indexmap", + "itoa 1.0.3", + "libc", + "libsqlite3-sys", + "log", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "rustls 0.20.7", + "rustls-pemfile", + "sha2 0.10.6", + "smallvec 1.9.0", + "sqlformat 0.2.0", + "sqlx-rt 0.6.2", + "stringprep", + "thiserror", + "tokio-stream", + "url", + "webpki-roots 0.22.5", ] [[package]] @@ -5207,8 +5321,27 @@ dependencies = [ "proc-macro2", "quote", "sha2 0.10.6", - "sqlx-core", - "sqlx-rt", + "sqlx-core 0.5.13", + "sqlx-rt 0.5.13", + "syn", + "url", +] + +[[package]] +name = "sqlx-macros" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b850fa514dc11f2ee85be9d055c512aa866746adfacd1cb42d867d68e6a5b0d9" +dependencies = [ + "dotenvy", + "either", + "heck 0.4.0", + "once_cell", + "proc-macro2", + "quote", + "sha2 0.10.6", + "sqlx-core 0.6.2", + "sqlx-rt 0.6.2", "syn", "url", ] @@ -5221,7 +5354,18 @@ checksum = "4db708cd3e459078f85f39f96a00960bd841f66ee2a669e90bf36907f5a79aae" dependencies = [ "once_cell", "tokio", - "tokio-rustls", + "tokio-rustls 0.22.0", +] + +[[package]] +name = "sqlx-rt" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24c5b2d25fa654cc5f841750b8e1cdedbe21189bf9a9382ee90bfa9dd3562396" +dependencies = [ + "once_cell", + "tokio", + "tokio-rustls 0.23.4", ] [[package]] @@ -5486,7 +5630,7 @@ dependencies = [ "tauri-utils", "tempfile", "thiserror", - "time 0.3.14", + "time 0.3.17", "tokio", "url", "uuid 1.1.2", @@ -5533,7 +5677,7 @@ dependencies = [ "sha2 0.10.6", "tauri-utils", "thiserror", - "time 0.3.14", + "time 0.3.17", "uuid 1.1.2", "walkdir", ] @@ -5661,7 +5805,7 @@ dependencies = [ "subtle 2.4.1", "subtle-encoding", "tendermint-proto", - "time 0.3.14", + "time 0.3.17", "zeroize", ] @@ -5694,7 +5838,7 @@ dependencies = [ "serde", "serde_bytes", "subtle-encoding", - "time 0.3.14", + "time 0.3.17", ] [[package]] @@ -5722,7 +5866,7 @@ dependencies = [ "tendermint-config", "tendermint-proto", "thiserror", - "time 0.3.14", + "time 0.3.17", "tokio", "tracing", "url", @@ -5804,27 +5948,37 @@ dependencies = [ [[package]] name = "time" -version = "0.3.14" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3f9a28b618c3a6b9251b6908e9c99e04b9e5c02e6581ccbb67d59c34ef7f9b" +checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" dependencies = [ "itoa 1.0.3", - "libc", - "num_threads", + "js-sys", + "serde", + "time-core", "time-macros", ] [[package]] -name = "time-macros" -version = "0.2.4" +name = "time-core" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +dependencies = [ + "time-core", +] [[package]] name = "tokio" -version = "1.21.2" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" +checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3" dependencies = [ "autocfg 1.1.0", "bytes", @@ -5866,9 +6020,20 @@ version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" dependencies = [ - "rustls", + "rustls 0.19.1", "tokio", - "webpki", + "webpki 0.21.4", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls 0.20.7", + "tokio", + "webpki 0.22.0", ] [[package]] @@ -5931,6 +6096,7 @@ dependencies = [ "nymsphinx-addressing", "nymsphinx-types", "rand 0.7.3", + "thiserror", "version-checker", ] @@ -6518,13 +6684,32 @@ dependencies = [ "untrusted", ] +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "webpki-roots" version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" dependencies = [ - "webpki", + "webpki 0.21.4", +] + +[[package]] +name = "webpki-roots" +version = "0.22.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368bfe657969fb01238bb756d351dcade285e0f6fcbd36dcb23359a5169975be" +dependencies = [ + "webpki 0.22.0", ] [[package]] diff --git a/nym-connect/src-tauri/src/config/mod.rs b/nym-connect/src-tauri/src/config/mod.rs index ade4ac2d57..c27bf6b6b7 100644 --- a/nym-connect/src-tauri/src/config/mod.rs +++ b/nym-connect/src-tauri/src/config/mod.rs @@ -1,17 +1,14 @@ -use std::path::PathBuf; - -use std::sync::Arc; -use tap::TapFallible; -use tokio::sync::RwLock; - -use client_core::config::Config as BaseConfig; -use config_common::NymConfig; -use nym_socks5::client::config::Config as Socks5Config; - use crate::{ error::{BackendError, Result}, state::State, }; +use client_core::config::Config as BaseConfig; +use config_common::NymConfig; +use nym_socks5::client::config::Config as Socks5Config; +use std::path::PathBuf; +use std::sync::Arc; +use tap::TapFallible; +use tokio::sync::RwLock; static SOCKS5_CONFIG_ID: &str = "nym-connect"; @@ -130,7 +127,7 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str } // Setup gateway by either registering a new one, or reusing exiting keys - let gateway = client_core::init::setup_gateway::( + let gateway = client_core::init::setup_gateway::<_, Socks5Config, _>( register_gateway, Some(chosen_gateway_id), config.get_base(), diff --git a/nym-connect/src-tauri/src/error.rs b/nym-connect/src-tauri/src/error.rs index b2b44ee345..cb677aac68 100644 --- a/nym-connect/src-tauri/src/error.rs +++ b/nym-connect/src-tauri/src/error.rs @@ -1,3 +1,4 @@ +use client_core::client::replies::reply_storage::fs_backend; use client_core::error::ClientCoreError; use serde::{Serialize, Serializer}; use thiserror::Error; @@ -33,7 +34,7 @@ pub enum BackendError { #[error("{source}")] ClientCoreError { #[from] - source: ClientCoreError, + source: ClientCoreError, }, #[error("Could not send disconnect signal to the SOCKS5 client")] diff --git a/service-providers/network-requester/src/connection.rs b/service-providers/network-requester/src/connection.rs index 95bdac06a3..f4ffaca992 100644 --- a/service-providers/network-requester/src/connection.rs +++ b/service-providers/network-requester/src/connection.rs @@ -1,8 +1,8 @@ // Copyright 2020 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::core::ReturnAddress; use client_connections::LaneQueueLengths; -use nymsphinx::addressing::clients::Recipient; use proxy_helpers::connection_controller::ConnectionReceiver; use proxy_helpers::proxy_runner::{MixProxySender, ProxyRunner}; use socks5_requests::{ConnectionId, Message as Socks5Message, RemoteAddress, Response}; @@ -18,14 +18,14 @@ pub(crate) struct Connection { id: ConnectionId, address: RemoteAddress, conn: Option, - return_address: Recipient, + return_address: ReturnAddress, } impl Connection { pub(crate) async fn new( id: ConnectionId, address: RemoteAddress, - return_address: Recipient, + return_address: ReturnAddress, ) -> io::Result { let conn = TcpStream::connect(&address).await?; @@ -40,14 +40,14 @@ impl Connection { pub(crate) async fn run_proxy( &mut self, mix_receiver: ConnectionReceiver, - mix_sender: MixProxySender<(Socks5Message, Recipient)>, + mix_sender: MixProxySender<(Socks5Message, ReturnAddress)>, lane_queue_lengths: LaneQueueLengths, shutdown: ShutdownListener, ) { let stream = self.conn.take().unwrap(); let remote_source_address = "???".to_string(); // we don't know ip address of requester let connection_id = self.id; - let recipient = self.return_address; + let return_address = self.return_address.clone(); let (stream, _) = ProxyRunner::new( stream, self.address.clone(), @@ -61,7 +61,7 @@ impl Connection { .run(move |conn_id, read_data, socket_closed| { ( Socks5Message::Response(Response::new(conn_id, read_data, socket_closed)), - recipient, + return_address.clone(), ) }) .await diff --git a/service-providers/network-requester/src/core.rs b/service-providers/network-requester/src/core.rs index 40f9cefd25..34fb42e7c0 100644 --- a/service-providers/network-requester/src/core.rs +++ b/service-providers/network-requester/src/core.rs @@ -15,13 +15,15 @@ use futures::stream::{SplitSink, SplitStream}; use futures::{SinkExt, StreamExt}; use log::*; use nymsphinx::addressing::clients::Recipient; +use nymsphinx::anonymous_replies::requests::AnonymousSenderTag; use nymsphinx::receiver::ReconstructedMessage; use proxy_helpers::connection_controller::{ BroadcastActiveConnections, Controller, ControllerCommand, ControllerSender, }; use proxy_helpers::proxy_runner::{MixProxyReader, MixProxySender}; use socks5_requests::{ - ConnectionId, Message as Socks5Message, NetworkRequesterResponse, Request, Response, + ConnectRequest, ConnectionId, Message as Socks5Message, NetworkRequesterResponse, Request, + Response, }; use statistics_common::collector::StatisticsSender; use std::path::PathBuf; @@ -41,6 +43,56 @@ pub struct ServiceProvider { stats_provider_addr: Option, } +// TODO: move elsewhere after things settle +#[derive(Debug, Clone)] +pub enum ReturnAddress { + Known(Box), + Anonymous(AnonymousSenderTag), +} + +impl From for ReturnAddress { + fn from(recipient: Recipient) -> Self { + ReturnAddress::Known(Box::new(recipient)) + } +} + +impl From for ReturnAddress { + fn from(sender_tag: AnonymousSenderTag) -> Self { + ReturnAddress::Anonymous(sender_tag) + } +} + +impl ReturnAddress { + fn new( + explicit_return_address: Option, + implicit_tag: Option, + ) -> Option { + // if somehow we received both, always prefer the explicit address since it's way easier to use + if let Some(recipient) = explicit_return_address { + return Some(ReturnAddress::Known(Box::new(recipient))); + } + if let Some(sender_tag) = implicit_tag { + return Some(ReturnAddress::Anonymous(sender_tag)); + } + None + } + + fn send_back_to(self, message: Vec, connection_id: u64) -> ClientRequest { + match self { + ReturnAddress::Known(recipient) => ClientRequest::Send { + recipient: *recipient, + message, + connection_id: Some(connection_id), + }, + ReturnAddress::Anonymous(sender_tag) => ClientRequest::Reply { + message, + sender_tag, + connection_id: Some(connection_id), + }, + } + } +} + impl ServiceProvider { pub fn new( listening_address: String, @@ -72,13 +124,12 @@ impl ServiceProvider { /// via the `websocket_writer`. async fn mixnet_response_listener( mut websocket_writer: SplitSink, - mut mix_reader: MixProxyReader<(Socks5Message, Recipient)>, + mut mix_reader: MixProxyReader<(Socks5Message, ReturnAddress)>, stats_collector: Option, mut client_connection_rx: ConnectionCommandReceiver, ) { loop { tokio::select! { - // TODO: wire SURBs in here once they're available socks5_msg = mix_reader.recv() => { if let Some((msg, return_address)) = socks5_msg { if let Some(stats_collector) = stats_collector.as_ref() { @@ -95,15 +146,10 @@ impl ServiceProvider { .processed(remote_addr, msg.size() as u32); } } - let conn_id = msg.conn_id(); // make 'request' to native-websocket client - let response_message = ClientRequest::Send { - recipient: return_address, - message: msg.into_bytes(), - with_reply_surb: false, - connection_id: Some(conn_id), - }; + let conn_id = msg.conn_id(); + let response_message = return_address.send_back_to(msg.into_bytes(), conn_id); let message = Message::Binary(response_message.serialize()); websocket_writer.send(message).await.unwrap(); @@ -179,7 +225,7 @@ impl ServiceProvider { let received = match deserialized_message { ServerResponse::Received(received) => received, - ServerResponse::LaneQueueLength(lane, queue_length) => { + ServerResponse::LaneQueueLength { lane, queue_length } => { Self::handle_lane_queue_length_response( &lane_queue_lengths, lane, @@ -200,33 +246,34 @@ impl ServiceProvider { async fn start_proxy( conn_id: ConnectionId, remote_addr: String, - return_address: Recipient, + return_address: ReturnAddress, controller_sender: ControllerSender, - mix_input_sender: MixProxySender<(Socks5Message, Recipient)>, + mix_input_sender: MixProxySender<(Socks5Message, ReturnAddress)>, lane_queue_lengths: LaneQueueLengths, shutdown: ShutdownListener, ) { - let mut conn = match Connection::new(conn_id, remote_addr.clone(), return_address).await { - Ok(conn) => conn, - Err(err) => { - error!( - "error while connecting to {:?} ! - {:?}", - remote_addr.clone(), - err - ); + let mut conn = + match Connection::new(conn_id, remote_addr.clone(), return_address.clone()).await { + Ok(conn) => conn, + Err(err) => { + error!( + "error while connecting to {:?} ! - {:?}", + remote_addr.clone(), + err + ); - // inform the remote that the connection is closed before it even was established - mix_input_sender - .send(( - Socks5Message::Response(Response::new(conn_id, Vec::new(), true)), - return_address, - )) - .await - .expect("InputMessageReceiver has stopped receiving!"); + // inform the remote that the connection is closed before it even was established + mix_input_sender + .send(( + Socks5Message::Response(Response::new(conn_id, Vec::new(), true)), + return_address, + )) + .await + .expect("InputMessageReceiver has stopped receiving!"); - return; - } - }; + return; + } + }; // Connect implies it's a fresh connection - register it with our controller let (mix_sender, mix_receiver) = mpsc::unbounded(); @@ -262,13 +309,25 @@ impl ServiceProvider { async fn handle_proxy_connect( &mut self, controller_sender: &mut ControllerSender, - mix_input_sender: &MixProxySender<(Socks5Message, Recipient)>, + mix_input_sender: &MixProxySender<(Socks5Message, ReturnAddress)>, lane_queue_lengths: LaneQueueLengths, - conn_id: ConnectionId, - remote_addr: String, - return_address: Recipient, + sender_tag: Option, + connect_req: Box, shutdown: ShutdownListener, ) { + let return_address = match ReturnAddress::new(connect_req.return_address, sender_tag) { + Some(address) => address, + None => { + log::warn!( + "attempted to start connection with no way of returning data back to the sender" + ); + return; + } + }; + + let remote_addr = connect_req.remote_addr; + let conn_id = connect_req.conn_id; + if !self.open_proxy && !self.outbound_request_filter.check(&remote_addr) { let log_msg = format!("Domain {:?} failed filter check", remote_addr); log::info!("{}", log_msg); @@ -315,23 +374,24 @@ impl ServiceProvider { async fn handle_proxy_message( &mut self, - raw_request: &[u8], + message: ReconstructedMessage, controller_sender: &mut ControllerSender, - mix_input_sender: &MixProxySender<(Socks5Message, Recipient)>, + mix_input_sender: &MixProxySender<(Socks5Message, ReturnAddress)>, lane_queue_lengths: LaneQueueLengths, stats_collector: Option, shutdown: ShutdownListener, ) { - let deserialized_msg = match Socks5Message::try_from_bytes(raw_request) { + let deserialized_msg = match Socks5Message::try_from_bytes(&message.message) { Ok(msg) => msg, Err(err) => { - error!("Failed to deserialized received message! - {}", err); + error!("Failed to deserialized received message! - {err}"); return; } }; match deserialized_msg { Socks5Message::Request(deserialized_request) => match deserialized_request { Request::Connect(req) => { + // TODO: stats might be invalid if connection fails to start if let Some(stats_collector) = stats_collector { stats_collector .connected_services @@ -343,9 +403,8 @@ impl ServiceProvider { controller_sender, mix_input_sender, lane_queue_lengths, - req.conn_id, - req.remote_addr, - req.return_address, + message.sender_tag, + req, shutdown, ) .await @@ -383,7 +442,7 @@ impl ServiceProvider { // channels responsible for managing messages that are to be sent to the mix network. The receiver is // going to be used by `mixnet_response_listener` let (mix_input_sender, mix_input_receiver) = - tokio::sync::mpsc::channel::<(Socks5Message, Recipient)>(1); + tokio::sync::mpsc::channel::<(Socks5Message, ReturnAddress)>(1); // Used to notify tasks to shutdown. Not all tasks fully supports this (yet). let shutdown = task::ShutdownNotifier::default(); @@ -450,11 +509,8 @@ impl ServiceProvider { return Err(NetworkRequesterError::ConnectionClosed); }; - let raw_message = received.message; - // TODO: here be potential SURB (i.e. received.reply_SURB) - self.handle_proxy_message( - &raw_message, + received, &mut controller_sender, &mix_input_sender, shared_lane_queue_lengths.clone(), diff --git a/service-providers/network-requester/src/statistics/collector.rs b/service-providers/network-requester/src/statistics/collector.rs index ac43252c33..73e6918ea5 100644 --- a/service-providers/network-requester/src/statistics/collector.rs +++ b/service-providers/network-requester/src/statistics/collector.rs @@ -12,6 +12,7 @@ use std::sync::Arc; use std::time::Duration; use tokio::sync::RwLock; +use crate::core::ReturnAddress; use nymsphinx::addressing::clients::Recipient; use ordered_buffer::OrderedMessageSender; use socks5_requests::{ConnectionId, Message as Socks5Message, RemoteAddress, Request}; @@ -77,13 +78,13 @@ pub struct ServiceStatisticsCollector { pub(crate) response_stats_data: Arc>, pub(crate) connected_services: Arc>>, stats_provider_addr: Recipient, - mix_input_sender: MixProxySender<(Socks5Message, Recipient)>, + mix_input_sender: MixProxySender<(Socks5Message, ReturnAddress)>, } impl ServiceStatisticsCollector { pub async fn new( stats_provider_addr: Option, - mix_input_sender: MixProxySender<(Socks5Message, Recipient)>, + mix_input_sender: MixProxySender<(Socks5Message, ReturnAddress)>, ) -> Result { let client = reqwest::Client::builder() .timeout(Duration::from_secs(3)) @@ -173,12 +174,12 @@ impl StatisticsCollector for ServiceStatisticsCollector { "{}:{}", DEFAULT_STATISTICS_SERVICE_ADDRESS, DEFAULT_STATISTICS_SERVICE_PORT ), - self.stats_provider_addr, + Some(self.stats_provider_addr), ); self.mix_input_sender .send(( Socks5Message::Request(connect_req), - self.stats_provider_addr, + self.stats_provider_addr.into(), )) .await .expect("MixProxyReader has stopped receiving!"); @@ -188,7 +189,10 @@ impl StatisticsCollector for ServiceStatisticsCollector { let ordered_msg = message_sender.wrap_message(msg).into_bytes(); let send_req = Request::new_send(conn_id, ordered_msg, true); self.mix_input_sender - .send((Socks5Message::Request(send_req), self.stats_provider_addr)) + .send(( + Socks5Message::Request(send_req), + self.stats_provider_addr.into(), + )) .await .expect("MixProxyReader has stopped receiving!"); diff --git a/validator-api/src/network_monitor/chunker.rs b/validator-api/src/network_monitor/chunker.rs index ec0da08871..0caaba0811 100644 --- a/validator-api/src/network_monitor/chunker.rs +++ b/validator-api/src/network_monitor/chunker.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use nymsphinx::forwarding::packet::MixPacket; +use nymsphinx::message::NymMessage; use nymsphinx::{ acknowledgements::AckKey, addressing::clients::Recipient, preparer::MessagePreparer, }; @@ -52,10 +53,9 @@ impl Chunker { ) -> Vec { let ack_key: AckKey = AckKey::new(&mut self.rng); - let (split_message, _reply_keys) = self + let split_message = self .message_preparer - .prepare_and_split_message(message, false, topology) - .expect("failed to split the message"); + .pad_and_split_message(NymMessage::new_plain(message)); let mut mix_packets = Vec::with_capacity(split_message.len()); for message_chunk in split_message { diff --git a/validator-api/src/network_monitor/monitor/processor.rs b/validator-api/src/network_monitor/monitor/processor.rs index 28ef3ae900..7b0649a49d 100644 --- a/validator-api/src/network_monitor/monitor/processor.rs +++ b/validator-api/src/network_monitor/monitor/processor.rs @@ -1,4 +1,4 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use crate::network_monitor::gateways_reader::GatewayMessages; @@ -68,27 +68,30 @@ struct ReceivedProcessorInner { } impl ReceivedProcessorInner { - fn on_message(&mut self, message: Vec) -> Result<(), ProcessingError> { + fn on_message(&mut self, mut message: Vec) -> Result<(), ProcessingError> { // if the nonce is none it means the packet was received during the 'waiting' for the // next test run if self.test_nonce.is_none() { return Err(ProcessingError::ReceivedOutsideTestRun); } - let encrypted_bytes = self + let plaintext = self .message_receiver - .recover_plaintext(self.client_encryption_keypair.private_key(), message) + .recover_plaintext_from_regular_packet( + self.client_encryption_keypair.private_key(), + &mut message, + ) .map_err(|_| ProcessingError::MalformedPacketReceived)?; let fragment = self .message_receiver - .recover_fragment(&encrypted_bytes) + .recover_fragment(plaintext) .map_err(|_| ProcessingError::MalformedPacketReceived)?; let (recovered, _) = self .message_receiver .insert_new_fragment(fragment) .map_err(|_| ProcessingError::MalformedPacketReceived)? .ok_or(ProcessingError::NonTestPacketReceived)?; // if it's a test packet it MUST BE reconstructed with single fragment - let test_packet = TestPacket::try_from_bytes(&recovered.message) + let test_packet = TestPacket::try_from_bytes(&recovered.into_inner_data()) .map_err(|_| ProcessingError::MalformedPacketReceived)?; // we know nonce is NOT none From 3b5eab5342321693b71de1f498650ee4bc21e80a Mon Sep 17 00:00:00 2001 From: farbanas Date: Tue, 13 Dec 2022 13:15:51 +0100 Subject: [PATCH 18/39] bumped everything by one patch version --- clients/client-core/Cargo.toml | 2 +- clients/native/Cargo.toml | 2 +- clients/socks5/Cargo.toml | 2 +- gateway/Cargo.toml | 2 +- mixnode/Cargo.toml | 2 +- nym-connect/package.json | 2 +- nym-connect/src-tauri/Cargo.toml | 2 +- nym-connect/src-tauri/tauri.conf.json | 2 +- nym-wallet/package.json | 2 +- nym-wallet/src-tauri/Cargo.toml | 2 +- nym-wallet/src-tauri/tauri.conf.json | 2 +- service-providers/network-requester/Cargo.toml | 2 +- service-providers/network-statistics/Cargo.toml | 2 +- tools/nym-cli/Cargo.toml | 2 +- validator-api/Cargo.toml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/clients/client-core/Cargo.toml b/clients/client-core/Cargo.toml index 56edca335b..e2344acc86 100644 --- a/clients/client-core/Cargo.toml +++ b/clients/client-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "client-core" -version = "1.1.2" +version = "1.1.3" authors = ["Dave Hrycyszyn "] edition = "2021" diff --git a/clients/native/Cargo.toml b/clients/native/Cargo.toml index 1b19bf32ad..74574cf256 100644 --- a/clients/native/Cargo.toml +++ b/clients/native/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-client" -version = "1.1.2" +version = "1.1.3" authors = ["Dave Hrycyszyn ", "Jędrzej Stuczyński "] description = "Implementation of the Nym Client" edition = "2021" diff --git a/clients/socks5/Cargo.toml b/clients/socks5/Cargo.toml index 42c477efec..56b9616684 100644 --- a/clients/socks5/Cargo.toml +++ b/clients/socks5/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-socks5-client" -version = "1.1.2" +version = "1.1.3" authors = ["Dave Hrycyszyn "] description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address" edition = "2021" diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index e2137a574c..ab26fccea7 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-gateway" -version = "1.1.2" +version = "1.1.3" authors = [ "Dave Hrycyszyn ", "Jędrzej Stuczyński ", diff --git a/mixnode/Cargo.toml b/mixnode/Cargo.toml index 6c958811d9..70c1b439d0 100644 --- a/mixnode/Cargo.toml +++ b/mixnode/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-mixnode" -version = "1.1.2" +version = "1.1.3" authors = [ "Dave Hrycyszyn ", "Jędrzej Stuczyński ", diff --git a/nym-connect/package.json b/nym-connect/package.json index 74c152c8a6..dbf42df71b 100644 --- a/nym-connect/package.json +++ b/nym-connect/package.json @@ -1,6 +1,6 @@ { "name": "@nym/nym-connect", - "version": "1.1.2", + "version": "1.1.3", "main": "index.js", "license": "MIT", "scripts": { diff --git a/nym-connect/src-tauri/Cargo.toml b/nym-connect/src-tauri/Cargo.toml index d5ae83e869..2c4e6d356d 100644 --- a/nym-connect/src-tauri/Cargo.toml +++ b/nym-connect/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-connect" -version = "1.1.2" +version = "1.1.3" description = "nym-connect" authors = ["Nym Technologies SA"] license = "" diff --git a/nym-connect/src-tauri/tauri.conf.json b/nym-connect/src-tauri/tauri.conf.json index 3b7d0d3c5c..8c0597d17e 100644 --- a/nym-connect/src-tauri/tauri.conf.json +++ b/nym-connect/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "package": { "productName": "nym-connect", - "version": "1.1.2" + "version": "1.1.3" }, "build": { "distDir": "../dist", diff --git a/nym-wallet/package.json b/nym-wallet/package.json index f31c68b9a6..26d58da9d1 100644 --- a/nym-wallet/package.json +++ b/nym-wallet/package.json @@ -1,6 +1,6 @@ { "name": "@nymproject/nym-wallet-app", - "version": "1.1.2", + "version": "1.1.3", "main": "index.js", "license": "MIT", "scripts": { diff --git a/nym-wallet/src-tauri/Cargo.toml b/nym-wallet/src-tauri/Cargo.toml index 1a9be48cd0..f166361e9e 100644 --- a/nym-wallet/src-tauri/Cargo.toml +++ b/nym-wallet/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym_wallet" -version = "1.1.2" +version = "1.1.3" description = "Nym Native Wallet" authors = ["Nym Technologies SA"] license = "" diff --git a/nym-wallet/src-tauri/tauri.conf.json b/nym-wallet/src-tauri/tauri.conf.json index d572941588..13362f5060 100644 --- a/nym-wallet/src-tauri/tauri.conf.json +++ b/nym-wallet/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "package": { "productName": "nym-wallet", - "version": "1.1.2" + "version": "1.1.3" }, "build": { "distDir": "../dist", diff --git a/service-providers/network-requester/Cargo.toml b/service-providers/network-requester/Cargo.toml index 050f06eda0..96d91d88ae 100644 --- a/service-providers/network-requester/Cargo.toml +++ b/service-providers/network-requester/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-network-requester" -version = "1.1.2" +version = "1.1.3" authors = ["Dave Hrycyszyn ", "Jędrzej Stuczyński "] edition = "2021" rust-version = "1.65" diff --git a/service-providers/network-statistics/Cargo.toml b/service-providers/network-statistics/Cargo.toml index 10b30d60c7..7c2917a381 100644 --- a/service-providers/network-statistics/Cargo.toml +++ b/service-providers/network-statistics/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-network-statistics" -version = "1.1.2" +version = "1.1.3" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/tools/nym-cli/Cargo.toml b/tools/nym-cli/Cargo.toml index f25479c7fe..d6ec40bb71 100644 --- a/tools/nym-cli/Cargo.toml +++ b/tools/nym-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-cli" -version = "1.1.2" +version = "1.1.3" authors = ["Nym Technologies SA"] edition = "2021" diff --git a/validator-api/Cargo.toml b/validator-api/Cargo.toml index f59e2f5838..ee2c169f65 100644 --- a/validator-api/Cargo.toml +++ b/validator-api/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-validator-api" -version = "1.1.2" +version = "1.1.3" authors = [ "Dave Hrycyszyn ", "Jędrzej Stuczyński ", From 5456b16e3b3d8d6478f6b41c44f41111aa05461f Mon Sep 17 00:00:00 2001 From: farbanas Date: Tue, 13 Dec 2022 13:23:27 +0100 Subject: [PATCH 19/39] updated changelogs --- CHANGELOG.md | 2 ++ nym-connect/CHANGELOG.md | 4 ++++ nym-wallet/CHANGELOG.md | 4 ++++ 3 files changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6cf4c0a5a..9be2ec4d63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// ## [Unreleased] +## [v1.1.3] (2022-12-13) + ### Changed - validator-api: can recover from shutdown during DKG process ([#1872]) diff --git a/nym-connect/CHANGELOG.md b/nym-connect/CHANGELOG.md index 1512078d20..7b96eb019b 100644 --- a/nym-connect/CHANGELOG.md +++ b/nym-connect/CHANGELOG.md @@ -1,5 +1,9 @@ ## UNRELEASED +## [nym-connect-v1.1.3](https://github.com/nymtech/nym/tree/nym-connect-v1.1.3) (2022-12-13) + +- socks5-client: added support for socks4a. + ## [nym-connect-v1.1.2](https://github.com/nymtech/nym/tree/nym-connect-v1.1.2) (2022-11-29) - socks5-client: fix error with client failing and disconnecting unnecessarily. diff --git a/nym-wallet/CHANGELOG.md b/nym-wallet/CHANGELOG.md index 2947400e8b..d6ca3521d9 100644 --- a/nym-wallet/CHANGELOG.md +++ b/nym-wallet/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## [nym-wallet-v1.1.3](https://github.com/nymtech/nym/releases/tag/nym-wallet-v1.1.3) (2022-12-13) + +- wallet: improved unbond screen. + ## [nym-wallet-v1.1.2](https://github.com/nymtech/nym/releases/tag/nym-wallet-v1.1.2) (2022-11-09) - wallet: Bity buy functionality From c11a4c23faac4afe8e069801193c86fbc5f2a0f4 Mon Sep 17 00:00:00 2001 From: Gala Date: Wed, 14 Dec 2022 11:16:08 +0100 Subject: [PATCH 20/39] adding bity icon and wallet address --- nym-wallet/src/components/Buy/Tutorial.tsx | 22 +++++++++------ nym-wallet/src/svg-icons/index.ts | 1 + nym-wallet/src/svg-icons/poweredByBity.tsx | 33 ++++++++++++++++++++++ 3 files changed, 47 insertions(+), 9 deletions(-) create mode 100644 nym-wallet/src/svg-icons/poweredByBity.tsx diff --git a/nym-wallet/src/components/Buy/Tutorial.tsx b/nym-wallet/src/components/Buy/Tutorial.tsx index 5f14e2c444..180ddbbd2a 100644 --- a/nym-wallet/src/components/Buy/Tutorial.tsx +++ b/nym-wallet/src/components/Buy/Tutorial.tsx @@ -1,8 +1,9 @@ import React, { useState } from 'react'; import { Button, Stack, Typography, Grid, useMediaQuery, useTheme } from '@mui/material'; import { Tune as TuneIcon, BorderColor as BorderColorIcon, Paid as PaidIcon } from '@mui/icons-material'; -import { NymCard } from '../NymCard'; +import { NymCard, ClientAddress } from '../../components'; import { SignMessageModal } from './SignMessageModal'; +import { PoweredByBity } from 'src/svg-icons'; // TODO retrieve this value from env const EXCHANGE_URL = 'https://buy.nymtech.net'; @@ -55,7 +56,7 @@ export const Tutorial = () => { const showBorder = useMediaQuery(theme.breakpoints.up('md')); return ( - + }> Follow below 3 steps to quickly and easily buy NYM tokens. You can purchase up to 1000 Swiss Francs per day without KYC. @@ -116,13 +117,16 @@ export const Tutorial = () => { } /> - - - + + + + + + ); diff --git a/nym-wallet/src/svg-icons/index.ts b/nym-wallet/src/svg-icons/index.ts index ec0d4b9c49..e0bd754736 100644 --- a/nym-wallet/src/svg-icons/index.ts +++ b/nym-wallet/src/svg-icons/index.ts @@ -3,3 +3,4 @@ export * from './undelegate'; export * from './bond'; export * from './unbond'; export * from './bonding'; +export * from './poweredByBity'; diff --git a/nym-wallet/src/svg-icons/poweredByBity.tsx b/nym-wallet/src/svg-icons/poweredByBity.tsx new file mode 100644 index 0000000000..3b061ae7d3 --- /dev/null +++ b/nym-wallet/src/svg-icons/poweredByBity.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { SvgIcon, SvgIconProps } from '@mui/material'; + +export const PoweredByBity = (props: SvgIconProps) => ( + + + + + + + + + + + + + + + + + + + +); From 3563ad67b275d49c77a6f7a2ca373e8cb1b43084 Mon Sep 17 00:00:00 2001 From: Gala Date: Wed, 14 Dec 2022 12:21:36 +0100 Subject: [PATCH 21/39] ui and copy changes --- nym-wallet/src/components/Buy/Tutorial.tsx | 29 +++++++++++----------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/nym-wallet/src/components/Buy/Tutorial.tsx b/nym-wallet/src/components/Buy/Tutorial.tsx index 5f14e2c444..8efd096d58 100644 --- a/nym-wallet/src/components/Buy/Tutorial.tsx +++ b/nym-wallet/src/components/Buy/Tutorial.tsx @@ -1,6 +1,7 @@ import React, { useState } from 'react'; import { Button, Stack, Typography, Grid, useMediaQuery, useTheme } from '@mui/material'; -import { Tune as TuneIcon, BorderColor as BorderColorIcon, Paid as PaidIcon } from '@mui/icons-material'; +import { Tune as TuneIcon, BorderColor as BorderColorIcon } from '@mui/icons-material'; +import { CoinMark } from '@nymproject/react/coins/CoinMark'; import { NymCard } from '../NymCard'; import { SignMessageModal } from './SignMessageModal'; @@ -27,8 +28,7 @@ const TutorialStep = ({ { return ( - + Follow below 3 steps to quickly and easily buy NYM tokens. You can purchase up to 1000 Swiss Francs per day without KYC. {showSignModal && setShowSignModal(false)} />} { title="Define purchase details" icon={} text={ - t.palette.nym.text.muted }}> + t.palette.nym.text.muted }}> Click on{' '} Buy NYM @@ -90,10 +92,10 @@ export const Tutorial = () => { /> } text={ - t.palette.nym.text.muted }}> + t.palette.nym.text.muted }}> When asked for signature, copy the message and sign it using{' '} Sign message @@ -106,12 +108,11 @@ export const Tutorial = () => { /> } + title="Make BTC tx and receive NYM" + icon={} text={ - t.palette.nym.text.muted }}> - {`Send the defined BTC amount to Bity's address that's given to you. As soon as your BTC transaction has 4 - confirmations, Bity will send the purchased NYM tokens to your wallet.`} + t.palette.nym.text.muted }}> + {`Send BTC to the given address. When the transaction is confirmed your purchased NYM tokens will be transferred in your wallet.`} } /> From 677d8c7fce5c88f03dffd9787aebef289c0d98ca Mon Sep 17 00:00:00 2001 From: Gala Date: Wed, 14 Dec 2022 12:30:10 +0100 Subject: [PATCH 22/39] text size --- nym-wallet/src/components/Buy/Tutorial.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nym-wallet/src/components/Buy/Tutorial.tsx b/nym-wallet/src/components/Buy/Tutorial.tsx index 8efd096d58..4369594801 100644 --- a/nym-wallet/src/components/Buy/Tutorial.tsx +++ b/nym-wallet/src/components/Buy/Tutorial.tsx @@ -80,7 +80,7 @@ export const Tutorial = () => { text={ t.palette.nym.text.muted }}> Click on{' '} - + Buy NYM {' '} button and follow the steps in the browser window that opens. You will be asked for purchase details i.e. @@ -97,7 +97,7 @@ export const Tutorial = () => { text={ t.palette.nym.text.muted }}> When asked for signature, copy the message and sign it using{' '} - + Sign message {' '} button below. Then copy and paste your signature back in the browser window. From 142a2bb26b72ee80408ee577e715bb3c89ec847c Mon Sep 17 00:00:00 2001 From: Gala Date: Wed, 14 Dec 2022 13:05:54 +0100 Subject: [PATCH 23/39] copy --- nym-wallet/src/components/Buy/Tutorial.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nym-wallet/src/components/Buy/Tutorial.tsx b/nym-wallet/src/components/Buy/Tutorial.tsx index 4369594801..9cb896211c 100644 --- a/nym-wallet/src/components/Buy/Tutorial.tsx +++ b/nym-wallet/src/components/Buy/Tutorial.tsx @@ -92,7 +92,7 @@ export const Tutorial = () => { /> } text={ t.palette.nym.text.muted }}> @@ -108,11 +108,11 @@ export const Tutorial = () => { /> } text={ t.palette.nym.text.muted }}> - {`Send BTC to the given address. When the transaction is confirmed your purchased NYM tokens will be transferred in your wallet.`} + {`Send the defined BTC amount to Bity's address that's given to you. As soon as your BTC tx has 4 confirmations, Bity will send the purchased NYM tokens to your wallet.`} } /> @@ -121,7 +121,7 @@ export const Tutorial = () => { - From a2d10d99569bc296cb9890022071e1ebb13988d5 Mon Sep 17 00:00:00 2001 From: Gala Date: Wed, 14 Dec 2022 14:12:16 +0100 Subject: [PATCH 24/39] remove warning error message --- .../bonding/node-settings/settings-pages/NodeUnbondPage.tsx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx b/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx index a1fb0ea3fe..22647cd0a9 100644 --- a/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx +++ b/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx @@ -34,12 +34,6 @@ export const NodeUnbondPage = ({ bondedNode, onConfirm, onError }: Props) => { - - To unbond, type{' '} t.palette.nym.highlight }}> From 27e6539e980450a5255430d7bf9bde3408bbc846 Mon Sep 17 00:00:00 2001 From: Gala Date: Wed, 14 Dec 2022 14:48:49 +0100 Subject: [PATCH 25/39] remove message only for gateways --- .../bonding/node-settings/settings-pages/NodeUnbondPage.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx b/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx index 22647cd0a9..c2ffce9123 100644 --- a/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx +++ b/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx @@ -34,6 +34,12 @@ export const NodeUnbondPage = ({ bondedNode, onConfirm, onError }: Props) => { + {isMixnode(bondedNode) && ( + + )} + To unbond, type{' '} t.palette.nym.highlight }}> From 80c81fa3d7ea3a85ce9599692e7e6a224e7ebbd0 Mon Sep 17 00:00:00 2001 From: Gala Date: Wed, 14 Dec 2022 14:52:33 +0100 Subject: [PATCH 26/39] using a plain string --- .../bonding/node-settings/settings-pages/NodeUnbondPage.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx b/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx index c2ffce9123..347ed2467a 100644 --- a/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx +++ b/nym-wallet/src/pages/bonding/node-settings/settings-pages/NodeUnbondPage.tsx @@ -35,9 +35,7 @@ export const NodeUnbondPage = ({ bondedNode, onConfirm, onError }: Props) => { {isMixnode(bondedNode) && ( - + )} From c0ffbb0cb2a5ce5be38a5f0eec9c7c9dcb0fc1ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 15 Dec 2022 11:21:40 +0000 Subject: [PATCH 27/39] Fix multi-surb backwards compatibility in pre 1.1.4 client config files (#2703) * Defaulting to 'false' value for 'send_anonymously' in socks5 config if not present * Created method to change all empty core client config fields to their default values * Using default values for surb reply storage in 'run' command if left unset --- clients/client-core/src/config/mod.rs | 44 ++++++++++++++++++------- clients/native/src/commands/run.rs | 4 +++ clients/socks5/src/client/config/mod.rs | 1 + clients/socks5/src/commands/run.rs | 4 +++ 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/clients/client-core/src/config/mod.rs b/clients/client-core/src/config/mod.rs index 0ce94ba646..0ec88a8095 100644 --- a/clients/client-core/src/config/mod.rs +++ b/clients/client-core/src/config/mod.rs @@ -88,16 +88,28 @@ impl Config { where T: NymConfig, { - let id = id.into(); + self.client.id = id.into(); + self.set_empty_fields_to_defaults(); + self + } + + pub fn set_empty_fields_to_defaults(&mut self) -> bool + where + T: NymConfig, + { + let id = &self.client.id; + let mut changes_made = false; // identity key setting if self.client.private_identity_key_file.as_os_str().is_empty() { + changes_made = true; self.client.private_identity_key_file = - self::Client::::default_private_identity_key_file(&id); + self::Client::::default_private_identity_key_file(id); } if self.client.public_identity_key_file.as_os_str().is_empty() { + changes_made = true; self.client.public_identity_key_file = - self::Client::::default_public_identity_key_file(&id); + self::Client::::default_public_identity_key_file(id); } // encryption key setting @@ -107,8 +119,9 @@ impl Config { .as_os_str() .is_empty() { + changes_made = true; self.client.private_encryption_key_file = - self::Client::::default_private_encryption_key_file(&id); + self::Client::::default_private_encryption_key_file(id); } if self .client @@ -116,32 +129,35 @@ impl Config { .as_os_str() .is_empty() { + changes_made = true; self.client.public_encryption_key_file = - self::Client::::default_public_encryption_key_file(&id); + self::Client::::default_public_encryption_key_file(id); } // shared gateway key setting if self.client.gateway_shared_key_file.as_os_str().is_empty() { + changes_made = true; self.client.gateway_shared_key_file = - self::Client::::default_gateway_shared_key_file(&id); + self::Client::::default_gateway_shared_key_file(id); } // ack key setting if self.client.ack_key_file.as_os_str().is_empty() { - self.client.ack_key_file = self::Client::::default_ack_key_file(&id); + changes_made = true; + self.client.ack_key_file = self::Client::::default_ack_key_file(id); } if self.client.reply_surb_database_path.as_os_str().is_empty() { + changes_made = true; self.client.reply_surb_database_path = - self::Client::::default_reply_surb_database_path(&id); + self::Client::::default_reply_surb_database_path(id); } if self.client.database_path.as_os_str().is_empty() { - self.client.database_path = self::Client::::default_database_path(&id); + changes_made = true; + self.client.database_path = self::Client::::default_database_path(id); } - - self.client.id = id; - self + changes_made } pub fn with_disabled_credentials(&mut self, disabled_credentials_mode: bool) { @@ -438,6 +454,10 @@ pub struct Client { database_path: PathBuf, /// Path to the persistent store for received reply surbs, unused encryption keys and used sender tags. + // this was set to use #[serde(default)] for the purposes of compatibility for multi-surbs introduced in 1.1.4. + // if you're reading this message and we have already introduced some breaking changes, feel free + // to remove that attribute since at this point the client configs should have gotten regenerated + #[serde(default)] reply_surb_database_path: PathBuf, /// nym_home_directory specifies absolute path to the home nym Clients directory. diff --git a/clients/native/src/commands/run.rs b/clients/native/src/commands/run.rs index 4267fcbac5..5eb6939944 100644 --- a/clients/native/src/commands/run.rs +++ b/clients/native/src/commands/run.rs @@ -103,6 +103,10 @@ pub(crate) async fn execute(args: &Run) -> Result<(), ClientError> { let override_config_fields = OverrideConfig::from(args.clone()); config = override_config(config, override_config_fields); + if config.get_base_mut().set_empty_fields_to_defaults() { + warn!("some of the core config options were left unset. the default values are going to get used instead."); + } + if !version_check(&config) { error!("failed the local version check"); return Err(ClientError::FailedLocalVersionCheck); diff --git a/clients/socks5/src/client/config/mod.rs b/clients/socks5/src/client/config/mod.rs index 97372e4c86..cda73334d3 100644 --- a/clients/socks5/src/client/config/mod.rs +++ b/clients/socks5/src/client/config/mod.rs @@ -143,6 +143,7 @@ pub struct Socks5 { /// slower and consume nearly double the bandwidth as it will require sending reply SURBs. /// /// Note that some service providers might not support this. + #[serde(default)] send_anonymously: bool, } diff --git a/clients/socks5/src/commands/run.rs b/clients/socks5/src/commands/run.rs index 612ecc02c2..48d4651d15 100644 --- a/clients/socks5/src/commands/run.rs +++ b/clients/socks5/src/commands/run.rs @@ -120,6 +120,10 @@ pub(crate) async fn execute(args: &Run) -> Result<(), Box Date: Thu, 15 Dec 2022 15:45:54 +0000 Subject: [PATCH 28/39] fix: ignore corrupted surb storage and instead create fresh one (#2711) * checking for correct surb metadata on db load * archiving corrupted database on load and attempting to start fresh session instead * checking for data corruption by looking at flush timestamp * Moving public import to separate section --- .../client/base_client/non_wasm_helpers.rs | 80 +++++++++++++------ .../reply_storage/backend/fs_backend/mod.rs | 16 +++- 2 files changed, 70 insertions(+), 26 deletions(-) diff --git a/clients/client-core/src/client/base_client/non_wasm_helpers.rs b/clients/client-core/src/client/base_client/non_wasm_helpers.rs index 8c51c784c8..2d710052b1 100644 --- a/clients/client-core/src/client/base_client/non_wasm_helpers.rs +++ b/clients/client-core/src/client/base_client/non_wasm_helpers.rs @@ -8,6 +8,57 @@ use crate::config::DebugConfig; use crate::error::ClientCoreError; use log::{error, info}; use std::path::Path; +use std::{fs, io}; +use time::OffsetDateTime; + +async fn setup_fresh_backend>( + db_path: P, + debug_config: &DebugConfig, +) -> Result> { + info!("creating fresh surb database"); + let mut storage_backend = match fs_backend::Backend::init(db_path).await { + Ok(backend) => backend, + Err(err) => { + error!("failed to setup persistent storage backend for our reply needs: {err}"); + return Err(ClientCoreError::SurbStorageError { source: err }); + } + }; + + // while I kinda hate that we're going to be creating `CombinedReplyStorage` twice, + // it will only be happening on the very first run and in practice won't incur huge + // costs since the storage is going to be empty + let mem_store = CombinedReplyStorage::new( + debug_config.minimum_reply_surb_storage_threshold, + debug_config.maximum_reply_surb_storage_threshold, + ); + storage_backend + .init_fresh(&mem_store) + .await + .map_err(|err| ClientCoreError::SurbStorageError { source: err })?; + + Ok(storage_backend) +} + +fn archive_corrupted_database>(db_path: P) -> io::Result<()> { + let db_path = db_path.as_ref(); + debug_assert!(db_path.exists()); + + let now = OffsetDateTime::now_utc().unix_timestamp(); + + let suffix = format!("_{now}.corrupted"); + + let new_extension = + if let Some(existing_extension) = db_path.extension().and_then(|ext| ext.to_str()) { + format!("{existing_extension}.{}", suffix) + } else { + suffix + }; + + let mut renamed = db_path.to_owned(); + renamed.set_extension(new_extension); + + fs::rename(db_path, renamed) +} pub async fn setup_fs_reply_surb_backend>( db_path: P, @@ -20,32 +71,13 @@ pub async fn setup_fs_reply_surb_backend>( match fs_backend::Backend::try_load(db_path).await { Ok(backend) => Ok(backend), Err(err) => { - error!("failed to setup persistent storage backend for our reply needs: {err}"); - Err(ClientCoreError::SurbStorageError { source: err }) + error!("failed to setup persistent storage backend for our reply needs: {err}. We're going to create a fresh database instead. This behaviour might change in the future"); + + archive_corrupted_database(db_path)?; + setup_fresh_backend(db_path, debug_config).await } } } else { - info!("creating fresh surb database"); - let mut storage_backend = match fs_backend::Backend::init(db_path).await { - Ok(backend) => backend, - Err(err) => { - error!("failed to setup persistent storage backend for our reply needs: {err}"); - return Err(ClientCoreError::SurbStorageError { source: err }); - } - }; - - // while I kinda hate that we're going to be creating `CombinedReplyStorage` twice, - // it will only be happening on the very first run and in practice won't incur huge - // costs since the storage is going to be empty - let mem_store = CombinedReplyStorage::new( - debug_config.minimum_reply_surb_storage_threshold, - debug_config.maximum_reply_surb_storage_threshold, - ); - storage_backend - .init_fresh(&mem_store) - .await - .map_err(|err| ClientCoreError::SurbStorageError { source: err })?; - - Ok(storage_backend) + setup_fresh_backend(db_path, debug_config).await } } diff --git a/clients/client-core/src/client/replies/reply_storage/backend/fs_backend/mod.rs b/clients/client-core/src/client/replies/reply_storage/backend/fs_backend/mod.rs index 50916e00c3..9fd48bcd2c 100644 --- a/clients/client-core/src/client/replies/reply_storage/backend/fs_backend/mod.rs +++ b/clients/client-core/src/client/replies/reply_storage/backend/fs_backend/mod.rs @@ -1,7 +1,6 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -pub use self::error::StorageError; use crate::client::replies::reply_storage::backend::fs_backend::manager::StorageManager; use crate::client::replies::reply_storage::backend::fs_backend::models::{ ReplySurbStorageMetadata, StoredReplyKey, StoredReplySurb, StoredSenderTag, StoredSurbSender, @@ -17,6 +16,8 @@ use std::fs; use std::path::{Path, PathBuf}; use time::OffsetDateTime; +pub use self::error::StorageError; + mod error; mod manager; mod models; @@ -66,6 +67,12 @@ impl Backend { return Err(StorageError::IncompleteDataFlush); } + let last_flush_timestamp = manager.get_previous_flush_timestamp().await?; + if last_flush_timestamp == 0 { + // either this client has been running since 1970 or the flush failed + return Err(StorageError::IncompleteDataFlush); + } + // the process has gone down without full graceful shutdown, // meaning the database doesn't contain valid data anymore // so we have to purge it @@ -75,7 +82,12 @@ impl Backend { manager.delete_all_reply_keys().await?; } - let last_flush_timestamp = manager.get_previous_flush_timestamp().await?; + if let Err(err) = manager.get_reply_surb_storage_metadata().await { + // we can't recover here, we HAVE TO initialise fresh (because we don't know correct starting metadata) + error!("it seems the client has been shutdown gracefully - we're missing valid surb data dump. the existing database cannot be used"); + return Err(err.into()); + } + let last_flush = match OffsetDateTime::from_unix_timestamp(last_flush_timestamp) { Ok(last_flush) => last_flush, Err(err) => { From a0a73421d0c15a73fc8dfe034201d9ce5eb38dca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Fri, 16 Dec 2022 11:19:53 +0100 Subject: [PATCH 29/39] fix clippy for new rustc --- validator-api/src/coconut/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validator-api/src/coconut/tests.rs b/validator-api/src/coconut/tests.rs index 2a687eef24..cc75a112b2 100644 --- a/validator-api/src/coconut/tests.rs +++ b/validator-api/src/coconut/tests.rs @@ -282,7 +282,7 @@ impl super::client::Client for DummyClient { self.dealer_details.write().unwrap().insert( self.validator_address.to_string(), DealerDetails { - address: Addr::unchecked(&self.validator_address.to_string()), + address: Addr::unchecked(self.validator_address.to_string()), bte_public_key_with_proof, announce_address, assigned_index, From 901275fd63b19d6f0e44017ccc433b56778e346e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Fri, 16 Dec 2022 12:02:23 +0100 Subject: [PATCH 30/39] wallet: rewrite some abci errors on the fly (#2716) * wallet: rewrite some abci errors on the fly * changelog: update * Tidy --- .../validator-client/src/connection_tester.rs | 2 +- .../src/nymd/cosmwasm_client/client.rs | 10 +--- .../validator-client/src/nymd/error.rs | 55 ++++++++++++++++--- nym-wallet/CHANGELOG.md | 4 ++ nym-wallet/src-tauri/src/error.rs | 33 ++++++++++- 5 files changed, 85 insertions(+), 19 deletions(-) diff --git a/common/client-libs/validator-client/src/connection_tester.rs b/common/client-libs/validator-client/src/connection_tester.rs index dc1acb8cd9..30e57ff95e 100644 --- a/common/client-libs/validator-client/src/connection_tester.rs +++ b/common/client-libs/validator-client/src/connection_tester.rs @@ -108,7 +108,7 @@ async fn test_nymd_connection( log::debug!("Checking: nymd_url: {url}: {}: {}", "failed".red(), e); false } - Ok(Err(NymdError::AbciError(code, log))) => { + Ok(Err(NymdError::AbciError { code, log, .. })) => { // We accept the mixnet contract not found as ok from a connection standpoint. This happens // for example on a pre-launch network. log::debug!( diff --git a/common/client-libs/validator-client/src/nymd/cosmwasm_client/client.rs b/common/client-libs/validator-client/src/nymd/cosmwasm_client/client.rs index 8da9d3192c..580a8c7c05 100644 --- a/common/client-libs/validator-client/src/nymd/cosmwasm_client/client.rs +++ b/common/client-libs/validator-client/src/nymd/cosmwasm_client/client.rs @@ -1,6 +1,7 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::nymd; use crate::nymd::coin::Coin; use crate::nymd::cosmwasm_client::helpers::{create_pagination, next_page_key}; use crate::nymd::cosmwasm_client::types::{ @@ -23,7 +24,6 @@ use cosmrs::rpc::endpoint::broadcast; use cosmrs::rpc::endpoint::tx::Response as TxResponse; use cosmrs::rpc::query::Query; use cosmrs::rpc::{self, HttpClient, Order}; -use cosmrs::tendermint::abci::Code as AbciCode; use cosmrs::tendermint::abci::Transaction; use cosmrs::tendermint::{abci, block, chain}; use cosmrs::{tx, AccountId, Coin as CosmosCoin, Tx}; @@ -66,13 +66,9 @@ pub trait CosmWasmClient: rpc::Client { req.encode(&mut buf)?; let res = self.abci_query(path, buf, None, false).await?; + let res_success = nymd::error::parse_abci_query_result(res)?; - match res.code { - AbciCode::Err(code) => return Err(NymdError::AbciError(code, res.log)), - AbciCode::Ok => (), - } - - Ok(Res::decode(res.value.as_ref())?) + Ok(Res::decode(res_success.value.as_ref())?) } async fn get_chain_id(&self) -> Result { diff --git a/common/client-libs/validator-client/src/nymd/error.rs b/common/client-libs/validator-client/src/nymd/error.rs index 0b6dcfe22b..e530f6c54d 100644 --- a/common/client-libs/validator-client/src/nymd/error.rs +++ b/common/client-libs/validator-client/src/nymd/error.rs @@ -2,16 +2,23 @@ // SPDX-License-Identifier: Apache-2.0 use crate::nymd::cosmwasm_client::types::ContractCodeId; -use cosmrs::tendermint::{abci, block}; -use cosmrs::{bip32, tx, AccountId}; -use std::io; -use std::time::Duration; +use cosmrs::{ + bip32, + rpc::endpoint::abci_query::AbciQuery, + tendermint::{ + abci::{self, Code as AbciCode}, + block, + }, + tx, AccountId, +}; use thiserror::Error; -pub use cosmrs::rpc::error::{ - Error as TendermintRpcError, ErrorDetail as TendermintRpcErrorDetail, +use std::{io, time::Duration}; + +pub use cosmrs::rpc::{ + error::{Error as TendermintRpcError, ErrorDetail as TendermintRpcErrorDetail}, + response_error::{Code, ResponseError}, }; -pub use cosmrs::rpc::response_error::{Code, ResponseError}; #[derive(Debug, Error)] pub enum NymdError { @@ -110,8 +117,12 @@ pub enum NymdError { #[error("Failed to estimate gas price for the transaction")] GasEstimationFailure, - #[error("Abci query failed with code {0} - {1}")] - AbciError(u32, abci::Log), + #[error("Abci query failed with code {code} - {log}")] + AbciError { + code: u32, + log: abci::Log, + pretty_log: Option, + }, #[error("Unsupported account type: {type_url}")] UnsupportedAccountType { type_url: String }, @@ -135,6 +146,32 @@ pub enum NymdError { UnexpectedBech32Prefix { got: String, expected: String }, } +// The purpose of parsing the abci query result is that we want to generate the `pretty_log` if +// possible. +pub fn parse_abci_query_result(query_result: AbciQuery) -> Result { + match query_result.code { + AbciCode::Ok => Ok(query_result), + AbciCode::Err(code) => Err(NymdError::AbciError { + code, + log: query_result.log.clone(), + pretty_log: try_parse_abci_log(&query_result.log), + }), + } +} + +// Some of the error strings returned by the query are a bit too technical to present to the +// enduser. So we special case some commonly encountered errors. +fn try_parse_abci_log(log: &abci::Log) -> Option { + if log + .value() + .contains("Maximum amount of locked coins has already been pledged") + { + Some("Maximum amount of locked tokens has alredy been used. You can only use up tp 10% of your locked tokens for bonding and delegating.".to_string()) + } else { + None + } +} + impl NymdError { pub fn is_tendermint_response_timeout(&self) -> bool { match &self { diff --git a/nym-wallet/CHANGELOG.md b/nym-wallet/CHANGELOG.md index d6ca3521d9..ef1fb52d15 100644 --- a/nym-wallet/CHANGELOG.md +++ b/nym-wallet/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## UNRELEASED + +- wallet: present some cases of the more technical errors (abci, ..) in a more human readable form. + ## [nym-wallet-v1.1.3](https://github.com/nymtech/nym/releases/tag/nym-wallet-v1.1.3) (2022-12-13) - wallet: improved unbond screen. diff --git a/nym-wallet/src-tauri/src/error.rs b/nym-wallet/src-tauri/src/error.rs index 46d8840947..efef933c73 100644 --- a/nym-wallet/src-tauri/src/error.rs +++ b/nym-wallet/src-tauri/src/error.rs @@ -24,9 +24,10 @@ pub enum BackendError { #[from] source: tendermint_rpc::Error, }, - #[error("{source}")] + #[error("{pretty_error}")] NymdError { - #[from] + pretty_error: String, + #[source] source: NymdError, }, #[error("{source}")] @@ -131,6 +132,34 @@ impl Serialize for BackendError { } } +impl From for BackendError { + fn from(source: NymdError) -> Self { + match source { + NymdError::AbciError { + code: _, + log: _, + ref pretty_log, + } => { + if let Some(pretty_log) = pretty_log { + Self::NymdError { + pretty_error: pretty_log.to_string(), + source, + } + } else { + Self::NymdError { + pretty_error: source.to_string(), + source, + } + } + } + nymd_error => Self::NymdError { + pretty_error: nymd_error.to_string(), + source: nymd_error, + }, + } + } +} + impl From for BackendError { fn from(e: ValidatorClientError) -> Self { match e { From 52156e0c3890f1ba746e11ab290ed0f75bb262da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Mon, 19 Dec 2022 09:12:33 +0100 Subject: [PATCH 31/39] validator-client: fix typo in error message --- common/client-libs/validator-client/src/nymd/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/client-libs/validator-client/src/nymd/error.rs b/common/client-libs/validator-client/src/nymd/error.rs index e530f6c54d..1ebaa4e020 100644 --- a/common/client-libs/validator-client/src/nymd/error.rs +++ b/common/client-libs/validator-client/src/nymd/error.rs @@ -166,7 +166,7 @@ fn try_parse_abci_log(log: &abci::Log) -> Option { .value() .contains("Maximum amount of locked coins has already been pledged") { - Some("Maximum amount of locked tokens has alredy been used. You can only use up tp 10% of your locked tokens for bonding and delegating.".to_string()) + Some("Maximum amount of locked tokens has alredy been used. You can only use up to 10% of your locked tokens for bonding and delegating.".to_string()) } else { None } From db3d379219acdb07a2df7dc1248516453d442b9d Mon Sep 17 00:00:00 2001 From: fmtabbara Date: Mon, 19 Dec 2022 15:07:49 +0000 Subject: [PATCH 32/39] update buy NYM text --- nym-wallet/src/components/Buy/Tutorial.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/nym-wallet/src/components/Buy/Tutorial.tsx b/nym-wallet/src/components/Buy/Tutorial.tsx index 472edb24cd..316f033347 100644 --- a/nym-wallet/src/components/Buy/Tutorial.tsx +++ b/nym-wallet/src/components/Buy/Tutorial.tsx @@ -56,10 +56,9 @@ export const Tutorial = () => { const showBorder = useMediaQuery(theme.breakpoints.up('md')); return ( - }> + }> - Follow below 3 steps to quickly and easily buy NYM tokens. You can purchase up to 1000 Swiss Francs per day - without KYC. + Follow below 3 steps to quickly and easily buy NYM tokens. You can purchase up to 1000 Swiss Francs per day. {showSignModal && setShowSignModal(false)} />} Date: Fri, 16 Dec 2022 12:10:06 +0000 Subject: [PATCH 33/39] Test and earn - add logging and clear local storage menu items - bump nym-connect version - add app version number - add reset trigger when clearing SP storage - bump tauri version (nym-connect and nym-wallet) - fix webpack config for prod builds - new selector for services, with an advanced section for service providers --- nym-connect/.storybook/main.js | 13 + .../.storybook/mocks/tauri/notification.js | 10 + nym-connect/Cargo.lock | 318 +- nym-connect/package.json | 10 +- nym-connect/public/growth.html | 11 + nym-connect/public/index.html | 2 +- nym-connect/public/log.html | 11 + nym-connect/src-tauri/Cargo.toml | 21 +- nym-connect/src-tauri/src/config/mod.rs | 7 + nym-connect/src-tauri/src/error.rs | 12 + nym-connect/src-tauri/src/logging.rs | 113 + nym-connect/src-tauri/src/main.rs | 32 +- nym-connect/src-tauri/src/menu.rs | 44 +- nym-connect/src-tauri/src/models/mod.rs | 24 +- .../src/operations/connection/connect.rs | 8 +- .../src/operations/connection/mod.rs | 1 + .../src/operations/connection/status.rs | 15 + .../src-tauri/src/operations/directory/mod.rs | 39 +- .../src-tauri/src/operations/export.rs | 18 + .../src/operations/growth/api_client.rs | 271 + .../src-tauri/src/operations/growth/assets.rs | 57 + .../src-tauri/src/operations/growth/mod.rs | 3 + .../src/operations/growth/test_and_earn.rs | 156 + .../src-tauri/src/operations/help/log.rs | 30 + .../src-tauri/src/operations/help/mod.rs | 2 + .../src-tauri/src/operations/help/storage.rs | 20 + nym-connect/src-tauri/src/operations/mod.rs | 2 + nym-connect/src-tauri/src/state.rs | 8 +- nym-connect/src-tauri/tauri.conf.json | 7 +- nym-connect/src/App.tsx | 13 +- nym-connect/src/components/AppVersion.tsx | 15 + nym-connect/src/components/AppWindowFrame.tsx | 5 +- .../src/components/CopyToClipboard.tsx | 8 +- nym-connect/src/components/ErrorFallback.tsx | 17 + .../Growth/TestAndEarnButtonArea.tsx | 83 + .../Growth/TestAndEarnCurrentDraw.stories.tsx | 94 + .../Growth/TestAndEarnCurrentDraw.tsx | 192 + .../Growth/TestAndEarnDraws.stories.tsx | 18 + .../components/Growth/TestAndEarnDraws.tsx | 195 + .../TestAndEarnEnterWalletAddress.stories.tsx | 41 + .../Growth/TestAndEarnEnterWalletAddress.tsx | 37 + .../components/Growth/TestAndEarnError.tsx | 13 + .../Growth/TestAndEarnPopup.stories.tsx | 167 + .../components/Growth/TestAndEarnPopup.tsx | 118 + .../components/Growth/TestAndEarnTakePart.tsx | 75 + .../Growth/TestAndEarnWinner.stories.tsx | 18 + .../components/Growth/TestAndEarnWinner.tsx | 114 + .../Growth/TestAndEarnWinnerWalletAddress.tsx | 12 + .../Growth/content/TestAndEarn/Error.mdx | 17 + .../content/TestAndEarn/Stage0_intro.mdx | 25 + .../TestAndEarn/WinnerEntersWalletAddress.mdx | 9 + .../content/TestAndEarnNotAvaialble.mdx | 3 + .../Growth/content/assets/matrix.webp | Bin 0 -> 1170192 bytes .../Growth/content/assets/winner.webp | Bin 0 -> 510504 bytes .../src/components/Growth/content/en.yaml | 43 + .../Growth/context/TestAndEarnContext.tsx | 272 + .../context/mocks/TestAndEarnContext.tsx | 262 + .../src/components/Growth/context/types.ts | 66 + .../src/components/LogViewer/index.tsx | 97 + .../src/components/ServiceProviderPopup.tsx | 37 + .../ServiceProviderSelector.stories.tsx | 342 ++ .../components/ServiceProviderSelector.tsx | 32 +- .../components/ServiceSelector.stories.tsx | 342 ++ .../src/components/ServiceSelector.tsx | 179 + nym-connect/src/context/main.tsx | 35 +- nym-connect/src/context/mocks/main.tsx | 10 +- nym-connect/src/growth.tsx | 23 + nym-connect/src/index.tsx | 13 +- nym-connect/src/layouts/ConnectedLayout.tsx | 2 + nym-connect/src/layouts/DefaultLayout.tsx | 35 +- nym-connect/src/log.tsx | 18 + nym-connect/src/stories/AppFlow.stories.tsx | 78 +- nym-connect/src/theme/index.tsx | 13 +- nym-connect/src/theme/mui-theme.d.ts | 4 + nym-connect/src/theme/theme.tsx | 60 +- nym-connect/src/typings/webp.d.ts | 4 + nym-connect/src/typings/yaml.d.ts | 9 + nym-connect/src/utils/index.ts | 20 +- nym-connect/webpack.common.js | 53 +- nym-connect/webpack.prod.js | 8 +- nym-wallet/Cargo.lock | 395 +- nym-wallet/package.json | 2 +- nym-wallet/src-tauri/Cargo.toml | 8 +- ts-packages/react-components/package.json | 3 +- .../WalletAddressFormField.stories.tsx | 42 + .../account/WalletAddressFormField.tsx | 105 + ts-packages/types/package.json | 3 +- ts-packages/types/src/utils/accounts/index.ts | 28 + ts-packages/types/src/utils/index.ts | 1 + ts-packages/webpack/webpack.common.js | 2 +- yarn.lock | 5016 ++++++++++++++++- 91 files changed, 9602 insertions(+), 614 deletions(-) create mode 100644 nym-connect/.storybook/mocks/tauri/notification.js create mode 100644 nym-connect/public/growth.html create mode 100644 nym-connect/public/log.html create mode 100644 nym-connect/src-tauri/src/logging.rs create mode 100644 nym-connect/src-tauri/src/operations/connection/status.rs create mode 100644 nym-connect/src-tauri/src/operations/growth/api_client.rs create mode 100644 nym-connect/src-tauri/src/operations/growth/assets.rs create mode 100644 nym-connect/src-tauri/src/operations/growth/mod.rs create mode 100644 nym-connect/src-tauri/src/operations/growth/test_and_earn.rs create mode 100644 nym-connect/src-tauri/src/operations/help/log.rs create mode 100644 nym-connect/src-tauri/src/operations/help/mod.rs create mode 100644 nym-connect/src-tauri/src/operations/help/storage.rs create mode 100644 nym-connect/src/components/AppVersion.tsx create mode 100644 nym-connect/src/components/ErrorFallback.tsx create mode 100644 nym-connect/src/components/Growth/TestAndEarnButtonArea.tsx create mode 100644 nym-connect/src/components/Growth/TestAndEarnCurrentDraw.stories.tsx create mode 100644 nym-connect/src/components/Growth/TestAndEarnCurrentDraw.tsx create mode 100644 nym-connect/src/components/Growth/TestAndEarnDraws.stories.tsx create mode 100644 nym-connect/src/components/Growth/TestAndEarnDraws.tsx create mode 100644 nym-connect/src/components/Growth/TestAndEarnEnterWalletAddress.stories.tsx create mode 100644 nym-connect/src/components/Growth/TestAndEarnEnterWalletAddress.tsx create mode 100644 nym-connect/src/components/Growth/TestAndEarnError.tsx create mode 100644 nym-connect/src/components/Growth/TestAndEarnPopup.stories.tsx create mode 100644 nym-connect/src/components/Growth/TestAndEarnPopup.tsx create mode 100644 nym-connect/src/components/Growth/TestAndEarnTakePart.tsx create mode 100644 nym-connect/src/components/Growth/TestAndEarnWinner.stories.tsx create mode 100644 nym-connect/src/components/Growth/TestAndEarnWinner.tsx create mode 100644 nym-connect/src/components/Growth/TestAndEarnWinnerWalletAddress.tsx create mode 100644 nym-connect/src/components/Growth/content/TestAndEarn/Error.mdx create mode 100644 nym-connect/src/components/Growth/content/TestAndEarn/Stage0_intro.mdx create mode 100644 nym-connect/src/components/Growth/content/TestAndEarn/WinnerEntersWalletAddress.mdx create mode 100644 nym-connect/src/components/Growth/content/TestAndEarnNotAvaialble.mdx create mode 100644 nym-connect/src/components/Growth/content/assets/matrix.webp create mode 100644 nym-connect/src/components/Growth/content/assets/winner.webp create mode 100644 nym-connect/src/components/Growth/content/en.yaml create mode 100644 nym-connect/src/components/Growth/context/TestAndEarnContext.tsx create mode 100644 nym-connect/src/components/Growth/context/mocks/TestAndEarnContext.tsx create mode 100644 nym-connect/src/components/Growth/context/types.ts create mode 100644 nym-connect/src/components/LogViewer/index.tsx create mode 100644 nym-connect/src/components/ServiceProviderPopup.tsx create mode 100644 nym-connect/src/components/ServiceProviderSelector.stories.tsx create mode 100644 nym-connect/src/components/ServiceSelector.stories.tsx create mode 100644 nym-connect/src/components/ServiceSelector.tsx create mode 100644 nym-connect/src/growth.tsx create mode 100644 nym-connect/src/log.tsx create mode 100644 nym-connect/src/typings/webp.d.ts create mode 100644 nym-connect/src/typings/yaml.d.ts create mode 100644 ts-packages/react-components/src/components/account/WalletAddressFormField.stories.tsx create mode 100644 ts-packages/react-components/src/components/account/WalletAddressFormField.tsx create mode 100644 ts-packages/types/src/utils/accounts/index.ts diff --git a/nym-connect/.storybook/main.js b/nym-connect/.storybook/main.js index c4a255d616..344c27778e 100644 --- a/nym-connect/.storybook/main.js +++ b/nym-connect/.storybook/main.js @@ -30,6 +30,19 @@ module.exports = { use: ['@svgr/webpack'], }); + config.module.rules.unshift({ + test: /\.ya?ml$/, + type: 'json', + use: [ + { + loader: 'yaml-loader', + options: { + asJSON: true, + }, + }, + ], + }); + config.resolve.extensions = ['.tsx', '.ts', '.js']; config.resolve.plugins = [new TsconfigPathsPlugin()]; diff --git a/nym-connect/.storybook/mocks/tauri/notification.js b/nym-connect/.storybook/mocks/tauri/notification.js new file mode 100644 index 0000000000..dcbe18e574 --- /dev/null +++ b/nym-connect/.storybook/mocks/tauri/notification.js @@ -0,0 +1,10 @@ +/** + * This is a mock for Tauri's API package (@tauri-apps/api/notification), to prevent stories from being excluded, because they either use + * or import dependencies that use Tauri. + */ + +module.exports = { + isPermissionGranted: () => undefined, + requestPermission: () => undefined, + sendNotification: () => undefined, +}; \ No newline at end of file diff --git a/nym-connect/Cargo.lock b/nym-connect/Cargo.lock index 711edb17af..a9f80869be 100644 --- a/nym-connect/Cargo.lock +++ b/nym-connect/Cargo.lock @@ -14,12 +14,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "adler32" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" - [[package]] name = "aes" version = "0.7.5" @@ -469,12 +463,11 @@ dependencies = [ [[package]] name = "cargo_toml" -version = "0.11.6" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4419e9adae9fd7e231b60d50467481bf8181ddeef6ed54683b23ae925c74c9c" +checksum = "aa0e3586af56b3bfa51fca452bd56e8dbbbd5d8d81cbf0b7e4e35b695b537eb8" dependencies = [ "serde", - "serde_derive", "toml", ] @@ -754,6 +747,17 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "colored" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59" +dependencies = [ + "atty", + "lazy_static", + "winapi", +] + [[package]] name = "colored" version = "2.0.0" @@ -1315,13 +1319,14 @@ dependencies = [ ] [[package]] -name = "deflate" -version = "0.7.20" +name = "dbus" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4" +checksum = "6f8bcdd56d2e5c4ed26a529c5a9029f5db8290d433497506f958eae3be148eb6" dependencies = [ - "adler32", - "byteorder", + "libc", + "libdbus-sys", + "winapi", ] [[package]] @@ -1470,6 +1475,12 @@ dependencies = [ "dtoa", ] +[[package]] +name = "dunce" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bd4b30a6560bbd9b4620f4de34c3f14f60848e58a9b7216801afcb4c7b31c3c" + [[package]] name = "dyn-clone" version = "1.0.9" @@ -1631,6 +1642,16 @@ dependencies = [ "instant", ] +[[package]] +name = "fern" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bdd7b0849075e79ee9a1836df22c717d1eba30451796fdc631b04565dd11e2a" +dependencies = [ + "colored 1.9.3", + "log", +] + [[package]] name = "ff" version = "0.10.1" @@ -2619,12 +2640,12 @@ dependencies = [ [[package]] name = "ico" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a4b3331534254a9b64095ae60d3dc2a8225a7a70229cd5888be127cdc1f6804" +checksum = "031530fe562d8c8d71c0635013d6d155bbfe8ba0aa4b4d2d24ce8af6b71047bd" dependencies = [ "byteorder", - "png 0.11.0", + "png", ] [[package]] @@ -2701,15 +2722,6 @@ dependencies = [ "cfb", ] -[[package]] -name = "inflate" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5f9f47468e9a76a6452271efadc88fe865a82be91fe75e6c0c57b87ccea59d4" -dependencies = [ - "adler32", -] - [[package]] name = "inout" version = "0.1.3" @@ -2748,9 +2760,9 @@ checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" [[package]] name = "itertools" -version = "0.10.4" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8bf247779e67a9082a4790b45e71ac7cfd1321331a5c856a74a9faebdab78d0" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ "either", ] @@ -2792,9 +2804,9 @@ dependencies = [ [[package]] name = "jni" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec" +checksum = "039022cdf4d7b1cf548d31f60ae783138e5fd42013f6271049d7df7afadef96c" dependencies = [ "cesu8", "combine", @@ -2913,6 +2925,15 @@ version = "0.2.132" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" +[[package]] +name = "libdbus-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c185b5b7ad900923ef3a8ff594083d4d9b5aea80bb4f32b8342363138c0d456b" +dependencies = [ + "pkg-config", +] + [[package]] name = "libgit2-sys" version = "0.14.0+1.5.0" @@ -2973,6 +2994,12 @@ dependencies = [ "safemem", ] +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "lioness" version = "0.1.2" @@ -3002,6 +3029,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", + "serde", ] [[package]] @@ -3033,6 +3061,19 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" +[[package]] +name = "mac-notification-sys" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e72d50edb17756489e79d52eb146927bec8eba9dd48faadf9ef08bca3791ad5" +dependencies = [ + "cc", + "dirs-next", + "objc-foundation", + "objc_id", + "time 0.3.17", +] + [[package]] name = "malloc_buf" version = "0.0.6" @@ -3254,6 +3295,17 @@ dependencies = [ "wasm-timer", ] +[[package]] +name = "notify-rust" +version = "4.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368e89ea58df747ce88be669ae44e79783c1d30bfd540ad0fc520b3f41f0b3b0" +dependencies = [ + "dbus", + "mac-notification-sys", + "tauri-winrt-notification", +] + [[package]] name = "num-derive" version = "0.3.3" @@ -3275,17 +3327,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-iter" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" -dependencies = [ - "autocfg 1.1.0", - "num-integer", - "num-traits", -] - [[package]] name = "num-rational" version = "0.4.1" @@ -3342,21 +3383,28 @@ dependencies = [ name = "nym-connect" version = "1.1.2" dependencies = [ + "anyhow", "bip39", + "chrono", "client-core", "config", + "crypto", "dirs", "eyre", + "fern", "fix-path-env", "futures", + "itertools", "log", "logging", "nym-socks5-client", "pretty_env_logger", "rand 0.8.5", "reqwest", + "rust-embed", "serde", "serde_json", + "serde_repr", "tap", "task", "tauri", @@ -3370,6 +3418,7 @@ dependencies = [ "topology", "ts-rs", "url", + "yaml-rust", ] [[package]] @@ -3594,9 +3643,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.14.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" [[package]] name = "opaque-debug" @@ -4046,18 +4095,6 @@ dependencies = [ "xml-rs", ] -[[package]] -name = "png" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0b0cabbbd20c2d7f06dbf015e06aad59b6ca3d9ed14848783e98af9aaf19925" -dependencies = [ - "bitflags", - "deflate", - "inflate", - "num-iter", -] - [[package]] name = "png" version = "0.17.6" @@ -4202,6 +4239,15 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" +[[package]] +name = "quick-xml" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11bafc859c6815fbaffbbbf4229ecb767ac913fecb27f9ad4343662e9ef099ea" +dependencies = [ + "memchr", +] + [[package]] name = "quote" version = "1.0.21" @@ -4454,9 +4500,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" dependencies = [ "aho-corasick", "memchr", @@ -4516,6 +4562,7 @@ dependencies = [ "serde_urlencoded", "tokio", "tokio-native-tls", + "tokio-socks", "tower-service", "url", "wasm-bindgen", @@ -4585,6 +4632,41 @@ dependencies = [ "opaque-debug 0.3.0", ] +[[package]] +name = "rust-embed" +version = "6.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "283ffe2f866869428c92e0d61c2f35dfb4355293cdfdc48f49e895c15f1333d1" +dependencies = [ + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "6.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31ab23d42d71fb9be1b643fe6765d292c5e14d46912d13f3ae2815ca048ea04d" +dependencies = [ + "proc-macro2", + "quote", + "rust-embed-utils", + "syn", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "7.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1669d81dfabd1b5f8e2856b8bbe146c6192b0ba22162edc738ac0a5de18f054" +dependencies = [ + "globset", + "sha2 0.10.6", + "walkdir", +] + [[package]] name = "rustc_version" version = "0.3.3" @@ -5440,6 +5522,27 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strum" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7ac893c7d471c8a21f31cfe213ec4f6d9afeed25537c772e08ef3f005f8729e" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339f799d8b549e3744c7ac7feb216383e4005d94bdb22561b3ab8f3b808ae9fb" +dependencies = [ + "heck 0.3.3", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "subtle" version = "1.0.0" @@ -5512,9 +5615,9 @@ dependencies = [ [[package]] name = "tao" -version = "0.14.0" +version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43336f5d1793543ba96e2a1e75f3a5c7dcd592743be06a0ab3a190f4fcb4b934" +checksum = "a1fa15735311b4816d030ff54da58560b047daca0970e1031aed5502e84231a8" dependencies = [ "bitflags", "cairo-rs", @@ -5547,12 +5650,12 @@ dependencies = [ "once_cell", "parking_lot 0.12.1", "paste", - "png 0.17.6", + "png", "raw-window-handle", "scopeguard", "serde", "unicode-segmentation", - "uuid 1.1.2", + "uuid 1.2.2", "windows 0.39.0", "windows-implement", "x11-dl", @@ -5589,9 +5692,9 @@ dependencies = [ [[package]] name = "tauri" -version = "1.1.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efbf22abd61d95ca9b2becd77f9db4c093892f73e8a07d21d8b0b2bf71a7bcea" +checksum = "d8ea1d785ab2164373703817bff144c4610a69ad3f659becaca0e1ea004b98d8" dependencies = [ "anyhow", "attohttpc", @@ -5609,6 +5712,7 @@ dependencies = [ "http", "ignore", "minisign-verify", + "notify-rust", "objc", "once_cell", "open", @@ -5633,7 +5737,7 @@ dependencies = [ "time 0.3.17", "tokio", "url", - "uuid 1.1.2", + "uuid 1.2.2", "webkit2gtk", "webview2-com", "windows 0.39.0", @@ -5642,9 +5746,9 @@ dependencies = [ [[package]] name = "tauri-build" -version = "1.1.1" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0991fb306849897439dbd4a72e4cbed2413e2eb26cb4b3ba220b94edba8b4b88" +checksum = "8807c85d656b2b93927c19fe5a5f1f1f348f96c2de8b90763b3c2d561511f9b4" dependencies = [ "anyhow", "cargo_toml", @@ -5658,16 +5762,16 @@ dependencies = [ [[package]] name = "tauri-codegen" -version = "1.1.1" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "356fa253e40ae4d6ff02075011f2f2bb4066f5c9d8c1e16ca6912d7b75903ba6" +checksum = "14388d484b6b1b5dc0f6a7d6cc6433b3b230bec85eaa576adcdf3f9fafa49251" dependencies = [ "base64", "brotli", "ico", "json-patch", "plist", - "png 0.17.6", + "png", "proc-macro2", "quote", "regex", @@ -5678,15 +5782,15 @@ dependencies = [ "tauri-utils", "thiserror", "time 0.3.17", - "uuid 1.1.2", + "uuid 1.2.2", "walkdir", ] [[package]] name = "tauri-macros" -version = "1.1.1" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6051fd6940ddb22af452340d03c66a3e2f5d72e0788d4081d91e31528ccdc4d" +checksum = "069319e5ecbe653a799b94b0690d9f9bf5d00f7b1d3989aa331c524d4e354075" dependencies = [ "heck 0.4.0", "proc-macro2", @@ -5698,30 +5802,29 @@ dependencies = [ [[package]] name = "tauri-runtime" -version = "0.11.1" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d49439a5ea47f474572b854972f42eda2e02a470be5ca9609cc83bb66945abe2" +checksum = "c507d954d08ac8705d235bc70ec6975b9054fb95ff7823af72dbb04186596f3b" dependencies = [ "gtk", "http", "http-range", - "infer", "rand 0.8.5", "raw-window-handle", "serde", "serde_json", "tauri-utils", "thiserror", - "uuid 1.1.2", + "uuid 1.2.2", "webview2-com", "windows 0.39.0", ] [[package]] name = "tauri-runtime-wry" -version = "0.11.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dce920995fd49907aa9bea7249ed1771454f11f7611924c920a1f75fb614d4" +checksum = "36b1c5764a41a13176a4599b5b7bd0881bea7d94dfe45e1e755f789b98317e30" dependencies = [ "cocoa", "gtk", @@ -5730,7 +5833,7 @@ dependencies = [ "raw-window-handle", "tauri-runtime", "tauri-utils", - "uuid 1.1.2", + "uuid 1.2.2", "webkit2gtk", "webview2-com", "windows 0.39.0", @@ -5739,15 +5842,16 @@ dependencies = [ [[package]] name = "tauri-utils" -version = "1.1.1" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e8fdae6f29cef959809a3c3afef510c5b715a446a597ab8b791497585363f39" +checksum = "5abbc109a6eb45127956ffcc26ef0e875d160150ac16cfa45d26a6b2871686f1" dependencies = [ "brotli", "ctor", "glob", "heck 0.4.0", "html5ever", + "infer", "json-patch", "kuchiki", "memchr", @@ -5764,6 +5868,17 @@ dependencies = [ "windows 0.39.0", ] +[[package]] +name = "tauri-winrt-notification" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c58de036c4d2e20717024de2a3c4bf56c301f07b21bc8ef9b57189fce06f1f3b" +dependencies = [ + "quick-xml", + "strum", + "windows 0.39.0", +] + [[package]] name = "tempfile" version = "3.3.0" @@ -6036,6 +6151,18 @@ dependencies = [ "webpki 0.22.0", ] +[[package]] +name = "tokio-socks" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51165dfa029d2a65969413a6cc96f354b86b464498702f174a4efa13608fd8c0" +dependencies = [ + "either", + "futures-util", + "thiserror", + "tokio", +] + [[package]] name = "tokio-stream" version = "0.1.10" @@ -6327,9 +6454,9 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" [[package]] name = "uuid" -version = "1.1.2" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd6469f4314d5f1ffec476e05f17cc9a78bc7a27a6a857842170bdf8d6f98d2f" +checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" dependencies = [ "getrandom 0.2.7", ] @@ -6358,7 +6485,7 @@ dependencies = [ "coconut-bandwidth-contract-common", "coconut-dkg-common", "coconut-interface", - "colored", + "colored 2.0.0", "config", "contracts-common", "cosmrs", @@ -6629,9 +6756,9 @@ dependencies = [ [[package]] name = "webkit2gtk" -version = "0.18.0" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29952969fb5e10fe834a52eb29ad0814ccdfd8387159b0933edf1344a1c9cdcc" +checksum = "b8f859735e4a452aeb28c6c56a852967a8a76c8eb1cc32dbf931ad28a13d6370" dependencies = [ "bitflags", "cairo-rs", @@ -7006,15 +7133,16 @@ dependencies = [ [[package]] name = "wry" -version = "0.21.1" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff5c1352b4266fdf92c63479d2f58ab4cd29dc4e78fbc1b62011ed1227926945" +checksum = "4c1ad8e2424f554cc5bdebe8aa374ef5b433feff817aebabca0389961fc7ef98" dependencies = [ "base64", "block", "cocoa", "core-graphics", "crossbeam-channel", + "dunce", "gdk", "gio", "glib", @@ -7030,6 +7158,7 @@ dependencies = [ "serde", "serde_json", "sha2 0.10.6", + "soup2", "tao", "thiserror", "url", @@ -7096,6 +7225,15 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + [[package]] name = "zeroize" version = "1.5.7" @@ -7119,9 +7257,9 @@ dependencies = [ [[package]] name = "zip" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf225bcf73bb52cbb496e70475c7bd7a3f769df699c0020f6c7bd9a96dcf0b8d" +checksum = "537ce7411d25e54e8ae21a7ce0b15840e7bfcff15b51d697ec3266cc76bdf080" dependencies = [ "byteorder", "crc32fast", diff --git a/nym-connect/package.json b/nym-connect/package.json index dbf42df71b..07134780ac 100644 --- a/nym-connect/package.json +++ b/nym-connect/package.json @@ -6,6 +6,7 @@ "scripts": { "prewebpack:dev": "yarn --cwd .. build", "webpack:dev": "yarn webpack serve --config webpack.dev.js", + "webpack:dev:onlyThis": "yarn webpack serve --config webpack.dev.js", "webpack:prod": "yarn webpack --progress --config webpack.prod.js", "tauri:dev": "RUST_DEBUG=1 yarn tauri dev", "tauri:build": "yarn tauri build", @@ -30,7 +31,7 @@ "@mui/material": "^5.2.2", "@mui/styles": "^5.2.2", "@nymproject/react": "^1.0.0", - "@tauri-apps/api": "^1.1.0", + "@tauri-apps/api": "^1.2.0", "@tauri-apps/tauri-forage": "^1.0.0-beta.2", "clsx": "^1.1.1", "luxon": "^2.3.0", @@ -39,6 +40,7 @@ "react-dom": "^17.0.2", "react-error-boundary": "^3.1.3", "react-hook-form": "^7.14.2", + "react-markdown": "^8.0.4", "react-router-dom": "^5.2.0", "semver": "^6.3.0", "yup": "^0.32.9" @@ -49,11 +51,12 @@ "@babel/preset-env": "^7.15.0", "@babel/preset-react": "^7.14.5", "@babel/preset-typescript": "^7.15.0", + "@mdx-js/loader": "^2.1.5", "@nymproject/eslint-config-react-typescript": "^1.0.0", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.4", "@storybook/react": "^6.5.8", "@svgr/webpack": "^6.1.1", - "@tauri-apps/cli": "^1.1.0", + "@tauri-apps/cli": "^1.2.2", "@testing-library/jest-dom": "^5.14.1", "@testing-library/react": "^12.0.0", "@types/jest": "^27.0.1", @@ -105,6 +108,7 @@ "webpack-cli": "^4.8.0", "webpack-dev-server": "^4.5.0", "webpack-favicons": "^1.3.8", - "webpack-merge": "^5.8.0" + "webpack-merge": "^5.8.0", + "yaml-loader": "^0.8.0" } } diff --git a/nym-connect/public/growth.html b/nym-connect/public/growth.html new file mode 100644 index 0000000000..08672aaa3c --- /dev/null +++ b/nym-connect/public/growth.html @@ -0,0 +1,11 @@ + + + + + + Nym Connect + + +
+ + diff --git a/nym-connect/public/index.html b/nym-connect/public/index.html index 752946edb6..2ba643a663 100644 --- a/nym-connect/public/index.html +++ b/nym-connect/public/index.html @@ -3,7 +3,7 @@ - nym-connect + Nym Connect
diff --git a/nym-connect/public/log.html b/nym-connect/public/log.html new file mode 100644 index 0000000000..5ced2243f1 --- /dev/null +++ b/nym-connect/public/log.html @@ -0,0 +1,11 @@ + + + + + + Nym Wallet Logs + + +
+ + diff --git a/nym-connect/src-tauri/Cargo.toml b/nym-connect/src-tauri/Cargo.toml index 46c2278178..8ddeba45bb 100644 --- a/nym-connect/src-tauri/Cargo.toml +++ b/nym-connect/src-tauri/Cargo.toml @@ -13,33 +13,40 @@ rust-version = "1.58" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [build-dependencies] -tauri-build = { version = "^1.1.1", features = [] } +tauri-build = { version = "^1.2.1", features = [] } -tauri-codegen = "^1.1.1" -tauri-macros = "^1.1.1" +tauri-codegen = "^1.2.1" +tauri-macros = "^1.2.1" [dependencies] - +anyhow = "1.0" bip39 = "1.0" +chrono = "0.4" dirs = "4.0" eyre = "0.6.5" fix-path-env = { git = "https://github.com/tauri-apps/fix-path-env-rs", branch = "release"} futures = "0.3" -log = "0.4" +fern = { version = "0.6.1", features = ["colored"] } +itertools = "0.10.5" +log = { version = "0.4", features = ["serde"] } pretty_env_logger = "0.4.0" rand = "0.8" -reqwest = { version = "0.11", features = ["json"] } +reqwest = { version = "0.11", features = ["json", "socks"] } +rust-embed = { version = "6.4.2", features = ["include-exclude"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +serde_repr = "0.1" tap = "1.0.1" -tauri = { version = "^1.1.1", features = ["clipboard-write-text", "macos-private-api", "shell-open", "system-tray", "updater", "window-close", "window-minimize", "window-start-dragging"] } +tauri = { version = "^1.2.2", features = ["clipboard-write-text", "macos-private-api", "notification-all", "shell-open", "system-tray", "updater", "window-close", "window-minimize", "window-start-dragging"] } tendermint-rpc = "0.23.0" thiserror = "1.0" tokio = { version = "1.21.2", features = ["sync", "time"] } url = "2.2" +yaml-rust = "0.4" client-core = { path = "../../clients/client-core" } config-common = { path = "../../common/config", package = "config" } +crypto = { path = "../../common/crypto" } logging = { path = "../../common/logging"} nym-socks5-client = { path = "../../clients/socks5" } task = { path = "../../common/task" } diff --git a/nym-connect/src-tauri/src/config/mod.rs b/nym-connect/src-tauri/src/config/mod.rs index c27bf6b6b7..7d4e62f7cd 100644 --- a/nym-connect/src-tauri/src/config/mod.rs +++ b/nym-connect/src-tauri/src/config/mod.rs @@ -44,6 +44,13 @@ impl Config { } } + #[allow(unused)] + pub fn new_with_port>(id: S, provider_mix_address: S, port: u16) -> Self { + Config { + socks5: Socks5Config::new(id, provider_mix_address).with_port(port), + } + } + pub fn get_socks5(&self) -> &Socks5Config { &self.socks5 } diff --git a/nym-connect/src-tauri/src/error.rs b/nym-connect/src-tauri/src/error.rs index cb677aac68..57fc38e1c8 100644 --- a/nym-connect/src-tauri/src/error.rs +++ b/nym-connect/src-tauri/src/error.rs @@ -27,6 +27,11 @@ pub enum BackendError { source: tauri::Error, }, #[error("{source}")] + TauriApiError { + #[from] + source: tauri::api::Error, + }, + #[error("{source}")] SerdeJsonError { #[from] source: serde_json::Error, @@ -36,6 +41,11 @@ pub enum BackendError { #[from] source: ClientCoreError, }, + #[error("{source}")] + ApiClientError { + #[from] + source: crate::operations::growth::api_client::ApiClientError, + }, #[error("Could not send disconnect signal to the SOCKS5 client")] CoundNotSendDisconnectSignal, @@ -57,6 +67,8 @@ pub enum BackendError { CouldNotGetConfigFilename, #[error("Could not load existing gateway configuration")] CouldNotLoadExistingGatewayConfiguration(std::io::Error), + #[error("Unable to open a new window")] + NewWindowError, } impl Serialize for BackendError { diff --git a/nym-connect/src-tauri/src/logging.rs b/nym-connect/src-tauri/src/logging.rs new file mode 100644 index 0000000000..c805411107 --- /dev/null +++ b/nym-connect/src-tauri/src/logging.rs @@ -0,0 +1,113 @@ +use std::str::FromStr; + +use fern::colors::ColoredLevelConfig; +use serde::Serialize; +use serde_repr::{Deserialize_repr, Serialize_repr}; +use tauri::Manager; + +pub fn setup_logging(app_handle: tauri::AppHandle) -> Result<(), log::SetLoggerError> { + let colors = ColoredLevelConfig::new(); + let base_config = fern::Dispatch::new() + .level(global_level()) + .filter_lowlevel_external_components() + .show_operations(); + + let stdout_config = fern::Dispatch::new() + .format(move |out, message, record| { + out.finish(format_args!( + "{}[{}][{}] {}", + chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"), + record.target(), + colors.color(record.level()), + message, + )) + }) + .chain(std::io::stdout()); + + let tauri_event_config = fern::Dispatch::new() + .format(move |out, message, record| { + out.finish(format_args!( + "{}[{}] {}", + chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"), + record.target(), + message, + )) + }) + .chain(fern::Output::call(move |record| { + let msg = LogMessage { + message: record.args().to_string(), + level: record.level().into(), + }; + app_handle.emit_all("log://log", msg).unwrap(); + })); + + base_config + .chain(stdout_config) + .chain(tauri_event_config) + .apply() +} + +trait FernExt { + fn show_operations(self) -> Self; + fn filter_lowlevel_external_components(self) -> Self; +} + +impl FernExt for fern::Dispatch { + fn show_operations(self) -> Self { + if ::std::env::var("RUST_TRACE_OPERATIONS").is_ok() { + self.level_for("nym_connect::operations", log::LevelFilter::Trace) + } else { + self + } + } + + fn filter_lowlevel_external_components(self) -> Self { + self.level_for("hyper", log::LevelFilter::Warn) + .level_for("tokio_reactor", log::LevelFilter::Warn) + .level_for("reqwest", log::LevelFilter::Warn) + .level_for("mio", log::LevelFilter::Warn) + .level_for("want", log::LevelFilter::Warn) + .level_for("sled", log::LevelFilter::Warn) + .level_for("tungstenite", log::LevelFilter::Warn) + .level_for("tokio_tungstenite", log::LevelFilter::Warn) + .level_for("rustls", log::LevelFilter::Warn) + .level_for("tokio_util", log::LevelFilter::Warn) + } +} + +fn global_level() -> log::LevelFilter { + if let Ok(s) = ::std::env::var("RUST_LOG") { + log::LevelFilter::from_str(&s).unwrap_or(log::LevelFilter::Info) + } else { + log::LevelFilter::Info + } +} + +#[derive(Debug, Serialize, Clone)] +struct LogMessage { + message: String, + level: LogLevel, +} + +// Serialize to u16 instead of strings. +#[derive(Debug, Clone, Deserialize_repr, Serialize_repr)] +#[repr(u16)] +enum LogLevel { + Trace = 1, + Debug, + Info, + Warn, + Error, +} + +impl From for LogLevel { + fn from(level: log::Level) -> Self { + match level { + log::Level::Trace => LogLevel::Trace, + log::Level::Debug => LogLevel::Debug, + log::Level::Info => LogLevel::Info, + log::Level::Warn => LogLevel::Warn, + log::Level::Error => LogLevel::Error, + } + } +} diff --git a/nym-connect/src-tauri/src/main.rs b/nym-connect/src-tauri/src/main.rs index 4f4e8bb5fb..608eca4130 100644 --- a/nym-connect/src-tauri/src/main.rs +++ b/nym-connect/src-tauri/src/main.rs @@ -6,8 +6,7 @@ use std::sync::Arc; use config_common::defaults::setup_env; -use logging::setup_logging; -use tauri::Menu; +use tauri::{Manager, Menu}; use tokio::sync::RwLock; use crate::menu::AddDefaultSubmenus; @@ -17,6 +16,7 @@ use crate::window::window_toggle; mod config; mod error; +mod logging; mod menu; mod models; mod operations; @@ -25,7 +25,6 @@ mod tasks; mod window; fn main() { - setup_logging(); setup_env(None); println!("Starting up..."); @@ -35,11 +34,13 @@ fn main() { log::warn!("Failed to fix PATH: {error}"); } + let context = tauri::generate_context!(); tauri::Builder::default() .manage(Arc::new(RwLock::new(State::new()))) .invoke_handler(tauri::generate_handler![ crate::config::get_config_file_location, crate::config::get_config_id, + crate::operations::connection::status::get_connection_status, crate::operations::connection::connect::get_gateway, crate::operations::connection::connect::get_service_provider, crate::operations::connection::connect::set_gateway, @@ -49,10 +50,31 @@ fn main() { crate::operations::directory::get_services, crate::operations::export::export_keys, crate::operations::window::hide_window, + crate::operations::growth::test_and_earn::growth_tne_get_client_id, + crate::operations::growth::test_and_earn::growth_tne_take_part, + crate::operations::growth::test_and_earn::growth_tne_get_draws, + crate::operations::growth::test_and_earn::growth_tne_ping, + crate::operations::growth::test_and_earn::growth_tne_submit_wallet_address, + crate::operations::growth::test_and_earn::growth_tne_enter_draw, + crate::operations::growth::test_and_earn::growth_tne_toggle_window, + crate::operations::help::log::help_log_toggle_window, ]) - .menu(Menu::new().add_default_app_submenu_if_macos()) + .menu(Menu::os_default(&context.package_info().name).add_default_app_submenus()) + .on_menu_event(|event| { + if event.menu_item_id() == menu::SHOW_LOG_WINDOW { + let _r = crate::operations::help::log::help_log_toggle_window( + event.window().app_handle(), + ); + } + if event.menu_item_id() == menu::CLEAR_STORAGE { + let _r = crate::operations::help::storage::help_clear_storage( + event.window().app_handle(), + ); + } + }) + .setup(|app| Ok(crate::logging::setup_logging(app.app_handle())?)) .system_tray(create_tray_menu()) .on_system_tray_event(tray_menu_event_handler) - .run(tauri::generate_context!()) + .run(context) .expect("error while running tauri application"); } diff --git a/nym-connect/src-tauri/src/menu.rs b/nym-connect/src-tauri/src/menu.rs index 368fc07d3a..4dac3ec540 100644 --- a/nym-connect/src-tauri/src/menu.rs +++ b/nym-connect/src-tauri/src/menu.rs @@ -1,40 +1,26 @@ -use crate::window_toggle; use tauri::{ - AppHandle, CustomMenuItem, Menu, SystemTray, SystemTrayEvent, SystemTrayMenu, + AppHandle, CustomMenuItem, Menu, Submenu, SystemTray, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem, Wry, }; -#[cfg(target_os = "macos")] -use tauri::{MenuItem, Submenu}; + +use crate::window_toggle; + +pub const SHOW_LOG_WINDOW: &str = "show_log_window"; +pub const CLEAR_STORAGE: &str = "clear_storage"; pub trait AddDefaultSubmenus { - fn add_default_app_submenu_if_macos(self) -> Self; + fn add_default_app_submenus(self) -> Self; } impl AddDefaultSubmenus for Menu { - fn add_default_app_submenu_if_macos(self) -> Menu { - #[cfg(target_os = "macos")] - return self - .add_submenu(Submenu::new( - "File", - Menu::new().add_native_item(MenuItem::Quit), - )) - .add_submenu(Submenu::new( - "Edit", - Menu::new() - .add_native_item(MenuItem::Copy) - .add_native_item(MenuItem::Cut) - .add_native_item(MenuItem::Paste) - .add_native_item(MenuItem::SelectAll), - )) - .add_submenu(Submenu::new( - "Window", - Menu::new() - .add_native_item(MenuItem::Hide) - .add_native_item(MenuItem::HideOthers) - .add_native_item(MenuItem::ShowAll), - )); - #[cfg(not(target_os = "macos"))] - return self; + fn add_default_app_submenus(self) -> Self { + let submenu = Submenu::new( + "Help", + Menu::new() + .add_item(CustomMenuItem::new(SHOW_LOG_WINDOW, "Show logs")) + .add_item(CustomMenuItem::new(CLEAR_STORAGE, "Clear all settings")), + ); + self.add_submenu(submenu) } } diff --git a/nym-connect/src-tauri/src/models/mod.rs b/nym-connect/src-tauri/src/models/mod.rs index e5076ac5c0..cde0deed96 100644 --- a/nym-connect/src-tauri/src/models/mod.rs +++ b/nym-connect/src-tauri/src/models/mod.rs @@ -39,21 +39,31 @@ impl fmt::Display for ConnectionStatusKind { pub const APP_EVENT_CONNECTION_STATUS_CHANGED: &str = "app:connection-status-changed"; #[cfg_attr(test, derive(ts_rs::TS))] -#[derive(Clone, serde::Serialize)] +#[derive(Clone, Serialize)] pub struct AppEventConnectionStatusChangedPayload { pub status: ConnectionStatusKind, } #[cfg_attr(test, derive(ts_rs::TS))] -#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct DirectoryService { pub id: String, pub description: String, pub items: Vec, } +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct HarbourMasterService { + pub service_provider_client_id: String, + pub gateway_identity_key: String, + pub ip_address: String, + pub last_successful_ping_utc: String, + pub last_updated_utc: String, + pub routing_score: f32, +} + #[cfg_attr(test, derive(ts_rs::TS))] -#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct DirectoryServiceProvider { pub id: String, pub description: String, @@ -63,3 +73,11 @@ pub struct DirectoryServiceProvider { /// Address of the gateway, e.g. 2BuMSfMW3zpeAjKXyKLhmY4QW1DXurrtSPEJ6CjX3SEh pub gateway: String, } + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct PagedResult { + pub page: u32, + pub size: u32, + pub total: i32, + pub items: Vec, +} diff --git a/nym-connect/src-tauri/src/operations/connection/connect.rs b/nym-connect/src-tauri/src/operations/connection/connect.rs index b377dfcec7..6170fec0b4 100644 --- a/nym-connect/src-tauri/src/operations/connection/connect.rs +++ b/nym-connect/src-tauri/src/operations/connection/connect.rs @@ -37,10 +37,10 @@ pub async fn get_service_provider(state: tauri::State<'_, Arc>>) - #[tauri::command] pub async fn set_service_provider( - service_provider: String, + service_provider: Option, state: tauri::State<'_, Arc>>, ) -> Result<()> { - log::trace!("Setting service_provider: {service_provider}"); + log::trace!("Setting service_provider: {:?}", &service_provider); let mut guard = state.write().await; guard.set_service_provider(service_provider); Ok(()) @@ -57,10 +57,10 @@ pub async fn get_gateway(state: tauri::State<'_, Arc>>) -> Result< #[tauri::command] pub async fn set_gateway( - gateway: String, + gateway: Option, state: tauri::State<'_, Arc>>, ) -> Result<()> { - log::trace!("Setting gateway: {gateway}"); + log::trace!("Setting gateway: {:?}", &gateway); let mut guard = state.write().await; guard.set_gateway(gateway); Ok(()) diff --git a/nym-connect/src-tauri/src/operations/connection/mod.rs b/nym-connect/src-tauri/src/operations/connection/mod.rs index 587edf0fc7..8c3449909e 100644 --- a/nym-connect/src-tauri/src/operations/connection/mod.rs +++ b/nym-connect/src-tauri/src/operations/connection/mod.rs @@ -1,2 +1,3 @@ pub mod connect; pub mod disconnect; +pub mod status; diff --git a/nym-connect/src-tauri/src/operations/connection/status.rs b/nym-connect/src-tauri/src/operations/connection/status.rs new file mode 100644 index 0000000000..ccf02400f3 --- /dev/null +++ b/nym-connect/src-tauri/src/operations/connection/status.rs @@ -0,0 +1,15 @@ +use crate::error::Result; +use std::sync::Arc; + +use tokio::sync::RwLock; + +use crate::models::ConnectionStatusKind; +use crate::state::State; + +#[tauri::command] +pub async fn get_connection_status( + state: tauri::State<'_, Arc>>, +) -> Result { + let state = state.read().await; + Ok(state.get_status()) +} diff --git a/nym-connect/src-tauri/src/operations/directory/mod.rs b/nym-connect/src-tauri/src/operations/directory/mod.rs index b6c45fa8c0..efc2ba175b 100644 --- a/nym-connect/src-tauri/src/operations/directory/mod.rs +++ b/nym-connect/src-tauri/src/operations/directory/mod.rs @@ -1,9 +1,13 @@ +use itertools::Itertools; + use crate::error::Result; -use crate::models::DirectoryService; +use crate::models::{DirectoryService, HarbourMasterService, PagedResult}; static SERVICE_PROVIDER_WELLKNOWN_URL: &str = "https://nymtech.net/.wellknown/connect/service-providers.json"; +static HARBOUR_MASTER_URL: &str = "https://harbourmaster.nymtech.net/v1/services/?size=100"; + #[tauri::command] pub async fn get_services() -> Result> { log::trace!("Fetching services"); @@ -12,5 +16,36 @@ pub async fn get_services() -> Result> { .json::>() .await?; log::trace!("Received: {:#?}", res); - Ok(res) + + // TODO: get paged + log::trace!("Fetching active services"); + let active_services = reqwest::get(HARBOUR_MASTER_URL) + .await? + .json::>() + .await?; + log::trace!("Active: {:#?}", active_services); + + let mut filtered: Vec = vec![]; + + for service in &res { + let items: _ = service + .items + .clone() + .into_iter() + .filter(|sp| { + active_services + .items + .iter() + .any(|active| active.service_provider_client_id == sp.address) + }) + .collect_vec(); + log::trace!("service = {} has {} items", service.id, items.len()); + filtered.push(DirectoryService { + id: service.id.clone(), + description: service.description.clone(), + items, + }) + } + + Ok(filtered) } diff --git a/nym-connect/src-tauri/src/operations/export.rs b/nym-connect/src-tauri/src/operations/export.rs index d4190c686a..93c2e81bc8 100644 --- a/nym-connect/src-tauri/src/operations/export.rs +++ b/nym-connect/src-tauri/src/operations/export.rs @@ -5,6 +5,24 @@ use crate::{ error::{BackendError, Result}, state::State, }; +use client_core::client::key_manager::KeyManager; +use client_core::config::persistence::key_pathfinder::ClientKeyPathfinder; +use crypto::asymmetric::identity; + +pub async fn get_identity_key( + state: &tauri::State<'_, Arc>>, +) -> Result> { + let config = { + let state = state.read().await; + state.load_socks5_config()? + }; + + let pathfinder = ClientKeyPathfinder::new_from_config(config.get_base()); + let key_manager = KeyManager::load_keys(&pathfinder)?; + let identity_keypair = key_manager.identity_keypair(); + + Ok(identity_keypair) +} /// Export the gateway keys as a JSON string blob #[tauri::command] diff --git a/nym-connect/src-tauri/src/operations/growth/api_client.rs b/nym-connect/src-tauri/src/operations/growth/api_client.rs new file mode 100644 index 0000000000..a8053e1977 --- /dev/null +++ b/nym-connect/src-tauri/src/operations/growth/api_client.rs @@ -0,0 +1,271 @@ +use serde::de::DeserializeOwned; +use serde::{Deserialize, Serialize}; +use thiserror::Error; + +#[allow(unused)] +#[derive(Error, Debug)] +pub enum ApiClientError { + #[error("{source}")] + Reqwest { + #[from] + source: reqwest::Error, + }, + #[error("{source}")] + SerdeJson { + #[from] + source: serde_json::Error, + }, + #[error("{0}")] + Status(String), +} + +const API_BASE_URL: &str = "https://growth-api.nymtech.net"; + +// For development mode, switch to this +// const API_BASE_URL: &str = "http://localhost:8000"; + +#[derive(Debug, Clone)] +pub struct GrowthApiClient { + base_url: String, +} + +impl GrowthApiClient { + pub fn new(resource_base: &str) -> Self { + let base_url = std::env::var("API_BASE_URL").unwrap_or_else(|_| API_BASE_URL.to_string()); + GrowthApiClient { + base_url: format!("{}{}", base_url, resource_base), + } + } + + pub fn registrations() -> Registrations { + Registrations::new(GrowthApiClient::new("/v1/tne")) + } + + pub fn daily_draws() -> DailyDraws { + DailyDraws::new(GrowthApiClient::new("/v1/tne/daily_draw")) + } + + pub(crate) async fn get(&self, url: &str) -> Result { + log::info!(">>> GET {}", url); + let proxy = reqwest::Proxy::all("socks5h://127.0.0.1:1080")?; + let client = reqwest::Client::builder() + .proxy(proxy) + .timeout(std::time::Duration::from_secs(10)) + .build()?; + + match client.get(format!("{}{}", self.base_url, url)).send().await { + Ok(res) => { + if res.status().is_client_error() || res.status().is_server_error() { + log::error!("<<< {}", res.status()); + return Err(ApiClientError::Status(res.status().to_string())); + } + match res.text().await { + Ok(response_body) => { + log::info!("<<< {}", response_body); + match serde_json::from_str(&response_body) { + Ok(res) => Ok(res), + Err(e) => { + log::error!("<<< JSON parsing error: {}", e); + Err(e.into()) + } + } + } + Err(e) => { + log::error!("<<< Request error: {}", e); + Err(e.into()) + } + } + } + Err(e) => { + log::error!("<<< Response parsing error: {}", e); + Err(e.into()) + } + } + } + + pub(crate) async fn post( + &self, + url: &str, + body: &REQ, + ) -> Result { + log::info!(">>> POST {}", url); + let proxy = reqwest::Proxy::all("socks5h://127.0.0.1:1080")?; + let client = reqwest::Client::builder() + .proxy(proxy) + .timeout(std::time::Duration::from_secs(10)) + .build()?; + + match client + .post(format!("{}{}", self.base_url, url)) + .json(body) + .send() + .await + { + Ok(res) => { + if res.status().is_client_error() || res.status().is_server_error() { + log::error!("<<< {}", res.status()); + return Err(ApiClientError::Status(res.status().to_string())); + } + match res.text().await { + Ok(response_body) => { + log::info!("<<< {}", response_body); + match serde_json::from_str(&response_body) { + Ok(res) => Ok(res), + Err(e) => { + log::error!("<<< JSON parsing error: {}", e); + Err(e.into()) + } + } + } + Err(e) => { + log::error!("<<< Request error: {}", e); + Err(e.into()) + } + } + } + Err(e) => { + log::error!("<<< Response parsing error: {}", e); + Err(e.into()) + } + } + } +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct ClientIdPartial { + pub client_id: String, + pub client_id_signature: String, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct Registration { + pub id: String, + pub client_id: String, + pub timestamp: String, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct Ping { + pub client_id: String, + pub timestamp: String, +} + +pub struct Registrations { + client: GrowthApiClient, +} + +impl Registrations { + pub fn new(client: GrowthApiClient) -> Self { + Registrations { client } + } + + pub async fn register( + &self, + registration: &ClientIdPartial, + ) -> Result { + self.client.post("/register", ®istration).await + } + + #[allow(dead_code)] + pub async fn unregister(&self, registration: &ClientIdPartial) -> Result<(), ApiClientError> { + self.client.post("/unregister", ®istration).await + } + + #[allow(dead_code)] + pub async fn status(&self, registration: &ClientIdPartial) -> Result<(), ApiClientError> { + self.client.post("/status", ®istration).await + } + + pub async fn ping(&self, registration: &ClientIdPartial) -> Result<(), ApiClientError> { + self.client.post("/ping", ®istration).await + } + + #[allow(dead_code)] + pub async fn health(&self) -> Result<(), ApiClientError> { + self.client.get("/health").await + } +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct DrawEntryPartial { + pub draw_id: String, + pub client_id: String, + pub client_id_signature: String, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct DrawEntry { + pub id: String, + pub draw_id: String, + pub timestamp: String, + pub status: Option, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct DrawWithWordOfTheDay { + pub id: String, + pub start_utc: String, + pub end_utc: String, + pub word_of_the_day: Option, + pub last_modified: String, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct ClaimPartial { + pub draw_id: String, + pub registration_id: String, + pub client_id: String, + pub client_id_signature: String, + pub wallet_address: String, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct Winner { + pub id: String, + pub client_id: String, + pub draw_id: String, + pub timestamp: String, + pub winner_reg_id: String, + pub winner_wallet_address: Option, + pub winner_claim_timestamp: Option, +} + +pub struct DailyDraws { + client: GrowthApiClient, +} + +impl DailyDraws { + pub fn new(client: GrowthApiClient) -> Self { + DailyDraws { client } + } + + pub async fn current(&self) -> Result { + self.client.get("/current").await + } + + pub async fn next(&self) -> Result { + self.client.get("/next").await + } + + #[allow(dead_code)] + pub async fn status(&self, draw_id: &str) -> Result { + self.client + .get(format!("/status/{}", draw_id).as_str()) + .await + } + + pub async fn enter(&self, entry: &DrawEntryPartial) -> Result { + self.client.post("/enter", entry).await + } + + pub async fn entries( + &self, + client_id: &ClientIdPartial, + ) -> Result, ApiClientError> { + self.client.post("/entries", client_id).await + } + + pub async fn claim(&self, claim: &ClaimPartial) -> Result { + self.client.post("/claim", claim).await + } +} diff --git a/nym-connect/src-tauri/src/operations/growth/assets.rs b/nym-connect/src-tauri/src/operations/growth/assets.rs new file mode 100644 index 0000000000..752b221916 --- /dev/null +++ b/nym-connect/src-tauri/src/operations/growth/assets.rs @@ -0,0 +1,57 @@ +use rust_embed::RustEmbed; +extern crate yaml_rust; +use yaml_rust::YamlLoader; + +#[derive(RustEmbed)] +#[folder = "../src/components/Growth/content/"] +#[include = "*.yaml"] +#[exclude = "*.mdx"] +struct Asset; + +#[derive(Debug)] +pub struct NotificationContent { + pub title: String, + pub body: String, +} + +#[derive(Debug)] +pub struct Notifications { + pub you_are_in_draw: NotificationContent, + pub take_part: NotificationContent, +} + +pub struct Content {} + +const RESOURCE_ERROR: &str = "❌ RESOURCE ERROR"; + +fn get_as_string_or_error_message(value: &yaml_rust::Yaml) -> String { + value.as_str().unwrap_or(RESOURCE_ERROR).to_string() +} + +impl Content { + pub fn get_notifications() -> Notifications { + let content = Asset::get("en.yaml").unwrap(); + let s = std::str::from_utf8(content.data.as_ref()).unwrap(); + let content = YamlLoader::load_from_str(s).unwrap(); + let content = &content[0]; + + Notifications { + you_are_in_draw: NotificationContent { + title: get_as_string_or_error_message( + &content["testAndEarn"]["notifications"]["youAreInDraw"]["title"], + ), + body: get_as_string_or_error_message( + &content["testAndEarn"]["notifications"]["youAreInDraw"]["body"], + ), + }, + take_part: NotificationContent { + title: get_as_string_or_error_message( + &content["testAndEarn"]["notifications"]["takePart"]["title"], + ), + body: get_as_string_or_error_message( + &content["testAndEarn"]["notifications"]["takePart"]["body"], + ), + }, + } + } +} diff --git a/nym-connect/src-tauri/src/operations/growth/mod.rs b/nym-connect/src-tauri/src/operations/growth/mod.rs new file mode 100644 index 0000000000..449c1bcee2 --- /dev/null +++ b/nym-connect/src-tauri/src/operations/growth/mod.rs @@ -0,0 +1,3 @@ +pub mod api_client; +pub mod assets; +pub mod test_and_earn; diff --git a/nym-connect/src-tauri/src/operations/growth/test_and_earn.rs b/nym-connect/src-tauri/src/operations/growth/test_and_earn.rs new file mode 100644 index 0000000000..c2216ce245 --- /dev/null +++ b/nym-connect/src-tauri/src/operations/growth/test_and_earn.rs @@ -0,0 +1,156 @@ +use crate::error::BackendError; +use crate::operations::export::get_identity_key; +use crate::operations::growth::api_client::{ + ClaimPartial, ClientIdPartial, DrawEntry, DrawEntryPartial, DrawWithWordOfTheDay, + GrowthApiClient, Registration, Winner, +}; +use crate::State; +use serde::{Deserialize, Serialize}; +use std::sync::Arc; +use tauri::api::notification::Notification; +use tauri::Manager; +use tokio::sync::RwLock; + +async fn get_client_id( + state: &tauri::State<'_, Arc>>, +) -> Result { + let keypair = get_identity_key(state).await?; + let client_id = keypair.public_key().to_base58_string(); + let client_id_signature = keypair + .private_key() + .sign(client_id.as_bytes()) + .to_base58_string(); + Ok(ClientIdPartial { + client_id, + client_id_signature, + }) +} + +#[tauri::command] +pub async fn growth_tne_get_client_id( + state: tauri::State<'_, Arc>>, +) -> Result { + get_client_id(&state).await +} + +#[tauri::command] +pub async fn growth_tne_take_part( + app_handle: tauri::AppHandle, + state: tauri::State<'_, Arc>>, +) -> Result { + let notifications = super::assets::Content::get_notifications(); + + let client_id = get_client_id(&state).await?; + let registration = GrowthApiClient::registrations() + .register(&client_id) + .await?; + + log::info!("<<< Test&Earn: registration details: {:?}", registration); + + if let Err(e) = Notification::new(&app_handle.config().tauri.bundle.identifier) + .title(notifications.take_part.title) + .body(notifications.take_part.body) + .show() + { + log::error!("Could not show notification. Error = {:?}", e); + } + + Ok(registration) +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct Draws { + pub current: Option, + pub next: Option, + pub draws: Vec, +} + +#[tauri::command] +pub async fn growth_tne_get_draws(client_details: ClientIdPartial) -> Result { + let draws_api = GrowthApiClient::daily_draws(); + + let current = draws_api.current().await.ok(); + let next = draws_api.next().await.ok(); + let draws = draws_api.entries(&client_details).await?; + + Ok(Draws { + current, + next, + draws, + }) +} + +#[tauri::command] +pub async fn growth_tne_enter_draw( + client_details: ClientIdPartial, + draw_id: String, +) -> Result { + Ok(GrowthApiClient::daily_draws() + .enter(&DrawEntryPartial { + draw_id, + client_id: client_details.client_id, + client_id_signature: client_details.client_id_signature, + }) + .await?) +} + +#[tauri::command] +pub async fn growth_tne_submit_wallet_address( + client_details: ClientIdPartial, + draw_id: String, + wallet_address: String, + registration_id: String, +) -> Result { + Ok(GrowthApiClient::daily_draws() + .claim(&ClaimPartial { + draw_id, + client_id: client_details.client_id, + client_id_signature: client_details.client_id_signature, + wallet_address, + registration_id, + }) + .await?) +} + +#[tauri::command] +pub async fn growth_tne_ping(client_details: ClientIdPartial) -> Result<(), BackendError> { + log::info!("Test&Earn is sending a ping..."); + Ok(GrowthApiClient::registrations() + .ping(&client_details) + .await?) +} + +#[tauri::command] +pub async fn growth_tne_toggle_window( + app_handle: tauri::AppHandle, + window_title: Option, +) -> Result<(), BackendError> { + if let Some(window) = app_handle.windows().get("growth") { + log::info!("Closing growth window..."); + if let Err(e) = window.close() { + log::error!("Unable to close growth window: {:?}", e); + } + return Ok(()); + } + + log::info!("Creating growth window..."); + match tauri::WindowBuilder::new( + &app_handle, + "growth", + tauri::WindowUrl::App("growth.html".into()), + ) + .title(window_title.unwrap_or_else(|| "NymConnect Test&Earn".to_string())) + .build() + { + Ok(window) => { + if let Err(e) = window.set_focus() { + log::error!("Unable to focus growth window: {:?}", e); + } + Ok(()) + } + Err(e) => { + log::error!("Unable to create growth window: {:?}", e); + Err(BackendError::NewWindowError) + } + } +} diff --git a/nym-connect/src-tauri/src/operations/help/log.rs b/nym-connect/src-tauri/src/operations/help/log.rs new file mode 100644 index 0000000000..e2cfd249b1 --- /dev/null +++ b/nym-connect/src-tauri/src/operations/help/log.rs @@ -0,0 +1,30 @@ +use crate::error::BackendError; +use tauri::Manager; + +#[tauri::command] +pub fn help_log_toggle_window(app_handle: tauri::AppHandle) -> Result<(), BackendError> { + if let Some(current_log_window) = app_handle.windows().get("log") { + log::info!("Closing log window..."); + if let Err(e) = current_log_window.close() { + log::error!("Unable to close log window: {:?}", e); + } + return Ok(()); + } + + log::info!("Creating log window..."); + match tauri::WindowBuilder::new(&app_handle, "log", tauri::WindowUrl::App("log.html".into())) + .title("Nym Connect Logs") + .build() + { + Ok(window) => { + if let Err(e) = window.set_focus() { + log::error!("Unable to focus log window: {:?}", e); + } + Ok(()) + } + Err(e) => { + log::error!("Unable to create log window: {:?}", e); + Err(BackendError::NewWindowError) + } + } +} diff --git a/nym-connect/src-tauri/src/operations/help/mod.rs b/nym-connect/src-tauri/src/operations/help/mod.rs new file mode 100644 index 0000000000..52dafe6d0f --- /dev/null +++ b/nym-connect/src-tauri/src/operations/help/mod.rs @@ -0,0 +1,2 @@ +pub mod log; +pub mod storage; diff --git a/nym-connect/src-tauri/src/operations/help/storage.rs b/nym-connect/src-tauri/src/operations/help/storage.rs new file mode 100644 index 0000000000..ab47ffa529 --- /dev/null +++ b/nym-connect/src-tauri/src/operations/help/storage.rs @@ -0,0 +1,20 @@ +use crate::error::BackendError; +use serde::Serialize; +use tauri::Manager; + +#[derive(Debug, Serialize, Clone)] +struct ClearStorageEvent { + kind: String, +} + +#[tauri::command] +pub fn help_clear_storage(app_handle: tauri::AppHandle) -> Result<(), BackendError> { + log::info!("Sending event to clear local storage..."); + + let event = ClearStorageEvent { + kind: "local_storage".to_string(), + }; + app_handle.emit_all("help://clear-storage", event)?; + + Ok(()) +} diff --git a/nym-connect/src-tauri/src/operations/mod.rs b/nym-connect/src-tauri/src/operations/mod.rs index 766762858e..1d0fa5b211 100644 --- a/nym-connect/src-tauri/src/operations/mod.rs +++ b/nym-connect/src-tauri/src/operations/mod.rs @@ -1,4 +1,6 @@ pub mod connection; pub mod directory; pub mod export; +pub mod growth; +pub mod help; pub mod window; diff --git a/nym-connect/src-tauri/src/state.rs b/nym-connect/src-tauri/src/state.rs index 3a98aa3747..9da1dab42b 100644 --- a/nym-connect/src-tauri/src/state.rs +++ b/nym-connect/src-tauri/src/state.rs @@ -64,16 +64,16 @@ impl State { &self.service_provider } - pub fn set_service_provider(&mut self, provider: String) { - self.service_provider = Some(provider); + pub fn set_service_provider(&mut self, provider: Option) { + self.service_provider = provider; } pub fn get_gateway(&self) -> &Option { &self.gateway } - pub fn set_gateway(&mut self, gateway: String) { - self.gateway = Some(gateway); + pub fn set_gateway(&mut self, gateway: Option) { + self.gateway = gateway; } /// The effective config id is the static config id appended with the id of the gateway diff --git a/nym-connect/src-tauri/tauri.conf.json b/nym-connect/src-tauri/tauri.conf.json index 8c0597d17e..05d22942c4 100644 --- a/nym-connect/src-tauri/tauri.conf.json +++ b/nym-connect/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "package": { "productName": "nym-connect", - "version": "1.1.3" + "version": "1.1.4" }, "build": { "distDir": "../dist", @@ -59,13 +59,16 @@ "startDragging": true, "close": true, "minimize": true + }, + "notification": { + "all": true } }, "windows": [ { "title": "NymConnect", "width": 240, - "height": 540, + "height": 675, "resizable": false, "decorations": false, "transparent": true diff --git a/nym-connect/src/App.tsx b/nym-connect/src/App.tsx index 90dd1a4230..9d5afd1427 100644 --- a/nym-connect/src/App.tsx +++ b/nym-connect/src/App.tsx @@ -1,15 +1,27 @@ import React, { useEffect } from 'react'; import { DateTime } from 'luxon'; +import { forage } from '@tauri-apps/tauri-forage'; import { ConnectionStatusKind } from './types'; import { useClientContext } from './context/main'; import { DefaultLayout } from './layouts/DefaultLayout'; import { ConnectedLayout } from './layouts/ConnectedLayout'; import { HelpGuideLayout } from './layouts/HelpGuideLayout'; +import { useTauriEvents } from './utils'; export const App: React.FC = () => { const context = useClientContext(); const [busy, setBusy] = React.useState(); const [showInfoModal, setShowInfoModal] = React.useState(false); + useTauriEvents('help://clear-storage', (_event) => { + console.log('About to clear local storage...'); + // clear local storage + try { + forage.clear()(); + console.log('Local storage cleared'); + } catch (e) { + console.error('Failed to clear local storage', e); + } + }); const handleConnectClick = React.useCallback(async () => { const currentStatus = context.connectionStatus; @@ -49,7 +61,6 @@ export const App: React.FC = () => { busy={busy} onConnectClick={handleConnectClick} services={context.services} - onServiceProviderChange={context.setServiceProvider} /> ); } diff --git a/nym-connect/src/components/AppVersion.tsx b/nym-connect/src/components/AppVersion.tsx new file mode 100644 index 0000000000..1b8adf40aa --- /dev/null +++ b/nym-connect/src/components/AppVersion.tsx @@ -0,0 +1,15 @@ +import { Typography, Box } from '@mui/material'; +import React from 'react'; +import { useClientContext } from 'src/context/main'; + +export const AppVersion = () => { + const { appVersion } = useClientContext(); + + return ( + + + Version {appVersion} + + + ); +}; diff --git a/nym-connect/src/components/AppWindowFrame.tsx b/nym-connect/src/components/AppWindowFrame.tsx index 5fc3d60ff6..80bed93f77 100644 --- a/nym-connect/src/components/AppWindowFrame.tsx +++ b/nym-connect/src/components/AppWindowFrame.tsx @@ -1,15 +1,16 @@ import React from 'react'; import { Box } from '@mui/material'; import { CustomTitleBar } from './CustomTitleBar'; +import { AppVersion } from './AppVersion'; export const AppWindowFrame: React.FC = ({ children }) => ( diff --git a/nym-connect/src/components/CopyToClipboard.tsx b/nym-connect/src/components/CopyToClipboard.tsx index 4e4031cf46..7a48662190 100644 --- a/nym-connect/src/components/CopyToClipboard.tsx +++ b/nym-connect/src/components/CopyToClipboard.tsx @@ -14,9 +14,13 @@ export const CopyToClipboard = ({ }) => { const [copied, setCopied] = useState(false); - const handleCopy = async (text: string) => { + const handleCopy = async (textToCopy: string) => { try { - await clipboard.writeText(text); + if (clipboard) { + await clipboard.writeText(textToCopy); + } else { + await navigator.clipboard.writeText(textToCopy); + } setCopied(true); } catch (e) { console.log(`failed to copy: ${e}`); diff --git a/nym-connect/src/components/ErrorFallback.tsx b/nym-connect/src/components/ErrorFallback.tsx new file mode 100644 index 0000000000..f582536b6b --- /dev/null +++ b/nym-connect/src/components/ErrorFallback.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import { FallbackProps } from 'react-error-boundary'; +import { Alert, AlertTitle, Button } from '@mui/material'; + +export const ErrorFallback = ({ error, resetErrorBoundary }: FallbackProps) => ( +
+ + {error.name} + {error.message} + + + Stack trace + {error.stack} + + +
+); diff --git a/nym-connect/src/components/Growth/TestAndEarnButtonArea.tsx b/nym-connect/src/components/Growth/TestAndEarnButtonArea.tsx new file mode 100644 index 0000000000..ed6219e31f --- /dev/null +++ b/nym-connect/src/components/Growth/TestAndEarnButtonArea.tsx @@ -0,0 +1,83 @@ +import React from 'react'; +import { Badge, Box, Button, Tooltip } from '@mui/material'; +import MonetizationOnIcon from '@mui/icons-material/MonetizationOn'; +import { invoke } from '@tauri-apps/api'; +import Content from './content/en.yaml'; +import { useClientContext } from '../../context/main'; +import { useTestAndEarnContext } from './context/TestAndEarnContext'; +import { NymShipyardTheme } from '../../theme'; +import { ConnectionStatusKind } from '../../types'; + +export const Wrapper: React.FC<{ disabled: boolean }> = ({ disabled, children }) => { + if (disabled) { + return ( + + +
{children}
+
+
+ ); + } + return <>{children}; +}; + +export const TestAndEarnButtonArea: React.FC = () => { + const clientContext = useClientContext(); + const context = useTestAndEarnContext(); + const disabled = clientContext.connectionStatus !== ConnectionStatusKind.connected; + const pinger = React.useRef(); + + const doPing = async () => { + if (context.clientDetails) { + try { + await invoke('growth_tne_ping', { clientDetails: context.clientDetails }); + } catch (_e) { + // console.error('Failed to ping: ', e); + } + } + }; + + React.useEffect(() => { + (async () => { + if (!disabled) { + // sleep a little until the SOCKS5 proxy connects + setTimeout(() => { + doPing(); + }, 1000 * 10); + + // update every 15 mins + pinger.current = setInterval(doPing, 1000 * 60 * 15); + } else if (pinger.current) { + clearInterval(pinger.current); + pinger.current = null; + } + })(); + }, [disabled, context.clientDetails]); + + const handleClick = async () => { + if (!disabled) { + await context.toggleGrowthWindow(Content.testAndEarn.popupWindow.title); + } + }; + + return ( + + + + + + + + ); +}; diff --git a/nym-connect/src/components/Growth/TestAndEarnCurrentDraw.stories.tsx b/nym-connect/src/components/Growth/TestAndEarnCurrentDraw.stories.tsx new file mode 100644 index 0000000000..99b9206e7a --- /dev/null +++ b/nym-connect/src/components/Growth/TestAndEarnCurrentDraw.stories.tsx @@ -0,0 +1,94 @@ +import * as React from 'react'; +import { ComponentMeta } from '@storybook/react'; +import { DateTime, Duration } from 'luxon'; +import { + TestAndEarnCurrentDraw, + TestAndEarnCurrentDrawEntered, + TestAndEarnCurrentDrawFuture, +} from './TestAndEarnCurrentDraw'; +import { NymShipyardTheme } from '../../theme'; +import { DrawEntryStatus } from './context/types'; +import { testMarkdown } from './context/mocks/TestAndEarnContext'; + +export default { + title: 'Growth/TestAndEarn/Components/Cards/Current Draw', + component: TestAndEarnCurrentDraw, +} as ComponentMeta; + +export const Valid = () => ( + + + +); + +export const EnteredMalformedDraw = () => ( + + + +); + +export const EnteredDraw = () => ( + + + +); + +export const Future = () => ( + + + +); diff --git a/nym-connect/src/components/Growth/TestAndEarnCurrentDraw.tsx b/nym-connect/src/components/Growth/TestAndEarnCurrentDraw.tsx new file mode 100644 index 0000000000..b9b029c414 --- /dev/null +++ b/nym-connect/src/components/Growth/TestAndEarnCurrentDraw.tsx @@ -0,0 +1,192 @@ +import React from 'react'; +import LoadingButton from '@mui/lab/LoadingButton'; +import { Alert, AlertTitle, Box, Card, CardContent, CardMedia, Link, Typography } from '@mui/material'; +import { SxProps } from '@mui/system'; +import { DateTime } from 'luxon'; +import ReactMarkdown from 'react-markdown'; +import assetAnimation from './content/assets/matrix.webp'; +import { CopyToClipboard } from '../CopyToClipboard'; +import { useTestAndEarnContext } from './context/TestAndEarnContext'; +import { DrawEntryStatus, DrawWithWordOfTheDay } from './context/types'; +import Content from './content/en.yaml'; + +export const TestAndEarnCurrentDrawFuture: React.FC<{ draw?: DrawWithWordOfTheDay }> = ({ draw }) => { + const startsUtc = React.useMemo(() => draw && DateTime.fromISO(draw.start_utc), [draw?.start_utc]); + const startsIn = React.useMemo(() => { + if (draw && startsUtc) { + return startsUtc.toRelative(); + } + return undefined; + }, [draw?.start_utc]); + + if (!draw || !startsUtc) { + return null; + } + return ( + + +

+ {Content.testAndEarn.draw.next.header} {startsIn} ⏰ +

+

on {startsUtc.toLocaleString(DateTime.DATETIME_FULL)}

+
+
+ ); +}; + +export const TestAndEarnCurrentDrawEnter: React.FC<{ draw?: DrawWithWordOfTheDay }> = ({ draw }) => { + const context = useTestAndEarnContext(); + const [busy, setBusy] = React.useState(false); + const [error, setError] = React.useState(); + const handleClick = async () => { + if (!draw) { + setError('No draw selected'); + return; + } + + setBusy(true); + try { + await context.enterDraw(draw.id); + } catch (e) { + const message = `${e}`; + console.error('Could not enter draw', message); + setError(message); + } + setBusy(false); + }; + return ( + + Complete today’s task for the chance to earn 1000 NYMs. + + Start task ✨ + + {error && ( + + + Oh no! Something went wrong. + {error} + + + )} + + ); +}; + +export const TestAndEarnCurrentDrawEntered: React.FC<{ draw?: DrawWithWordOfTheDay }> = ({ draw }) => { + if (!draw || !draw.entry) { + return null; + } + + if (!draw.word_of_the_day) { + return ( + + Oh no! Something is wrong + Someone configured the wrong instructions for the task, you will not be able to see it until this is fixed + + ); + } + + return ( + + + {draw.word_of_the_day} + + + {Content.testAndEarn.task.afterText} + + {draw.entry.id} + + + {Content.testAndEarn.task.beforeSocials} + + + Twitter + {' '} + - remember to + + @nymproject + {' '} + and use the hashtag{' '} + + #PrivacyLovesCompany + + + or + + Nym{' '} + + Telegram channel + + + + ); +}; + +export const TestAndEarnCurrentDraw: React.FC<{ + draw?: DrawWithWordOfTheDay; + sx?: SxProps; +}> = ({ draw, sx }) => { + const [trigger, setTrigger] = React.useState(DateTime.now().toISO()); + const endsUtc = React.useMemo(() => draw && DateTime.fromISO(draw.end_utc), [draw?.end_utc]); + const closesIn = React.useMemo(() => { + if (draw && endsUtc) { + return endsUtc.toRelative(); + } + return undefined; + }, [trigger, endsUtc]); + + React.useEffect(() => { + const timer = setInterval(() => setTrigger(DateTime.now().toISO()), 1000 * 3600 * 15); + return () => clearInterval(timer); + }, []); + + if (draw && closesIn && endsUtc) { + return ( + + +

+ {"Today's task ends "} + {closesIn} + + {endsUtc.weekdayLong} {endsUtc.toLocaleString(DateTime.DATETIME_FULL)} + +

+ {!draw.entry && } + {draw.entry && } +
+ +
+ ); + } + + return null; +}; + +export const TestAndEarnCurrentDrawWithState: React.FC<{ + sx?: SxProps; +}> = ({ sx }) => { + const context = useTestAndEarnContext(); + + if ( + context.draws?.current?.entry?.status === DrawEntryStatus.winner || + context.draws?.current?.entry?.status === DrawEntryStatus.claimed || + context.draws?.current?.entry?.status === DrawEntryStatus.noWin + ) { + return null; + } + + if (!context.draws?.current) { + return ; + } + + return ; +}; diff --git a/nym-connect/src/components/Growth/TestAndEarnDraws.stories.tsx b/nym-connect/src/components/Growth/TestAndEarnDraws.stories.tsx new file mode 100644 index 0000000000..83776d8e20 --- /dev/null +++ b/nym-connect/src/components/Growth/TestAndEarnDraws.stories.tsx @@ -0,0 +1,18 @@ +import * as React from 'react'; +import { ComponentMeta } from '@storybook/react'; +import { NymShipyardTheme } from 'src/theme'; +import { TestAndEarnDraws } from './TestAndEarnDraws'; +import { MockTestAndEarnProvider_RegisteredWithAllDraws } from './context/mocks/TestAndEarnContext'; + +export default { + title: 'Growth/TestAndEarn/Components/Cards/Draws', + component: TestAndEarnDraws, +} as ComponentMeta; + +export const Draws = () => ( + + + + + +); diff --git a/nym-connect/src/components/Growth/TestAndEarnDraws.tsx b/nym-connect/src/components/Growth/TestAndEarnDraws.tsx new file mode 100644 index 0000000000..6dd9b8954a --- /dev/null +++ b/nym-connect/src/components/Growth/TestAndEarnDraws.tsx @@ -0,0 +1,195 @@ +import React from 'react'; +import LoadingButton from '@mui/lab/LoadingButton'; +import { + Alert, + AlertTitle, + Button, + Card, + CardContent, + Chip, + Dialog, + Table, + TableBody, + TableCell, + TableContainer, + TableRow, + Tooltip, + Typography, +} from '@mui/material'; +import { SxProps } from '@mui/system'; +import { DateTime } from 'luxon'; +import { useTestAndEarnContext } from './context/TestAndEarnContext'; +import { DrawEntry, DrawEntryStatus } from './context/types'; +import { CopyToClipboard } from '../CopyToClipboard'; +import { TestAndEarnEnterWalletAddress } from './TestAndEarnEnterWalletAddress'; +import Content from './content/en.yaml'; + +const statusToText = (status: string): string => Content.testAndEarn.status.chip[status] || '-'; + +const statusToColor = (status: string): 'info' | 'success' | 'warning' | undefined => { + switch (status) { + case DrawEntryStatus.pending: + return 'info'; + case DrawEntryStatus.winner: + return 'warning'; + case DrawEntryStatus.claimed: + return 'success'; + default: + return undefined; + } +}; + +const StatusText: React.FC<{ entry: DrawEntry }> = ({ entry }) => { + const context = useTestAndEarnContext(); + const [busy, setBusy] = React.useState(false); + const [error, setError] = React.useState(); + const [showWalletCapture, setShowWalletCapture] = React.useState(false); + + const clear = () => { + setShowWalletCapture(false); + setError(undefined); + setBusy(false); + }; + + const handleStartWalletCapture = async () => { + setBusy(true); + setShowWalletCapture(true); + }; + + const cancelEndWalletCapture = async () => { + setBusy(false); + setShowWalletCapture(false); + }; + + const handleEndWalletCapture = async () => { + setBusy(true); + setShowWalletCapture(false); + + if (!context.walletAddress) { + setError('Wallet address is not set'); + return; + } + if (!entry.draw_id) { + setError('Task id is not set'); + return; + } + + try { + await context.claim(entry.draw_id, context.walletAddress); + } catch (e) { + const message = `${e}`; + console.error('Failed to submit claim'); + setError(message); + } + setBusy(false); + }; + + if (error) { + return ( + + Oh no! Failed to submit claim + {error} + + + ); + } + + if (showWalletCapture) { + return ( + + + + ); + } + + switch (entry.status) { + case DrawEntryStatus.pending: + return <>{Content.testAndEarn.status.text.Pending}; + case DrawEntryStatus.winner: + return ( + <> + {Content.testAndEarn.status.text.Winner} + + {Content.testAndEarn.winner.claimButton.text} + + + ); + case DrawEntryStatus.claimed: + return <>{Content.testAndEarn.status.text.Claimed}; + case DrawEntryStatus.noWin: + return <>{Content.testAndEarn.status.text.NoWin}; + default: + return null; + } +}; + +export const TestAndEarnDraws: React.FC<{ + sx?: SxProps; +}> = ({ sx }) => { + const context = useTestAndEarnContext(); + + const draws = React.useMemo( + () => + (context.draws?.draws || []).map((item) => ({ + ...item, + timestamp: DateTime.fromISO(item.timestamp).toLocaleString(DateTime.DATETIME_FULL), + })), + [context.draws?.draws], + ); + + if (!context.draws) { + return null; + } + + return ( + + + Here is a history of the tasks you have completed: + + + + {draws.map((entry) => ( + + {entry.timestamp} + + + + + + + + + + {entry.id} + + + ))} + +
+
+
+
+ ); +}; + +export const TestAndEarnDrawsWithState: React.FC<{ + sx?: SxProps; +}> = ({ sx }) => { + const context = useTestAndEarnContext(); + + const drawCount = context.draws?.draws?.length || 0; + if (drawCount < 1) { + return null; + } + + return ; +}; diff --git a/nym-connect/src/components/Growth/TestAndEarnEnterWalletAddress.stories.tsx b/nym-connect/src/components/Growth/TestAndEarnEnterWalletAddress.stories.tsx new file mode 100644 index 0000000000..0f5c4ea0de --- /dev/null +++ b/nym-connect/src/components/Growth/TestAndEarnEnterWalletAddress.stories.tsx @@ -0,0 +1,41 @@ +import * as React from 'react'; +import { ComponentMeta } from '@storybook/react'; +import { Box } from '@mui/material'; +import { TestAndEarnEnterWalletAddress } from './TestAndEarnEnterWalletAddress'; +import { TestAndEarnContextProvider } from './context/TestAndEarnContext'; +import { NymShipyardTheme } from '../../theme'; + +export default { + title: 'Growth/TestAndEarn/Components/Enter wallet address', + component: TestAndEarnEnterWalletAddress, +} as ComponentMeta; + +export const Empty = () => ( + + + + + + + +); + +export const ErrorValue = () => ( + + + + + + + +); + +export const ValidValue = () => ( + + + + + + + +); diff --git a/nym-connect/src/components/Growth/TestAndEarnEnterWalletAddress.tsx b/nym-connect/src/components/Growth/TestAndEarnEnterWalletAddress.tsx new file mode 100644 index 0000000000..80d7f2de5b --- /dev/null +++ b/nym-connect/src/components/Growth/TestAndEarnEnterWalletAddress.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { WalletAddressFormField } from '@nymproject/react/account/WalletAddressFormField'; +import { SxProps } from '@mui/system'; +import { Paper, Stack, Button, Box } from '@mui/material'; +import ArrowCircleRightIcon from '@mui/icons-material/ArrowCircleRight'; +import { useTestAndEarnContext } from './context/TestAndEarnContext'; + +export const TestAndEarnEnterWalletAddress: React.FC<{ + initialValue?: string; + placeholder?: string; + onSubmit?: () => Promise | void; + sx?: SxProps; +}> = ({ initialValue, placeholder, onSubmit, sx }) => { + const context = useTestAndEarnContext(); + const [isAddressValid, setAddressIsValid] = React.useState(false); + return ( + + + + + + + + + + + ); +}; diff --git a/nym-connect/src/components/Growth/TestAndEarnError.tsx b/nym-connect/src/components/Growth/TestAndEarnError.tsx new file mode 100644 index 0000000000..3fcf4efb59 --- /dev/null +++ b/nym-connect/src/components/Growth/TestAndEarnError.tsx @@ -0,0 +1,13 @@ +import React from 'react'; +import { Box, Button } from '@mui/material'; + +export const TestAndEarnError: React.FC<{ error?: string }> = ({ error = 'An error has occurred' }) => ( + + + {error} + + + +); diff --git a/nym-connect/src/components/Growth/TestAndEarnPopup.stories.tsx b/nym-connect/src/components/Growth/TestAndEarnPopup.stories.tsx new file mode 100644 index 0000000000..ac38ec1d4b --- /dev/null +++ b/nym-connect/src/components/Growth/TestAndEarnPopup.stories.tsx @@ -0,0 +1,167 @@ +/* eslint-disable react/jsx-pascal-case */ +import * as React from 'react'; +import { ComponentMeta } from '@storybook/react'; +import { Alert, Box } from '@mui/material'; +import { NymShipyardTheme } from 'src/theme'; +import { TestAndEarnPopup, TestAndEarnPopupContent } from './TestAndEarnPopup'; +import { TestAndEarnContextProvider } from './context/TestAndEarnContext'; +import { MockProvider } from '../../context/mocks/main'; +import { ConnectionStatusKind } from '../../types'; +import { TestAndEarnCurrentDraw } from './TestAndEarnCurrentDraw'; +import { TestAndEarnWinner } from './TestAndEarnWinner'; +import { TestAndEarnDraws } from './TestAndEarnDraws'; +import { TestAndEarnWinnerWalletAddress } from './TestAndEarnWinnerWalletAddress'; +import { + MockTestAndEarnProvider_NotRegistered, + MockTestAndEarnProvider_Registered, + MockTestAndEarnProvider_RegisteredAndError, + MockTestAndEarnProvider_RegisteredWithDraws, + MockTestAndEarnProvider_RegisteredWithDrawsAndEntry, + MockTestAndEarnProvider_RegisteredWithDrawsAndEntryAndNoWinner, + MockTestAndEarnProvider_RegisteredWithDrawsAndEntryAndWinner, + MockTestAndEarnProvider_RegisteredWithDrawsAndEntryAndWinnerClaimed, + MockTestAndEarnProvider_RegisteredWithDrawsAndEntryAndWinnerCollectWallet, + MockTestAndEarnProvider_RegisteredWithDrawsNoCurrent, +} from './context/mocks/TestAndEarnContext'; + +export default { + title: 'Growth/TestAndEarn/Content/Popup', + component: TestAndEarnPopupContent, +} as ComponentMeta; + +const MacOSWindow: React.FC<{ width?: string | number; height?: string | number; title?: string }> = ({ + title, + width, + height, + children, +}) => ( + + + + + + + + + + + + + + + + + + + {title || 'Window title'} + + + {children} + +); + +const Wrapper: React.FC<{ text: React.ReactNode }> = ({ text }) => ( + + + {text} + + + + + +); + +export const Stage0 = () => ( + + + + + +); + +export const Stage1EnterDraw = () => ( + + + + + +); + +export const Stage2GetTask = () => ( + + + + + +); + +export const Stage3Winner = () => ( + + + + + +); + +export const Stage3NoPrize = () => ( + + + + + +); + +export const Stage4EnterWalletAddress = () => ( + + + + + +); + +export const Stage5ClaimedPrize = () => ( + + + + + +); + +export const Stage6DrawsFinished = () => ( + + + + + +); + +export const Connecting = () => ( + + + + + +); + +export const Disconnected = () => ( + + + + + +); + +export const Error = () => ( + + + + + +); diff --git a/nym-connect/src/components/Growth/TestAndEarnPopup.tsx b/nym-connect/src/components/Growth/TestAndEarnPopup.tsx new file mode 100644 index 0000000000..73e8008069 --- /dev/null +++ b/nym-connect/src/components/Growth/TestAndEarnPopup.tsx @@ -0,0 +1,118 @@ +import React from 'react'; +import { Box, CircularProgress, LinearProgress, Stack, Typography } from '@mui/material'; +import { useClientContext } from '../../context/main'; +import ErrorContent from './content/TestAndEarn/Error.mdx'; +import ContentStep0 from './content/TestAndEarn/Stage0_intro.mdx'; +import ContentNotAvailable from './content/TestAndEarnNotAvaialble.mdx'; +import { ConnectionStatusKind } from '../../types'; +import { useTestAndEarnContext } from './context/TestAndEarnContext'; +import { TestAndEarnWinnerWithState } from './TestAndEarnWinner'; +import { TestAndEarnCurrentDrawWithState } from './TestAndEarnCurrentDraw'; +import { TestAndEarnDrawsWithState } from './TestAndEarnDraws'; + +enum Stages { + mustRegister = 'mustRegister', + registered = 'registered', +} + +export const TestAndEarnPopupContent: React.FC<{ + stage?: string; + connectionStatus?: ConnectionStatusKind; + error?: string; +}> = ({ connectionStatus, error, stage = Stages.mustRegister }) => { + if (error) { + return ( + + + + ); + } + + if (!connectionStatus || connectionStatus === ConnectionStatusKind.disconnected) { + return ( + + + + ); + } + + if (connectionStatus === ConnectionStatusKind.connecting || connectionStatus === ConnectionStatusKind.disconnecting) { + return ( + + + Please wait... + + ); + } + + switch (stage) { + case Stages.mustRegister: + return ( + + + + ); + case Stages.registered: + return ( + + + + + + ); + default: + return ( + + + + Waiting for task information... + + + ); + } +}; + +export const TestAndEarnPopup: React.FC = () => { + const clientContext = useClientContext(); + const context = useTestAndEarnContext(); + + React.useEffect(() => { + if (clientContext.connectionStatus === ConnectionStatusKind.connected) { + context.refresh(); + } + }, [clientContext.connectionStatus]); + + const stage = React.useMemo(() => { + if (context.registration) { + return Stages.registered; + } + return Stages.mustRegister; + }, [context.registration?.id]); + + React.useEffect(() => { + const interval = setInterval(context.refresh, 1000 * 60 * 5); + return () => clearInterval(interval); + }, []); + + if (!context.loadedOnce && clientContext.connectionStatus === ConnectionStatusKind.connected) { + const message = 'Waiting for data to be transferred over the mixnet...'; + return ( + + + + {message} + {/* {process.env.NODE_ENV === 'development' &&
{JSON.stringify(context, null, 2)}
} */} +
+
+ ); + } + + return ( + <> + {context.loading && } + {/* */} + + {/* {process.env.NODE_ENV === 'development' &&
{JSON.stringify(context, null, 2)}
} */} + + ); +}; diff --git a/nym-connect/src/components/Growth/TestAndEarnTakePart.tsx b/nym-connect/src/components/Growth/TestAndEarnTakePart.tsx new file mode 100644 index 0000000000..c5b08975f2 --- /dev/null +++ b/nym-connect/src/components/Growth/TestAndEarnTakePart.tsx @@ -0,0 +1,75 @@ +import React from 'react'; +import { Alert, AlertTitle, Box, Checkbox, Link, Stack } from '@mui/material'; +import LoadingButton from '@mui/lab/LoadingButton'; +import { SxProps } from '@mui/system'; +import ArrowCircleRightIcon from '@mui/icons-material/ArrowCircleRight'; +import { invoke } from '@tauri-apps/api'; +import { useTestAndEarnContext } from './context/TestAndEarnContext'; +import { ClientId, Registration } from './context/types'; + +export const TestAndEarnTakePart: React.FC<{ + websiteLinkUrl: string; + websiteLinkText: string; + content: string; + sx?: SxProps; +}> = ({ content, websiteLinkText, websiteLinkUrl, sx }) => { + const [agree, setAgree] = React.useState(false); + const [busy, setBusy] = React.useState(false); + const [error, setError] = React.useState(); + const context = useTestAndEarnContext(); + const handleNext = async () => { + try { + setBusy(true); + if (context.clientDetails) { + const registration: Registration = await invoke('growth_tne_take_part'); + console.log('Registration: ', { registration }); + await context.setAndStoreRegistration(registration); + if (registration) { + console.log('Registered...'); + } else { + setError('Failed to get registration details'); + } + } else { + setError('Failed to get client details'); + } + } catch (e) { + const message = `${e}`; + console.error('An error occurred', message); + setError(message); + setBusy(false); // the busy state only resets on errors, for success stats, the context will navigate the window away + } + }; + return ( + <> + + + setAgree(checked)} /> + + {content} + + + + + {websiteLinkText} + + + } + onClick={handleNext} + > + Next + + + {error && ( + + Oh no! Something went wrong + {error} + + )} + + ); +}; diff --git a/nym-connect/src/components/Growth/TestAndEarnWinner.stories.tsx b/nym-connect/src/components/Growth/TestAndEarnWinner.stories.tsx new file mode 100644 index 0000000000..ed12362122 --- /dev/null +++ b/nym-connect/src/components/Growth/TestAndEarnWinner.stories.tsx @@ -0,0 +1,18 @@ +import * as React from 'react'; +import { ComponentMeta } from '@storybook/react'; +import { NymShipyardTheme } from 'src/theme'; +import { TestAndEarnWinner, TestAndEarnWinnerWithState } from './TestAndEarnWinner'; +import { MockTestAndEarnProvider_RegisteredWithDrawsAndEntryAndWinner } from './context/mocks/TestAndEarnContext'; + +export default { + title: 'Growth/TestAndEarn/Components/Cards/Winner', + component: TestAndEarnWinner, +} as ComponentMeta; + +export const Winner = () => ( + + + + + +); diff --git a/nym-connect/src/components/Growth/TestAndEarnWinner.tsx b/nym-connect/src/components/Growth/TestAndEarnWinner.tsx new file mode 100644 index 0000000000..600d8f6f4b --- /dev/null +++ b/nym-connect/src/components/Growth/TestAndEarnWinner.tsx @@ -0,0 +1,114 @@ +import React from 'react'; +import { Alert, AlertTitle, Button, Card, CardContent, CardMedia, Dialog, Typography } from '@mui/material'; +import { SxProps } from '@mui/system'; +import LoadingButton from '@mui/lab/LoadingButton'; +import winner from './content/assets/winner.webp'; +import { useTestAndEarnContext } from './context/TestAndEarnContext'; +import { DrawEntry, DrawEntryStatus } from './context/types'; +import { TestAndEarnEnterWalletAddress } from './TestAndEarnEnterWalletAddress'; +import Content from './content/en.yaml'; + +export const TestAndEarnWinner: React.FC<{ + sx?: SxProps; + entry?: DrawEntry; +}> = ({ sx, entry }) => { + const context = useTestAndEarnContext(); + const [busy, setBusy] = React.useState(false); + const [error, setError] = React.useState(); + const [showWalletCapture, setShowWalletCapture] = React.useState(false); + + const clear = () => { + setShowWalletCapture(false); + setError(undefined); + setBusy(false); + }; + + const handleStartWalletCapture = async () => { + setBusy(true); + setShowWalletCapture(true); + }; + + const cancelEndWalletCapture = async () => { + setBusy(false); + setShowWalletCapture(false); + }; + + const handleEndWalletCapture = async () => { + setBusy(true); + setShowWalletCapture(false); + + if (!context.walletAddress) { + setError('Wallet address is not set'); + return; + } + if (!entry?.draw_id) { + setError('Draw id is not set'); + return; + } + + try { + await context.claim(entry.draw_id, context.walletAddress); + } catch (e) { + const message = `${e}`; + console.error('Failed to submit claim', entry.draw_id, context.walletAddress); + setError(message); + } + setBusy(false); + }; + + return ( + <> + {showWalletCapture && ( + + + + )} + + + + + {Content.testAndEarn.winner.card.header} + + + {entry && ( + <> + {Content.testAndEarn.winner.card.text} {entry.draw_id}. + + )} + + {Content.testAndEarn.winner.claimButton.text} + + + {error && ( + + Oh no! Failed to submit claim + {error} + + + )} + + + + ); +}; + +export const TestAndEarnWinnerWithState: React.FC<{ + sx?: SxProps; +}> = ({ sx }) => { + const context = useTestAndEarnContext(); + + if (context.draws?.current?.entry?.status === DrawEntryStatus.winner) { + return ; + } + + // when the user does not have any unclaimed prizes, don't render anything + return null; +}; diff --git a/nym-connect/src/components/Growth/TestAndEarnWinnerWalletAddress.tsx b/nym-connect/src/components/Growth/TestAndEarnWinnerWalletAddress.tsx new file mode 100644 index 0000000000..8592b651dd --- /dev/null +++ b/nym-connect/src/components/Growth/TestAndEarnWinnerWalletAddress.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { Box, Button, Card, CardContent, CardMedia, Typography } from '@mui/material'; +import { SxProps } from '@mui/system'; +import Content from './content/TestAndEarn/WinnerEntersWalletAddress.mdx'; + +export const TestAndEarnWinnerWalletAddress: React.FC<{ + sx?: SxProps; +}> = ({ sx }) => ( + + + +); diff --git a/nym-connect/src/components/Growth/content/TestAndEarn/Error.mdx b/nym-connect/src/components/Growth/content/TestAndEarn/Error.mdx new file mode 100644 index 0000000000..05afd5a492 --- /dev/null +++ b/nym-connect/src/components/Growth/content/TestAndEarn/Error.mdx @@ -0,0 +1,17 @@ +import { Alert, AlertTitle, Link } from '@mui/material'; +import { TestAndEarnError } from '../../TestAndEarnError'; + + + Oh no! Something went wrong + + Sorry about that. Here is some more information about the error that occurred: + + + + Any error reports that you send us will contain information about your client, the gateway you're using and your IP address. + + We need this information to make Nym better for everyone. + + + +If you'd like more information about Test&Earn please look on the Shipyard website. diff --git a/nym-connect/src/components/Growth/content/TestAndEarn/Stage0_intro.mdx b/nym-connect/src/components/Growth/content/TestAndEarn/Stage0_intro.mdx new file mode 100644 index 0000000000..557a800084 --- /dev/null +++ b/nym-connect/src/components/Growth/content/TestAndEarn/Stage0_intro.mdx @@ -0,0 +1,25 @@ +import { Card, CardContent, Link, Typography } from '@mui/material'; +import { TestAndEarnTakePart } from '../../TestAndEarnTakePart'; + +### Test privacy & Earn tokens! + + +Help us stress test the Nym privacy system and have the chance to earn 1000 NYMs per day! + + +All you need to do is: + +1. Make sure you're running NymConnect and it is connected. +2. Note your reference number. +3. NymConnect will ping you a task every day. + +Complete the task, post it on Twitter #PrivacyLovesCompany or Telegram along with your reference number! + +Thank you for being part of the Nym community and helping to build a flourishing and free digital society. #PrivacyLovesCompany and we love you! + + + + + + diff --git a/nym-connect/src/components/Growth/content/TestAndEarn/WinnerEntersWalletAddress.mdx b/nym-connect/src/components/Growth/content/TestAndEarn/WinnerEntersWalletAddress.mdx new file mode 100644 index 0000000000..d519ce49eb --- /dev/null +++ b/nym-connect/src/components/Growth/content/TestAndEarn/WinnerEntersWalletAddress.mdx @@ -0,0 +1,9 @@ +import { TestAndEarnEnterWalletAddress } from '../../TestAndEarnEnterWalletAddress'; + +### 🎉 Congratulations! One more thing... + +We need one more thing from you, and that is your wallet address: + + + +Once you've submitting your wallet address over the mixnet, we will be in touch to arrange sending your tokens to you. \ No newline at end of file diff --git a/nym-connect/src/components/Growth/content/TestAndEarnNotAvaialble.mdx b/nym-connect/src/components/Growth/content/TestAndEarnNotAvaialble.mdx new file mode 100644 index 0000000000..fc9a0a3c5d --- /dev/null +++ b/nym-connect/src/components/Growth/content/TestAndEarnNotAvaialble.mdx @@ -0,0 +1,3 @@ +## 😕 Sorry, Test&Earn is only accessible while you are connected to the mixnet + +Please connect to any service provider and try again once the connection has been established. \ No newline at end of file diff --git a/nym-connect/src/components/Growth/content/assets/matrix.webp b/nym-connect/src/components/Growth/content/assets/matrix.webp new file mode 100644 index 0000000000000000000000000000000000000000..2b1517166cd4d85be71b1a6589c01984414f0bbd GIT binary patch literal 1170192 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 z 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%0AY1&r(HrcX7DYOZJTf@ZFE+ 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
  • $uI=I`3 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 z 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%0DGu5|BKR4$kh!k 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%0D%{OY%Vnv&7Ir%O1##EOe(KI`-UPgKrw7 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

    2T|FdVh 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 )NSw^p*%xo*j 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

    OF)K;hIIf<;wc0gwGW?r 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�sxURyBMpA|alhJ8P)_QkPmT(m)9Jzbp@v_Bs3-zhWhVPi8uN#&N7LzouyIq( zfnL(>UE;2k!sOpu@ZyKqW)$Ig7|YIEyxd2Lw@6?s-BH^BtH(=YjMySYD}cNIg>p2_ zx&8<7764oseB*1Z*RMOfvAUKE*@cxA0MMxp2!$lFYlS6Fp(bm-{gJEToZRC-d05#= znZ+wfKeG?NLi#kF$<;07NB0F10oe)wO$e?#1cf7>0M?EdwfPjnzlo3I1^=WZ^66X- zURn&y6toBC{AEcPDj0Uz`LtFc8}OE*0cU1KScIYjVIl9|kr70%9?1wL6UH^_u~6g6 zsM85SYO}NLS|EKI(+D&w%5G0ZrvlFO5xVGx)`V*>yyo#M%zt8+xH(Nuxk%?8g7> z^67{s3}z`}SA)!>sFEPt{61(&R3UvH<}IJBQb6Gn+2%AU&^h;|X@}?l(PUHwK zgJ5l|QQen(%i4wC2&w`RPU}aKn)1u5@F6uce*%8rITs6&FaE9U(CKI?>v^BzW`x}_ zqGmKQ$Yh(jrOc*M4NJZD{7MH0zb({@)Gd=MYRH_dc-ITT=$=P@n4CUeI)AD-(2IGS z;xt5*jk0=e=&K~+^zL}vB~M*$si7me#_-f6q&O$ZqVaQx0c^ePS`@Pg9_oV5 zO)@Yc=AbJV|0HqSDLj{WsHNm}m+>J@A<= zy;AtY(=HLcFz7XjL-%nSG%ZoaIYN7*v#^FRltWT6-ey=$uG&!Dw(hTyEdym9g-mWv zb0m_A62Q46@O_jahlc#Xg!#F4fQ*(xqiA7lgsJ)=y(dDbAJ8!Zti`GG$6L-G>CLo) z(Vu0h?8?BS!kZ2g5H812_Wc*NeObGZ+f!iXPUzS`K=tbgHT5orPUSF3#@%|2pq{KO zxy0UNiGAp3Dy83~XVL3^cj{0Imc*J4UgG!jjsWR~)A*Wk2YC9TW*s<_Kv*&oW_P}L z&GBZFVP;345@JNJ6%vF$+mw!lLe9;2Un#XEbEpW23iIYu`X66*IXIk$qnK(PbH>p9 zk@$O27jZ0NS?;g0x$lE{^sao2P;aju6Rt~Xr&u?AVb!A5b+Fn2CucE1y$0M3Aa@|G zbGMkBu6r#bYS40aq;Im&62HPoRz{Ckj*qxtRub1wsLACie}>?)>_p}qtn_1n9f48# zz2xlOWAt5Aqcp4j9}4%6MzQ7DG|d-X!)x?rD-!O{lBsA~nO!K%%+rPF`MLeWmMw}Y zfejgd{iQL2Fs^?E-OX+MK|GCuPeOj@^s;$arspF(yT(UgLG%yxXP<}>Cb1B**nOV} z_zktQ|FrSPLGF3QNR!=WyyKco4NZcX3<5~61c5vh%NF*c$6SCk1NjwAFS>{N{HSh( z#7jc|7Y>;B;vH5L(20#o>)(w4Wnj z005wtcBP!nQ1yII;?jkWFPI<)$GBG63_tyxY4j;-5)XT9B!asll0#oe^Kkd z^q;@^W8Qz^ybt)D`K$6Xw*TC`N^(oMi>Kpio=4a?;rkooTO@z-J+43T|Kay{@dNn3 z-v9L90iVymyMNW}q5IM7llru4W7V>-u1?r^cC4$ZLgJl0h;6(Ng-rQl|Kgv5&{yeh z7Ud}h$va9rs1r5W@xZ3Uhn)loTR7T8r9Wt~VvnOz;BS5y+=?;I;pjevGK_w?IRUSy6dTVjSm5s5Rz|Fa?A|ZD9G3QHW~~oMdbt_AD{m z^RGc1nUF^7Z&ecOY?|yG$$N{znMF*WxiFlb-2E2;`UJT4HUHhRM=<47<&=-A$YlK) z4##GbSB!^SCMu280Q$|(=AV}WZU-gu5DIExkOG;#R?l}NI7;TT3~+Pehy5e6 zJKSM+n6p#L!?G1yH|t3kIYirMsZNIlT7mYG&8qMl<2ur}#?#*=9| zjHzb~ky(m11P3V|8&~uHN;R|*#jn3!@NY8Kk{h;HX3%| zgh5ZL`)4T2k>F;Y-;YSA&r*0SjM}~BGiytUlS`rt)dC~~Tu7i@6s?$0_>X*!=-CDT zS{EJ;Hm8gH3oHq|BVvvl^+{on6mUUL}ZMY|?w z4Fk~=#=y_isH)Rim3J@zUXR_235*?k@j?sc1u<~ctJm>d8-eGewiN1v{_p8l0xkXUn#EmO#p>C*X7v<`L5Hav{HC`mSq zx;GeXY~DL6e57-Hx20gaQ*p@udguekUtN>S_VrV>m`W9>1kv`6*AvC$Y`4=qobWI7 zLeju6bHU)>TMB695&4m>SgzP^XsKLTl=tFX@QYLGojK!Y#89x@Qm#@x^An=Ih!4b3 z3&!p20X+EIh>L=~JA8I8yG&*kIwcY^h+md4R$CQ87uy^C5#`lgKKh=R6B~j~h26}M z21mDcEEK7GG+2G%m^RBzs%R#1+V_A0VYLy+%()ls!@c9GKm7wWLACcPUZl1T4~j11 zF`fe`q5rR~fccX4yt*Y`y zF1Q&&{%V&avBk@YOaK3%g)Q%GB^_1S({WO@ZyIJ0r zipsOt+PSstF{E+W0r-MNz$XdY>2yWDJ{FTrE$q+x$$U|GcPg;~3iGYkp7tq2HUYkC zH=klMg5~FpTOvhooxKMCpl^$Xo2 z6!DKt^y_xi0TT560@z@o3sb3}@|!oq=IKPDjCB}B3e=QaLjP7>x8d+HHSEvlJr^Q3 zaNmW)pF`fD^Yxtg8pte5$7F=3AyA#MSQ5`kFbVKr-SDpPaI4#^D&f=SqHvf7w6}E;ZQhfR)AVB ziajhOG;E#d=|w9#XjZ}6i_nlSEol$BiadvegytW(O?d#cwJ#6)W^{ek*c|Y08`+6- zV~fOrSk^8`OS#6TO5S0s3M+O?@>~o#d?(6>{~T+mx$CI&?Q+T8*a5}+#$SI?pi1#n zv5-4jYvoeBjw*1QsU`PKtM_ZmM-b%|N~N!>c2z)aU(bCSj%Ep1oO?(xB=HF><*`wK zaG(Laa2b_FVV4W~M1$$RZPUGdwF|Q2qWOqr7Huc2YirRP)`^fTH4>9h>=j&jROeKF z*12_EA~XrQLGlosBt^fOWk!n&QoxYkRB z-&qU#qFSmjVA?v&AJ59ic|ry)knV;0j3HCrv-v26c&XoVhW4|eO}LEcI{!RYRo&9* z%A>S<@Zku*maXQ~KEfNq-}YP+kg?U*;DZAst9Yt1knMIng$@0# z#SQtE6)&%TezY0dmh!qzJ=@%x)kB2w4@EXADV7!R#i)+pk9Jh8+_ zzjuFJf9L`%^R!!U`6(`A_T9t#2P8Yva4okvjNM8%lH=@1a6kX`%NKhgNgqIz4Vu6J z{{3;(?MqF9XxUC-cgf9s-6HkG@R*FjK9ntAX$s zgK?W^nDwAu0x@yLTa_44SHrV$a)@=GC+yjtQooPA-GmS|=(Iuhz^>woND{*P@gi*+ zNnEU4m@;|%$yn`I^55a(qp`+21m4J!j^g_>?k6h~IJ6D2KaFuFH|*T|Y?QliX6LFN zXs)o;>-K^Vtd84CZ+6{;5XkOToP{duzbrf*Ph5^j#KCp(~^u6lV zBLZ*Kpt)rj?K&iP&(6Vqo~Mf+2p!sAgwE_BWGlcrXpQBS=ohmsOq+-9_QAwZ}$OgN~yLx--CdpxRoh839ojF5{Z}N}1c;!SR(K

    #n^v^ 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

    ;3Bv^0k&>l~HN$#E3Z}53KS_(If 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%0DTt-U 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�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ຫ@(3~j`qB>DaoE@8^k6vD|}{u5dT5+)ajFX4Z4|Hu2Exk}-%;onSA5}LO~pRWol0a3%q3H3@KBF;Diuj-vv*G! z>|cbKUshw#-@}Vv?(N@7&4`)YiUmJcz|c})mt=p`2$@>zfSLJ}@~r5Mr6VMwZM?nc zLmpn^Dy_y_il;kwLAlW;3iKf@HuN_;5Me5KdN`id2O0(7b7nr3Q@N&7DRGL^(q5T! zSs?-z@(|5GCwFNiZ0TG!hT8MhUGT-|EorW#ETVV+9e>DB=aU-cxFF98Su%+%0ugKE((O%d-ZU-z1^gjFN)E*CiOsRTbYAb zpJ`66lwa9UK|F%Mqkr2U4`{r~&w=a1#lAzLq}3E~w$=CZB*8eIm zZ3I<*J}2TsXRzI?X7jwjV8^+gy-jc-gGZfR=C$+N;iQ{=k_$6gPgLA?a0Rwij#&?N zPbEnqmFya=-l4yB)|!US7U8!>07E!SnYiTum+1pyOqDZNBZe|1U#o9j9bz<+P(n9( z=q~jAf&Q2V`5WQ_nVfZYOm&1mVa`KCxin(J0;Qn&qrW#tiRcEZRQ}js8&}Gp;rzYB zx85(#bYSeHR5?hkGE5TrM%c^0+XnUBriw^=(Z9C-<$wN}RRJN$3526|(|CA}!ZP^dCS34@wa=_9Xs}Z%D9SELO>npgMC%u|e>2y!h7bKUG8h+b%yKGbWY}ah z;Qj60OZg*)HIFWrLkwFO@BqMb*~UK75W;Z?>ZnYq57@@W zzj6Z_e{IdY6q580VZlK7(c)dixZ4+>>agQkh?c+(X#CgQ1i3`l;;@#%@%y*W_Ws6f5mBVWE7gW1N(ejSv} zM!`T!&sF9&c|Q3v*-&mc%ycK>*`*iwi5vBE9UI8!8hckjM?Jmi zqYQQHnV3HMHc6B{su`II?<5L^gcMRfO%+o%R=$DU_leS5Q^;i20=k3D%%jCi%N>yu zB5APcU^&6~+JMoSOr5DPK9oKx=nBv#nv-nQTMrU|EEuAA6A91F{NqCTh28TSXqk}$ zZ#5U!&wuf5L{G8~PcIaG+-eta-XYJ3Fg-`~6Q`5RP$FiPSaW!`>7Z6*{tWR6&hI=; z={}w2!Cmf!m*i~MER|yFeo!tQG(G{8?N^>+pIwD#iY5lv+PkoRBcoK!ZP5IxtISD8 zhJc2-{o%$oLh$ZnXt@57udrI9frORtERuJF;J#$u7P}Ljl_(TlM|jgg2l8?FH&;m; zA#8CaJ+5FqJo65K4xW5`t|O%3%I^pHNjL?BByjvSqnWnyRig3R8pbstYqh@K=zDrM zGXcF4-y%|&T7K!)QN@lw2d$1@iL=lp&&QBP=jitpUu&rni^5VUA%Q*|hq5Ox?yQcJ0emcH`r0bqQEd z%cKl-oC{RlT?OKgUI--n=Bw#MTo50XCHV|nPMRx%RFfJj};T!tsJCq3POSWkt)E3cDy?x`Z|T>enK2u#vVC z_D-zV^y15t;HEC#2*^7*`@S`J)NPvo7H;rbHufJ3>E&Lh(47|UU3ezDmaR$Tt2 zB#mv2U$T8s8)GzpNd3z5@6ts^+QG`N_gmZgSea3Y}U#*as3>OuECWi9WZN#@JzbSl6?ve_1% zWBJRx{L@Sxza<5GlT?nJnwCX-xH3*QtIJB5^ReK|ay zZ&1Nh0;E4^GTH=rY*9)00wBo0=#`war-U0`vv9K`hjrc~3c!K4f;v^YeP%Kj7yAI@ zQ!3$NIJjfxV184aA^VM`K%SPK28xtEpUQ2un&{I}W@wKZ+MF*gCDLZunTCd_bE=rG zDN{TlVMY$6y!pj^Ws?i2Y81jm!}kX8v-#a`3HI1vma0P^Eov_9f!iO|{Q5w1q0-g-0FNtRc6_t=kB;DIZ;40oPWTwsCr3`uai_k=2q4m)W;Qf%_xdADr zin@oyKgf2*4J-pwfGyRv@)>!vAZRbElw*2Uj;$#pPyJuWn4p3Ez^2%-#NV4ebPIg+(&%31QZk65a|N@Cc{T6K0tj!fp?rfKEvreq0hYdDKqNB|7qO@PKK!P2Bo?Wy(u&ct~CD(~o zNx0X+aZo5BpbzT+46nrKnpblUX6E1ay9;s>P;NGfYK9V_P!wBjzTVd%-zXOtZhl95 zhbn5}OTh8gYqpRX>PN>6VBL4{{5)N5oz)1IOD~njB2qNJy>iqEER*9<k)hs`~Qw-*P4AEJPIkOEF8=v^z2p7CoERX%!n4&!GzEwX;n4+lY`WitHP>WCLT{J z+11>v&~Zc+Vu_v-W?7F4QYrZh&Cj}Kv4l47t(rr;e>6^0d^@1w>A|@Vjv4@xzt}vB zG-3sL+eTxm7#dvJupwqJ@M)z3Lo8^uG3Kb5Bil<=+A9P^!pgt5omL67=rX9CF#tvy zvxsS^GZw;pzimuJFP*57Qfr=&fi32i=W##ewr%Fb_0=#_MWn__cm?~L;+ zE7c*oO{#<0H6cTFUlF8vQqc*rixeZUahKa8 zx5BdDVHw^k*R8bxJV3+0>BB#l?1$@lHqjYY939<+7EwQVfcVQk`w-S$3r|3*Pt~R! znXZ?VF}>V?^(;h1ZQB&?Nfh>Yipm6;LhWNUL4OTh3mz_K7YeoQB9o>07Wnf4IzD^{AGcp+a4O9Hd+|Flgm=z z|G#?k-~S!HaPfgJ&;fw6ls{Vy!2EVybX?&0ML<|?L0!IG1|Kj2JA2vjx_u>Wy*Krn zZx7;Kd=V}C9CD)r(1#$CVn4ByNl}uYVS4W3GP13Nv2=`kpQr`1VMyisBp!@iSojOE z)2jJ|00v%_3Raq1wt>zJ1fxz!K!B)M2m?B)A-;fpF=#MU_9-a?pILQd5Fhf8SpO|} zr6<5~8!eNO@}6r4Ed;$Y6?>%nHwM@F4~2rh0a2c&a-XpYr&Z~Z%->mAmV_|v4O|kv zg97A8LM?kN51tuCK$+v+(l62Cu)zHXPSkYNwa;ndv#m^@39v?+C%E16IjGs^Xzg38 z`uTjk)dRV@5K;7iNNQwo(S$LmTMb6k^+2i1XQ0YX&Nu#n==I|bF@h_lC5;fCwHkC- zwHnGdt&*j#Cy>gX3bU4*neovn{AJXBR-7;5#i$(F|Zy&q8wIw7icI z&-L0o`hlLF175Mnd|Uauoa(_j58EFOI$F$AAFbTog-OLS62TPks9-S!xZezVZl$y~ zZaU2{R(noAFX~w$zJ}Un?y$&eUMc_cBp1(+MB@%LXF7VKwK?Zena?hIB#VEjX83Ytge;yhaHad@*FkVl{rY=pz03E%R zUZl0)S!JkS1$S5{uyHWeC4&JC$w!4 zv&GB2MzPJ{^!XHkh1eRJknUx-x)8&M9>@ z@iSftC?wCvopFoL?q}f9r{D73&HxL-)TOJw)OH?)@N(qzzO?!plQf0BTQQ~%lcdT{ z{nL{`Tc_7}$HM?n{OUcAHNda`!pCa#K))hEOkfzWRjzjT0bN*5E|GI#J%bp<0;JK3 zitb%-DbsB-m<^sGmH%;_ei^1n1FpgTiUE*Xpv1p?i85hMpCK zLgT|Y0D~E6y*Bu06&E3cJjWJ50GF^g*Wj%@n#7+Ay8C>3{|yKw8Gr?qu`Mf)*(hBg zpXXbPByV8`SX~!2ti-`>Te*WCIF>U+D-TTX6POZav~|^3j|zopT;bA)(&M*|9Z@`4 zpP-Ox#0V*Pi}?jjni6KgHk%u@GYbc{7dv6m$M*CGgxnsL+!?XqC+c1v{~P3-o8s-IBlx9AOvYnY zwekq0j?>ay@)*kp9f+$(5r-4Mk&@*s=!jb&2JBfFuMW66r23ZYkeK$Ey)J3ryi8oN z{ZZW0{Na}T2*3qL1>imBG~E`|E=AOLexvc9?xpuVSF!td%AO%5 zbv%-E?KGR8Es3Hl3o;QK;n;F*pqjFKrmp#RvOVvorX=9-4jjDbWMInFzkJheOuW92 zp9O9h-6rBX1-@>x`g51TJghhdDZJiG)Yeo5FRcHm>SA$)RXGc+d)6#~0na~RL;M+h z{EQS9?<{B>$4e#q6|3QasZ2NDU`ZhY`o3m4XpI(P2;TevkFpdNo2}oukdX~>pVUTF z(*Tw--kI{B;Mw|8%@Bux7QyPdrp#M-T&Bx>?NW1h%Hbr3AFe!yx`dmTQrw;4kr+X$ z7Fa(1w39(*A3K-$MDw6a9X-bYnb73glr4%2X>-zVkn5y~uOHIY8?H5}UWJ6Jt`{++ zq~C2Jtzv%I#V|XHZ%u0J%N^he@!@TK&R=9h*tclaLXWYN0Ok4$e2Lmk1p16~MF{I5 z0SNy+>xX8MUlq+~%^x_VW$=YF6SeF9wIRw_Ltf0QlEA$eB93N}NeU(I9B<&=gr8>~ z&N~bJ`cV1R>sWfGg#&8~I)W@aXl}2;2BzI?mwC$bDs#%H?-mewWnuHT%C@>V4-}Ygi=tnt{z;2NeDC`JZ4MYhr)}N#NA32Hp zR@*^0_wu4$rQozMsl7=KP?C#hyN`l(7Ki7WqbRcLvdeYGT{?qdoGTAz6#^w8s-o5+ zi1H7ZXIh=lwV^kaFSRM1#ex!`c)omf8brleUDfS(XrgV?T|(S!PBMNyRa0t z+3`c!mTmcw;Yw{PJI?V==Cms?X_0xS>gI;qgEfOqcpN6t0>_*+ix6K-ztC3VR^{m# zrILvOdW>Cz^!g`g+G(Mpcc?23bW%k5lzPR>)di8#kpr3Z&bdZ%tH)yayVawr#4*2n zK|Q~j2Dky^L4d%`p(UXn5ohfgG4&aamPStwbFFG&z~bWdBT5zMl9$5bRoTrFJ2k!i zEAv(pp)7mw-sr!xzFM5uHBC_a(It>MIV?4`9fv-@KR@M0{^gUv@ya)7-dE7w<^|Og>q-+JeN{LD z#Mz>*AAZ|D@B|;7Hx&~hVnzR0>Hr#x%(?*Z`R%pFo(B$Ee};63@`r92KG0EYh4cf( z!b}jO(9#2J+8TZ>Gnw?%U56Y#I7=NhaJmzRbe`WO!gqXEPEkZXAm}5Ngc}zG~6ugQHA(_(f~_{#l*-I7-)T4pJEa-`IR z)iONXHovZ_hNj|LtT!qNXLzBM#nnxO%W}#~Ut?(7GvjoG#lm^GKo3q~-9oML#@d}^ zlKbwyZnpv2_`lidd4KdJsw$$XC9;_P+!GgyoD7yuR}^=Uf%tdro;w!VB8Rc&WT#uMYJ8X&XE>7IW z$sK9#7Y@3H9EDJ>F1jNHjfS8Q-f4O${Sfk&PmQ~}*iw+mNGAtEMv^L(D8T=^^H4@D z3O*dhrdS8o!o9H9LrJL?34H~E47 z`CM3kSrF-iOm}t9{ptNI0Rd~QXz$0+bk17O?$=xd&z)?!y&HcT8o}BBa8!6Ws0)lT z?ow-UKtcU$>N%2L`@VC8s)l{vTkL$0<)&IilPe_?SOD2o^eghg^qbW8rmy`aVAXqs zw&gV~S@KTixK^&QTID%bS5nj~3Dgb4*n<=R;INVysRanu5$0{v4hmy#M5WhW3f_}W zn3Pgb591;1ZXEICx@yW&X*tID7y8uTjR&xV1EO1zQ z;h*y?OaQds!xShEIK`~?OQ{R?;4GrG?~H~^?{>qX@+T|Jw4!hCRe*ihw$4o6II4EB zvAR;Am`EZPmfmmpkdBqx&K`OiwHwkv5|H9|67a8*HvQ+Kuq*nSsO-&I6MU9K)vF#m zb&z!&52*19cqpaPFBV2F$%BLwZ;OKV8-D*U*DtmZKg0{|g7?T5CqR0gt(JQrmt#GKKqrxiYRs%N0tab%hSl%4mFV5mtzy144)^XIvL++K#7Z`2sdXi3AZMYT zAQrChdZu$vF?!LvdZu7h>3M{P8_Cb)@b~366vVY>RLe)=ndN{>TDSpslIib63Di)# z6#=elQh!LO`oef^z3O-`K*^^?WaajW1JpW=f=;^V;km}`I$cRoL6C9LQ;!PY!j=}| z$j9u?X&nfn5_V6!Wk|VPoc{Pk0Pvc$YE&wKh6SY>phdIvp??SZSfIEmFjwr%8AsLZ z8B)EnC?d=Au9l+1nz1fAxTg+jVKnS5yg19un#;IiQ&qOL8y}N2`4kV&vvy2B-~YSe zG@H0YThalmeI&9l8QPwSUit%Z5Vvq`%ymdzBSpqT>+jB6nYR~9p208F=7osx3LBus z>;yez&uu)g3OzVvI{R?v&F&dFJ)i!VNeLz6RwccV`w;F>x85v_8Y$oe7$mkEUP?Fu*WI9qmQ>fu=FM0|REq|YlrVOy7X z`ZMZdgg3;fVn)zu1B8{tV3#Vk%dCbFRji##HrpULuR7O_zbV}WhIm|=O4AE5uTx5y zYiG2BaMYiTG^P~QJtnd# zhKb0}`q@&LtJOSsMnj4UTnDcOPol~AkZxhm!Qo_8h>4TC zjX6l&f31rl=C0t2^>koo-ZU$UE4D4b=&51inRl8Nh8z#y@*Y?JtMwq7h+(Roo*~v7 zhGxFbnNxswf-F12?2Tnu3BBQtjC5r18R^y08UPycA2qA$4RrvHpd-{bcT9#o4q_ioRf){-b5hajm$dS_6t~%u4l$!UiOKzz8=JVj2{a0 zk`xLlLFE5)0h(=!e^jn}>;7*^0K4VY{iCS<8fWpS&%gtP4g}gh0duycU5nicxpNfQ zZ4(VcafUFRU7sKeBMzbkp|vp+aKCbquXU(*>2l1FYNit!=l<~d2T;P#w1vD!@PhbIDpObgV%de<3rTe^q*7bp~MJK-3saR%;9nBcE-Vc zvfMC4yI$_`V@WQFYPY*3a6e^iRtPdjT>IbnC}>kShlGL%4(nWUWq_`KrJw~HwzC%LQsY1n8Q zqt5|RLyNxPuq=v$MUsjwu_vil-*hU7LG9h0eto!$za4!P1gS6v6dQPV9_LD17!{+D zE6l2)1Qtao(aSqcV8ujQl&oF!=!1KrHSAb=4zJqIPfXb9)hZ54-eh}ma=ZD7m+6lH zl(q{V@x6mZ3q{38b%rtR6q+@rK3=f3#QZ(H<`FZxM{v9eiFkHinLQ69)(I3Ff#olN z{^Q55CPInS;UlfILEk`21cktJf*}N}1n-{H?3B_IiQ{!u*V_iaA&Yw8 z^WP>NmKOtd_i)Ah@9n#7SLQS_0`Bz(;GxD6#z%-h@x)>LjHXsP>u5e1aQ;C6EgD&psw%`4h@_OJn%e>ITki_{DRs05YuDmwB8@Gr+t zxQ8-#KLv!A@vw}lx8DeCxA2dV-&+nun>C!5LePOw-}BU=bh>jfmcFQs9xxwvn)3Tb zEwN`dPvp{uQ7Ks$50i2NZy5=q3Unr5 z20`p{#MVGufTNaXNWN!Pg!+arh1_9bm=|G;-g-SrnhXwPj{53?q52-}K!lPDW2pmH zafj7AUZ6Tzj77=skeVDw&K0l_Qb!=(;414i8n!}=6Y89Y444z)6Nrf=L7l$5G|_{K zIkQ3U#5W}k)a`uGC(#};IpC9E_RxBHOOgv1;@QbXakZ)L*tOq76;!9kp@F3tUJ}7; z3?RNskPoSIDV>G)ni;2 z0jK;Z$uM|Q5b3YjGos~ZN|jx$?!DsXG@Jwl&YxaX?4Yp^UGV_tvGRwPJNhT6UxwrB z2t-Fl!x~Yh|psY-fwh7|AWc7uYU0bu}nTsE~(WQ zj(^L^qEDj+!9sdl#yY_CgKv1mMdfBE5CPLQcdf)R&bULgy@>-YqDp4S0?YPE`3{na zr^?y=q5zc%`lD?eMZ*7yxcrgB&^-$R2{Q^Z-Vk;hlV=C8l|+jF zS#>~YD-!Xz1MmGC+X_en3_fsz7+?VVX7GRjHSpV-cWH{AKLhc@Rbqrxh$iiblN59< zj*D8AkB-UKWIkC6`_vp8qwurc68{z*nG3=!DJGI(0j!H#_?3On_N$5OyTlhD8!>0TxQE{0BYo#e;cxHZQ!7m?pirOb&w}yAUgH7{=+Wn4X?Yu~BCHZM^ydYC7|_4lgGKxFbs;#XI;>1((=QAy}Fab8EW zq}#g%UVdnEaNTD)^bFi;6~`@9`SLovrza|lWbU}VXXSI8LQawBhV{Q)l64xI_ti>ixe zEADPSNt3!unXBOaV3CLo#t;*Vm#zALgUS=ofo_yqc7K07iPN6y6!b!Nw(YAwgi1Y| zktKx&-@MqbW-W~yDQ_nv8)eplT9_mYoQX!Gbljm3?ZK(wcCHlmecMPoXpvAd6~2)O zfj%OpN`KOzNwL)>4WYI?7so7IhjHcfwdc+NDOL&H-k6g_kcG6TZmFODK0GiVN4%Xd z6Wn^EGB?2AP&jX{)i>W-%kjH7K}Nqo%=`hL-^a4+_XQ`EcX9H`z}Jc&0+42aV)4XA zml$IoO$>eKP)?Veh{(Z|Osji8`RSxSA=a6&!ln~ssCQefa&szsDUvaT;E_aSB^~3{ z7`2L2bRrqj3DXJ7Ym)uiOw*cI-)78QAlInW|W;gv%L!H<{p{4MGV-tbo(OeWl zkQMjnc^NhwnTsAe0dnFyHEQGqEwQTldiZ7bp=)~y@@5K9lYv$vk_y8Y9aEcJVx&bx ztOvCzafRE27?gAJYi}FZqD;R}7Umjad=cJBNCt_=VId~=SEKLgLZ)YTzDQE%d%nyg zFt38rneeXd`R}an&y8s-+GqR5W9pVr6TYt7>oZQ}eL{n?w9DsdSZjjj$c};9S_eIHyR=l3BO0FGRYbLraS?%MkA=$(=_ z5VL^io?za;sI&cOe;~G$Nf$hK@n%4v8O!%GI*Q1C`FWop(I5x<`m!OniXn+P3sr7b zO7MQDI_A%?uM=Y(nIWtWR2}EIUR*0DitXdP9La>rEi#y~ga^U$U+@9bv=DAq>5zAV zXX>ygBzi+{Ni_bkfWxKN+UjF9Rb38dxm-pcVi$(0Ck@qw_xSR*#TkJ#WRKsu(jr1WdAK_K z+(|{5H9ttelNd|Py#d=3U44iwHrqOR=~U-!Jk%9Er_9h6w;>4kn@X21L4Ul5HFrp$ z#%{gZyrEanc>peqF~2O}LcL}jn!TK7$%Nj-jjBpM_e|DtHChxHP7IJbNH7HA%JW2d z7wEd=!&O-FlrVbBQEXG4!*!hr4dIi~kI-?~7ni^?ETxXy^Y{lk`7fy7WfCzg%2w$PA>kHB)U!ce~W6+J!mZOjZCD&_@CRAt$vkg6!EbmE*qmKt8a! zA}|2-NKWsc@U8SvG`tp0$${0zTGAha*c7?vY17UDR*+h$0n^O~Vksosz(PLD&e686 zJ~FDvJZ$PsEzOn|fx&yXvlBmIVduDOd-(I~wbvh!XSo~DQA6@);Lb}ue;6c#Sx%r*?oz!i)d(A&9>N)95n!Z-<6N(Y1(<2a_fNzayT0O#d8nK{k@4{GhJKFe2&9&3PgPS8KbBUa zcNUWefe{_X6oSe@c_`2f6AEyEdvh}6GGO*V2M;?_?`NoLlPCpn<7)n8IB1alV`RUb zD^!1l4!)|_IxzpH-)e=S8T&f@T_Td%M)#-(rbp|}n{et`<&Rwo8WK$$oOSl2PSR#@v1*A7;&$Tf^4I6=qIAgLT_G&A-t!lgd&O5ndU!1 zjr;5?1Wg^9Z3Whc_Mh_Uky?5wlMHqIBLO7H#uiTXOI=Rm27jtFOFwr7KH(8WX_(PY zuo*emnSzf_>zeHEQXGLGPCx65G)QlB8}S?-fE&-qbD|vM)ZGpKrTs|j?UBMnlzdDS zcimN|fT_7M@}B4jIU+w1nw2L&^%THOBPV;Ib>71t!KL_>2T6y0-6II&QeWvH)F!<) zm%=v%+3%Dw#lMJ1pkIOu|9U%2nBX3}B#tvcpb^N_2h=R330pVa+WV|MZjnxswEPYd z)~AHC7Bi3SePhicP@LV|TJ>hBNZ1^KWubK(KcF4{JWZ){!7K1|A@=<%yb$5eQZ*y40*PMm2ZP~KI$ zUA?#pOq=wch-hU}B^Pxkf*;&xJIpzdomKSR{tM@VjSc;cVWV9G68`Z#g)S`hYwC9t zEIh)nC`XXU5HhwJ`+#5n4C7Y=_OS3XkF3V_JqD?BlC%xYvY3b;dWDrkTb1?i_Jve` z=cOUR;fDA>P}^}Hkf(<81%2zIq^n)M5ZXb8GXXt&q*DH5&&*@!jg61BukK#iP&th4 zx60v8lOvEKy2^@TN4UQql^nmf=L4&;%`yq zY)PY|F?^~AL%Au88EiYxIU5cOzSfoAA-!m-kxh#r)5zr~_4rSZHBBzNOmdE?Vbv8lPYI%e=R95Wf-$70>}GUB!!&vK}s$z(WwPFpb1^jUC3;*OjnhR8U}*!{VJRE zNi&xTr_drJ4qp^fJ5YoHn(__ga74r+v-B&+IF6vTIapH{Yy9JgQT2QUEJ3=AMJL;1 zUm=q_h7VFkdpa+SOv;Q*9!lNzPVjstBsq%}BS|eta0fuLImC_ugSt`B!Kfukp zphN$10I^uwV&Lvdc#q&cvnCwc%Xe>mhP+E+)V-gTE|GadA;&`Rw4ex2;ed_Z1ti~_ zrMuSqTpUqeKpL(W^hA$F>@$6%1yxX*1F9X{*?h`Bo@ssghuT_`)P;QI=29USbWZnU z;|P~pmK-M72O%({&R|))ajj_37IRy_A$d6zIbP`PZ@!!5)Y*o9X1NxV9wc7bFSEbk zU6QbbAIg6QYQ@jF!bEY#E0STE`emg@%L!RZWD!^h-Q(C#E%04QPJ=2>d+GtGYVYzy zwUA@-5f=txUt@a|3%L@c))(aP0^wgcWUuw+=q6ETFT#b3eNLufke#Ny~ z_Du4nASt7Ahx@BY3qOnA6?N4Cr~D`htp`LS9{%le;=(>j5AE_*%>`7i%K{=Sac!ex z9Arkvup|eMH`6-x`h&^vD4#OzsN^2h&1HQ}0M6%o&&=A>B;!rv`<8&~FTShBfmN{8 z*Vd)xFfpQ%VFHb-3l_9et{}VD-{9*q-ScF>eRC@7C)Z99ruSx8bNPZvCz@u^z+@Y1 z7f?=HgR!UUbawSPg2dv);RcexIUw<3?5}OqAhP?Frp-2Uj5nxF86&Hy7!1Hw=bITOvPg`{0QgLQ?o*ZS5V*yuK;oj9zI~jj_IAo#%{x5(mTFzAAwC+=# zjn?s_j%JXR={4mu(g^E-cciN&w9H1d9RrSdCJPq2h(2HD8BN=X^JCl~Ij4aI4Xq+p zVh$$8R*e(yaA5r0i}6M1fR+A4-?pz@764joKjJ%Kphg6e1b-JDF$Yj6NOvP{7C~Z?LfH$v>l_CQjjf=2&*&e;-)z*c8 ztn`_na@68bg8hje_12;m0%>hIM_};A?MhgpiA@?X!x^+7jS4GVde`LqR2aV2WzThF z5*ZV&E1#YhX*r{ckh6W?#&#^@MJeeSm)fYBgd6G%m+e93>DOIbqXhyU?-5Apxg^|* z^^;~DZIt_^8C@Mu+?oN#f?>#Z9GH0rSaXI7TQ5w-*lAS;?t}A@;IcrkxjiXeeP%XJ z7WZWAuRq;g(;rZ5lU7jZ`D%q(sx(Q}P--dNY>sWP?rx1mNfQMkh)&@Cs(YpU8Y%zd zf-iplzpVXj{gQf*`6Mevjy{E0z=99C{-V%D_P>;a`a^dn?gJ@?wE4RxTN2CffoY)! zGONy|*HgW4YaxU=f2V`T;SXsqY<}yc}pCwD-#Mp^H(|_gnHoaSNUqTc40ACe+*1;tO3Y4MkdF-+11302?|%59v#RkzE`2=rRsyrl@^C^7w2YK#OfO z@*eNs8UU6#DYUhmcRQQNzkqKeaNJWv8pX6m(rKy3ct<=w0;V=`@=F#$Vv3_Y1aUwP zKT`4~DBk|{N|Z4{V8$de5dITYT6(X?&;S_iJ)r<&6WfP8)c2i3cbDk~&j?z1{C`9n zENQgLhfTyTtPb?w;H^!nE4J!T>CdwgVp!b&!qa&v;oZEpKb9b-E#$zq@(3YAV2LVM z2$xWfAP3XKH>ttA@Ilp=2m&e+V*uMK(^DB0NW7z)0pu2VFd{wi*z>`T zr>OxV$*fK?POV3x27+4kLE`&+-v#UUzYbHLm)X0)g(2=SJ)d_*)1%O2X|^m}9o zayg4&CPADwl8=-NElKr77cC>j;W|s7@)(?3Zr2FL6+!1=K6Z(D$eJ`y|gvfLQ7*E)= z9_&;}oX8k0ktx^rf2%D?SJXj4n$}nS^`<^d1H)MOZ>fBQEtF4+XF8p?KB-X`i?giF zn`oy8NrPj5uU87_Dn(a}uvvkulh>>=t0=NO0LLq$ggmLd7wneyFOo_k z801)zZ~xFj`T{*L&4&u876A&O*!5{Gw+UR!tgE0tkg9G9^4g*?!1Czr5T?aK?-NDk zrTjMfrn<86Pq^2gtanX5;A`yv?truAQ8q=BW&@l~chySnAdzFcfF==2E85Mi2~34G zLz&J-Xf@CoDWGl2RFUriG&RbA_MXhd9U1HbKzt)3y(vIs4(SHf3v&(8Ag(RuSEJeZ z7?#>Y*SU1C_Vm*c)Y=9fxe+e7UtW-h_zhgosQ8tg+`ck@j^BNd22n*vm%ED!_ULSq z1?tEbiobWg=`-JOe?3cegQkhD20KPm%^uHNP2yUoQ+F`8$^@WElahh|6CCP)^0zu# zjz;6w>Vq+falz+4Qn<_AtZczY#C)mv7MY7ZFU|_7uQe83WY=CWQ`&HDkyW5+3jQSi z`G0RUugdDlX~$3SJT<@*ZGKP{AO|)#aF#qJKEtC(Kb(qa{9W3Vo^NDPvy%ARz)Q)T zJm5;dp>+H}W@-p`!iTizmwg*S2i0Jp($H3Cr_a+P7v0yxD=}&-e38 zQ>hlxT<&i#Pb{2pnzXptZ#ehdK}BYYxwD#LNIxVg3u&m2E||p$74NzHVC=Oy(J3FI zSytIk3RW-BN=|K+5g8@zQtky#d{irAeW19u#1`n6ywVla@5}Iu<;o=Hr=RpaiZEhU zD26G_70O<@RfV=`E_NXD`Ebq|K(*8z`rVzB$1U_+CgDCI2ozFt*e3;5Pz zbA_r0sG^((E62}%5@K-dlpD{WvR6g-?39+w8e2viw2`~Wndk&dfYTmj=_^Cg{njx* z8avMwyqeu6Ar&6-T5oXU-C-WMbL)rmc3>$x=$woZ6y&|kg|LDy`qNs&kIa$%6-9)| zYx)ptx9(K}@HwD6EQsCXT>?33g$lk&UNA3cQ}igZZXD<(ZW<=Vx_;lmhnl67|>fI&`lu=qKPxa8v_i0Kk` z!yxcWCX&+EW!qy^=hak~d%)PB)7Vyf)2L3#>9A$dh-!)Jpvn%Vr#2)9?6H1s{rp*t zYjzUmr@ahkaZcqB>eRTL{%@cpzVE&co8T~Ymf239_56LUFG3a65;8|)LVB%Aw5rCy z^HwGZH=4GbHH=Dvj~?UuMMfes0*8HFHP|m-YTHNu(Wy+$MFu~S+)s8LH@Y+bZ{qC{ zZx3Jwka=oQ{~ML?rs>a=RiB6-AAbOIk-m10n0SU1xp@=Rkgk6|XtFYp%(2tDkxT^y zdYM_VIA7zA(skbHP~{uUeNz)qA#I z*z8yQyt<<=n~Cm)c?ZYLc~kC*+keSmkU-tmQlYr90}>9xbJ30b${ai8=AJh#>x2pU zMB{b&w%v{eGt2*n1n8MzaC?UAx-y#TtAB-$e1&m`!YxOUP6CaRAl#T>%`3)42Pgr~ z-*?xcIoJGCEzi>W$NXJSKZhM=@evIE-F9@9*;@;10+R*BDWL+!#LK2LT7A7zn=1@< zbNpCAm}JlPTV)qz#UG5ijKb3*HUrOPf`Ck{fioUQH1~3XnVO0fI?PTs%1bJ^WzXb#&?s36Jo zk*whp09u;r6sNI%k*{^KPUmp%T}HWSE#Z_caeEjzn2BxD35=HPJJ*NB-{sjo{dv03 z<2iC9m#qxDAC|)<54)*fqHc`9YlG4=3(S5PuBHk)wngMlppX!|aY%X1J$2|`L*96w zaVKFCFw`GQJ^mA&wP`f#quye`6?PzC9&cbiOEPOI*n}eX%~fkDhB~8?7ps zk9od*MH^*C&)jKVQp1a`H5Kc&9^*20g=6n%< zvS#PLA#}W`YYDPDNB80H=zwT!&0yF`!eqUCab%Q?@ztnc=Ha1GTsT~t5GDD>erHJT>?P_G8I?A* zlKLimo}PX2Yi>2G2wTqfJY?!}T~=9`fRLwKUKPpV?OJ5D@WByj)%b)OSh<0u-OwHv zsyA_}-zCpt>K9!kL%gxfBadpP$!PJ?!y+yRJQXHkFK@p5^uh%>V#ef+8LQPiSn9My zeWSNSqxo)@io`w|=N`Z+;2~Q!n{OrHFN=FrXUX2jVQ}x_IKep=IKiD_B%yU`4^BvT zE`BurW*tiPMoHa*D}v1oWP~d4Y<~)TWY1j156-?ox6x}gIEe2pbY0oO%i0a@(Dls< z0TsRNP7}eX=H-c$V?!>(-d&Pn`SM)8>s>b4)mFdbm4(ybs5t((M?U-OWJ~NWD{>mr zdPLAJkF?ICFenW`i-?fu2nevzDG^!YVvc8}z|3#D(o`^lZoBl+(XJLBB>Q~L8htL~dExg`SFF_!$>9>E?sB=GT zA!q1~bGScO(e9Oz{)c7m2OH3Cz43o$eU2`&I1OPPaujcwU%w^P8qW^L)MkHIM7~nA zli8_f3ydn%Q?A&~s0N5rLLern@=zcO=D%|np+gP`T-rrQM7R=q-d0^mPlTgD-WI>ki*o;>j zSFqP(X+})E-S7|;xec-k*Xc`I7uXt@6Ux#7;eKs?9z$?M@K|6+&QbnLw7-?s zI62np*T`T{qgD+wE5969zp<}HN1iosrrI$^;FSACZ;Gw}L=90E`J9kzqVDO);*;rPG3JKHLcQHEE^ z?3=bKKnXutOduqQBnO;EGMtX6?FKCJ*PXCT;r~1cZr-@;E6spu^T>+$js1FTfdm&a zyHAeJ;|d{+stFj=YPX)2C-`IL4|WNitgLL(lUA%0d(sC)!B+7@QYJD1?-|6_z&_fg zEO&L(*Q`bri^S$){P5Tn-@CsT5qoEsiA4Vbb{nZpuUFVF;m= zvv$CUvIB3p(F_6Mx#w1xql00KK_By=48Tbas0pDi|~L2&{rPTUM5KKP$-lHhFRE7;jET1t_K1RNx{7rpKd-P z^&LBD`O}-BZ85OZ>6kLZdyZdQYIz@S&IaRgQUJJ#?dwt>+A>}Kf_o%f86X>h+lJ8} z+cFT|zMvq2aYY1uL71gKlxBYxvX9*_1FB_1^~_&irl0UnJKl8Lu7kfILm8Kfojg_R zi6ceM;Tq2iW6-*_1}$MWb5G?{GL))Po~pb-1?Ek5Cpodp2~Cvc+)F@2-uqJ=Q?hC! z`7P*%r3$qEXD=cMQ*wpR>xXOHCUBbQBaA6mWDXLgjhcn1M7_sPdLrE-eB% zN2_k7j=wc~fm6TQ$Nd?M@R+bd-j)c6pd@iYc#>>^0af2-FFw|ewTFJP0G}A>1Bz;p zA8S`Sgm#8_!f)8%@PWfT&uutIU&j7^jT%XfW&oo4cDiV9oIb&t?wmci?8^h z+X2!yGZ+LYLag;?!FrdaM_YsQ;5dbdYNF#wc6EyMoV}xXzr-vEogomNAS1A9$i381 z!>&J=RLUj0Odmr_Ee+C+6#>Q&i3${IYPmFJ2)~o@&(VFndSBv`7pf{6%Z%5ng3z&z z1LYvMOzqCesT!qfQHd^Gf@z*OUk=GQIK>URi0`pvbm)5|aGX+@sae%~ttkjU<<1DL zCN?-_`ca6C>F-Ofua7>$)Im_Xt3-dk@l%)S2YTn@!c0@Xt$y{Jx^{@1V4;=lIg>|F z9^t>a;ODKSmnzqB{SFNoq>djf2su+!*`V-9LuF$cB;0rIz1-k$Lv4>Vr+DRxQhs2h zT#i3)JNit}yn>=9Ne#qyhTT&%+eazE3pg=jvL%{l3$Kg_j~-3`TJz%F(X9oHA+HuM zp-<13{t@M5{<$?4RtR*;;<{xWdD2(aGsg(ZS!&aPklc z0GL6=7S}W82zg~h)L`arcpSU@KxmDiMbLl)VGSF>@%;JOb%n5{C*Ghpzcyj9cTkop z#Hv9F{oW=uuk{}^-8>&sQeE-4f3rtZPlaXSBlv5W1VjgRWy7=1>9WA z(s*+*ERY&&u%E2Ne+~?#kBVuc&9S6{+BsC1mp7$jL2%SH%%>m7tExfm_Pwq`=}nfG zqWOvRQ6`-6+#W6LYgd?^H(BzV?|!~FCv0SHV09Y2aINmwHs*3k67eKTUR)I-ZWT6A zeBVt=*AIl>x7laDFX7rDPjS5aSiQHDdn@Q!RXua<8u|EzqWscuE&1s;)la~)^U6-v z6rtixzhrcrd7NpV2~7dA>b}PiRQj@u0EeMWYE#*CEYWi-2L9A#Sm&iy=ScI_db?k1 z95m9y=q1KW26n`S5t{k{dN8_Yt#*4mQPL%j#TJbFAZ8R~?awA@W^`~n*ei zlQW^^syLM}TJ)QMYq;CsW&_2C4f7Fv91aZeG^p|2+kQ;(NKf#?hx8O8C}2H}fq|X! zT(&lEUK6b{eh`c1?CJ~yRM7$e$%BM)PTq(a$#>pCY(Q^WEWVC8KKeRPDTUGf!_lhB zu-@jJx4=g+U4#(*bk;zZ@g|IWD%3{PU|mMwHec*GkPROkH`~7qY*+myY(wHj5NSvdo{jNPik4e;-!WpFa#=zWA5dg#cU7MCTWtNWHsvV3dpYDK zJJN0oj5=lw4I+^D3+nE*S;zzPCbyp=JsAr;8W<-5be@X5ap}8emiBbmRbA60l;|>U zSs9y9l^bye3}**;H48cVG>zxTIQf$5U4Obw0A)a$ze2*467^ERccgdh0UvMvCTETA z`tzzTmfbKaaT)pUrf(r@WMSb4BYX(tbfkAR2-m$h053u#%^x@*KeKP-jadJivn>C# ztwS7PKhfscu4|9OwL46watEara*U+XBXiW!9oIKz7GQVd2=6P4V8S};KlJA|)g-nj z;kwxS{^=;}YbIsxd(ZvMv2xg9`cG*?-wwkQ%Vg^z8;|#L^WWk?=B^XMAd^Vgld^C| z#-#h$>J^mA2|#?~am>2gd7(RWF1+%7UD{UVSo`7T)0jpuet!<_%|1RMKL^>grwkH= zE;*H^t;p_30vKOTAO1=#CO$*6!Xkn<@a}Bo@oeH6vB;XbiBg-w2RphO(ero^%zTCR z_=23vKcu~mSwZ>b&sLG$q){Ajh*8;kL7{UTRvvVYv^O+W?|Uj7Wf%U7=V-Dyxw46b*}p$&?|g-&Pu<>tD6 zrEVP@$t~4m^)sjJ?DaX~p+J!32e^VALi?u_?A0ZW|HeHQ7{9_p{lCwni8U$7#!dn< zf)$!8s{2X@!(a6RBJLsmQO}<=0Zv+ye2=*z<{kFZv&G}|fUBjeCFNM~IYpW5I zrn0*Uz8Q(hdX<*uG)g}3?{I?_WPxIqb;a8}yYId9B(1R^Z7Gc0B)+VIkwN%I-JkIU z66icOhtmLnwjkfAd%UI{+(Fgeu;|A#MzRC79gtpKl;)`>&nb6Oe9cKzg>Ly^kS-oK zT3KMOT~{LAAXhk`T&M^M=<0zTjOVFMuV4!2)6{r8(%~U(gf?PCPtb-DTTXca3$jQD z2C5Xdv!RldR6^czD`IlqyszUi*?n_*X-mp)1s%mS?r<|R2}lZ?FFdwxB4b(_UJC_r zbcKph65!)f6$O%)8370-@{6PN+5|9c^~}O1-`(n@B#pr6KV69!Sra{XUDCaLdxs089&=a_m0uDB zzi9j{8qfEpqqc?O8ZP-VIv(jPS2OvFQsR7VGTd-YiDpfKU!pQn@w-y%Ohz)Vkvh&W z->&}m?ZE#q&0>MT3=qi45?m(1@sRZX9zMf?LJ9uk@>RfHU~oz`8*%O-5c;v%uvpCS z*G={jKiQ+>$w|Rs5{1!zGj*x$e0Pket5Up?C*~rEbU*p94IHcDYchjKX67uC((>wQ z*g{;N=8RPw9vD_r?(MkIEjSA%yVFwJ+R&)fqT<&%K{zqa?~BxiVwEgxDuJRQZoBFW zz`A+|G6d!#p^v=3abU?Y&6uYC1_oN(Uj7~@kGgudB{I@@{k zFlBedn0v#Z9x(+&R3%`O|3Jpf-vJ}QE6)J@Hbu_%&W=@`yvGW*&#)K{)>B^qJ4dZ3 z(@6D?vf30?JfJ$g0?5mI2Qm@RAII`q>+aXybzWiT3C*VtJJ~KvC==YP_yPL|g}bZD zIerU<%|X8?{7A^W9LtTNs1JdsmMHk<5KBE!C@`cBtvAJoT&-pN^&0R-8=iI5Chw0Y zRXq|1%xyPI@ZS%ga!gMaZrvl4s8*taz%1~E{h-W_DKA|IC{n@f+cDeK37;%*Sk0WU z)zS()ctnmR%3XAiX2=1?2C1(JPU?$HBTCJ($IIl;@o{zhTh%3EquoISES%xD$~b9l zy?{v5?XFwuKz(;|-VCegYJ~ju;k!MEK#bdA*0oqqlHv+#sHRHV$O!{JKWh2F*`gjF zU%jDg)ze|Wr+@XgZj+4?qh6J2Ef*0HDtGXj)J-5!&zw;Y-R(oIvNtZnNOQAfbEIU% z<>;=_z=ZC+;)L0QwfKHY9Dk9k))W_>m6?79_ze}zJT)UoQoNuS;!qVgsube5u|05P zdsMW)?)N}ULA#<16EIdY2lH7}0d=b6BtAnyX4#ncM@O6|f~CfP3u&S0RxwvXu_UPn zUc!A6G33OE>g`v~G?&c_Xk2s}f=3?1kT)lfaf2~^m}V04mBHC=R^^PM&78|FFx6-a z0EcT;tI|e@CL&`g=Z1rSa}Upw#1p$Ti*y%Wmq=;7erMCJN~**D=47LLrDu=dsy=FCna0%$pL?(wJp)>8s+J0;V0KS``lEY|Wr|*GlkcR862M&IR=Kt6ZqjHb1qu zMK+0}uU+Cx$v&zkoayXOT0lLxi66yd1R=V14cj9m)%<{qMkQU(m5#GC?yZG4b}y=g+9U+zqi2-nSUb&xJKga)aj6pF@`TKgvN)5jv7 zFeXG->5i*|;4CH@wDj;5Ghw|=aAZaT&Hcr0gCi<82_0Mf6_NDWH5?axd|1*JF9-(lN5;`()7?sqOR@cAfDC-4TJF1lBP0R zj~Ls%7*#b$&MRMg!wr2Sr9849nL#XKl)vo*_Bf)A_#Y!!L^Ylh(WAsQo)NrO#9B<_ z=v^p*5&#L9wda#@as)=dpzNUZJw*ygR>&8&XvZBhK)AL$NmCo}wUJZkaJZnqg$%|X zJZo|mM*+ydMOMGMu1>##QO&FvU2ajvXxoELaGe z7W6;U<0Nklq5Tg2F0&o+B@wZSs{=Ry~vO#r0LaZoN%^hlX~@XKT$C}oY9}+C>CXl>H zU7EAXFnOfI94{}Cae#7f#nCRR1jRSujm&qWTf_J9`@Cr_l)!fv zLPNceoAYrFrH8N@HoWHi-)qbHDb$-aw5VH<4%gKwr`$$ExD1Dn0;J%!M=>JGF3c?Q z*^yFN%`|GiR!yKtq6ITn!^JPq7C&!&JeWLDqoVR|iLu=Nh+-gC@O%LhV!i}fp*SZ0 z4GE%OZVRlXZqZ{aZ44(4+e_|oY7q)qNJH=9g#S|cdAK?Djkh3}Hi+`J7b~2uQP-M~ z>K}bEIGlZMj3tYjLMj(URWi8{MX%<>KCPr;%2cAhk_PLQF5kRPxE)M^XnejgZP6WR zG5w9C)M$ij8r+&7&c_FcILY=aY-?U6j}!PD3$vUB>{)3=q6bTt2kN$D+qzII{*n$m@^Rcjd4r;&7r2Du$f8Wn>@7y&*Fz%V{60tUPJ zkL4LKiix{z)YUJ*%hm-EJZafw@Q@Ngy1xb|JVqx!#-TEfQgc%6OC178PP>5%5d39-V`f0&Q5c3+%w=cl3Qa8!XLXAW5i@IX`yN>Qsa*+LSh&!w zJ;bRZ=3}iHo0(W-cxNe;pL1xc`+yl3B`8>&4p`(ZK>KNtHwEF76!`!iP9;@=-vRqa zQcRyRWD$7XJkf^0z$)eOUZG_nAP^J{Z5V8B*R6P>U2KlA6d49hosaU#L;(~1Kk??k zq>iog7-PCbFuE*w0qC)Fm|;YdY3XZYWfr#9=V38^7fplh00B?!mC_PHA?Y6&uui*T z?|%5N$9weuK$av#i_sTMSr}5$?}^Q7uGbi}__I4Nfr@CUeXxTF_FSep*b>g!`v1#? zt6kV;lGOFavM_UI&Nj16^cfy?%jWd+pyeKxs z7D687PGT0ou^>27rZd>Kkez>P;q4MOpt^?2?sCil9)}6UGj3{P=zdf1{zyUzMohW% zXK0nYsIJZ#)1j2&6ffg@0^ua7qu5vNVL61dwt%nt%mNOabh> z(5B#4C_bJf6}nznCY2KMyX0uDRopU85XFsTk>*=h7>BKL8*E^m{&?yj}7QBPRvMVTU^$ zi`*CqGwVLjFbAEs6N4P3+>#hv+QZr9IkN)ySp{Z+$OQau_-b^|a+SR{J(J;cW$?k3 zkW9n}+pM{#919z(57u4Z2{;)})L(0CKxZbDl*2jq(;OIy>l68#>g>1n&OJzG5N~ud zpKNRzN2u;{y{3+P7#AowQ(M)g8qUa&jqcmtv=6oS73>z}VZH*xs@_8pJ$z>)nvaR; zsxL?qYI(gx6%gN6N|3?+ei#uEO@GUW=Cq5&9cA_vpf#N&c-X%e2r_~~cWGFLeo*KREiNM}+NI$CX; zPXfRa3vfe9`)xXIHhSky&C1h^9~?}L?}hglg6!Hw1VbxvP01@}#XzsC&5slnU4?3| zO3xA<0=YgF&$&GZ?PCMabq2M{)IfU`?x96m_;fZsXcQBK!(@?-dk8PfnPX}QJ$=KB z-N`18VypPT5iUoiC1vg9q5Z<==VoT(-#+q)Lf<9IU65*=EyeR z6xyG>q=x?h@b@tXWN|>|YqTumruX(ERhSxw?UmYJ8^%TB;Qz{p{^*F^xscgx=P2e5 zZv9G20o`;HxKW`ISzeaeQ<~|0HU5Z98R%@LZFQw&?r%Xo3}bnsG53Qir`Wz_w$ltJ+$Z!6E}VQMqg~S~&~@ZAR}dp%!J8{3z7T zD6znw2oQ*)Q(^F1?(TOfaZa^Jj%*7vcxm}JWK*o7^To(_Xw}C12PZT(!5mCr+;|9h z3_Jz;oH>5TV1{wq=6TPj6Kf(QGpDy(8d;=-!r-Z0CngSIzK5WF-?K;g_RYWu|NYmA z$x^%}o-|3YWNwhNBoCo@dPMKjNmzu=VyDWjPCG9~1E$xINtUH7Ag8KjKESD!WZ; zDzcrFK_d8Yu1&W_c1`zePsN^bn*3*IRga%4Xh5Yc$L%=lkUotKYL~XP7D_u)-Lg5{ z=TrPg&82V#&GX*~uFJ$a6gZ~R5+Ty4u51%6=V~QwV6N?LtP!|7(5t16QJPgKLpX7? zWE1xx{`}EHU93UjssyLy;LMu<2rHf~VUcDgqeFM)><#x)-#i-Y6v2d{$S}Pqj$FW?P@uLDQW{Nnk=t zZc85#5Y-A9V0*fSw@h+S5$qTqlAKo}EPTgo{(?Y#q>_bus~P@s>|2-;zS|?q-JbI( z?e~->38ruN7CYmVd#%|L{n)@Qb~nWwSwXeEUx=3bRIyO>=13oD=O$buXjpXp`E8vVhC@$1GS8}UH+ zHVu|8o6Kl01n<$XyC4$-Fm0|b%10pTRXxGh)>n;4do~3(>FYTUrO&k~V_*d``w^YS z*9-!QXDbty&b`5ik5AGfJ+O=7cPr)}VYi`q2v`K0JN~ZCPx%TfE*XpygJ@}#FJPkg z3-N&{vzp`K2j9}o@(^k>YRH4qvvN0;ZL@v2b@va4AHyenXC=C2=X>rP5HE)Fg5#Xod=nzZ(Qf4yD9_al4hLUzWn+NP+r~k;0}i<+PP(m2yKhdKF_AE z3E4nFV}f&!nx=RCYp*s4kmhJ;Yd2j9@A_P5tc$V9@A#f>}X`rNFC2`Ov?9lMa|8XWKV&i2zZA!5uY*{Nh)b?{07N zh;lSbnI_8fJfvAFWN>{#2)H65tez@4%FtgIWqtb=D@)DV?l2zbSF z-qkmpM)HG?rWE30VhMoeZ2f(ECy)Po=RQ_Y_;rP0u?iy^ug{uZ3!wD^&u1D9n@F^=#aY`T@Q<~D@-?C`3p-@NhL$J#y= z;EV{u<VJ|JlrNx5*FUR+w_AKWfQ-63<`K5m))no(gIl)tNRKD%?qo zQw_{h!E{n1n)Efqi^f(C_U7nruA8rdBTY~@^3({6_Etv6xbQ2L`>&WlK%nSHMQNYW zGv;P(e&T7%mw>u;W80-F>!Z8St(mhU(R2Cd#Qsrl8vxTOV`lT-p&DznWM5w6E%a-4 zeW?7Mz>GYfFO+4Il98X>6!4{I8~MqUkfp$>xMB$DH!Fef{dBs*c7l19>Xm3Pzge_$^p- z#18?k#7?(NR}r;7m}`L5pNY$vDL>tJaLed1WggTxGp6#_hgf6j@H{0uXN((l<#vcS zco}&i>qDfpwsM-K$%Y4G9{}l4yP&wh(P@VMppX}z{cyMDHh^xcx2x^{Uz+@{MzrOzE z|BCsM{Zl4=kpIo-FY@2Mzq=*rC&VTe@9lv}3 zd;H(4|80Nq`+@&C{_TTqk z`#;_M1pht$>Hkywf486i|8zgQKm5JbKWD%79#+TO`I>R{)f7aECF5!hk~1nI-JJ=d z*e8qA;}rX+p}u=9hrgcuGlO`PReTF>F6r-#F$i-a5A`1P#fz>g)k^`PzV_15oXoS+ z%`!>Foy;EdAg1Y=SaIpTKEg*ty$^Wd3Tnt=G1C?l6@0eo@m%c+yBJdafMlY&~aA53JE z+Q_!Bl_ywkuiQ1BC-+$E6MJ3lfo{xG^qS}b<#Bru$aAoGasMmb3Ca9ASPsAW-Q;4R z52IPwIdgaXx61aX|H}i{lFlA{zb(!f1FRv3iRgz7*QPg5mL3Y#V?kz<5P~M9oK*jH zv2fNr>RNM#A+Z!;cSpKYORauYp1dqlnvG|lHo~XlyI%M@V5r_3RTzS~TvRne*qM9&S*;zVU(X~&isLfHr}?h zIV;+mgnG!k+&YF)Sy*w7F=?2~lCd+p_}z1#kePYNY*9mlTTQ*;k1wVLwtE*3Y9-h;zhXsb*N^*1%zI800>v9esGMfTgy-xa$9R zl20L`uV1-boZ3DN%e1Yd;gDwTx66IFf>7G6%FEe)FqHB>Y)|v@_#V80ciQ{;z3$v) zG)3@y8SrD7a|dv~D4+mXsDb_|lf8i1DbH2TVkoJHrY0EruSI8DmW9ltEj}wi=NTFS zYERoGR%k{M<>eR>^W<;zw6X=xnq^~Rf5sVNMM0OZPzIxy8a2rSn-#}Tqj;zS4yxp~ zNk7LlJ_lC^b3{brjvO&Q_d=T8xnIu(ols5_jQ9};=RX_dRj*J7Ah`WTswVC)1znu+ z;$K&>zaZRJU|PSA<0}DDpVNefO`w-*^H|HrLf*HE^(rx3`$wH7X+q^<2lgSXbS%y+ z1Q;&}6=(s}{T>t!)$Ya1b1!>S3tF&3J9iSrdeAJW)8hqU90a@ia!|!%Z`&{=VIumr zmJjfrwWQT0t9FhR@{H}JXq=b8yu-g%O3I)mk-eiO95dKkZpLN&W)4u5BT3*)Pq@UL zkwFd4NQ``-@thY@YX)tX*ho+I5ZSla6mN<(*?Z!76ZKQEGaQowpKH~T9i;`FgWC9z zD4COJ6ksa{GUnS+&N>j21rLsk3OI6>V}@A7CS$q zc2|V$JDpo(x4n7dD@uP@xb0B8)nSNP?k$FMc5c9}rULgj+Z{~cB<-|!a~29{!D?O0LpZ`RbOMzOFW+Qrv3i6j{(E_0=;b?JteNE%zcr0-OT zYBqU_rULX>4pTh)Yyjqaz@4(NosP}9FEng>6huvlxC26cFy+|rC|_EHFPWCStn;~j zf*(+M+-oCf#_`p>8ax@G&%-1 zhlnu}f=YVq^(67O!KHB}=0FjAid<5I`lPvK!nP{lK1@8C?XXElC{43L@y8FL>p-^| z_G4aTNa#Myk{a_ky6;_wlDU;^Cy3E@+nK>x^e&J2ywQ{nkGfb!(PLXTe9WK0U=K(H zo*9#L8Y=#Xm&twn*rJF(qD-W_e@K;fih|2%FdD~p3YF4CoM5pjiPeWDL zx`nn`Z~~hAfD8BrjWbVe)sOM1`#LY1A9Q1)b`myGLk-43u(hn>KkPR@0%C<-2Fz zOrp5uQ>X8UVW`HZ{~>$X)va=5EPUCAC`(J;Dbm-_mX>{St#2@v1(Th{SiGc#a1=>~ z!5z{Q+c7UoQ9>B{9nw89R4~Ww0Y5pT2n`-hPUWBL+OxlK5o(faY7Sy-zEu;JCe)yA zVC=nGARYt#%f5oO@9x22j9I2Tjh6l2&9S77V8h2mysW+JPdA_FHB z(7iKXYWsX~M$?JG4`3fO-prFf7{$BH}tdFWoQPpg$h0GlXd$4vxVX zhu(X36--e->^+VkaG0-2W3ReamVq1ACS=J4`<6!mHT~O%38Wbw- zU;%15;$6HjgoZy(*DJWNA4i&)guNkeS#mnQ4G6`+RhrLjbWq*dmA`at^kZN|2txnk zcI-9NyZIh*Wm~*if>ja>1d<4GE1m81ycCWs-}|S!)Ue`rIz6AnEjOv0WZN8FY(w~> z#;Z|h{r~{}`wW=-1-v zACM#kGl*u5uWCTm`f}h*10ze-Afi%)?83&HU-l8}h}WFji$bS|?w;Bf^#y+M6VyM; zG(abs=8yn8AzvvGAAl_E>mHBr5PTL5w;xLYDQSDL-Z5{vG!dRj(q=n-`)RWbqn7im z5yt|b{X!QF=YM%~7Ilm&Y$};yf!Vu}9ZwH$ySo~?SpagF=&`Lbr8LK-j*a7TM?TNX zAJ!Q|w(5ZQPn`LyB$VWaZeY^!d+q@MBa{8p*)!b-r8dqh{FL@F`$`uf!dU6@T|mv1l1#fY4u1j>s8;I&q)c{3fMK#O0 zeq}rgtsy030`HaD-WdTR+t>)_3qj;Eb$Isz%<*H;X&Vx4L3_KvhHIFSEo&fnK=89Y z*OLvwt)RdPwg{w@+G-u+Db(307(({22Dy=sVzb*gL0T{nD%3}+;(KOF0DJ)uchG(Q z#=yEg>t`#fynTQVj_ytuys+7xN`0M9ce9ct)Cq2VYC zu}1~;=)W^#JIuBq+^AHH9})TJFj=MaNB4=ThYOhK4MMiKJcPTHKahG$de}*=S;^P+ z&78PiA24npL}GE+Un@}GC#*(=6mpRw4DH?%1cn95I{}2<>PA5=^hotf)P@UfO)jqw zEPR-jwdw0ZK2!YoVS&C53GYqvPM_7={-{5clg_A8mHm ztf0|Dr!VQ%FaUc~hy9DL#ZIH)`gyi#fVc?=+K&a0I^eEcDB$}q6{Cw-U5MT-=9op!9 zO^K!%s)$y2r5;g0Zcj+ZrQSYjX<@Or*%}{OyyR0AL8}mbvz&)0N!>z`A$;~Wp|RbX zpSv%U3}wwnJ>h6O>0g+C)%r6iIBWi(G^IolT2cul9Jrad3}i3&VRXwsI|>EnmWB0S z&c*FkrfLGD)^_wdFw|V={lY>wk%6}L%R@B|Q_T;7nRS(-#vbECISa0L=lj#*-|LJG zI*GhqIT~U|eRc^;abHtI#RRQt_cP%a;WYea3qKwC>2r;fDUXmJ8t|m@o?^+j+vJR= z+$>3P)cAFpylK8U`N8;MyUi43JS_pC%PY9Vii|s_@E9Y(_jyr}wGj+j+E<#xzE=#L zvkS`X&mCL>j<rYkIu%g$%p9VQ#Hdde#Auu0`}=Bo@Luuk%j~YxPD&v&_p0 zaWH+~CN);_IZsU^48}=Bf5*>9b%>Mb@`IJ=6DY={C{YuxC>d9=YB~U#Re?@3*bFLl zd=BtC|4EKIfTI?#`*Y{f$0`u-C4U!lD+1Dh*rK*>=`?&{PACA|!VJA&WL6UNcK`*ub$(QvWtb_Mb(z zq^t08yW`SQL$9LJ7N0pCE1ex1S-oSt4#X{H*a2$;gQw3nT;_~t3S4s36Ss>;az))24Y__wabd`TCNb!{k!_|vij@nb(;KP@rSVbxmZzFhE6&=ej3rl z44{l}8(}SIlM*-Q5S=Yw&Tx8!-zGOP1D61_oky9_`wjc1i1Ro}(P~g1t@`E3``wor zuCJd;mTRqCZ?jFt-}#Ai)nRl4UgUXQL`3X6?X67mbN*aN^u^`j)QHcKPU&9gXRB30 zB(EvbKpiVOziK$~mA=;b3F=+HqUe%#F2_xF!ULbXUi7bM>}5&;#HB8L>beV!&GoMSZ9{+_PpJWK6`^?%?asIZ6VF4AGMscp}>^vEjuEpT##96X7#0VC7# zy+4DiCB3@s@ABGuIo%}?W`o9p49HNtPuAbNEZ(#e&iRrM57tiKGLTZF@Z!r+T_c3{P+L_M2nDJ3xrzZapEA&O_qB@0-?bbS!;F zD-#Ex1^b>Wh0z|$^w3!jA9($1TM}5ul@l!rJH}GPmz;&L4`fjbGu8F(Hg{##dBdT= zsYtr6{apZr#MS5v^s+{5HG|9> z^VM4s(%dNmZU+dby!sBqz}7V}Av5~v)^fY$dt|aFk0xLHzDFx^87W!iWP48YX!~~M za!xmt>I55HL-IO(y8&KeBfKU123W@Sbx4@L2GJB^`1KY7EcX_`ic}gvn(`jjZ|4dlWvn%TL?Vb*jo#&rgip|I_ zVt}Kt8J*R8K-#K_!~FIL42nxUz`psDzteS~P6aEOXNaR2(7X=DnFq?K*~XaH##!wZ zatawFgTcie`+$&>gB&E%Wb}d@2TUiG9W2UooIJ*VB7y|_j?`5aX{X1O7kR{VxoGAsLZR0N4 z|L|)9ZmSl{ch6*zDyGowhxAz(s6i-W*9TNo{1b!OE+QR0>T6#-;Pe3>tVY+5;EkYI z(vbP78axS*28hBpkn+ym+D`=-64d0Y=krCln3vGMX}@asDe@+H>?DAjv$!^rMg}C* zhGA@_Ec+sciz0aji6o~X^ft33T34X0m6)L40(x>jZBJU4-SHpMPeId(T>BC6<1@JR_z6zA;!8CLFCV&VYvdF95Ty z?=A7K_*iUQaCalo;0p`n)===#~a!fjVp z+hS-{H)HU2>V_`KhPWoFy#hoKXj;Y_;lKy}cr??Ipx=e3I+C}QnE#M95X@uwu_URj zCT({toS00TzP3Iay9Cadv&ub_r&z&zxvfy-I)KN4CJ91S3Lwe%N1oytPl(?qthjR> z>r3K+9#QbO=pu!OW^cno3-t>QcKE#}{G;hX(sB-A&iElM7j2E~0IoHVtdA1rN}hjngnF+SWd2%DB!M&)Hxte0h9D} zcXt;Mx#uK6Gl~{EoA!!>1^{zIt=M3b1gu_bK9vI3Oa)4VY$r#2w=tmduW42^F?L(0(wH(WpN=wF5FVGoP1ps4g?Z<72-I^ zAoZZLc*~_F+=_+t0_MKJI^mXVF+<}TS+4l{9EG}WlX1ntQ?mf?+9|tue5&BTOlGd9 z9x_d5G35KMAhax;Z`Xr?C#0$bdT?#uq{ie+Uorj8*Dcv!r^xgqEEzjw57-PBwLQjD zLX~Z}aGhoa2v~}jx$6?*fCQ=`W<=#+pCgvjyP|JE3`W)&6LVcFbyjnl+3_u*^OEFw zIjt|xhwi+Y1AmAg*=V`nPvCeI_P9nZj6R*nYOAiss*NbG)PVPs$;3eQYJfCz@eJLv z!L*ND8bDE+=H!8h!Th6=fB|``dBSck84{prN|e&T5LGoILZ3;!IYW^#>RTz3-i--< z(2UkQ|Ax!f0ENp+tBsTw7i7sWP4i+SDHw*>FYHvtOguECM zaxdReP!`YwX^ta{@5u9Fwbb-z^xuzi1_mRXbqY8&KCZ&CVpr`|bti)7)5W_ThyBnI&QkU4mrfk>ss`Cv7sCvS`#uGf@>%jBH=Z zDaWvE(kt2`IY$_tUHWlAJR~P|cfL_f|4)rG$={kEn!?pXso1la{zYA(|6UzXUj6|& z#pR(>wp%ma??JU!0|A<*67@H}K&pc?KD0iy({eCS+(*f8oqt1bP${M;w^<_6F z{PPYh&WR3B5NZNeofd|#8Bx_I&65oi%8m0!;hhv)MZc_^s^-q((0%L-cK_9M)(QA5 z=8V|ui)zW-u9x`d!nw_X?&CnlIfjZiO!wlnM$_(W$g5?G4P%}OXTcJ7EO(;##xJ7Z z-ITFepH)znnjrv#M<1uYK~|JM>`<*7&q2&69dyWFL=YFNEzt%LroIeW<URTX)LeSUbS@k@TheQoT;+sSMKF=7xIKqa)TK0J>}mK`liUC*JJ{L2P1K zY&~+GlK-cBPSHEAOG{^xW~fI8!I6>w0aMPjT1?$4#oT~)vH*^*5d2uJYiAbYv}lv4r@xyn_6l)4 z0BD-uH;DXDa*{dl4YHN@fy|I7%2Kr>;8C}%rmNi0jLf!^M%tquMIE6c^koAfc z-7Aa825Dy$-(zO}M!$29xSW4z%n{uuU9;4cc9kg&Bt8m|2fKT7ItOZwNWzX!F<_Sj zB>nXZ7WauXW5cVjw^JL6u#dfX&QX8zbw})qSC9SzM*P0NU26JZ+{|dyXqnHcxbp(L zA%nI|2rB^37-*lB>;ZEUOElbmv%!mjk-iqi19cZILl8$!36fR0SpElPVwigz=w!i>I@O z#-n9I5I{(^1vbLWAFkHWTp>!aF}gLGr9FG)w#!XLa3TS9bW-k4o;MEqq#n>@5~rYq z!$HEa@(ED0t$-wGxx}YDDW8s37kGPxH^`kE=yfH1z6_=s6`YKK2k!F@El0Fko`Qqx z(zo$FD_`nXrz`B;I$HwHpW7$b0-ELnb$}5mX`O5gMykZw`^!_KA#6n&(T&@-NL;Z- z#~#)QLrU{N) z_2r=v8H}tE>}TM24ciTcunyMMTuVT2PKcQxJsRqyUbVQjTRoL~a4(A(vRyZV_>QUJ z3v_dbCuLQwNNP@?x^Q$R8BiIwWNP z9!`bZBF@zVq;WNC#!34OaA+{iB0;v+goeQ_%qtQ%4qZ?igt_ujHmcMwdh$}OnO73n z@_TP6aniKXY(sso!kv)6alP@Og<$uCAJu1RoB~=1xBG^#%<&HYO)=!O3V4NX;AQXH zpNd0ctvEb7ttVMdOS*r;(QKtT6g~EeepNLLs@MN7E(`Cg^eaaXwO9%3(dz@_lE~|= zPQ}@r>X`VfLg7aL2k~W;rI_cQ_Zoz5ns3uY9ch5YFU*$)@g>C*kfrLVwM2A4&r6_C z*%_gyaHV<){&<4HM+|4hm38SNc=9DsIjyjZAeuk61qXJ2T6UC0bac@+5w-6MfXaW= zso7bl6FfsLSCWng$hwGvK;HS;t`HWa5^ z!+~)0RjROJnit8;Ze)7^G?Fw)XoB&6y^j`v5!)ANxi&YWH(`>0pOgoCeyH z*0uz(v6N821aaMS(sZYR_Jj)O>)g-vorSE-V_jr_GC zG1Fhi`~RqJwc;`e6;C3l6RtSV)OlEJO3(kT-kSC?%hrY0Kx$;ifftOKKto#7kIaT& zw#N5OB-RDta|y^I*i8@gi(`~rGaj!U)VDxS-{w!w<*%4-`yR-;&?w5=kq?3nj#e3_;?*yU(%w|oVrTSXUx%?uv}v7pW!$sfR@Pzw@NYSDLc(&hmZLc^tcnf#_?g8jMV{EBP} z$IA7mkuUq{~ zeiTTXW>~Q?NpjF!$QMOUguzbs3MGtQ?g=kf5y4CAoQyin8%dQ`Y3ZuXeyNLc9AAed zyaw#HghFS_3;Bf9rI(U1_t@w6=8fJzMEI2Mvc}vL<<)`MF#Sf!&DTk>W@_Tv`;?B; zF{qot2tMisM7d{B6&OM<<0nVDhnj$o&Pnd{7{}of&EkvEJ$~}oZmpQyIyF|Y1R?4c z*~_?cpu%YAMJ`OW#*P4cZ8BeaO3$sJ_GV|BCXd7JyXj%nMW48s?(X86(Yrn%eH`ZV zv>|2`tZEpy25yPVbvVjYF7HdY8t8?KO|c{pfX98L4?N#m3QH0x97$L`GlrT6mv|K5 z+)M*>90pq2T_ct6!6m8wEEFJ)6c>2z-M!wp1)}VM26tRb0iKwm)QjU}l4iAd{w6IkUKT zP>t53@Wv}Yl0-230h=vLt-#7%inI^*zkODB&INyLWkVHHiowc6+JUz@w2dZ@9106I z3NRUQ2&)OQ=#Z4>`nQ}Vlf|XnhvdX^N?ytnsJCcz8K$26QZXv_D)!=zz+U>T0S@Un z{Kr_AL4eFdkv&{KLmD0uD_+Y=eLmYBJJcRPLoZVHiR;06mPg3Ek8CZ%b6<&WIe?tlbQ zbA-(73w(J34lJ^$smmp3IkTLw_CK9v#c@oUg~t{Y4G3^YTBz+(Dh*&@R!)mSgp%F& z$|pfhk(mkO@`PD&v2K_EKm;dVia6nIiWph|`Y+~~{RHHVinG`5IMBr#7i4f!2JYv4 z_#W5V*ZO-3-tH2#zGFniHKn6t7Fw2hPzBT;xDHa;B0#|cXLfs zYh`C(e9? zdTHRbJJMdb|HcQP$(?rw5&BW`)wS^$E^mny^7ing~Tr91P9W5+xa2E*W4X(iP1~ChI-x z?6&;>z}EI9C^9vtk2+~`N$F26&tsxv^*wYs@O%TGun3O5qb818S(ItS4FrD|sMD0C zqD%ke%?ef$zBie7Rr~z@j6GsSzvd};=N&8uc%x-%9uIdxJB#@4H1?&4=aA7S-!}0X zE1{VI8=YTa*81mTlE^?auWL%CX+nvBgk_kqB?+$AHbe>%G}toEVrI@ac9f1Kfh~WF z?9*F|3&!?q4_~*8*mMp=6Sg(Af#~SoVmmT&P6qo0=l69=!+T?apO1o;ma{;`)D-5N z&UI=B7ZwW&KX$wD6o|DSMGK%`M2CK5foVZ==^_a5`x6Lvk`Y61s~?9_Q|-Qoq7dV`Gkkb{t%YyX7_+=|Cyvf!?&1Qq-4^QswWg;E=ivyy}65|`FoEp1O zb(>DacX$QKxsN_&*bqYuH|T`GWWr(F-|aB4sHi?0aSBCTU%3MbO`W+%s17I_8t0zY z)p>?X;rRmJ#!mX_x<}Wl*W$>X2achDt>dK+|I z*Lzr`fuT;LrG%5{?B}6yLY@zNNcwS`@-4SZ8}ymLq}Pie;U224+5c*+7YR2Zd1o

    aZz$=`_SyMv@SAXAPReah1Gk`YMFVY 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

    6uO^~ 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 literal 0 HcmV?d00001 diff --git a/nym-connect/src/components/Growth/content/en.yaml b/nym-connect/src/components/Growth/content/en.yaml new file mode 100644 index 0000000000..849323e24e --- /dev/null +++ b/nym-connect/src/components/Growth/content/en.yaml @@ -0,0 +1,43 @@ +testAndEarn: + mainWindow: + button: + text: + default: Join Test&Earn + entered: Test&Earn + claim: Claim your reward + popup: + disconnected: Test&Earn is only available when connected. Please connect to any service provider. + help: + url: https://shipyard.nymtech.net/test-and-win + popupWindow: + title: NymConnect Test&Earn 🌈 + notifications: + takePart: + title: Thanks for taking part in Ter&Earn + body: Watch out for new tasks 👀 and take part to earn + youAreInDraw: + title: Thanks for completing the task ✨ + body: Post a message on Telegram, Discord or Twitter for a chance to to be selected 🤞 good luck + task: + afterText: Copy your reference number + beforeSocials: "And include it in your post to:" + draw: + next: + header: The next task starts + winner: + claimButton: + text: Claim your reward! + card: + header: You are a top contributor! + text: Congratulations, you have earned the reward for + status: + chip: + Pending: Good luck 🤞 + Winner: Rewarded! + Claimed: Claimed + NoWin: No rewards + text: + Pending: Task completed. Good luck 🤞 + Winner: Well done 🎉 + Claimed: You have claimed the reward 💰 + NoWin: Sorry you were not a top contributor, better luck next time! diff --git a/nym-connect/src/components/Growth/context/TestAndEarnContext.tsx b/nym-connect/src/components/Growth/context/TestAndEarnContext.tsx new file mode 100644 index 0000000000..f70e8a407d --- /dev/null +++ b/nym-connect/src/components/Growth/context/TestAndEarnContext.tsx @@ -0,0 +1,272 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import React, { createContext, useCallback, useContext, useMemo, useState } from 'react'; +import { forage } from '@tauri-apps/tauri-forage'; +import { invoke } from '@tauri-apps/api'; +import { ClientId, DrawEntry, Draws, Registration } from './types'; +import { useClientContext } from '../../../context/main'; +import { ConnectionStatusKind } from '../../../types'; + +export type TTestAndEarnContext = { + loadedOnce: boolean; + loading: boolean; + clientDetails?: ClientId; + registration?: Registration; + walletAddress?: string; + draws?: Draws; + isWinnerWithUnclaimedPrize?: boolean; + isEnterWallet?: boolean; + error?: string; + setWalletAddress: (newWalletAddress: string) => void; + clearStorage: () => Promise; + toggleGrowthWindow: (windowTitle?: string) => Promise; + setAndStoreClientId: (newClientId: ClientId) => Promise; + setAndStoreRegistration: (registration: Registration) => Promise; + enterDraw: (drawId: string) => Promise; + claim: (drawId: string, walletAddress: string) => Promise; + refresh: () => Promise; +}; + +const defaultValue: TTestAndEarnContext = { + loadedOnce: false, + loading: true, + setWalletAddress: () => undefined, + clearStorage: async () => undefined, + toggleGrowthWindow: async () => undefined, + setAndStoreRegistration: async () => undefined, + setAndStoreClientId: async () => undefined, + enterDraw: async () => ({} as DrawEntry), + claim: async () => undefined, + refresh: async () => undefined, +}; + +export const TestAndEarnContext = createContext(defaultValue); + +const CLIENT_ID_KEY = 'tne_client_id'; +const REGISTRATION_KEY = 'tne_registration'; + +export const TestAndEarnContextProvider = ({ children }: { children: React.ReactNode }) => { + const clientContext = useClientContext(); + const [loadedOnce, setLoadedOnce] = useState(false); + const [loading, setLoading] = useState(true); + const [walletAddress, setWalletAddress] = useState(); + const [registration, setRegistration] = useState(); + const [clientDetails, setClientDetails] = useState(); + const [draws, setDraws] = useState(); + + const setAndStoreClientId = async (newClientId: ClientId) => { + await forage.setItem({ key: CLIENT_ID_KEY, value: newClientId } as any)(); + setClientDetails((prevState) => { + if ( + prevState?.client_id !== newClientId.client_id || + prevState?.client_id_signature !== newClientId.client_id_signature + ) { + console.log('Setting client details'); + return newClientId; + } + console.log('Skipping client details'); + return prevState; + }); + }; + const loadClientDetails = async () => { + const data: ClientId | undefined = await forage.getItem({ key: CLIENT_ID_KEY })(); + if (data) { + try { + setClientDetails((prevState) => { + if (prevState?.client_id !== data.client_id || prevState?.client_id_signature !== data.client_id_signature) { + console.log('Setting client details'); + return data; + } + console.log('Skipping client details'); + return prevState; + }); + } catch (e) { + console.error('Failed to get registration'); + } + } else { + const clientId: ClientId = await invoke('growth_tne_get_client_id'); + await setAndStoreClientId(clientId); + } + }; + + const loadRegistration = async () => { + const data: Registration | undefined = await forage.getItem({ key: REGISTRATION_KEY })(); + if (data) { + try { + setRegistration((prevState) => { + if ( + prevState?.timestamp !== data.timestamp || + prevState.client_id_signature !== data.client_id_signature || + prevState.id !== data.id + ) { + console.log('Setting registration'); + return data; + } + console.log('Skipping registration'); + return prevState; + }); + } catch (e) { + console.error('Failed to get registration'); + } + } + }; + + const loadDraws = React.useCallback(async () => { + setLoading(true); + let clientDetailsForDraws = clientDetails; + try { + if (!clientDetailsForDraws) { + console.log('[loadDraws] client details not set, trying to get...'); + clientDetailsForDraws = await invoke('growth_tne_get_client_id'); + } + + if (!clientDetailsForDraws) { + console.log('[loadDraws] failed to get client details not set, skipping...'); + setLoading(false); + setLoadedOnce(true); + return; + } + + const newDraws: Draws = await invoke('growth_tne_get_draws', { clientDetails: clientDetailsForDraws }); + console.log('[loadDraws] draws = ', newDraws); + + // find the entered draw and keep a reference + const entered = newDraws.draws.find((draw) => draw.draw_id === newDraws.current?.id); + if (newDraws.current) { + newDraws.current.entry = entered; + } + + console.log('[loadDraws] setting draws'); + setDraws(newDraws); + } catch (e) { + console.error('Could not get draws: ', e); + } + setLoading(false); + setLoadedOnce(true); + console.log('[loadDraws] done, loaded once'); + }, [clientDetails]); + + React.useEffect(() => { + loadClientDetails().catch(console.error); + loadRegistration().catch(console.error); + }, []); + + React.useEffect(() => { + if (registration && clientContext.connectionStatus === ConnectionStatusKind.connected) { + setTimeout(() => { + loadDraws().catch(console.error); + }, 1000 * 3); + } + }, [registration?.id, registration?.timestamp, clientContext.connectionStatus]); + + const refresh = React.useCallback(async () => { + console.log('Refreshing...'); + + console.log('Loading client details...'); + await loadClientDetails(); + + console.log('Loading registration...'); + await loadRegistration(); + + console.log('Loading draws...'); + await loadDraws(); + + console.log('Refresh complete.'); + }, [clientDetails]); + + const clearStorage = async () => { + await forage.setItem({ key: REGISTRATION_KEY, value: undefined })(); + }; + + const toggleGrowthWindow = useCallback(async (windowTitle?: string) => { + try { + await invoke('growth_tne_toggle_window', { windowTitle }); + } catch (e) { + console.error('Failed to toggle growth window', e); + } + }, []); + + const setAndStoreRegistration = async (newRegistration: Registration) => { + await forage.setItem({ key: REGISTRATION_KEY, value: newRegistration } as any)(); + setRegistration(newRegistration); + }; + + const enterDraw = async (drawId: string): Promise => { + if (!clientDetails) { + throw new Error('No client details set'); + } + if (!draws) { + throw new Error('No draws set'); + } + + const existingEntry: DrawEntry | undefined = draws.draws.filter((d) => d.draw_id === drawId)[0]; + if (existingEntry) { + throw new Error('Already entered into draw'); + } + + const entry: DrawEntry = await invoke('growth_tne_enter_draw', { clientDetails, drawId }); + console.log('Entered draw', { entry }); + + await loadDraws(); + + return entry; + }; + + const claim = async (drawId: string, newWalletAddress: string) => { + if (!clientDetails) { + throw new Error('No client details set'); + } + if (!draws) { + throw new Error('No draws set'); + } + if (!registration) { + throw new Error('No registration set'); + } + + const registrationId = registration.id; + + const args = { + registrationId, + clientDetails, + drawId, + walletAddress: newWalletAddress, + }; + console.log({ args }); + await invoke('growth_tne_submit_wallet_address', args); + + await loadDraws(); + }; + + const contextValue = useMemo( + () => ({ + loadedOnce, + loading, + clientDetails, + registration, + walletAddress, + draws, + clearStorage, + toggleGrowthWindow, + setWalletAddress, + setAndStoreClientId, + setAndStoreRegistration, + enterDraw, + refresh, + claim, + }), + [ + loadedOnce, + loading, + walletAddress, + registration, + refresh, + draws, + draws?.current?.last_modified, + draws?.current?.entry, + draws?.draws.length, + clientDetails, + ], + ); + return {children}; +}; + +export const useTestAndEarnContext = () => useContext(TestAndEarnContext); diff --git a/nym-connect/src/components/Growth/context/mocks/TestAndEarnContext.tsx b/nym-connect/src/components/Growth/context/mocks/TestAndEarnContext.tsx new file mode 100644 index 0000000000..215367d643 --- /dev/null +++ b/nym-connect/src/components/Growth/context/mocks/TestAndEarnContext.tsx @@ -0,0 +1,262 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import React from 'react'; +import { DateTime } from 'luxon'; +import { TTestAndEarnContext, TestAndEarnContext } from '../TestAndEarnContext'; +import { DrawEntry, DrawEntryStatus, DrawWithWordOfTheDay } from '../types'; + +const methodDefaults = { + loadedOnce: true, + loading: false, + refresh: async () => undefined, + setAndStoreClientId: async () => undefined, + setAndStoreRegistration: async () => undefined, + clearStorage: async () => undefined, + toggleGrowthWindow: async () => undefined, + setWalletAddress: async () => undefined, + enterDraw: async () => ({} as DrawEntry), + claim: async () => undefined, +}; + +const mockValues_NotRegistered: TTestAndEarnContext = { + ...methodDefaults, +}; + +export const MockTestAndEarnProvider_NotRegistered = ({ children }: { children: React.ReactNode }) => ( + {children} +); + +export const testMarkdown = `**Create a sentence including "Nym" and one or more of the following words** *(in any language)*: + +- Privacy +- Pleasure +- Pineapple +- Mix +`; + +const mockValues_Registered: TTestAndEarnContext = { + ...methodDefaults, + registration: { + id: '1234', + client_id_signature: 'signature', + client_id: '5678', + timestamp: '2022-12-12T18:17:37.840Z', + }, +}; + +export const MockTestAndEarnProvider_Registered = ({ children }: { children: React.ReactNode }) => ( + {children} +); + +const allDraws: DrawEntry[] = [ + { + draw_id: '1111', + timestamp: DateTime.now().toISO(), + id: 'AAAA', + status: DrawEntryStatus.pending, + }, + { + draw_id: '2222', + timestamp: DateTime.now().toISO(), + id: 'BBBB', + status: DrawEntryStatus.noWin, + }, + { + draw_id: '2222', + timestamp: DateTime.now().toISO(), + id: 'BBBB', + status: DrawEntryStatus.claimed, + }, + { + draw_id: '2222', + timestamp: DateTime.now().toISO(), + id: 'BBBB', + status: DrawEntryStatus.winner, + }, +]; + +const draws: DrawEntry[] = [ + { + draw_id: '1111', + timestamp: DateTime.now().toISO(), + id: 'AAAA', + status: DrawEntryStatus.pending, + }, + { + draw_id: '2222', + timestamp: DateTime.now().toISO(), + id: 'BBBB', + status: DrawEntryStatus.noWin, + }, +]; + +const drawsWithWin: DrawEntry[] = [ + { + draw_id: '1111', + timestamp: DateTime.now().toISO(), + id: 'AAAA', + status: DrawEntryStatus.winner, + }, + { + draw_id: '2222', + timestamp: DateTime.now().toISO(), + id: 'BBBB', + status: DrawEntryStatus.noWin, + }, +]; + +const drawsWithClaim: DrawEntry[] = [ + { + draw_id: '1111', + timestamp: DateTime.now().toISO(), + id: 'AAAA', + status: DrawEntryStatus.claimed, + }, + { + draw_id: '2222', + timestamp: DateTime.now().toISO(), + id: 'BBBB', + status: DrawEntryStatus.noWin, + }, +]; + +const current: DrawWithWordOfTheDay = { + id: '1111', + start_utc: DateTime.now().toISO(), + end_utc: DateTime.now().plus({ day: 1 }).minus({ second: 25 }).toISO(), + last_modified: DateTime.now().toISO(), + word_of_the_day: testMarkdown, +}; + +const mockValues_RegisteredWithAllDrawsAndEntry: TTestAndEarnContext = { + ...mockValues_Registered, + draws: { + current: { + ...current, + }, + draws: allDraws, + }, +}; + +export const MockTestAndEarnProvider_RegisteredWithAllDraws = ({ children }: { children: React.ReactNode }) => ( + + {children} + +); + +const mockValues_RegisteredWithDrawsNoCurrent: TTestAndEarnContext = { + ...mockValues_Registered, + draws: { + draws: drawsWithClaim, + }, +}; + +export const MockTestAndEarnProvider_RegisteredWithDrawsNoCurrent = ({ children }: { children: React.ReactNode }) => ( + {children} +); + +const mockValues_RegisteredWithDraws: TTestAndEarnContext = { + ...mockValues_Registered, + draws: { + current, + draws, + }, +}; + +export const MockTestAndEarnProvider_RegisteredWithDraws = ({ children }: { children: React.ReactNode }) => ( + {children} +); + +const mockValues_RegisteredWithDrawsAndEntry: TTestAndEarnContext = { + ...mockValues_Registered, + draws: { + current: { + ...current, + entry: mockValues_RegisteredWithDraws.draws!.draws[0], + }, + draws, + }, +}; + +export const MockTestAndEarnProvider_RegisteredWithDrawsAndEntry = ({ children }: { children: React.ReactNode }) => ( + {children} +); + +const mockValues_RegisteredWithDrawsAndEntryAndWinner: TTestAndEarnContext = { + ...mockValues_Registered, + draws: { + current: { + ...current, + entry: drawsWithWin[0], + }, + draws: drawsWithWin, + }, + isWinnerWithUnclaimedPrize: true, +}; + +export const MockTestAndEarnProvider_RegisteredWithDrawsAndEntryAndWinner = ({ + children, +}: { + children: React.ReactNode; +}) => ( + + {children} + +); + +const mockValues_RegisteredWithDrawsAndEntryAndNoWinner: TTestAndEarnContext = { + ...mockValues_RegisteredWithDrawsAndEntry, + isWinnerWithUnclaimedPrize: false, +}; + +export const MockTestAndEarnProvider_RegisteredWithDrawsAndEntryAndNoWinner = ({ + children, +}: { + children: React.ReactNode; +}) => ( + + {children} + +); + +const mockValues_RegisteredWithDrawsAndEntryAndWinnerCollectWallet: TTestAndEarnContext = { + ...mockValues_Registered, + draws: { + draws: drawsWithWin, + }, +}; + +export const MockTestAndEarnProvider_RegisteredWithDrawsAndEntryAndWinnerCollectWallet = ({ + children, +}: { + children: React.ReactNode; +}) => ( + + {children} + +); + +const mockValues_RegisteredWithDrawsAndEntryAndWinnerClaimed: TTestAndEarnContext = { + ...mockValues_Registered, + draws: { + draws: drawsWithClaim, + }, +}; + +export const MockTestAndEarnProvider_RegisteredWithDrawsAndEntryAndWinnerClaimed = ({ + children, +}: { + children: React.ReactNode; +}) => ( + + {children} + +); + +const mockValues_RegisteredAndError: TTestAndEarnContext = { + ...mockValues_Registered, + error: 'Error message text will go here', +}; + +export const MockTestAndEarnProvider_RegisteredAndError = ({ children }: { children: React.ReactNode }) => ( + {children} +); diff --git a/nym-connect/src/components/Growth/context/types.ts b/nym-connect/src/components/Growth/context/types.ts new file mode 100644 index 0000000000..ebedf20d91 --- /dev/null +++ b/nym-connect/src/components/Growth/context/types.ts @@ -0,0 +1,66 @@ +import { DateTime } from 'luxon'; + +export interface ClientId { + client_id: string; + client_id_signature: string; +} + +export interface Registration { + id: string; + client_id: string; + client_id_signature: string; + timestamp: string; +} + +export interface DrawEntryPartial { + draw_id: string; + client_id: string; + client_id_signature: string; +} + +export enum DrawEntryStatus { + pending = 'Pending', + winner = 'Winner', + noWin = 'NoWin', + claimed = 'Claimed', +} + +export interface DrawEntry { + id: string; + draw_id: string; + timestamp: string; + status: DrawEntryStatus; +} + +export interface DrawWithWordOfTheDay { + id: string; + start_utc: string; + end_utc: string; + word_of_the_day?: string; + last_modified: string; + entry?: DrawEntry; +} + +export interface ClaimPartial { + draw_id: string; + registration_id: string; + client_id: string; + client_id_signature: string; + wallet_address: string; +} + +export interface Winner { + id: string; + client_id: string; + draw_id: string; + timestamp: string; + winner_reg_id: string; + winner_wallet_address?: string; + winner_claim_timestamp?: string; +} + +export interface Draws { + current?: DrawWithWordOfTheDay; + next?: DrawWithWordOfTheDay; + draws: DrawEntry[]; +} diff --git a/nym-connect/src/components/LogViewer/index.tsx b/nym-connect/src/components/LogViewer/index.tsx new file mode 100644 index 0000000000..f2a9d2e6d0 --- /dev/null +++ b/nym-connect/src/components/LogViewer/index.tsx @@ -0,0 +1,97 @@ +import React, { FC, useEffect, useRef, useState } from 'react'; +import type { UnlistenFn } from '@tauri-apps/api/event'; +import { listen } from '@tauri-apps/api/event'; +import { Box, Paper, Chip, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from '@mui/material'; + +// see https://github.com/tauri-apps/tauri-plugin-log/blob/dev/webview-src/index.ts#L4 +enum LogLevel { + Trace = 1, + Debug, + Info, + Warn, + Error, +} + +const getLogLevelName = (value: LogLevel) => { + switch (value) { + case LogLevel.Trace: + return 'Trace'; + case LogLevel.Debug: + return 'Debug'; + case LogLevel.Info: + return 'Info'; + case LogLevel.Warn: + return 'Warn'; + case LogLevel.Error: + return 'Error'; + default: + return 'Unknown'; + } +}; + +// see https://github.com/tauri-apps/tauri-plugin-log/blob/dev/webview-src/index.ts#L147 +interface RecordPayload { + level: LogLevel; + message: string; +} + +export const LogViewer: FC = () => { + const unlisten = useRef(); + const messages = useRef([]); + const [messageCount, setMessageCount] = useState(0); + + useEffect(() => { + listen('log://log', (event) => { + console.log(event.payload); + const payload = event.payload as RecordPayload; + messages.current.unshift(payload); + setMessageCount((prev) => prev + 1); + }).then((fn) => { + unlisten.current = fn; + }); + + return () => { + if (unlisten.current) { + unlisten.current(); + } + }; + }, []); + + return ( + + + + + + + Severity + Log message + + + + {messages.current.map((m) => ( + + + + + {m.message} + + ))} + +
    +
    +
    + theme.palette.divider, + }} + > + {messageCount} log entries since opening this window + +
    + ); +}; diff --git a/nym-connect/src/components/ServiceProviderPopup.tsx b/nym-connect/src/components/ServiceProviderPopup.tsx new file mode 100644 index 0000000000..27ecfba127 --- /dev/null +++ b/nym-connect/src/components/ServiceProviderPopup.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { Autocomplete, Box, Chip, Dialog, DialogProps, TextField, Typography } from '@mui/material'; +import { ServiceProvider, Service, Services } from '../types/directory'; + +export const ServiceProviderPopup: React.FC< + DialogProps & { services: Services; onServiceProviderChanged: (sp?: ServiceProvider, s?: Service) => void } +> = ({ services, onServiceProviderChanged, ...dialogProps }) => { + const options = services.flatMap((s) => + s.items.map((sp) => ({ id: `${s.id}-${sp.id}`, title: sp.description, service: s, sp })), + ); + return ( +

    + + // filterOptions.filter((o) => o.title.toLowerCase().includes(inputValue.toLowerCase())) + // } + options={options} + groupBy={(option) => option.service.description} + getOptionLabel={(option) => option.title} + onChange={(event, value) => onServiceProviderChanged(value?.sp, value?.service)} + isOptionEqualToValue={(option, value) => option.id.toLowerCase() === value?.id.toLowerCase()} + renderOption={(props, option) => ( + img': { mr: 2, flexShrink: 0 } }} {...props} fontSize="small"> + + {option.id} + +

    {option.title}

    +
    + )} + renderInput={(params) => } + /> +
    + ); +}; diff --git a/nym-connect/src/components/ServiceProviderSelector.stories.tsx b/nym-connect/src/components/ServiceProviderSelector.stories.tsx new file mode 100644 index 0000000000..c7df76ea4a --- /dev/null +++ b/nym-connect/src/components/ServiceProviderSelector.stories.tsx @@ -0,0 +1,342 @@ +import * as React from 'react'; +import { ComponentMeta } from '@storybook/react'; +import { Box } from '@mui/material'; +import { ServiceProviderSelector } from './ServiceProviderSelector'; +import { Services } from '../types/directory'; + +export default { + title: 'Components/Service Provider Selector', + component: ServiceProviderSelector, +} as ComponentMeta; + +const width = 240; + +export const Loading = () => ( + + + +); + +const services: Services = JSON.parse(`[ + { + "id": "keybase", + "description": "Keybase", + "items": [ + { + "id": "nym-keybase", + "description": "Nym Keybase Service Provider", + "address": "Entztfv6Uaz2hpYHQJ6JKoaCTpDL5dja18SuQWVJAmmx.Cvhn9rBJw5Ay9wgHcbgCnVg89MPSV5s2muPV2YF1BXYu@Fo4f4SQLdoyoGkFae5TpVhRVoXCF8UiypLVGtGjujVPf", + "gateway": "Fo4f4SQLdoyoGkFae5TpVhRVoXCF8UiypLVGtGjujVPf" + }, + { + "id": "shipyard-keybase-1", + "description": "Nym Keybase Service Provider", + "address": "D55ksecHzY6vAeqk8MCTzCfj2pqwJeKCKZCUUGnwGnn3.FS42vXS5a6GNTb1qk3aVk5mjSiJCAuawbBVyQZZVfhvt@DfNMqQRy6pPkU8Z5rBsxRwzDUzAMXHPFwMhjF16ScZqn", + "gateway": "DfNMqQRy6pPkU8Z5rBsxRwzDUzAMXHPFwMhjF16ScZqn" + }, + { + "id": "shipyard-keybase-2", + "description": "Nym Keybase Service Provider", + "address": "DFdDtW7LNBATxQ4ef3jNbqs3cRE8b9wDZTCctHCQRULa.4AbKiTNVUwYFWHhy98o5pT9dELiUrkXoJQ9wHqPgf6GV@GJqd3ZxpXWSNxTfx7B1pPtswpetH4LnJdFeLeuY5KUuN", + "gateway": "GJqd3ZxpXWSNxTfx7B1pPtswpetH4LnJdFeLeuY5KUuN" + }, + { + "id": "shipyard-keybase-3", + "description": "Nym Keybase Service Provider", + "address": "6Y1HE1jJ92P9yoHer11TR4A2NdZePrLGaBNFf65MnYGe.FwXoh217odQDWNmViqzNX28fauYrjB3PYLrVvpqnQrX4@5vC8spDvw5VDQ8Zvd9fVvBhbUDv9jABR4cXzd4Kh5vz", + "gateway": "5vC8spDvw5VDQ8Zvd9fVvBhbUDv9jABR4cXzd4Kh5vz" + }, + { + "id": "shipyard-keybase-4", + "description": "Nym Keybase Service Provider", + "address": "3zzhLtWvaJgn755MkRckG5aRnoTZich8ASn395iSsTgj.J1R5VuxXbh2eNHiaRbrwbKGXrrEQcHKLdzf8eg9HTB6q@3B7PsbXFuqq6rerYFLw5HPbQb4UmBqAhfWURRovMmWoj", + "gateway": "3B7PsbXFuqq6rerYFLw5HPbQb4UmBqAhfWURRovMmWoj" + }, + { + "id": "shipyard-keybase-5", + "description": "Nym Keybase Service Provider", + "address": "CHuXdZJYQ8xH7ekgN9gAuVtQ7ZikjjHEZY5BSN7yc5mN.29dFvqicKQQQvoX1vup44mspmc249RH5xgLibWMwTYGT@CfWcDJq8QBz6cVAPCYSaLbaJEhVTmHEmyYgQ6C5GdDW9", + "gateway": "CfWcDJq8QBz6cVAPCYSaLbaJEhVTmHEmyYgQ6C5GdDW9" + } + ] + }, + { + "id": "electrum", + "description": "Electrum Wallet", + "items": [ + { + "id": "nym-electrum", + "description": "Nym Electrum Service Provider", + "address": "DpB3cHAchJiNBQi5FrZx2csXb1mrHkpYh9Wzf8Rjsuko.ANNWrvHqMYuertHGHUrZdBntQhpzfbWekB39qez9U2Vx@2BuMSfMW3zpeAjKXyKLhmY4QW1DXurrtSPEJ6CjX3SEh", + "gateway": "2BuMSfMW3zpeAjKXyKLhmY4QW1DXurrtSPEJ6CjX3SEh" + }, + { + "id": "shipyard-electrum-1", + "description": "Nym Electrum Service Provider", + "address": "8Tb73cFQpXCLpgxEA2VSDru2hHrcZ3KQcyMsGbxcTjBp.4x5tu66k8YkHk4tYac1qwEFbNq5WsKiX5kR51q5KKH88@4WgKhJdmUffz4e1o1ftVAGS3HnG56LiNAxA9dmaekrVd", + "gateway": "4WgKhJdmUffz4e1o1ftVAGS3HnG56LiNAxA9dmaekrVd" + }, + { + "id": "shipyard-electrum-2", + "description": "Nym Electrum Service Provider", + "address": "GR6z31MwCsvxHrnvvVN1Cpasd8aQ1giwQqPTZM9dN7VH.5rEiqakSPDrBtKmvpU8Shnhz6gRM85JLoB7AX4h7PJYr@5Ao1J38frnU9Rx5YVeF5BWExcnDTcW8etNe9W2sRASXD", + "gateway": "5Ao1J38frnU9Rx5YVeF5BWExcnDTcW8etNe9W2sRASXD" + } + ] + }, + { + "id": "telegram", + "description": "Telegram", + "items": [ + { + "id": "shipyard-telegram-2", + "description": "Nym Telegram Service Provider", + "address": "C4w6ewbQtoaZEeoaaNw1xVASChqo4WVjNfuYEUFjZxpc.8F1D7rQXf2jGoj1Ken7PiGDM8HS2Ug79wSoc9nZ1iqh1@62F81C9GrHDRja9WCqozemRFSzFPMecY85MbGwn6efve", + "gateway": "62F81C9GrHDRja9WCqozemRFSzFPMecY85MbGwn6efve" + }, + { + "id": "shipyard-telegram-3", + "description": "Nym Telegram Service Provider", + "address": "DStL3BEUZuQZfbij1KAY3BvJh8rC5jpr9mc6AQ6aTLUu.Ax9foYaKfFgX6g8y393GoNpKkKrnDGFGRZwxDv9R7X6M@FQon7UwF5knbUr2jf6jHhmNLbJnMreck1eUcVH59kxYE", + "gateway": "FQon7UwF5knbUr2jf6jHhmNLbJnMreck1eUcVH59kxYE" + }, + { + "id": "shipyard-telegram-4", + "description": "Nym Telegram Service Provider", + "address": "8gRdGTzsDxYzpasRQhsRg59MCgNNhnfag2oFfwwZPXnB.DtDrGz7ScVm4o7sN4K3CYUJveYgz7fcXELBVLNDfMS9Y@3ojQD6V7skM1bSXJX7fVQvscjmcgptzdixQEaAha2ixh", + "gateway": "3ojQD6V7skM1bSXJX7fVQvscjmcgptzdixQEaAha2ixh" + }, + { + "id": "shipyard-telegram-5", + "description": "Nym Telegram Service Provider", + "address": "AR3oEM6Uvmfs6fyddwSehoBUKCFxz7MdFi4z7aahuHuY.3ZKapg9A3Py1PXhyLbCJr8ZbJsEV6NZdN1WJaGGut5tj@EEyq16v63aotPBCepxUpCgAojrNasZ6Hk1PjpRyBAdEp", + "gateway": "EEyq16v63aotPBCepxUpCgAojrNasZ6Hk1PjpRyBAdEp" + }, + { + "id": "shipyard-telegram-6", + "description": "Nym Telegram Service Provider", + "address": "7n1BYhsXSwcr8Qim8AqZTAodqFia4QG6T7CRc1ihQHpv.7o4trpGqu2LHMUiXc3dddgfGET1CFFcAK9gKYoHoSn5e@BTZNB3bkkEePsT14GN8ofVtM1SJae4YLWjpBerrKYfr", + "gateway": "BTZNB3bkkEePsT14GN8ofVtM1SJae4YLWjpBerrKYfr" + }, + { + "id": "shipyard-telegram-7", + "description": "Nym Telegram Service Provider", + "address": "Gv4TWhUKrvJfqh1jBRPGEQrikNZvZse2kS3ZgN9Z2nAZ.7KGPaaqUEum2C59jLvw7f8Ug8a48YuZdjjZu3t4JES4U@C7J8SwZQqjWqhBryyjJxLt7FacVuPTwAmR2otGy53ayi", + "gateway": "C7J8SwZQqjWqhBryyjJxLt7FacVuPTwAmR2otGy53ayi" + }, + { + "id": "shipyard-telegram-8", + "description": "Nym Telegram Service Provider", + "address": "8Mqgp12cpF6FSXMeqzxgFgQXvTSapyNqGAi5wy7ub4ge.7z7PDsiJGiGxGz4p77v5L5fZhXBJ5qNZ8CgJwYNr6H6J", + "gateway": "3zd3wrCK8Dz5TXrcvk5dG5s9EEdf4Ck1v9VgBPMMFVkR" + }, + { + "id": "shipyard-telegram-9", + "description": "Nym Telegram Service Provider", + "address": "F3N5eiPDZcGFC985Go4Mpv8p9uxFD1L3jRUdrLCbrZLm.EyTxWwwTwYpPrJBmc97GLd1LpUAphjptS5y1ed182bGk@GAjhJcrd6f1edaqUkfWCff6zdHoqo756qYrc2TfPuCXJ", + "gateway": "GAjhJcrd6f1edaqUkfWCff6zdHoqo756qYrc2TfPuCXJ" + }, + { + "id": "shipyard-telegram-10", + "description": "Nym Telegram Service Provider", + "address": "G7y7e1nVBr8fmQSzdeAxXnCmmmJb5k8N3E8LBV31KE5g.GRRUCj6t6cCUUjakmTWzidMLiYA7EdCedKnup8osaBC6@AJad2R9virYEYXEsTcicN5y5tyPoixrhhAGsxoESZVnc", + "gateway": "AJad2R9virYEYXEsTcicN5y5tyPoixrhhAGsxoESZVnc" + }, + { + "id": "shipyard-telegram-11", + "description": "Nym Telegram Service Provider", + "address": "2kq9Z7RyDZtb8kxXjyP3ZT8VMWHg6JXFDChGuuNBk7Hw.F5XYbBaGSoF8qAo8faPcaNRPHEq3Y25BDcwESeabUS9S@HaLyPQrhBTq75dnGeBUdYWeFVA2BBn39MgkhEt3VTMMM", + "gateway": "HaLyPQrhBTq75dnGeBUdYWeFVA2BBn39MgkhEt3VTMMM" + }, + { + "id": "shipyard-telegram-12", + "description": "Nym Telegram Service Provider", + "address": "GegdtpNzYj4QCgpih9Kxv7ZVZxmVdxYHsDkiPsbT71XG.E8xtE8mrapjzFtyuziZSrsScAKhwZMH5wNpKWtKfzJ5Y@9Byd9VAtyYMnbVAcqdoQxJnq76XEg2dbxbiF5Aa5Jj9J", + "gateway": "9Byd9VAtyYMnbVAcqdoQxJnq76XEg2dbxbiF5Aa5Jj9J" + }, + { + "id": "shipyard-telegram-13", + "description": "Nym Telegram Service Provider", + "address": "4SsrDQeEtG3mpeD9nN5CDdGaCsxFvNeYMhoviDzNNB9f.GyqG6iK5rBvhe3HXLR11m6ULpf13ATgYvkkidLmteDLs@5EpkkrMFYAM3XcaztXnZwBWquURHSKsyc9JxUCengDFS", + "gateway": "5EpkkrMFYAM3XcaztXnZwBWquURHSKsyc9JxUCengDFS" + }, + { + "id": "shipyard-telegram-14", + "description": "Nym Telegram Service Provider", + "address": "9JoHRu2RrSD1fjbj9NSTASgjv9Szep7Nhd9L2PywxbBi.AZhAUDNX6iH8BqXyR5c7TJuzpwMEvDXrabNLGuRukvVf@9xJM74FwwHhEKKJHihD21QSZnHM2QBRMoFx9Wst6qNBS", + "gateway": "9xJM74FwwHhEKKJHihD21QSZnHM2QBRMoFx9Wst6qNBS" + }, + { + "id": "shipyard-telegram-15", + "description": "Nym Telegram Service Provider", + "address": "3K174ijjXqCkhMDT9xLcqjS4MXk2QsqZt4PdgNcuUrnn.BNnHnQmWoj6Uo6kkS1QkPqsdHaXrcwyR9F6MnnzDkZJL@C7J8SwZQqjWqhBryyjJxLt7FacVuPTwAmR2otGy53ayi", + "gateway": "C7J8SwZQqjWqhBryyjJxLt7FacVuPTwAmR2otGy53ayi" + }, + { + "id": "shipyard-telegram-16", + "description": "Nym Telegram Service Provider", + "address": "BqX5Q3MEcbTnM39hUswQchLW68SrqbhL8K5ucrLmtP39.AWrVsFoVC9s6KjdpcasATmZPA3GtMsUxcfHpAkuNdtFG@Emswx6KXyjRfq1c2k4d4uD2e6nBSbH1biorCZUei8UNS", + "gateway": "Emswx6KXyjRfq1c2k4d4uD2e6nBSbH1biorCZUei8UNS" + }, + { + "id": "shipyard-telegram-17", + "description": "Nym Telegram Service Provider", + "address": "2tQxccgcqdkuUvLqgiEkEN4rNRZ5QknygnKAFcS4gfoe.EVrY5q5sqDqBUbS3wHsRRZhk2MAw1S17hNoH1Bicyv7n@DAGQxdxwAkwjaLjTw1B9vndia4YyFD15qRgcTQxrmkom", + "gateway": "DAGQxdxwAkwjaLjTw1B9vndia4YyFD15qRgcTQxrmkom" + }, + { + "id": "shipyard-telegram-18", + "description": "Nym Telegram Service Provider", + "address": "8YG1rcEauJA814Nd7hSxjNe2UrRwrGsrXTm1Cmd3gRrU.FxYaYqpNN8PciNsySs3zYPrTB1J8AYUu9DBsM2vVDDfF@7EfEESLo71GUvx3UEW79LgTegHUBPUocUzGyJVv6LHog", + "gateway": "7EfEESLo71GUvx3UEW79LgTegHUBPUocUzGyJVv6LHog" + }, + { + "id": "shipyard-telegram-19", + "description": "Nym Telegram Service Provider", + "address": "HPiXADVFLwLQPNpPtyYefzvYntC6tp9UJ5fJZGfkqvDt.2EUUxmeT3AiaUzAcE5SyXRAk8a2JXBkRz4B8McSdkrST@9ACTkYraCqE9jMb6zb6ne8EDQGGhZw5ykNiq9YRUdHTD", + "gateway": "9ACTkYraCqE9jMb6zb6ne8EDQGGhZw5ykNiq9YRUdHTD" + }, + { + "id": "shipyard-telegram-20", + "description": "Nym Telegram Service Provider", + "address": "2QLnEEnTmf2NRWtcQPWBeRcg7Hej5WSPWRWwtTpEEZWF.BheS78ozc8ngvhsXNNnshdJzpoYsmEvhfn3WKUYF5dRU@C2uyokSPoxhku9GexRxEo1e8KPZ7q6e8FXmK3gtY8kkF", + "gateway": "C2uyokSPoxhku9GexRxEo1e8KPZ7q6e8FXmK3gtY8kkF" + }, + { + "id": "shipyard-telegram-21", + "description": "Nym Telegram Service Provider", + "address": "FuBbnwiANfaXZnn683jBapK5XVm5ttgZSykU3vqPSHoD.94MFGv1VcBLTkRwzBDQUkWjvqtZYVBrJg2Q8JGbizcib@CTqYPY8htdAQMXCzRW9SjZzZuqYwSt2iUh6HPaNgmTvK", + "gateway": "CTqYPY8htdAQMXCzRW9SjZzZuqYwSt2iUh6HPaNgmTvK" + }, + { + "id": "shipyard-telegram-22", + "description": "Nym Telegram Service Provider", + "address": "9EbQx5jQznSVbftFom7sqUSHAACrsfvMhrzhaFt4A3SZ.D1FQCirL4YKwfcmtMGvB5Rugt5sAzGEhdSjJ3bHVQRZ@7Zh1Sz5dXpA6s53CbtcdqhQhLqwf4cLynL7KqHKcjrG4", + "gateway": "7Zh1Sz5dXpA6s53CbtcdqhQhLqwf4cLynL7KqHKcjrG4" + }, + { + "id": "shipyard-telegram-24", + "description": "Nym Telegram Service Provider", + "address": "6Umawwvf551VyB3Ko46NgKLqJdTFJeToCM67mrTmM3G.3A4sesBac4KGuMTFjvYBwLpksMJvbMbteGJQgmm4PV4Y@AnnYnEtBjB2a5sHmeRCnBq43qxyHDf95Bqd7cwQyKNLR", + "gateway": "AnnYnEtBjB2a5sHmeRCnBq43qxyHDf95Bqd7cwQyKNLR" + }, + { + "id": "shipyard-telegram-25", + "description": "Nym Telegram Service Provider", + "address": "CDtxTeoyqq83JpV9G8cR5HRHRdMMaVspQsCwH3Qnajt3.F5EHK9HFcdGrE2hqA7bK9AUmkbihujYDhtNNqHKxW765@BDkeNx7JQm5NsQakst9s8htogZXhpTQedFAgZpvsGCqH", + "gateway": "BDkeNx7JQm5NsQakst9s8htogZXhpTQedFAgZpvsGCqH" + }, + { + "id": "shipyard-telegram-26", + "description": "Nym Telegram Service Provider", + "address": "HukZkLG2DoarQEqaoDLuqW1GFf2NSHDUMGBZiyJGRYJD.9GyU8wPsyzcvRjcyk8hiNpTJbXCmq5F3VoVhFBZYuHR3@GsGEZiDBz8SWfHGaK5SDmhfbTEM55v37WCYYcT9wTSxN", + "gateway": "GsGEZiDBz8SWfHGaK5SDmhfbTEM55v37WCYYcT9wTSxN" + }, + { + "id": "shipyard-telegram-27", + "description": "Nym Telegram Service Provider", + "address": "773y8iMVJiRk4dRbjQzkJVbrei4TwkePNE5WTEttt77d.3Mw47C9XZj3oAzk1iSqC5Y36tbBsjtaTtdgaHM3Zsdma@7fiZtNL1RACQTwGrKLBT9nbY77bfwZnX9rqcWqc53qgv", + "gateway": "7fiZtNL1RACQTwGrKLBT9nbY77bfwZnX9rqcWqc53qgv" + }, + { + "id": "shipyard-telegram-28", + "description": "Nym Telegram Service Provider", + "address": "6jQJEorCu7YiP9HdDaMeHxcNhxeNmZ1kpd836GnqLZX.HsJqEmNTszGecsKqFB37i84nBXxqf4ETgrKmKmBvMGHC@FYnDMQzT49ZGM23gVqpTxfih14V6wuedNXirekmt37zE", + "gateway": "FYnDMQzT49ZGM23gVqpTxfih14V6wuedNXirekmt37zE" + }, + { + "id": "shipyard-telegram-29", + "description": "Nym Telegram Service Provider", + "address": "BiCSyovpFMuSnTvF2TdiuZwrytXDrd9AH47ZMcCxscVC.G9YpdicA9BBNoVHDgjWjgt17wv5WYKWcbE3vPJJVpSJD@GAjhJcrd6f1edaqUkfWCff6zdHoqo756qYrc2TfPuCXJ", + "gateway":"GAjhJcrd6f1edaqUkfWCff6zdHoqo756qYrc2TfPuCXJ" + }, + { + "id": "shipyard-telegram-30", + "description": "Nym Telegram Service Provider", + "address": "AQRRAs9oc8QWXAFBs44YhCKUny7AyLsfLy91pwmGgxuf.CWUKoKA1afSKyw5BnFJJg19UDgnaVATupsFhQpyTEBHJ@EBT8jTD8o4tKng2NXrrcrzVhJiBnKpT1bJy5CMeArt2w", + "gateway": "EBT8jTD8o4tKng2NXrrcrzVhJiBnKpT1bJy5CMeArt2w" + }, + { + "id": "shipyard-telegram-31", + "description": "Nym Telegram Service Provider", + "address": "6YqjAZK3Pr1ngiBLcDkotboB5WiN6k6NPpbXvShH4pR5.9Ss6VW3Xbyi8LuxduNNwnXEv9njHCQ2PLSP1UK6tsoa5@42XCK9dMS9m5XJLzQd2dBuwimk6ndZnczhZaV5VPFkQD", + "gateway": "42XCK9dMS9m5XJLzQd2dBuwimk6ndZnczhZaV5VPFkQD" + }, + { + "id": "shipyard-telegram-32", + "description": "Nym Telegram Service Provider", + "address": "EmYWLeybmj86Vzr62vxuZ3T15jwMNHggzK7sQwid96yp.GyaF9WprSr56cxUdGf5TpcUvAjb2VbAr8CVBrmBUYAaw@GL5wESoz4oSbpBaTki9qB9213FGUQXCiRjbzDkhWwoBC", + "gateway": "GL5wESoz4oSbpBaTki9qB9213FGUQXCiRjbzDkhWwoBC" + }, + { + "id": "shipyard-telegram-33", + "description": "Nym Telegram Service Provider", + "address": "4PDb96cck5btTj6G7rsomqwHJsp4qu8uPvFCbwHfjFUx.C5dKbaoakH7egsZvAueRbwLFbmxnQaVMeSr6QTMpuBAA@58ceEFaLJh6zAo3cirzT1BDQm7D3L5acnQrxGH1D6TAY", + "gateway": "58ceEFaLJh6zAo3cirzT1BDQm7D3L5acnQrxGH1D6TAY" + }, + { + "id": "shipyard-telegram-34", + "description": "Nym Telegram Service Provider", + "address": "BeZbeMf9vcpUf368qDd85dtLwXLj4Ee5bsHMB2fUD8uX.HELVbppkwU1jmzUAUrCEbHeJfVciSeo8VGAkbJSpwxsb@ADdHkiTfkpsSt31zVToWW9j3KikH24aLAAwDKtCYE5jY", + "gateway":"ADdHkiTfkpsSt31zVToWW9j3KikH24aLAAwDKtCYE5jY" + }, + { + "id": "shipyard-telegram-35", + "description": "Nym Telegram Service Provider", + "address": "Bp4JRFyf7GB9L9J95AqMPnz9zbGmPnViA5fDXKeNraLJ.D6CTdcjJVxDmH2UQvzXuPWg9Se9xXYe76uDMypXvhzd7@6UjGEeQZK14C5K2kenycTkqt7qRjEHGLgaQx3FWySo3N", + "gateway": "6UjGEeQZK14C5K2kenycTkqt7qRjEHGLgaQx3FWySo3N" + }, + { + "id": "shipyard-telegram-36", + "description": "Nym Telegram Service Provider", + "address": "91h7io6BGhVjbtC7dbbRcScyTJcTfnMsTQZ6aWMVsrWR.Epb4hANXCp8cGEY3wSgawux991ti9Z5Y1FHTMzAKFa6E@DF4TE7V8kJkttMvnoSVGnRFFRt6WYGxxiC2w1XyPQnHe", + "gateway": "DF4TE7V8kJkttMvnoSVGnRFFRt6WYGxxiC2w1XyPQnHe" + }, + { + "id": "shipyard-telegram-37", + "description": "Nym Telegram Service Provider", + "address": "Cy2wuwKpWZ3iWzKU3ZWL1qqcVfJ5Cq85dU7UHVWwv2gc.9AhC9b2zVcLnXLGriMdxjpsWJpq6iAdCavDi63udbL89@678qVUJ21uwxZBhp3r56z7GRf6gMh3NYDHruTegPtgMf", + "gateway": "678qVUJ21uwxZBhp3r56z7GRf6gMh3NYDHruTegPtgMf" + }, + { + "id": "shipyard-telegram-38", + "description": "Nym Telegram Service Provider", + "address": "GgUeUWW1NRSuquZYeZf3WkppE92EQUHJrFjNZtYU1jow.CSEjwrRi4f4uyw7N6L2LPKw2tB8spcMbFu99wHZzFZSj@77TSuVU8d1oXKbPzjec2xh4i3Wj5WwUyy9Lr36sm8gZm", + "gateway": "77TSuVU8d1oXKbPzjec2xh4i3Wj5WwUyy9Lr36sm8gZm" + }, + { + "id": "shipyard-telegram-39", + "description": "Nym Telegram Service Provider", + "address": "kz4zWwSkYiQxqxXFPNcGUByTPQWXascD9RfYsmSxY7n.ajp3SjbBVBjrU9nXpSQXAXzbb6EHJJyhbY6cc1ajayx@BTZNB3bkkEePsT14GN8ofVtM1SJae4YLWjpBerrKYf", + "gateway": "HyS2UZtZX3kQXdazbdE99DhCjBXjbG61LC9QsmXwbxrU" + } + ] + }, + { + "id": "blockstream", + "description": "Blockstream Green", + "items": [ + { + "id": "nym-blockstream", + "description": "Nym Blockstream Green Service Provider", + "address": "GiRjFWrMxt58pEMuusm4yT3RxoMD1MMPrR9M2N4VWRJP.3CNZBPq4vg7v7qozjGjdPMXcvDmkbWPCgbGCjQVw9n6Z@2xU4CBE6QiiYt6EyBXSALwxkNvM7gqJfjHXaMkjiFmYW", + "gateway": "2xU4CBE6QiiYt6EyBXSALwxkNvM7gqJfjHXaMkjiFmYW" + } + ] + } +]`); +export const Loaded = () => ( + + + +); + +export const ServiceAlreadySelected = () => ( + + console.log('New service provider selected: ', serviceProvider)} + /> + +); diff --git a/nym-connect/src/components/ServiceProviderSelector.tsx b/nym-connect/src/components/ServiceProviderSelector.tsx index 9dee82fbb4..16086aa5e1 100644 --- a/nym-connect/src/components/ServiceProviderSelector.tsx +++ b/nym-connect/src/components/ServiceProviderSelector.tsx @@ -1,6 +1,7 @@ import React, { useEffect, useMemo } from 'react'; import { Box, CircularProgress, Stack, TextField, Tooltip, Typography, MenuItem, ListItemIcon } from '@mui/material'; import { ServiceProvider, Service, Services } from '../types/directory'; +import { useTauriEvents } from '../utils'; type ServiceWithRandomSp = { id: string; @@ -8,13 +9,31 @@ type ServiceWithRandomSp = { sp: ServiceProvider; }; +const defaultServiceValue = { id: '', description: '', items: [] }; + export const ServiceProviderSelector: React.FC<{ - onChange?: (serviceProvider: ServiceProvider) => void; + onChange?: (serviceProvider?: ServiceProvider) => void; services?: Services; currentSp?: ServiceProvider; }> = ({ services, currentSp, onChange }) => { - const [service, setService] = React.useState({ id: '', description: '', items: [] }); + const [service, setService] = React.useState(defaultServiceValue); const [serviceProvider, setServiceProvider] = React.useState(currentSp); + const [resetTrigger, setResetTrigger] = React.useState(new Date().toISOString()); + + const handleSelectSp = (newServiceProvider?: ServiceProvider) => { + if (newServiceProvider && newServiceProvider !== currentSp) { + setServiceProvider(newServiceProvider); + onChange?.(newServiceProvider); + } + }; + + // when the user clears local storage, reset the selector + useTauriEvents('help://clear-storage', () => { + setService(defaultServiceValue); + setServiceProvider(undefined); + onChange?.(undefined); + setResetTrigger(new Date().toISOString()); + }); useEffect(() => { if (!serviceProvider && currentSp) { @@ -39,13 +58,6 @@ export const ServiceProviderSelector: React.FC<{ } }, [serviceProvider, services]); - const handleSelectSp = (newServiceProvider?: ServiceProvider) => { - if (newServiceProvider && newServiceProvider !== currentSp) { - setServiceProvider(newServiceProvider); - onChange?.(newServiceProvider); - } - }; - if (!services) { return ( @@ -64,7 +76,7 @@ export const ServiceProviderSelector: React.FC<{ description, sp: items[Math.floor(Math.random() * items.length)], })), - [services], + [services, resetTrigger], ); if (!service) return null; diff --git a/nym-connect/src/components/ServiceSelector.stories.tsx b/nym-connect/src/components/ServiceSelector.stories.tsx new file mode 100644 index 0000000000..56be7c19ee --- /dev/null +++ b/nym-connect/src/components/ServiceSelector.stories.tsx @@ -0,0 +1,342 @@ +import * as React from 'react'; +import { ComponentMeta } from '@storybook/react'; +import { Box } from '@mui/material'; +import { ServiceSelector } from './ServiceSelector'; +import { Services } from '../types/directory'; + +export default { + title: 'Components/Service Selector', + component: ServiceSelector, +} as ComponentMeta; + +const width = 240; + +export const Loading = () => ( + + + +); + +const services: Services = JSON.parse(`[ + { + "id": "keybase", + "description": "Keybase", + "items": [ + { + "id": "nym-keybase", + "description": "Nym Keybase Service Provider", + "address": "Entztfv6Uaz2hpYHQJ6JKoaCTpDL5dja18SuQWVJAmmx.Cvhn9rBJw5Ay9wgHcbgCnVg89MPSV5s2muPV2YF1BXYu@Fo4f4SQLdoyoGkFae5TpVhRVoXCF8UiypLVGtGjujVPf", + "gateway": "Fo4f4SQLdoyoGkFae5TpVhRVoXCF8UiypLVGtGjujVPf" + }, + { + "id": "shipyard-keybase-1", + "description": "Nym Keybase Service Provider", + "address": "D55ksecHzY6vAeqk8MCTzCfj2pqwJeKCKZCUUGnwGnn3.FS42vXS5a6GNTb1qk3aVk5mjSiJCAuawbBVyQZZVfhvt@DfNMqQRy6pPkU8Z5rBsxRwzDUzAMXHPFwMhjF16ScZqn", + "gateway": "DfNMqQRy6pPkU8Z5rBsxRwzDUzAMXHPFwMhjF16ScZqn" + }, + { + "id": "shipyard-keybase-2", + "description": "Nym Keybase Service Provider", + "address": "DFdDtW7LNBATxQ4ef3jNbqs3cRE8b9wDZTCctHCQRULa.4AbKiTNVUwYFWHhy98o5pT9dELiUrkXoJQ9wHqPgf6GV@GJqd3ZxpXWSNxTfx7B1pPtswpetH4LnJdFeLeuY5KUuN", + "gateway": "GJqd3ZxpXWSNxTfx7B1pPtswpetH4LnJdFeLeuY5KUuN" + }, + { + "id": "shipyard-keybase-3", + "description": "Nym Keybase Service Provider", + "address": "6Y1HE1jJ92P9yoHer11TR4A2NdZePrLGaBNFf65MnYGe.FwXoh217odQDWNmViqzNX28fauYrjB3PYLrVvpqnQrX4@5vC8spDvw5VDQ8Zvd9fVvBhbUDv9jABR4cXzd4Kh5vz", + "gateway": "5vC8spDvw5VDQ8Zvd9fVvBhbUDv9jABR4cXzd4Kh5vz" + }, + { + "id": "shipyard-keybase-4", + "description": "Nym Keybase Service Provider", + "address": "3zzhLtWvaJgn755MkRckG5aRnoTZich8ASn395iSsTgj.J1R5VuxXbh2eNHiaRbrwbKGXrrEQcHKLdzf8eg9HTB6q@3B7PsbXFuqq6rerYFLw5HPbQb4UmBqAhfWURRovMmWoj", + "gateway": "3B7PsbXFuqq6rerYFLw5HPbQb4UmBqAhfWURRovMmWoj" + }, + { + "id": "shipyard-keybase-5", + "description": "Nym Keybase Service Provider", + "address": "CHuXdZJYQ8xH7ekgN9gAuVtQ7ZikjjHEZY5BSN7yc5mN.29dFvqicKQQQvoX1vup44mspmc249RH5xgLibWMwTYGT@CfWcDJq8QBz6cVAPCYSaLbaJEhVTmHEmyYgQ6C5GdDW9", + "gateway": "CfWcDJq8QBz6cVAPCYSaLbaJEhVTmHEmyYgQ6C5GdDW9" + } + ] + }, + { + "id": "electrum", + "description": "Electrum Wallet", + "items": [ + { + "id": "nym-electrum", + "description": "Nym Electrum Service Provider", + "address": "DpB3cHAchJiNBQi5FrZx2csXb1mrHkpYh9Wzf8Rjsuko.ANNWrvHqMYuertHGHUrZdBntQhpzfbWekB39qez9U2Vx@2BuMSfMW3zpeAjKXyKLhmY4QW1DXurrtSPEJ6CjX3SEh", + "gateway": "2BuMSfMW3zpeAjKXyKLhmY4QW1DXurrtSPEJ6CjX3SEh" + }, + { + "id": "shipyard-electrum-1", + "description": "Nym Electrum Service Provider", + "address": "8Tb73cFQpXCLpgxEA2VSDru2hHrcZ3KQcyMsGbxcTjBp.4x5tu66k8YkHk4tYac1qwEFbNq5WsKiX5kR51q5KKH88@4WgKhJdmUffz4e1o1ftVAGS3HnG56LiNAxA9dmaekrVd", + "gateway": "4WgKhJdmUffz4e1o1ftVAGS3HnG56LiNAxA9dmaekrVd" + }, + { + "id": "shipyard-electrum-2", + "description": "Nym Electrum Service Provider", + "address": "GR6z31MwCsvxHrnvvVN1Cpasd8aQ1giwQqPTZM9dN7VH.5rEiqakSPDrBtKmvpU8Shnhz6gRM85JLoB7AX4h7PJYr@5Ao1J38frnU9Rx5YVeF5BWExcnDTcW8etNe9W2sRASXD", + "gateway": "5Ao1J38frnU9Rx5YVeF5BWExcnDTcW8etNe9W2sRASXD" + } + ] + }, + { + "id": "telegram", + "description": "Telegram", + "items": [ + { + "id": "shipyard-telegram-2", + "description": "Nym Telegram Service Provider", + "address": "C4w6ewbQtoaZEeoaaNw1xVASChqo4WVjNfuYEUFjZxpc.8F1D7rQXf2jGoj1Ken7PiGDM8HS2Ug79wSoc9nZ1iqh1@62F81C9GrHDRja9WCqozemRFSzFPMecY85MbGwn6efve", + "gateway": "62F81C9GrHDRja9WCqozemRFSzFPMecY85MbGwn6efve" + }, + { + "id": "shipyard-telegram-3", + "description": "Nym Telegram Service Provider", + "address": "DStL3BEUZuQZfbij1KAY3BvJh8rC5jpr9mc6AQ6aTLUu.Ax9foYaKfFgX6g8y393GoNpKkKrnDGFGRZwxDv9R7X6M@FQon7UwF5knbUr2jf6jHhmNLbJnMreck1eUcVH59kxYE", + "gateway": "FQon7UwF5knbUr2jf6jHhmNLbJnMreck1eUcVH59kxYE" + }, + { + "id": "shipyard-telegram-4", + "description": "Nym Telegram Service Provider", + "address": "8gRdGTzsDxYzpasRQhsRg59MCgNNhnfag2oFfwwZPXnB.DtDrGz7ScVm4o7sN4K3CYUJveYgz7fcXELBVLNDfMS9Y@3ojQD6V7skM1bSXJX7fVQvscjmcgptzdixQEaAha2ixh", + "gateway": "3ojQD6V7skM1bSXJX7fVQvscjmcgptzdixQEaAha2ixh" + }, + { + "id": "shipyard-telegram-5", + "description": "Nym Telegram Service Provider", + "address": "AR3oEM6Uvmfs6fyddwSehoBUKCFxz7MdFi4z7aahuHuY.3ZKapg9A3Py1PXhyLbCJr8ZbJsEV6NZdN1WJaGGut5tj@EEyq16v63aotPBCepxUpCgAojrNasZ6Hk1PjpRyBAdEp", + "gateway": "EEyq16v63aotPBCepxUpCgAojrNasZ6Hk1PjpRyBAdEp" + }, + { + "id": "shipyard-telegram-6", + "description": "Nym Telegram Service Provider", + "address": "7n1BYhsXSwcr8Qim8AqZTAodqFia4QG6T7CRc1ihQHpv.7o4trpGqu2LHMUiXc3dddgfGET1CFFcAK9gKYoHoSn5e@BTZNB3bkkEePsT14GN8ofVtM1SJae4YLWjpBerrKYfr", + "gateway": "BTZNB3bkkEePsT14GN8ofVtM1SJae4YLWjpBerrKYfr" + }, + { + "id": "shipyard-telegram-7", + "description": "Nym Telegram Service Provider", + "address": "Gv4TWhUKrvJfqh1jBRPGEQrikNZvZse2kS3ZgN9Z2nAZ.7KGPaaqUEum2C59jLvw7f8Ug8a48YuZdjjZu3t4JES4U@C7J8SwZQqjWqhBryyjJxLt7FacVuPTwAmR2otGy53ayi", + "gateway": "C7J8SwZQqjWqhBryyjJxLt7FacVuPTwAmR2otGy53ayi" + }, + { + "id": "shipyard-telegram-8", + "description": "Nym Telegram Service Provider", + "address": "8Mqgp12cpF6FSXMeqzxgFgQXvTSapyNqGAi5wy7ub4ge.7z7PDsiJGiGxGz4p77v5L5fZhXBJ5qNZ8CgJwYNr6H6J", + "gateway": "3zd3wrCK8Dz5TXrcvk5dG5s9EEdf4Ck1v9VgBPMMFVkR" + }, + { + "id": "shipyard-telegram-9", + "description": "Nym Telegram Service Provider", + "address": "F3N5eiPDZcGFC985Go4Mpv8p9uxFD1L3jRUdrLCbrZLm.EyTxWwwTwYpPrJBmc97GLd1LpUAphjptS5y1ed182bGk@GAjhJcrd6f1edaqUkfWCff6zdHoqo756qYrc2TfPuCXJ", + "gateway": "GAjhJcrd6f1edaqUkfWCff6zdHoqo756qYrc2TfPuCXJ" + }, + { + "id": "shipyard-telegram-10", + "description": "Nym Telegram Service Provider", + "address": "G7y7e1nVBr8fmQSzdeAxXnCmmmJb5k8N3E8LBV31KE5g.GRRUCj6t6cCUUjakmTWzidMLiYA7EdCedKnup8osaBC6@AJad2R9virYEYXEsTcicN5y5tyPoixrhhAGsxoESZVnc", + "gateway": "AJad2R9virYEYXEsTcicN5y5tyPoixrhhAGsxoESZVnc" + }, + { + "id": "shipyard-telegram-11", + "description": "Nym Telegram Service Provider", + "address": "2kq9Z7RyDZtb8kxXjyP3ZT8VMWHg6JXFDChGuuNBk7Hw.F5XYbBaGSoF8qAo8faPcaNRPHEq3Y25BDcwESeabUS9S@HaLyPQrhBTq75dnGeBUdYWeFVA2BBn39MgkhEt3VTMMM", + "gateway": "HaLyPQrhBTq75dnGeBUdYWeFVA2BBn39MgkhEt3VTMMM" + }, + { + "id": "shipyard-telegram-12", + "description": "Nym Telegram Service Provider", + "address": "GegdtpNzYj4QCgpih9Kxv7ZVZxmVdxYHsDkiPsbT71XG.E8xtE8mrapjzFtyuziZSrsScAKhwZMH5wNpKWtKfzJ5Y@9Byd9VAtyYMnbVAcqdoQxJnq76XEg2dbxbiF5Aa5Jj9J", + "gateway": "9Byd9VAtyYMnbVAcqdoQxJnq76XEg2dbxbiF5Aa5Jj9J" + }, + { + "id": "shipyard-telegram-13", + "description": "Nym Telegram Service Provider", + "address": "4SsrDQeEtG3mpeD9nN5CDdGaCsxFvNeYMhoviDzNNB9f.GyqG6iK5rBvhe3HXLR11m6ULpf13ATgYvkkidLmteDLs@5EpkkrMFYAM3XcaztXnZwBWquURHSKsyc9JxUCengDFS", + "gateway": "5EpkkrMFYAM3XcaztXnZwBWquURHSKsyc9JxUCengDFS" + }, + { + "id": "shipyard-telegram-14", + "description": "Nym Telegram Service Provider", + "address": "9JoHRu2RrSD1fjbj9NSTASgjv9Szep7Nhd9L2PywxbBi.AZhAUDNX6iH8BqXyR5c7TJuzpwMEvDXrabNLGuRukvVf@9xJM74FwwHhEKKJHihD21QSZnHM2QBRMoFx9Wst6qNBS", + "gateway": "9xJM74FwwHhEKKJHihD21QSZnHM2QBRMoFx9Wst6qNBS" + }, + { + "id": "shipyard-telegram-15", + "description": "Nym Telegram Service Provider", + "address": "3K174ijjXqCkhMDT9xLcqjS4MXk2QsqZt4PdgNcuUrnn.BNnHnQmWoj6Uo6kkS1QkPqsdHaXrcwyR9F6MnnzDkZJL@C7J8SwZQqjWqhBryyjJxLt7FacVuPTwAmR2otGy53ayi", + "gateway": "C7J8SwZQqjWqhBryyjJxLt7FacVuPTwAmR2otGy53ayi" + }, + { + "id": "shipyard-telegram-16", + "description": "Nym Telegram Service Provider", + "address": "BqX5Q3MEcbTnM39hUswQchLW68SrqbhL8K5ucrLmtP39.AWrVsFoVC9s6KjdpcasATmZPA3GtMsUxcfHpAkuNdtFG@Emswx6KXyjRfq1c2k4d4uD2e6nBSbH1biorCZUei8UNS", + "gateway": "Emswx6KXyjRfq1c2k4d4uD2e6nBSbH1biorCZUei8UNS" + }, + { + "id": "shipyard-telegram-17", + "description": "Nym Telegram Service Provider", + "address": "2tQxccgcqdkuUvLqgiEkEN4rNRZ5QknygnKAFcS4gfoe.EVrY5q5sqDqBUbS3wHsRRZhk2MAw1S17hNoH1Bicyv7n@DAGQxdxwAkwjaLjTw1B9vndia4YyFD15qRgcTQxrmkom", + "gateway": "DAGQxdxwAkwjaLjTw1B9vndia4YyFD15qRgcTQxrmkom" + }, + { + "id": "shipyard-telegram-18", + "description": "Nym Telegram Service Provider", + "address": "8YG1rcEauJA814Nd7hSxjNe2UrRwrGsrXTm1Cmd3gRrU.FxYaYqpNN8PciNsySs3zYPrTB1J8AYUu9DBsM2vVDDfF@7EfEESLo71GUvx3UEW79LgTegHUBPUocUzGyJVv6LHog", + "gateway": "7EfEESLo71GUvx3UEW79LgTegHUBPUocUzGyJVv6LHog" + }, + { + "id": "shipyard-telegram-19", + "description": "Nym Telegram Service Provider", + "address": "HPiXADVFLwLQPNpPtyYefzvYntC6tp9UJ5fJZGfkqvDt.2EUUxmeT3AiaUzAcE5SyXRAk8a2JXBkRz4B8McSdkrST@9ACTkYraCqE9jMb6zb6ne8EDQGGhZw5ykNiq9YRUdHTD", + "gateway": "9ACTkYraCqE9jMb6zb6ne8EDQGGhZw5ykNiq9YRUdHTD" + }, + { + "id": "shipyard-telegram-20", + "description": "Nym Telegram Service Provider", + "address": "2QLnEEnTmf2NRWtcQPWBeRcg7Hej5WSPWRWwtTpEEZWF.BheS78ozc8ngvhsXNNnshdJzpoYsmEvhfn3WKUYF5dRU@C2uyokSPoxhku9GexRxEo1e8KPZ7q6e8FXmK3gtY8kkF", + "gateway": "C2uyokSPoxhku9GexRxEo1e8KPZ7q6e8FXmK3gtY8kkF" + }, + { + "id": "shipyard-telegram-21", + "description": "Nym Telegram Service Provider", + "address": "FuBbnwiANfaXZnn683jBapK5XVm5ttgZSykU3vqPSHoD.94MFGv1VcBLTkRwzBDQUkWjvqtZYVBrJg2Q8JGbizcib@CTqYPY8htdAQMXCzRW9SjZzZuqYwSt2iUh6HPaNgmTvK", + "gateway": "CTqYPY8htdAQMXCzRW9SjZzZuqYwSt2iUh6HPaNgmTvK" + }, + { + "id": "shipyard-telegram-22", + "description": "Nym Telegram Service Provider", + "address": "9EbQx5jQznSVbftFom7sqUSHAACrsfvMhrzhaFt4A3SZ.D1FQCirL4YKwfcmtMGvB5Rugt5sAzGEhdSjJ3bHVQRZ@7Zh1Sz5dXpA6s53CbtcdqhQhLqwf4cLynL7KqHKcjrG4", + "gateway": "7Zh1Sz5dXpA6s53CbtcdqhQhLqwf4cLynL7KqHKcjrG4" + }, + { + "id": "shipyard-telegram-24", + "description": "Nym Telegram Service Provider", + "address": "6Umawwvf551VyB3Ko46NgKLqJdTFJeToCM67mrTmM3G.3A4sesBac4KGuMTFjvYBwLpksMJvbMbteGJQgmm4PV4Y@AnnYnEtBjB2a5sHmeRCnBq43qxyHDf95Bqd7cwQyKNLR", + "gateway": "AnnYnEtBjB2a5sHmeRCnBq43qxyHDf95Bqd7cwQyKNLR" + }, + { + "id": "shipyard-telegram-25", + "description": "Nym Telegram Service Provider", + "address": "CDtxTeoyqq83JpV9G8cR5HRHRdMMaVspQsCwH3Qnajt3.F5EHK9HFcdGrE2hqA7bK9AUmkbihujYDhtNNqHKxW765@BDkeNx7JQm5NsQakst9s8htogZXhpTQedFAgZpvsGCqH", + "gateway": "BDkeNx7JQm5NsQakst9s8htogZXhpTQedFAgZpvsGCqH" + }, + { + "id": "shipyard-telegram-26", + "description": "Nym Telegram Service Provider", + "address": "HukZkLG2DoarQEqaoDLuqW1GFf2NSHDUMGBZiyJGRYJD.9GyU8wPsyzcvRjcyk8hiNpTJbXCmq5F3VoVhFBZYuHR3@GsGEZiDBz8SWfHGaK5SDmhfbTEM55v37WCYYcT9wTSxN", + "gateway": "GsGEZiDBz8SWfHGaK5SDmhfbTEM55v37WCYYcT9wTSxN" + }, + { + "id": "shipyard-telegram-27", + "description": "Nym Telegram Service Provider", + "address": "773y8iMVJiRk4dRbjQzkJVbrei4TwkePNE5WTEttt77d.3Mw47C9XZj3oAzk1iSqC5Y36tbBsjtaTtdgaHM3Zsdma@7fiZtNL1RACQTwGrKLBT9nbY77bfwZnX9rqcWqc53qgv", + "gateway": "7fiZtNL1RACQTwGrKLBT9nbY77bfwZnX9rqcWqc53qgv" + }, + { + "id": "shipyard-telegram-28", + "description": "Nym Telegram Service Provider", + "address": "6jQJEorCu7YiP9HdDaMeHxcNhxeNmZ1kpd836GnqLZX.HsJqEmNTszGecsKqFB37i84nBXxqf4ETgrKmKmBvMGHC@FYnDMQzT49ZGM23gVqpTxfih14V6wuedNXirekmt37zE", + "gateway": "FYnDMQzT49ZGM23gVqpTxfih14V6wuedNXirekmt37zE" + }, + { + "id": "shipyard-telegram-29", + "description": "Nym Telegram Service Provider", + "address": "BiCSyovpFMuSnTvF2TdiuZwrytXDrd9AH47ZMcCxscVC.G9YpdicA9BBNoVHDgjWjgt17wv5WYKWcbE3vPJJVpSJD@GAjhJcrd6f1edaqUkfWCff6zdHoqo756qYrc2TfPuCXJ", + "gateway":"GAjhJcrd6f1edaqUkfWCff6zdHoqo756qYrc2TfPuCXJ" + }, + { + "id": "shipyard-telegram-30", + "description": "Nym Telegram Service Provider", + "address": "AQRRAs9oc8QWXAFBs44YhCKUny7AyLsfLy91pwmGgxuf.CWUKoKA1afSKyw5BnFJJg19UDgnaVATupsFhQpyTEBHJ@EBT8jTD8o4tKng2NXrrcrzVhJiBnKpT1bJy5CMeArt2w", + "gateway": "EBT8jTD8o4tKng2NXrrcrzVhJiBnKpT1bJy5CMeArt2w" + }, + { + "id": "shipyard-telegram-31", + "description": "Nym Telegram Service Provider", + "address": "6YqjAZK3Pr1ngiBLcDkotboB5WiN6k6NPpbXvShH4pR5.9Ss6VW3Xbyi8LuxduNNwnXEv9njHCQ2PLSP1UK6tsoa5@42XCK9dMS9m5XJLzQd2dBuwimk6ndZnczhZaV5VPFkQD", + "gateway": "42XCK9dMS9m5XJLzQd2dBuwimk6ndZnczhZaV5VPFkQD" + }, + { + "id": "shipyard-telegram-32", + "description": "Nym Telegram Service Provider", + "address": "EmYWLeybmj86Vzr62vxuZ3T15jwMNHggzK7sQwid96yp.GyaF9WprSr56cxUdGf5TpcUvAjb2VbAr8CVBrmBUYAaw@GL5wESoz4oSbpBaTki9qB9213FGUQXCiRjbzDkhWwoBC", + "gateway": "GL5wESoz4oSbpBaTki9qB9213FGUQXCiRjbzDkhWwoBC" + }, + { + "id": "shipyard-telegram-33", + "description": "Nym Telegram Service Provider", + "address": "4PDb96cck5btTj6G7rsomqwHJsp4qu8uPvFCbwHfjFUx.C5dKbaoakH7egsZvAueRbwLFbmxnQaVMeSr6QTMpuBAA@58ceEFaLJh6zAo3cirzT1BDQm7D3L5acnQrxGH1D6TAY", + "gateway": "58ceEFaLJh6zAo3cirzT1BDQm7D3L5acnQrxGH1D6TAY" + }, + { + "id": "shipyard-telegram-34", + "description": "Nym Telegram Service Provider", + "address": "BeZbeMf9vcpUf368qDd85dtLwXLj4Ee5bsHMB2fUD8uX.HELVbppkwU1jmzUAUrCEbHeJfVciSeo8VGAkbJSpwxsb@ADdHkiTfkpsSt31zVToWW9j3KikH24aLAAwDKtCYE5jY", + "gateway":"ADdHkiTfkpsSt31zVToWW9j3KikH24aLAAwDKtCYE5jY" + }, + { + "id": "shipyard-telegram-35", + "description": "Nym Telegram Service Provider", + "address": "Bp4JRFyf7GB9L9J95AqMPnz9zbGmPnViA5fDXKeNraLJ.D6CTdcjJVxDmH2UQvzXuPWg9Se9xXYe76uDMypXvhzd7@6UjGEeQZK14C5K2kenycTkqt7qRjEHGLgaQx3FWySo3N", + "gateway": "6UjGEeQZK14C5K2kenycTkqt7qRjEHGLgaQx3FWySo3N" + }, + { + "id": "shipyard-telegram-36", + "description": "Nym Telegram Service Provider", + "address": "91h7io6BGhVjbtC7dbbRcScyTJcTfnMsTQZ6aWMVsrWR.Epb4hANXCp8cGEY3wSgawux991ti9Z5Y1FHTMzAKFa6E@DF4TE7V8kJkttMvnoSVGnRFFRt6WYGxxiC2w1XyPQnHe", + "gateway": "DF4TE7V8kJkttMvnoSVGnRFFRt6WYGxxiC2w1XyPQnHe" + }, + { + "id": "shipyard-telegram-37", + "description": "Nym Telegram Service Provider", + "address": "Cy2wuwKpWZ3iWzKU3ZWL1qqcVfJ5Cq85dU7UHVWwv2gc.9AhC9b2zVcLnXLGriMdxjpsWJpq6iAdCavDi63udbL89@678qVUJ21uwxZBhp3r56z7GRf6gMh3NYDHruTegPtgMf", + "gateway": "678qVUJ21uwxZBhp3r56z7GRf6gMh3NYDHruTegPtgMf" + }, + { + "id": "shipyard-telegram-38", + "description": "Nym Telegram Service Provider", + "address": "GgUeUWW1NRSuquZYeZf3WkppE92EQUHJrFjNZtYU1jow.CSEjwrRi4f4uyw7N6L2LPKw2tB8spcMbFu99wHZzFZSj@77TSuVU8d1oXKbPzjec2xh4i3Wj5WwUyy9Lr36sm8gZm", + "gateway": "77TSuVU8d1oXKbPzjec2xh4i3Wj5WwUyy9Lr36sm8gZm" + }, + { + "id": "shipyard-telegram-39", + "description": "Nym Telegram Service Provider", + "address": "kz4zWwSkYiQxqxXFPNcGUByTPQWXascD9RfYsmSxY7n.ajp3SjbBVBjrU9nXpSQXAXzbb6EHJJyhbY6cc1ajayx@BTZNB3bkkEePsT14GN8ofVtM1SJae4YLWjpBerrKYf", + "gateway": "HyS2UZtZX3kQXdazbdE99DhCjBXjbG61LC9QsmXwbxrU" + } + ] + }, + { + "id": "blockstream", + "description": "Blockstream Green", + "items": [ + { + "id": "nym-blockstream", + "description": "Nym Blockstream Green Service Provider", + "address": "GiRjFWrMxt58pEMuusm4yT3RxoMD1MMPrR9M2N4VWRJP.3CNZBPq4vg7v7qozjGjdPMXcvDmkbWPCgbGCjQVw9n6Z@2xU4CBE6QiiYt6EyBXSALwxkNvM7gqJfjHXaMkjiFmYW", + "gateway": "2xU4CBE6QiiYt6EyBXSALwxkNvM7gqJfjHXaMkjiFmYW" + } + ] + } +]`); +export const Loaded = () => ( + + + +); + +export const ServiceAlreadySelected = () => ( + + console.log('New service provider selected: ', serviceProvider)} + /> + +); diff --git a/nym-connect/src/components/ServiceSelector.tsx b/nym-connect/src/components/ServiceSelector.tsx new file mode 100644 index 0000000000..895188cd23 --- /dev/null +++ b/nym-connect/src/components/ServiceSelector.tsx @@ -0,0 +1,179 @@ +import React, { useEffect } from 'react'; +import { + Box, + CircularProgress, + Divider, + FormControl, + InputLabel, + MenuItem, + Select, + Stack, + Typography, +} from '@mui/material'; +import { Service, ServiceProvider, Services } from '../types/directory'; +import { useTauriEvents } from '../utils'; +import { ServiceProviderPopup } from './ServiceProviderPopup'; + +export const ServiceSelector: React.FC<{ + onChange?: (serviceProvider?: ServiceProvider) => void; + services?: Services; + currentSp?: ServiceProvider; +}> = ({ services, currentSp, onChange }) => { + const [service, setService] = React.useState(); + const [serviceProvider, setServiceProvider] = React.useState(currentSp); + const [isPopupVisible, setPopupVisible] = React.useState(false); + + const getService = () => { + if (!services || !currentSp) { + return undefined; + } + return services.find((s) => + s.items.some( + ({ id, address, gateway }) => + id === currentSp.id && address === currentSp.address && gateway === currentSp.gateway, + ), + ); + }; + + useEffect(() => { + if (!service && currentSp) { + setServiceProvider(currentSp); + setService(getService()); + } + }, [currentSp, services]); + + /** + * Gets a random service provider from the currently selected service. + * + * If there is no service selected, or it does not have items, `undefined` is returned. + */ + const getRandomServiceProviderForService = (serviceToUse?: Service): ServiceProvider | undefined => { + if (!serviceToUse?.items.length) { + return undefined; + } + return serviceToUse.items[Math.floor(Math.random() * serviceToUse.items.length)]; + }; + + const handleServiceSelected = React.useCallback( + (newService?: Service) => { + console.log(newService?.id, service?.id); + // if the user has chosen a new service, then pick a random service provider + if (newService?.id !== service?.id) { + const newServiceProvider = getRandomServiceProviderForService(newService); + setServiceProvider(newServiceProvider); + onChange?.(newServiceProvider); + setService(newService); + } + }, + [service], + ); + + // clears the display and fire on change (to trigger upstream storage clearance) + const clearServiceProviderAndFireOnChange = () => { + setService(undefined); + setServiceProvider(undefined); + onChange?.(undefined); + }; + + // when the user clears local storage, reset the selector + useTauriEvents('help://clear-storage', () => { + clearServiceProviderAndFireOnChange(); + }); + + const handleAdvancedSpChange = (newServiceProvider?: ServiceProvider, newService?: Service) => { + setPopupVisible(false); + setService(newService); + setServiceProvider(newServiceProvider); + onChange?.(newServiceProvider); + }; + + const handleNewService = (newServiceId?: string) => { + const newService = (services || []).find((s) => s.id === newServiceId); + setService(newService); + }; + + if (!services) { + return ( + + theme.palette.common.white}> + + Loading services... + + + ); + } + + return ( + + + + Select a service + + + + setPopupVisible(false)} + onServiceProviderChanged={handleAdvancedSpChange} + /> + + ); +}; diff --git a/nym-connect/src/context/main.tsx b/nym-connect/src/context/main.tsx index 5d2b049bf9..945952f2ef 100644 --- a/nym-connect/src/context/main.tsx +++ b/nym-connect/src/context/main.tsx @@ -4,11 +4,12 @@ import { invoke } from '@tauri-apps/api'; import type { UnlistenFn } from '@tauri-apps/api/event'; import { listen } from '@tauri-apps/api/event'; import { forage } from '@tauri-apps/tauri-forage'; +import { Error } from 'src/types/error'; +import { TauriEvent } from 'src/types/event'; +import { getVersion } from '@tauri-apps/api/app'; import { ConnectionStatusKind } from '../types'; import { ConnectionStatsItem } from '../components/ConnectionStats'; import { ServiceProvider, Services } from '../types/directory'; -import { Error } from 'src/types/error'; -import { TauriEvent } from 'src/types/event'; const TAURI_EVENT_STATUS_CHANGED = 'app:connection-status-changed'; @@ -16,6 +17,7 @@ type ModeType = 'light' | 'dark'; export type TClientContext = { mode: ModeType; + appVersion?: string; connectionStatus: ConnectionStatusKind; connectionStats?: ConnectionStatsItem[]; connectedSince?: DateTime; @@ -30,7 +32,7 @@ export type TClientContext = { setConnectionStatus: (connectionStatus: ConnectionStatusKind) => void; setConnectionStats: (connectionStats: ConnectionStatsItem[] | undefined) => void; setConnectedSince: (connectedSince: DateTime | undefined) => void; - setServiceProvider: (serviceProvider: ServiceProvider) => void; + setServiceProvider: (serviceProvider?: ServiceProvider) => void; startConnecting: () => Promise; startDisconnecting: () => Promise; @@ -47,11 +49,26 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode const [serviceProvider, setRawServiceProvider] = React.useState(); const [showHelp, setShowHelp] = useState(false); const [error, setError] = useState(); + const [appVersion, setAppVersion] = useState(); + + const getAppVersion = async () => { + const version = await getVersion(); + setAppVersion(version); + }; useEffect(() => { invoke('get_services').then((result) => { setServices(result as Services); }); + getAppVersion(); + }, []); + + useEffect(() => { + // when mounting, load the connection state (needed for the Growth window, that checks the connection state) + (async () => { + const currentStatus: ConnectionStatusKind = await invoke('get_connection_status'); + setConnectionStatus(currentStatus); + })(); }, []); useEffect(() => { @@ -103,10 +120,12 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode } as any)(); }; - const setServiceProvider = useCallback(async (newServiceProvider: ServiceProvider) => { - await invoke('set_gateway', { gateway: newServiceProvider.gateway }); - await invoke('set_service_provider', { serviceProvider: newServiceProvider.address }); - await setSpInStorage(newServiceProvider); + const setServiceProvider = useCallback(async (newServiceProvider?: ServiceProvider) => { + await invoke('set_gateway', { gateway: newServiceProvider?.gateway }); + await invoke('set_service_provider', { serviceProvider: newServiceProvider?.address }); + if (newServiceProvider) { + await setSpInStorage(newServiceProvider); + } setRawServiceProvider(newServiceProvider); }, []); @@ -149,6 +168,7 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode const contextValue = useMemo( () => ({ mode, + appVersion, setMode, error, clearError, @@ -167,6 +187,7 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode handleShowHelp, }), [ + appVersion, mode, error, connectedSince, diff --git a/nym-connect/src/context/mocks/main.tsx b/nym-connect/src/context/mocks/main.tsx index e2974413eb..9b09b6dc71 100644 --- a/nym-connect/src/context/mocks/main.tsx +++ b/nym-connect/src/context/mocks/main.tsx @@ -3,6 +3,7 @@ import { ConnectionStatusKind } from 'src/types'; import { ClientContext, TClientContext } from '../main'; const mockValues: TClientContext = { + appVersion: 'v1.x.x', mode: 'dark', connectionStatus: ConnectionStatusKind.disconnected, services: [], @@ -19,6 +20,9 @@ const mockValues: TClientContext = { startDisconnecting: async () => {}, }; -export const MockProvider = ({ children }: { children: React.ReactNode }) => { - return {children}; -}; +export const MockProvider: React.FC<{ + children?: React.ReactNode; + connectionStatus?: ConnectionStatusKind; +}> = ({ connectionStatus = ConnectionStatusKind.disconnected, children }) => ( + {children} +); diff --git a/nym-connect/src/growth.tsx b/nym-connect/src/growth.tsx new file mode 100644 index 0000000000..d90a8bb462 --- /dev/null +++ b/nym-connect/src/growth.tsx @@ -0,0 +1,23 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import { ErrorBoundary } from 'react-error-boundary'; +import { ClientContextProvider } from './context/main'; +import { ErrorFallback } from './components/Error'; +import { NymShipyardTheme } from './theme'; +import { TestAndEarnPopup } from './components/Growth/TestAndEarnPopup'; +import { TestAndEarnContextProvider } from './components/Growth/context/TestAndEarnContext'; + +const root = document.getElementById('root-growth'); + +ReactDOM.render( + + + + + + + + + , + root, +); diff --git a/nym-connect/src/index.tsx b/nym-connect/src/index.tsx index 66a3e11d17..bd41e06822 100644 --- a/nym-connect/src/index.tsx +++ b/nym-connect/src/index.tsx @@ -6,17 +6,20 @@ import { ErrorFallback } from './components/Error'; import { NymMixnetTheme } from './theme'; import { App } from './App'; import { AppWindowFrame } from './components/AppWindowFrame'; +import { TestAndEarnContextProvider } from './components/Growth/context/TestAndEarnContext'; const root = document.getElementById('root'); ReactDOM.render( - - - - - + + + + + + + , root, diff --git a/nym-connect/src/layouts/ConnectedLayout.tsx b/nym-connect/src/layouts/ConnectedLayout.tsx index 8e34415b39..0bf61fd4c0 100644 --- a/nym-connect/src/layouts/ConnectedLayout.tsx +++ b/nym-connect/src/layouts/ConnectedLayout.tsx @@ -9,6 +9,7 @@ import { ConnectionStatsItem } from '../components/ConnectionStats'; import { ConnectionButton } from '../components/ConnectionButton'; import { IpAddressAndPort } from '../components/IpAddressAndPort'; import { ServiceProvider } from '../types/directory'; +import { TestAndEarnButtonArea } from '../components/Growth/TestAndEarnButtonArea'; export const ConnectedLayout: React.FC<{ status: ConnectionStatusKind; @@ -44,5 +45,6 @@ export const ConnectedLayout: React.FC<{ {/* */} + ); diff --git a/nym-connect/src/layouts/DefaultLayout.tsx b/nym-connect/src/layouts/DefaultLayout.tsx index ed42aad5fe..5c414a5bc1 100644 --- a/nym-connect/src/layouts/DefaultLayout.tsx +++ b/nym-connect/src/layouts/DefaultLayout.tsx @@ -1,15 +1,16 @@ import React from 'react'; -import { Typography } from '@mui/material'; -import { Box } from '@mui/material'; +import { Box, Typography } from '@mui/material'; import { ConnectionStatus } from 'src/components/ConnectionStatus'; import { ConnectionTimer } from 'src/components/ConntectionTimer'; import { InfoModal } from 'src/components/InfoModal'; import { Error } from 'src/types/error'; import { ConnectionButton } from '../components/ConnectionButton'; -import { ServiceProviderSelector } from '../components/ServiceProviderSelector'; +import { ServiceSelector } from '../components/ServiceSelector'; import { useClientContext } from '../context/main'; import { ConnectionStatusKind } from '../types'; -import { ServiceProvider, Services } from '../types/directory'; +import { Services } from '../types/directory'; +import { TestAndEarnButtonArea } from '../components/Growth/TestAndEarnButtonArea'; +import { AppVersion } from '../components/AppVersion'; export const DefaultLayout: React.FC<{ error?: Error; @@ -19,30 +20,32 @@ export const DefaultLayout: React.FC<{ isError?: boolean; clearError: () => void; onConnectClick?: (status: ConnectionStatusKind) => void; - onServiceProviderChange?: (serviceProvider: ServiceProvider) => void; -}> = ({ status, error, services, busy, isError, onConnectClick, onServiceProviderChange, clearError }) => { - const handleServiceProviderChange = (newServiceProvider: ServiceProvider) => { - onServiceProviderChange?.(newServiceProvider); - }; - - const { serviceProvider: currentSp } = useClientContext(); +}> = ({ status, error, services, busy, isError, onConnectClick, clearError }) => { + const context = useClientContext(); return ( {error && } - - Connect to the Nym
    mixnet for privacy. -
    - + + + Connect to the Nym
    mixnet for privacy. +
    + + This is experimental software. Do not rely on it for strong anonymity (yet). + +
    + + +
    ); }; diff --git a/nym-connect/src/log.tsx b/nym-connect/src/log.tsx new file mode 100644 index 0000000000..cd17271368 --- /dev/null +++ b/nym-connect/src/log.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import { ErrorBoundary } from 'react-error-boundary'; +import { LogViewer } from './components/LogViewer'; +import { ErrorFallback } from './components/ErrorFallback'; +import { NymMixnetTheme } from './theme'; + +const Log = () => ( + + + + + +); + +const root = document.getElementById('root-log'); + +ReactDOM.render(, root); diff --git a/nym-connect/src/stories/AppFlow.stories.tsx b/nym-connect/src/stories/AppFlow.stories.tsx index 34064e6202..7055288f63 100644 --- a/nym-connect/src/stories/AppFlow.stories.tsx +++ b/nym-connect/src/stories/AppFlow.stories.tsx @@ -8,12 +8,16 @@ import { ConnectionStatusKind } from '../types'; import { DefaultLayout } from '../layouts/DefaultLayout'; import { ConnectedLayout } from '../layouts/ConnectedLayout'; import { Services } from '../types/directory'; +import { TestAndEarnButtonArea } from '../components/Growth/TestAndEarnButtonArea'; export default { title: 'App/Flow', component: AppWindowFrame, } as ComponentMeta; +const width = 240; +const height = 575; + export const Mock: ComponentStory = () => { const context = useClientContext(); const [busy, setBusy] = React.useState(); @@ -67,45 +71,47 @@ export const Mock: ComponentStory = () => { context.connectionStatus === ConnectionStatusKind.connecting ) { return ( - - {}} - /> - + + + {}} + /> + + ); } return ( - - { - return undefined; - }} - status={context.connectionStatus} - busy={busy} - onConnectClick={handleConnectClick} - ipAddress="127.0.0.1" - port={1080} - connectedSince={context.connectedSince} - serviceProvider={services[0].items[0]} - stats={[ - { - label: 'in:', - totalBytes: 1024, - rateBytesPerSecond: 1024 * 1024 * 1024 + 10, - }, - { - label: 'out:', - totalBytes: 1024 * 1024 * 1024 * 1024 * 20, - rateBytesPerSecond: 1024 * 1024 + 10, - }, - ]} - /> - + + + undefined} + status={context.connectionStatus} + busy={busy} + onConnectClick={handleConnectClick} + ipAddress="127.0.0.1" + port={1080} + connectedSince={context.connectedSince} + serviceProvider={services[0].items[0]} + stats={[ + { + label: 'in:', + totalBytes: 1024, + rateBytesPerSecond: 1024 * 1024 * 1024 + 10, + }, + { + label: 'out:', + totalBytes: 1024 * 1024 * 1024 * 1024 * 20, + rateBytesPerSecond: 1024 * 1024 + 10, + }, + ]} + /> + + ); }; diff --git a/nym-connect/src/theme/index.tsx b/nym-connect/src/theme/index.tsx index 075aa7920a..08f5c62924 100644 --- a/nym-connect/src/theme/index.tsx +++ b/nym-connect/src/theme/index.tsx @@ -1,8 +1,7 @@ -import React, { useContext } from 'react'; +import React from 'react'; import { createTheme, ThemeProvider } from '@mui/material/styles'; import { CssBaseline } from '@mui/material'; import { getDesignTokens } from './theme'; -import { ClientContext } from '../context/main'; import '../../../assets/fonts/non-variable/fonts.css'; /** @@ -17,3 +16,13 @@ export const NymMixnetTheme: React.FC<{ mode: 'light' | 'dark' }> = ({ children, ); }; + +export const NymShipyardTheme: React.FC<{ mode?: 'light' | 'dark' }> = ({ children, mode = 'dark' }) => { + const theme = React.useMemo(() => createTheme(getDesignTokens(mode, true)), [mode]); + return ( + + + {children} + + ); +}; diff --git a/nym-connect/src/theme/mui-theme.d.ts b/nym-connect/src/theme/mui-theme.d.ts index ef042f6305..6c4d88fe39 100644 --- a/nym-connect/src/theme/mui-theme.d.ts +++ b/nym-connect/src/theme/mui-theme.d.ts @@ -38,6 +38,7 @@ declare module '@mui/material/styles' { light: string; dark: string; }; + shipyard: string; } interface NymPaletteVariant { @@ -52,6 +53,9 @@ declare module '@mui/material/styles' { topNav: { background: string; }; + shipyard: { + main: string; + }; } /** diff --git a/nym-connect/src/theme/theme.tsx b/nym-connect/src/theme/theme.tsx index 5b70f5118b..a580ae0b4e 100644 --- a/nym-connect/src/theme/theme.tsx +++ b/nym-connect/src/theme/theme.tsx @@ -30,6 +30,7 @@ const nymPalette: NymPalette = { light: '#F2F2F2', dark: '#1D2125', }, + shipyard: '#817FFA', }; const darkMode: NymPaletteVariant = { @@ -44,6 +45,9 @@ const darkMode: NymPaletteVariant = { topNav: { background: '#111826', }, + shipyard: { + main: '#817FFA', + }, }; const lightMode: NymPaletteVariant = { @@ -58,6 +62,9 @@ const lightMode: NymPaletteVariant = { topNav: { background: '#111826', }, + shipyard: { + main: '#817FFA', + }, }; /** @@ -103,6 +110,35 @@ const variantToMUIPalette = (variant: NymPaletteVariant): PaletteOptions => ({ }, }); +/** + * Map a Nym palette variant onto the MUI palette for Shipyard + */ +const variantShipyardToMUIPalette = (variant: NymPaletteVariant): PaletteOptions => ({ + text: { + primary: variant.text.main, + }, + primary: { + main: nymPalette.shipyard, + contrastText: '#fff', + }, + secondary: { + main: variant.mode === 'dark' ? nymPalette.background.light : nymPalette.background.dark, + }, + success: { + main: nymPalette.success, + }, + info: { + main: nymPalette.info, + }, + warning: { + main: nymPalette.warning, + }, + background: { + default: variant.background.main, + paper: variant.background.paper, + }, +}); + /** * Returns the Network Explorer palette for light mode. */ @@ -125,6 +161,17 @@ const createDarkModePalette = (): PaletteOptions => ({ ...variantToMUIPalette(darkMode), }); +/** + * Returns the Shipyard palette for dark mode. + */ +const createShipyardDarkModePalette = (): PaletteOptions => ({ + nym: { + ...nymPalette, + ...nymMixnetPalette(darkMode), + }, + ...variantShipyardToMUIPalette(darkMode), +}); + /** * IMPORANT: if you need to get the default MUI theme, use the following * @@ -157,12 +204,19 @@ const createDarkModePalette = (): PaletteOptions => ({ * * @param mode The theme mode: 'light' or 'dark' */ -export const getDesignTokens = (mode: PaletteMode): ThemeOptions => { - // first, create the palette from user's choice of light or dark mode +export const getDesignTokens = (mode: PaletteMode, isShipyard: boolean = false): ThemeOptions => { + let overrides; + if (isShipyard) { + overrides = createShipyardDarkModePalette(); + } else { + overrides = mode === 'light' ? createLightModePalette() : createDarkModePalette(); + } + + // create the palette from user's choice of light or dark mode const { palette } = createTheme({ palette: { mode, - ...(mode === 'light' ? createLightModePalette() : createDarkModePalette()), + ...overrides, }, }); diff --git a/nym-connect/src/typings/webp.d.ts b/nym-connect/src/typings/webp.d.ts new file mode 100644 index 0000000000..d594a17f53 --- /dev/null +++ b/nym-connect/src/typings/webp.d.ts @@ -0,0 +1,4 @@ +declare module '*.webp' { + const value: any; + export default value; +} diff --git a/nym-connect/src/typings/yaml.d.ts b/nym-connect/src/typings/yaml.d.ts new file mode 100644 index 0000000000..4c36d21ec0 --- /dev/null +++ b/nym-connect/src/typings/yaml.d.ts @@ -0,0 +1,9 @@ +declare module '*.yml' { + const content: { [key: string]: any }; + export default content; +} + +declare module '*.yaml' { + const content: { [key: string]: any }; + export default content; +} diff --git a/nym-connect/src/utils/index.ts b/nym-connect/src/utils/index.ts index 70b786d12e..9dc9fd09e3 100644 --- a/nym-connect/src/utils/index.ts +++ b/nym-connect/src/utils/index.ts @@ -1 +1,19 @@ -// TODO +import { useEffect, useRef } from 'react'; +import { EventName, listen, UnlistenFn, EventCallback } from '@tauri-apps/api/event'; + +export const useTauriEvents = (event: EventName, handler: EventCallback) => { + const unlisten = useRef(); + + // list for events to clear local storage + useEffect(() => { + listen(event, handler).then((fn) => { + unlisten.current = fn; + }); + + return () => { + if (unlisten.current) { + unlisten.current(); + } + }; + }, []); +}; diff --git a/nym-connect/webpack.common.js b/nym-connect/webpack.common.js index 0e6b071aaa..38423b5e6b 100644 --- a/nym-connect/webpack.common.js +++ b/nym-connect/webpack.common.js @@ -2,6 +2,12 @@ const path = require('path'); const { mergeWithRules } = require('webpack-merge'); const { webpackCommon } = require('@nymproject/webpack'); +const entry = { + app: path.resolve(__dirname, 'src/index.tsx'), + growth: path.resolve(__dirname, 'src/growth.tsx'), + log: path.resolve(__dirname, 'src/log.tsx'), +}; + module.exports = mergeWithRules({ module: { rules: { @@ -9,10 +15,45 @@ module.exports = mergeWithRules({ use: 'replace', }, }, -})(webpackCommon(__dirname, 'public/index.html'), { - entry: path.resolve(__dirname, 'src/index.tsx'), - output: { - path: path.resolve(__dirname, 'dist'), - publicPath: '/', +})( + webpackCommon(__dirname, [ + { filename: 'index.html', chunks: ['app'], template: path.resolve(__dirname, 'public/index.html') }, + { filename: 'log.html', chunks: ['log'], template: path.resolve(__dirname, 'public/log.html') }, + { filename: 'growth.html', chunks: ['growth'], template: path.resolve(__dirname, 'public/growth.html') }, + ]), + { + module: { + rules: [ + { + test: /\.mdx?$/, + use: [ + { + loader: '@mdx-js/loader', + /** @type {import('@mdx-js/loader').Options} */ + options: {}, + }, + ], + }, + { + test: /\.ya?ml$/, + type: 'asset/resource', + use: [ + { + loader: 'yaml-loader', + options: { + asJSON: true, + }, + }, + ], + }, + ], + }, + entry, + output: { + clean: true, + path: path.resolve(__dirname, 'dist'), + filename: '[name].bundle.js', + publicPath: '/', + }, }, -}); +); diff --git a/nym-connect/webpack.prod.js b/nym-connect/webpack.prod.js index 40e7bc95d7..0e9061e25a 100644 --- a/nym-connect/webpack.prod.js +++ b/nym-connect/webpack.prod.js @@ -2,10 +2,16 @@ const path = require('path'); const { default: merge } = require('webpack-merge'); const common = require('./webpack.common'); +const entry = { + app: path.resolve(__dirname, 'src/index.tsx'), + growth: path.resolve(__dirname, 'src/growth.tsx'), + log: path.resolve(__dirname, 'src/log.tsx'), +}; + module.exports = merge(common, { mode: 'production', node: { __dirname: false, }, - entry: path.resolve(__dirname, './src/index'), + entry, }); diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 3b99531457..41db8105db 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -14,12 +14,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "adler32" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" - [[package]] name = "aead" version = "0.4.3" @@ -153,20 +147,18 @@ dependencies = [ [[package]] name = "attohttpc" -version = "0.19.1" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "262c3f7f5d61249d8c00e5546e2685cd15ebeeb1bc0f3cc5449350a1cb07319e" +checksum = "1fcf00bc6d5abb29b5f97e3c61a90b6d3caa12f3faf897d4a3e3607c050a35a7" dependencies = [ "flate2", "http", "log", "native-tls", - "openssl", "serde", "serde_json", "serde_urlencoded", "url", - "wildmatch", ] [[package]] @@ -438,12 +430,11 @@ dependencies = [ [[package]] name = "cargo_toml" -version = "0.11.4" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e270ef0cd868745878982f7ce470aa898d0d4bb248af67f0cf66f54617913ef" +checksum = "aa0e3586af56b3bfa51fca452bd56e8dbbbd5d8d81cbf0b7e4e35b695b537eb8" dependencies = [ "serde", - "serde_derive", "toml", ] @@ -1076,16 +1067,6 @@ dependencies = [ "syn", ] -[[package]] -name = "deflate" -version = "0.7.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4" -dependencies = [ - "adler32", - "byteorder", -] - [[package]] name = "der" version = "0.5.1" @@ -1226,6 +1207,12 @@ dependencies = [ "dtoa", ] +[[package]] +name = "dunce" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bd4b30a6560bbd9b4620f4de34c3f14f60848e58a9b7216801afcb4c7b31c3c" + [[package]] name = "dyn-clone" version = "1.0.4" @@ -1304,19 +1291,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "embed-resource" -version = "1.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936c1354206a875581696369aef920e12396e93bbd251c43a7a3f3fa85023a7d" -dependencies = [ - "cc", - "rustc_version 0.4.0", - "toml", - "vswhom", - "winreg 0.10.1", -] - [[package]] name = "embed_plist" version = "1.2.2" @@ -1325,9 +1299,9 @@ checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" [[package]] name = "encoding_rs" -version = "0.8.30" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dc8abb250ffdda33912550faa54c88ec8b998dec0b2c55ab224921ce11df" +checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" dependencies = [ "cfg-if", ] @@ -1569,21 +1543,6 @@ version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" -[[package]] -name = "futures-lite" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - [[package]] name = "futures-macro" version = "0.3.21" @@ -2234,12 +2193,12 @@ dependencies = [ [[package]] name = "ico" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a4b3331534254a9b64095ae60d3dc2a8225a7a70229cd5888be127cdc1f6804" +checksum = "031530fe562d8c8d71c0635013d6d155bbfe8ba0aa4b4d2d24ce8af6b71047bd" dependencies = [ "byteorder", - "png 0.11.0", + "png", ] [[package]] @@ -2316,15 +2275,6 @@ dependencies = [ "cfb", ] -[[package]] -name = "inflate" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5f9f47468e9a76a6452271efadc88fe865a82be91fe75e6c0c57b87ccea59d4" -dependencies = [ - "adler32", -] - [[package]] name = "instant" version = "0.1.12" @@ -2386,23 +2336,9 @@ dependencies = [ [[package]] name = "jni" -version = "0.18.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24967112a1e4301ca5342ea339763613a37592b8a6ce6cf2e4494537c7a42faf" -dependencies = [ - "cesu8", - "combine", - "jni-sys", - "log", - "thiserror", - "walkdir", -] - -[[package]] -name = "jni" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec" +checksum = "039022cdf4d7b1cf548d31f60ae783138e5fd42013f6271049d7df7afadef96c" dependencies = [ "cesu8", "combine", @@ -2803,17 +2739,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-iter" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" -dependencies = [ - "autocfg 1.1.0", - "num-integer", - "num-traits", -] - [[package]] name = "num-rational" version = "0.4.1" @@ -3047,9 +2972,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.14.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" [[package]] name = "opaque-debug" @@ -3146,12 +3071,6 @@ dependencies = [ "system-deps 6.0.2", ] -[[package]] -name = "parking" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" - [[package]] name = "parking_lot" version = "0.11.2" @@ -3290,9 +3209,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pest" @@ -3498,18 +3417,6 @@ dependencies = [ "xml-rs", ] -[[package]] -name = "png" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0b0cabbbd20c2d7f06dbf015e06aad59b6ca3d9ed14848783e98af9aaf19925" -dependencies = [ - "bitflags", - "deflate", - "inflate", - "num-iter", -] - [[package]] name = "png" version = "0.17.6" @@ -3598,11 +3505,11 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] @@ -3854,9 +3761,9 @@ dependencies = [ [[package]] name = "raw-window-handle" -version = "0.4.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b800beb9b6e7d2df1fe337c9e3d04e3af22a124460fb4c30fcc22c9117cefb41" +checksum = "ed7e3d950b66e19e0c372f3fa3fbbcf85b1746b571f74e0c2af6042a5c93420a" dependencies = [ "cty", ] @@ -3891,9 +3798,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" dependencies = [ "aho-corasick", "memchr", @@ -3957,7 +3864,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg 0.7.0", + "winreg", ] [[package]] @@ -3973,13 +3880,12 @@ dependencies = [ [[package]] name = "rfd" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f121348fd3b9035ed11be1f028e8944263c30641f8c5deacf57a4320782fb402" +checksum = "0149778bd99b6959285b0933288206090c50e2327f47a9c463bfdbf45c8823ea" dependencies = [ "block", "dispatch", - "embed-resource", "glib-sys", "gobject-sys", "gtk-sys", @@ -3993,7 +3899,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "windows", + "windows 0.37.0", ] [[package]] @@ -4234,9 +4140,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.136" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" dependencies = [ "serde_derive", ] @@ -4261,9 +4167,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.136" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" dependencies = [ "proc-macro2", "quote", @@ -4630,13 +4536,13 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.86" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" +checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -4679,9 +4585,9 @@ dependencies = [ [[package]] name = "tao" -version = "0.12.2" +version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6fd7725dc1e593e9ecabd9fe49c112a204c8c8694db4182e78b2a5af490b1ae" +checksum = "a1fa15735311b4816d030ff54da58560b047daca0970e1031aed5502e84231a8" dependencies = [ "bitflags", "cairo-rs", @@ -4701,7 +4607,7 @@ dependencies = [ "gtk", "image", "instant", - "jni 0.19.0", + "jni", "lazy_static", "libc", "log", @@ -4712,13 +4618,13 @@ dependencies = [ "once_cell", "parking_lot 0.12.1", "paste", - "png 0.17.6", + "png", "raw-window-handle", "scopeguard", "serde", "unicode-segmentation", - "uuid 1.1.2", - "windows", + "uuid 1.2.2", + "windows 0.39.0", "windows-implement", "x11-dl", ] @@ -4742,9 +4648,9 @@ dependencies = [ [[package]] name = "tauri" -version = "1.0.5" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1a56a8b125069c2682bd31610109b4436c050c74447bee1078217a0325c1add" +checksum = "d8ea1d785ab2164373703817bff144c4610a69ad3f659becaca0e1ea004b98d8" dependencies = [ "anyhow", "attohttpc", @@ -4752,9 +4658,9 @@ dependencies = [ "cocoa", "dirs-next", "embed_plist", + "encoding_rs", "flate2", - "futures", - "futures-lite", + "futures-util", "glib", "glob", "gtk", @@ -4786,18 +4692,18 @@ dependencies = [ "time 0.3.7", "tokio", "url", - "uuid 1.1.2", + "uuid 1.2.2", "webkit2gtk", "webview2-com", - "windows", + "windows 0.39.0", "zip", ] [[package]] name = "tauri-build" -version = "1.0.4" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acafb1c515c5d14234a294461bd43c723639a84891a45f6a250fd3441ad2e8ed" +checksum = "8807c85d656b2b93927c19fe5a5f1f1f348f96c2de8b90763b3c2d561511f9b4" dependencies = [ "anyhow", "cargo_toml", @@ -4811,16 +4717,16 @@ dependencies = [ [[package]] name = "tauri-codegen" -version = "1.0.4" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16d62a3c8790d6cba686cea6e3f7f569d12c662c3274c2d165a4fd33e3871b72" +checksum = "14388d484b6b1b5dc0f6a7d6cc6433b3b230bec85eaa576adcdf3f9fafa49251" dependencies = [ "base64", "brotli", "ico", "json-patch", "plist", - "png 0.17.6", + "png", "proc-macro2", "quote", "regex", @@ -4831,15 +4737,15 @@ dependencies = [ "tauri-utils", "thiserror", "time 0.3.7", - "uuid 1.1.2", + "uuid 1.2.2", "walkdir", ] [[package]] name = "tauri-macros" -version = "1.0.4" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7296fa17996629f43081e1c66d554703900187ed900c5bf46f97f0bcfb069278" +checksum = "069319e5ecbe653a799b94b0690d9f9bf5d00f7b1d3989aa331c524d4e354075" dependencies = [ "heck 0.4.0", "proc-macro2", @@ -4851,29 +4757,29 @@ dependencies = [ [[package]] name = "tauri-runtime" -version = "0.10.2" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4cff3b4d9469727fa2107c4b3d2eda110df1ba45103fb420178e536362fae4" +checksum = "c507d954d08ac8705d235bc70ec6975b9054fb95ff7823af72dbb04186596f3b" dependencies = [ "gtk", "http", "http-range", - "infer", + "rand 0.8.5", "raw-window-handle", "serde", "serde_json", "tauri-utils", "thiserror", - "uuid 1.1.2", + "uuid 1.2.2", "webview2-com", - "windows", + "windows 0.39.0", ] [[package]] name = "tauri-runtime-wry" -version = "0.10.2" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fa8c4edaf01d8b556e7172c844b1b4dd3399adcd1a606bd520fc3e65f698546" +checksum = "36b1c5764a41a13176a4599b5b7bd0881bea7d94dfe45e1e755f789b98317e30" dependencies = [ "cocoa", "gtk", @@ -4882,24 +4788,25 @@ dependencies = [ "raw-window-handle", "tauri-runtime", "tauri-utils", - "uuid 1.1.2", + "uuid 1.2.2", "webkit2gtk", "webview2-com", - "windows", + "windows 0.39.0", "wry", ] [[package]] name = "tauri-utils" -version = "1.0.3" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12ff4b68d9faeb57c9c727bf58c9c9768d2b67d8e84e62ce6146e7859a2e9c6b" +checksum = "5abbc109a6eb45127956ffcc26ef0e875d160150ac16cfa45d26a6b2871686f1" dependencies = [ "brotli", "ctor", "glob", "heck 0.4.0", "html5ever", + "infer", "json-patch", "kuchiki", "memchr", @@ -4913,7 +4820,7 @@ dependencies = [ "thiserror", "url", "walkdir", - "windows", + "windows 0.39.0", ] [[package]] @@ -5326,6 +5233,12 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" + [[package]] name = "unicode-normalization" version = "0.1.9" @@ -5337,9 +5250,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" +checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" [[package]] name = "unicode-xid" @@ -5365,13 +5278,12 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.2.2" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +checksum = "22fe195a4f217c25b25cb5058ced57059824a678474874038dc88d211bf508d3" dependencies = [ "form_urlencoded", "idna", - "matches", "percent-encoding", "serde", ] @@ -5390,9 +5302,9 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" [[package]] name = "uuid" -version = "1.1.2" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd6469f4314d5f1ffec476e05f17cc9a78bc7a27a6a857842170bdf8d6f98d2f" +checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" dependencies = [ "getrandom 0.2.5", ] @@ -5521,32 +5433,6 @@ dependencies = [ "serde", ] -[[package]] -name = "vswhom" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b" -dependencies = [ - "libc", - "vswhom-sys", -] - -[[package]] -name = "vswhom-sys" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22025f6d8eb903ebf920ea6933b70b1e495be37e2cb4099e62c80454aaf57c39" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "waker-fn" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" - [[package]] name = "walkdir" version = "2.3.2" @@ -5664,9 +5550,9 @@ dependencies = [ [[package]] name = "webkit2gtk" -version = "0.18.0" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29952969fb5e10fe834a52eb29ad0814ccdfd8387159b0933edf1344a1c9cdcc" +checksum = "b8f859735e4a452aeb28c6c56a852967a8a76c8eb1cc32dbf931ad28a13d6370" dependencies = [ "bitflags", "cairo-rs", @@ -5730,13 +5616,13 @@ dependencies = [ [[package]] name = "webview2-com" -version = "0.16.0" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a489a9420acabb3c2ed0434b6f71f6b56b9485ec32665a28dec1ee186d716e0f" +checksum = "b4a769c9f1a64a8734bde70caafac2b96cada12cd4aefa49196b3a386b8b4178" dependencies = [ "webview2-com-macros", "webview2-com-sys", - "windows", + "windows 0.39.0", "windows-implement", ] @@ -5753,24 +5639,19 @@ dependencies = [ [[package]] name = "webview2-com-sys" -version = "0.16.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0258c53ee9adc0a4f8ba1c8c317588f7a58c7048a55b621d469ba75ab3709ca1" +checksum = "aac48ef20ddf657755fdcda8dfed2a7b4fc7e4581acce6fe9b88c3d64f29dee7" dependencies = [ "regex", "serde", "serde_json", "thiserror", - "windows", + "windows 0.39.0", "windows-bindgen", + "windows-metadata", ] -[[package]] -name = "wildmatch" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6c48bd20df7e4ced539c12f570f937c6b4884928a87fee70a479d72f031d4e0" - [[package]] name = "winapi" version = "0.3.9" @@ -5808,7 +5689,6 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57b543186b344cc61c85b5aab0d2e3adf4e0f99bc076eff9aa5927bcc0b8a647" dependencies = [ - "windows-implement", "windows_aarch64_msvc 0.37.0", "windows_i686_gnu 0.37.0", "windows_i686_msvc 0.37.0", @@ -5817,10 +5697,24 @@ dependencies = [ ] [[package]] -name = "windows-bindgen" -version = "0.37.0" +name = "windows" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bed7be31ade0af08fec9b5343e9edcc005d22b1f11859b8a59b24797f5858e8" +checksum = "f1c4bd0a50ac6020f65184721f758dba47bb9fbc2133df715ec74a237b26794a" +dependencies = [ + "windows-implement", + "windows_aarch64_msvc 0.39.0", + "windows_i686_gnu 0.39.0", + "windows_i686_msvc 0.39.0", + "windows_x86_64_gnu 0.39.0", + "windows_x86_64_msvc 0.39.0", +] + +[[package]] +name = "windows-bindgen" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68003dbd0e38abc0fb85b939240f4bce37c43a5981d3df37ccbaaa981b47cb41" dependencies = [ "windows-metadata", "windows-tokens", @@ -5828,9 +5722,9 @@ dependencies = [ [[package]] name = "windows-implement" -version = "0.37.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a1062e555f7d9d66fd1130ed4f7c6ec41a47529ee0850cd0e926d95b26bb14" +checksum = "ba01f98f509cb5dc05f4e5fc95e535f78260f15fea8fe1a8abdd08f774f1cee7" dependencies = [ "syn", "windows-tokens", @@ -5838,9 +5732,9 @@ dependencies = [ [[package]] name = "windows-metadata" -version = "0.37.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f33f2b90a6664e369c41ab5ff262d06f048fc9685d9bf8a0e99a47750bb0463" +checksum = "9ee5e275231f07c6e240d14f34e1b635bf1faa1c76c57cfd59a5cdb9848e4278" [[package]] name = "windows-sys" @@ -5857,9 +5751,9 @@ dependencies = [ [[package]] name = "windows-tokens" -version = "0.37.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3263d25f1170419995b78ff10c06b949e8a986c35c208dc24333c64753a87169" +checksum = "f838de2fe15fe6bac988e74b798f26499a8b21a9d97edec321e79b28d1d7f597" [[package]] name = "windows_aarch64_msvc" @@ -5873,6 +5767,12 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2623277cb2d1c216ba3b578c0f3cf9cdebeddb6e66b1b218bb33596ea7769c3a" +[[package]] +name = "windows_aarch64_msvc" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec7711666096bd4096ffa835238905bb33fb87267910e154b18b44eaabb340f2" + [[package]] name = "windows_i686_gnu" version = "0.36.1" @@ -5885,6 +5785,12 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3925fd0b0b804730d44d4b6278c50f9699703ec49bcd628020f46f4ba07d9e1" +[[package]] +name = "windows_i686_gnu" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "763fc57100a5f7042e3057e7e8d9bdd7860d330070251a73d003563a3bb49e1b" + [[package]] name = "windows_i686_msvc" version = "0.36.1" @@ -5897,6 +5803,12 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce907ac74fe331b524c1298683efbf598bb031bc84d5e274db2083696d07c57c" +[[package]] +name = "windows_i686_msvc" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bc7cbfe58828921e10a9f446fcaaf649204dcfe6c1ddd712c5eebae6bda1106" + [[package]] name = "windows_x86_64_gnu" version = "0.36.1" @@ -5909,6 +5821,12 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2babfba0828f2e6b32457d5341427dcbb577ceef556273229959ac23a10af33d" +[[package]] +name = "windows_x86_64_gnu" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6868c165637d653ae1e8dc4d82c25d4f97dd6605eaa8d784b5c6e0ab2a252b65" + [[package]] name = "windows_x86_64_msvc" version = "0.36.1" @@ -5921,6 +5839,12 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4dd6dc7df2d84cf7b33822ed5b86318fb1781948e9663bacd047fc9dd52259d" +[[package]] +name = "windows_x86_64_msvc" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e4d40883ae9cae962787ca76ba76390ffa29214667a111db9e0a1ad8377e809" + [[package]] name = "winreg" version = "0.7.0" @@ -5930,15 +5854,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "winreg" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" -dependencies = [ - "winapi", -] - [[package]] name = "winres" version = "0.1.12" @@ -5950,19 +5865,23 @@ dependencies = [ [[package]] name = "wry" -version = "0.19.0" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce19dddbd3ce01dc8f14eb6d4c8f914123bf8379aaa838f6da4f981ff7104a3f" +checksum = "4c1ad8e2424f554cc5bdebe8aa374ef5b433feff817aebabca0389961fc7ef98" dependencies = [ + "base64", "block", "cocoa", "core-graphics", + "crossbeam-channel", + "dunce", "gdk", "gio", "glib", "gtk", + "html5ever", "http", - "jni 0.18.0", + "kuchiki", "libc", "log", "objc", @@ -5970,13 +5889,15 @@ dependencies = [ "once_cell", "serde", "serde_json", + "sha2 0.10.2", + "soup2", "tao", "thiserror", "url", "webkit2gtk", "webkit2gtk-sys", "webview2-com", - "windows", + "windows 0.39.0", "windows-implement", ] @@ -6001,9 +5922,9 @@ dependencies = [ [[package]] name = "x11-dl" -version = "2.19.1" +version = "2.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea26926b4ce81a6f5d9d0f3a0bc401e5a37c6ae14a1bfaa8ff6099ca80038c59" +checksum = "b1536d6965a5d4e573c7ef73a2c15ebcd0b2de3347bdf526c34c297c00ac40f0" dependencies = [ "lazy_static", "libc", diff --git a/nym-wallet/package.json b/nym-wallet/package.json index 26d58da9d1..a4cf864326 100644 --- a/nym-wallet/package.json +++ b/nym-wallet/package.json @@ -32,7 +32,7 @@ "@nymproject/react": "^1.0.0", "@nymproject/types": "^1.0.0", "@storybook/react": "^6.5.8", - "@tauri-apps/api": "^1.0.2", + "@tauri-apps/api": "^1.2.0", "@tauri-apps/tauri-forage": "^1.0.0-beta.2", "big.js": "^6.2.1", "bs58": "^4.0.1", diff --git a/nym-wallet/src-tauri/Cargo.toml b/nym-wallet/src-tauri/Cargo.toml index f166361e9e..dc390aec7c 100644 --- a/nym-wallet/src-tauri/Cargo.toml +++ b/nym-wallet/src-tauri/Cargo.toml @@ -13,10 +13,10 @@ rust-version = "1.58" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [build-dependencies] -tauri-build = { version = "=1.0.4", features = [] } +tauri-build = { version = "=1.2.1", features = [] } -tauri-codegen = "=1.0.4" -tauri-macros = "=1.0.4" +tauri-codegen = "=1.2.1" +tauri-macros = "=1.2.1" [dependencies] bip39 = "1.0" @@ -38,7 +38,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_repr = "0.1" strum = { version = "0.23", features = ["derive"] } -tauri = { version = "=1.0.5", features = ["clipboard-all", "shell-open", "updater", "window-maximize"] } +tauri = { version = "=1.2.2", features = ["clipboard-all", "shell-open", "updater", "window-maximize"] } tendermint-rpc = "0.23.0" thiserror = "1.0" tokio = { version = "1.10", features = ["full"] } diff --git a/ts-packages/react-components/package.json b/ts-packages/react-components/package.json index 5ccf942c02..24011b0149 100644 --- a/ts-packages/react-components/package.json +++ b/ts-packages/react-components/package.json @@ -28,7 +28,8 @@ "react-dom": "17", "@nymproject/nym-validator-client": "^0.18.0", "@nymproject/types": "1", - "base58": "4" + "base58": "4", + "bech32": "^1.1.4" }, "dependencies": { "flat": "^5.0.2", diff --git a/ts-packages/react-components/src/components/account/WalletAddressFormField.stories.tsx b/ts-packages/react-components/src/components/account/WalletAddressFormField.stories.tsx new file mode 100644 index 0000000000..af85590431 --- /dev/null +++ b/ts-packages/react-components/src/components/account/WalletAddressFormField.stories.tsx @@ -0,0 +1,42 @@ +import * as React from 'react'; +import { ComponentMeta } from '@storybook/react'; +import { Box } from '@mui/material'; +import { WalletAddressFormField } from './WalletAddressFormField'; + +export default { + title: 'Accounts/Wallet Address', + component: WalletAddressFormField, +} as ComponentMeta; + +export const Empty = () => ; + +export const ErrorValue = () => ; + +export const ValidValue = () => ; + +export const ReadOnlyValidValue = () => ( + +); + +export const ReadOnlyErrorValue = () => ; + +export const WithLabel = () => ( + + + +); + +export const WithPlaceholder = () => ( + +); + +export const FullWidth = () => ( + +); + +export const HideValidTick = () => ( + +); diff --git a/ts-packages/react-components/src/components/account/WalletAddressFormField.tsx b/ts-packages/react-components/src/components/account/WalletAddressFormField.tsx new file mode 100644 index 0000000000..147f7c8b99 --- /dev/null +++ b/ts-packages/react-components/src/components/account/WalletAddressFormField.tsx @@ -0,0 +1,105 @@ +import * as React from 'react'; +import { ChangeEvent } from 'react'; +import { InputAdornment, TextField } from '@mui/material'; +import { TextFieldProps } from '@mui/material/TextField/TextField'; +import { validateWalletAddress } from '@nymproject/types'; +import DoneIcon from '@mui/icons-material/Done'; +import { SxProps } from '@mui/system'; + +export const WalletAddressFormField: React.FC<{ + showTickOnValid?: boolean; + fullWidth?: boolean; + required?: boolean; + readOnly?: boolean; + initialValue?: string; + placeholder?: string; + label?: string; + helperText?: string; + onChanged?: (newValue: string) => void; + onValidate?: (isValid: boolean, error?: string) => void; + textFieldProps?: TextFieldProps; + errorText?: string; + sx?: SxProps; +}> = ({ + required, + fullWidth, + placeholder, + label, + readOnly, + initialValue, + errorText, + sx, + onChanged, + onValidate, + textFieldProps, + showTickOnValid = true, +}) => { + const [value, setValue] = React.useState(initialValue); + const [validationError, setValidationError] = React.useState(); + + const doValidation = (newValue?: string): boolean => { + if (validateWalletAddress(newValue)) { + setValidationError(undefined); + if (onValidate) { + onValidate(true); + } + return true; + } + + const newValidationError = 'Account address is not valid'; + setValidationError(newValidationError); + if (onValidate) { + onValidate(false, newValidationError); + } + + return false; + }; + + React.useEffect(() => { + // validate initial value (only if set), so that validation error UI hints are set without the user typing + if (initialValue) { + doValidation(initialValue); + } + + if (errorText) { + setValidationError(errorText); + } + }, [initialValue, errorText]); + + const handleChange = (event: ChangeEvent) => { + const newValue = event.target.value; + + if (doValidation(newValue)) { + setValue(newValue); + } + + if (onChanged) { + onChanged(newValue); + } + }; + + return ( + + + + ), + }} + placeholder={placeholder} + label={label} + sx={sx} + {...textFieldProps} + aria-readonly={readOnly} + error={validationError !== undefined} + helperText={validationError} + defaultValue={initialValue} + onChange={handleChange} + InputLabelProps={{ shrink: true }} + /> + ); +}; diff --git a/ts-packages/types/package.json b/ts-packages/types/package.json index 0cbaede674..7017554f51 100644 --- a/ts-packages/types/package.json +++ b/ts-packages/types/package.json @@ -6,7 +6,8 @@ "types": "dist/index.d.ts", "peerDependencies": { "@cosmjs/math": "^0.27.1", - "bs58": "4" + "bs58": "4", + "bech32": "^1.1.4" }, "devDependencies": { "@nymproject/eslint-config-react-typescript": "^1.0.0", diff --git a/ts-packages/types/src/utils/accounts/index.ts b/ts-packages/types/src/utils/accounts/index.ts new file mode 100644 index 0000000000..ef756b31a9 --- /dev/null +++ b/ts-packages/types/src/utils/accounts/index.ts @@ -0,0 +1,28 @@ +import { decode } from 'bech32'; + +export const validateWalletAddress = (address?: string, prefix: string = 'n', logErrorToConsole = false): boolean => { + if (!address) { + return false; + } + + if (address.length < 1) { + return false; + } + + if (!address.startsWith(prefix)) { + return false; + } + + try { + // try to decode the address + decode(address); + } catch (e) { + if (logErrorToConsole) { + // eslint-disable-next-line no-console + console.error('Failed to decode address', e); + } + return false; + } + + return true; +}; diff --git a/ts-packages/types/src/utils/index.ts b/ts-packages/types/src/utils/index.ts index b1c792c669..7a8f61fd81 100644 --- a/ts-packages/types/src/utils/index.ts +++ b/ts-packages/types/src/utils/index.ts @@ -1,3 +1,4 @@ export * from './coin'; export * from './keys'; export * from './decimal'; +export * from './accounts'; diff --git a/ts-packages/webpack/webpack.common.js b/ts-packages/webpack/webpack.common.js index d352518ef7..6c74ed3a13 100644 --- a/ts-packages/webpack/webpack.common.js +++ b/ts-packages/webpack/webpack.common.js @@ -35,7 +35,7 @@ module.exports = (baseDir, htmlPath) => ({ use: ['@svgr/webpack'], }, { - test: /\.(png|jpe?g|gif|md)$/i, + test: /\.(png|jpe?g|gif|md|webp)$/i, // More information here https://webpack.js.org/guides/asset-modules/ type: 'asset', }, diff --git a/yarn.lock b/yarn.lock index e5b2cfa58e..e8e2321843 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"@adobe/css-tools@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.0.1.tgz#b38b444ad3aa5fedbb15f2f746dcd934226a12dd" + integrity sha512-+u76oB43nOHrF4DDWRLWDCtci7f3QJoEBigemIdIeTi1ODqjx6Tad9NCVnPRwewWlKkVab5PlK8DCtPTyX7S8g== + "@ampproject/remapping@^2.1.0": version "2.1.2" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.2.tgz#4edca94973ded9630d20101cd8559cedb8d8bd34" @@ -9,6 +14,15 @@ dependencies: "@jridgewell/trace-mapping" "^0.3.0" +"@apideck/better-ajv-errors@^0.3.1": + version "0.3.6" + resolved "https://registry.yarnpkg.com/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz#957d4c28e886a64a8141f7522783be65733ff097" + integrity sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA== + dependencies: + json-schema "^0.4.0" + jsonpointer "^5.0.0" + leven "^3.1.0" + "@babel/code-frame@7.12.11": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" @@ -23,11 +37,23 @@ dependencies: "@babel/highlight" "^7.16.7" +"@babel/code-frame@^7.16.0", "@babel/code-frame@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" + integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== + dependencies: + "@babel/highlight" "^7.18.6" + "@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.4", "@babel/compat-data@^7.16.8", "@babel/compat-data@^7.17.0": version "7.17.0" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.0.tgz#86850b8597ea6962089770952075dcaabb8dba34" integrity sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng== +"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.0", "@babel/compat-data@^7.20.1": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.5.tgz#86f172690b093373a933223b4745deeb6049e733" + integrity sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g== + "@babel/core@7.12.9": version "7.12.9" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.9.tgz#fd450c4ec10cdbb980e2928b7aa7a28484593fc8" @@ -71,6 +97,36 @@ json5 "^2.1.2" semver "^6.3.0" +"@babel/core@^7.11.1", "@babel/core@^7.16.0": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.5.tgz#45e2114dc6cd4ab167f81daf7820e8fa1250d113" + integrity sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.20.5" + "@babel/helper-compilation-targets" "^7.20.0" + "@babel/helper-module-transforms" "^7.20.2" + "@babel/helpers" "^7.20.5" + "@babel/parser" "^7.20.5" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.20.5" + "@babel/types" "^7.20.5" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" + +"@babel/eslint-parser@^7.16.3": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.19.1.tgz#4f68f6b0825489e00a24b41b6a1ae35414ecd2f4" + integrity sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ== + dependencies: + "@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1" + eslint-visitor-keys "^2.1.0" + semver "^6.3.0" + "@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.17.3", "@babel/generator@^7.7.2": version "7.17.3" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.3.tgz#a2c30b0c4f89858cb87050c3ffdfd36bdf443200" @@ -80,6 +136,15 @@ jsesc "^2.5.1" source-map "^0.5.0" +"@babel/generator@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.5.tgz#cb25abee3178adf58d6814b68517c62bdbfdda95" + integrity sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA== + dependencies: + "@babel/types" "^7.20.5" + "@jridgewell/gen-mapping" "^0.3.2" + jsesc "^2.5.1" + "@babel/helper-annotate-as-pure@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" @@ -87,6 +152,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-annotate-as-pure@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb" + integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-builder-binary-assignment-operator-visitor@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz#38d138561ea207f0f69eb1626a418e4f7e6a580b" @@ -95,6 +167,14 @@ "@babel/helper-explode-assignable-expression" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz#acd4edfd7a566d1d51ea975dff38fd52906981bb" + integrity sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.18.6" + "@babel/types" "^7.18.9" + "@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz#06e66c5f299601e6c7da350049315e83209d551b" @@ -105,6 +185,16 @@ browserslist "^4.17.5" semver "^6.3.0" +"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.20.0": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz#6bf5374d424e1b3922822f1d9bdaa43b1a139d0a" + integrity sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ== + dependencies: + "@babel/compat-data" "^7.20.0" + "@babel/helper-validator-option" "^7.18.6" + browserslist "^4.21.3" + semver "^6.3.0" + "@babel/helper-create-class-features-plugin@^7.16.10", "@babel/helper-create-class-features-plugin@^7.16.7", "@babel/helper-create-class-features-plugin@^7.17.1", "@babel/helper-create-class-features-plugin@^7.17.6": version "7.17.6" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.6.tgz#3778c1ed09a7f3e65e6d6e0f6fbfcc53809d92c9" @@ -131,6 +221,19 @@ "@babel/helper-replace-supers" "^7.16.7" "@babel/helper-split-export-declaration" "^7.16.7" +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.20.2", "@babel/helper-create-class-features-plugin@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.5.tgz#327154eedfb12e977baa4ecc72e5806720a85a06" + integrity sha512-3RCdA/EmEaikrhayahwToF0fpweU/8o2p8vhc1c/1kftHOdTKuC65kik/TLc+qfbS8JKw4qqJbne4ovICDhmww== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" + "@babel/helper-member-expression-to-functions" "^7.18.9" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/helper-replace-supers" "^7.19.1" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-create-regexp-features-plugin@^7.16.7": version "7.17.0" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz#1dcc7d40ba0c6b6b25618997c5dbfd310f186fe1" @@ -139,6 +242,14 @@ "@babel/helper-annotate-as-pure" "^7.16.7" regexpu-core "^5.0.1" +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz#5ea79b59962a09ec2acf20a963a01ab4d076ccca" + integrity sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + regexpu-core "^5.2.1" + "@babel/helper-define-polyfill-provider@^0.1.5": version "0.1.5" resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.1.5.tgz#3c2f91b7971b9fc11fe779c945c014065dea340e" @@ -167,6 +278,18 @@ resolve "^1.14.2" semver "^6.1.2" +"@babel/helper-define-polyfill-provider@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz#8612e55be5d51f0cd1f36b4a5a83924e89884b7a" + integrity sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww== + dependencies: + "@babel/helper-compilation-targets" "^7.17.7" + "@babel/helper-plugin-utils" "^7.16.7" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + semver "^6.1.2" + "@babel/helper-environment-visitor@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" @@ -174,6 +297,11 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-environment-visitor@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" + integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== + "@babel/helper-explode-assignable-expression@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz#12a6d8522fdd834f194e868af6354e8650242b7a" @@ -181,6 +309,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-explode-assignable-expression@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz#41f8228ef0a6f1a036b8dfdfec7ce94f9a6bc096" + integrity sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-function-name@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f" @@ -198,6 +333,14 @@ "@babel/template" "^7.16.7" "@babel/types" "^7.17.0" +"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" + integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== + dependencies: + "@babel/template" "^7.18.10" + "@babel/types" "^7.19.0" + "@babel/helper-get-function-arity@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419" @@ -212,6 +355,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-member-expression-to-functions@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz#42b9ca4b2b200123c3b7e726b0ae5153924905b0" @@ -226,6 +376,13 @@ dependencies: "@babel/types" "^7.17.0" +"@babel/helper-member-expression-to-functions@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz#1531661e8375af843ad37ac692c132841e2fd815" + integrity sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg== + dependencies: + "@babel/types" "^7.18.9" + "@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" @@ -233,6 +390,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" + integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.16.7": version "7.17.6" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.17.6.tgz#3c3b03cc6617e33d68ef5a27a67419ac5199ccd0" @@ -247,6 +411,20 @@ "@babel/traverse" "^7.17.3" "@babel/types" "^7.17.0" +"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.19.6", "@babel/helper-module-transforms@^7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz#ac53da669501edd37e658602a21ba14c08748712" + integrity sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.20.2" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.19.1" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.20.1" + "@babel/types" "^7.20.2" + "@babel/helper-optimise-call-expression@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz#a34e3560605abbd31a18546bd2aad3e6d9a174f2" @@ -254,6 +432,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-optimise-call-expression@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe" + integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-plugin-utils@7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" @@ -269,6 +454,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz#86c2347da5acbf5583ba0a10aed4c9bf9da9cf96" integrity sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA== +"@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629" + integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ== + "@babel/helper-remap-async-to-generator@^7.16.8": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz#29ffaade68a367e2ed09c90901986918d25e57e3" @@ -278,6 +468,16 @@ "@babel/helper-wrap-function" "^7.16.8" "@babel/types" "^7.16.8" +"@babel/helper-remap-async-to-generator@^7.18.6", "@babel/helper-remap-async-to-generator@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519" + integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-wrap-function" "^7.18.9" + "@babel/types" "^7.18.9" + "@babel/helper-replace-supers@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz#e9f5f5f32ac90429c1a4bdec0f231ef0c2838ab1" @@ -289,6 +489,17 @@ "@babel/traverse" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz#e1592a9b4b368aa6bdb8784a711e0bcbf0612b78" + integrity sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-member-expression-to-functions" "^7.18.9" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/traverse" "^7.19.1" + "@babel/types" "^7.19.0" + "@babel/helper-simple-access@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz#d656654b9ea08dbb9659b69d61063ccd343ff0f7" @@ -296,6 +507,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-simple-access@^7.19.4", "@babel/helper-simple-access@^7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz#0ab452687fe0c2cfb1e2b9e0015de07fc2d62dd9" + integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA== + dependencies: + "@babel/types" "^7.20.2" + "@babel/helper-skip-transparent-expression-wrappers@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz#0ee3388070147c3ae051e487eca3ebb0e2e8bb09" @@ -303,6 +521,13 @@ dependencies: "@babel/types" "^7.16.0" +"@babel/helper-skip-transparent-expression-wrappers@^7.18.9": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz#fbe4c52f60518cab8140d77101f0e63a8a230684" + integrity sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg== + dependencies: + "@babel/types" "^7.20.0" + "@babel/helper-split-export-declaration@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" @@ -310,6 +535,18 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-string-parser@^7.19.4": + version "7.19.4" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" + integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== + "@babel/helper-validator-identifier@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" @@ -320,11 +557,21 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== +"@babel/helper-validator-identifier@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" + integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== + "@babel/helper-validator-option@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== +"@babel/helper-validator-option@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" + integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== + "@babel/helper-wrap-function@^7.16.8": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz#58afda087c4cd235de92f7ceedebca2c41274200" @@ -335,6 +582,16 @@ "@babel/traverse" "^7.16.8" "@babel/types" "^7.16.8" +"@babel/helper-wrap-function@^7.18.9": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz#75e2d84d499a0ab3b31c33bcfe59d6b8a45f62e3" + integrity sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q== + dependencies: + "@babel/helper-function-name" "^7.19.0" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.20.5" + "@babel/types" "^7.20.5" + "@babel/helpers@^7.12.5", "@babel/helpers@^7.17.2": version "7.17.2" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.2.tgz#23f0a0746c8e287773ccd27c14be428891f63417" @@ -344,7 +601,16 @@ "@babel/traverse" "^7.17.0" "@babel/types" "^7.17.0" -"@babel/highlight@^7.10.4": +"@babel/helpers@^7.20.5": + version "7.20.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.6.tgz#e64778046b70e04779dfbdf924e7ebb45992c763" + integrity sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w== + dependencies: + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.20.5" + "@babel/types" "^7.20.5" + +"@babel/highlight@^7.10.4", "@babel/highlight@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== @@ -367,6 +633,11 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.3.tgz#b07702b982990bf6fdc1da5049a23fece4c5c3d0" integrity sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA== +"@babel/parser@^7.18.10", "@babel/parser@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.5.tgz#7f3c7335fe417665d929f34ae5dceae4c04015e8" + integrity sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA== + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.7.tgz#4eda6d6c2a0aa79c70fa7b6da67763dfe2141050" @@ -374,6 +645,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2" + integrity sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz#cc001234dfc139ac45f6bcf801866198c8c72ff9" @@ -383,6 +661,15 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" "@babel/plugin-proposal-optional-chaining" "^7.16.7" +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz#a11af19aa373d68d561f08e0a57242350ed0ec50" + integrity sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" + "@babel/plugin-proposal-optional-chaining" "^7.18.9" + "@babel/plugin-proposal-async-generator-functions@^7.16.8": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz#3bdd1ebbe620804ea9416706cd67d60787504bc8" @@ -392,6 +679,16 @@ "@babel/helper-remap-async-to-generator" "^7.16.8" "@babel/plugin-syntax-async-generators" "^7.8.4" +"@babel/plugin-proposal-async-generator-functions@^7.20.1": + version "7.20.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.1.tgz#352f02baa5d69f4e7529bdac39aaa02d41146af9" + integrity sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-remap-async-to-generator" "^7.18.9" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-proposal-class-properties@^7.12.1", "@babel/plugin-proposal-class-properties@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz#925cad7b3b1a2fcea7e59ecc8eb5954f961f91b0" @@ -400,6 +697,14 @@ "@babel/helper-create-class-features-plugin" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-proposal-class-properties@^7.16.0", "@babel/plugin-proposal-class-properties@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" + integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-proposal-class-static-block@^7.16.7": version "7.17.6" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.17.6.tgz#164e8fd25f0d80fa48c5a4d1438a6629325ad83c" @@ -409,6 +714,15 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-class-static-block" "^7.14.5" +"@babel/plugin-proposal-class-static-block@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz#8aa81d403ab72d3962fc06c26e222dacfc9b9020" + integrity sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-proposal-decorators@^7.12.12": version "7.17.2" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.17.2.tgz#c36372ddfe0360cac1ee331a238310bddca11493" @@ -420,6 +734,17 @@ "@babel/plugin-syntax-decorators" "^7.17.0" charcodes "^0.2.0" +"@babel/plugin-proposal-decorators@^7.16.4": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.5.tgz#28ba1a0e5044664a512967a19407d7fc26925394" + integrity sha512-Lac7PpRJXcC3s9cKsBfl+uc+DYXU5FD06BrTFunQO6QIQT+DwyzDPURAowI3bcvD1dZF/ank1Z5rstUJn3Hn4Q== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.20.5" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-replace-supers" "^7.19.1" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/plugin-syntax-decorators" "^7.19.0" + "@babel/plugin-proposal-dynamic-import@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz#c19c897eaa46b27634a00fee9fb7d829158704b2" @@ -428,6 +753,14 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-dynamic-import" "^7.8.3" +"@babel/plugin-proposal-dynamic-import@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz#72bcf8d408799f547d759298c3c27c7e7faa4d94" + integrity sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-proposal-export-default-from@^7.12.1": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.16.7.tgz#a40ab158ca55627b71c5513f03d3469026a9e929" @@ -444,6 +777,14 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" +"@babel/plugin-proposal-export-namespace-from@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz#5f7313ab348cdb19d590145f9247540e94761203" + integrity sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-proposal-json-strings@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz#9732cb1d17d9a2626a08c5be25186c195b6fa6e8" @@ -452,6 +793,14 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-json-strings" "^7.8.3" +"@babel/plugin-proposal-json-strings@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz#7e8788c1811c393aff762817e7dbf1ebd0c05f0b" + integrity sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-proposal-logical-assignment-operators@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz#be23c0ba74deec1922e639832904be0bea73cdea" @@ -460,6 +809,14 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" +"@babel/plugin-proposal-logical-assignment-operators@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz#8148cbb350483bf6220af06fa6db3690e14b2e23" + integrity sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1", "@babel/plugin-proposal-nullish-coalescing-operator@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz#141fc20b6857e59459d430c850a0011e36561d99" @@ -468,6 +825,22 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" +"@babel/plugin-proposal-nullish-coalescing-operator@^7.16.0", "@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" + integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-proposal-numeric-separator@^7.16.0", "@babel/plugin-proposal-numeric-separator@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz#899b14fbafe87f053d2c5ff05b36029c62e13c75" + integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-proposal-numeric-separator@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz#d6b69f4af63fb38b6ca2558442a7fb191236eba9" @@ -496,6 +869,17 @@ "@babel/plugin-syntax-object-rest-spread" "^7.8.3" "@babel/plugin-transform-parameters" "^7.16.7" +"@babel/plugin-proposal-object-rest-spread@^7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz#a556f59d555f06961df1e572bb5eca864c84022d" + integrity sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ== + dependencies: + "@babel/compat-data" "^7.20.1" + "@babel/helper-compilation-targets" "^7.20.0" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.20.1" + "@babel/plugin-proposal-optional-catch-binding@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz#c623a430674ffc4ab732fd0a0ae7722b67cb74cf" @@ -504,6 +888,14 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" +"@babel/plugin-proposal-optional-catch-binding@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz#f9400d0e6a3ea93ba9ef70b09e72dd6da638a2cb" + integrity sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-proposal-optional-chaining@^7.12.7", "@babel/plugin-proposal-optional-chaining@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz#7cd629564724816c0e8a969535551f943c64c39a" @@ -513,6 +905,15 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" "@babel/plugin-syntax-optional-chaining" "^7.8.3" +"@babel/plugin-proposal-optional-chaining@^7.16.0", "@babel/plugin-proposal-optional-chaining@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz#e8e8fe0723f2563960e4bf5e9690933691915993" + integrity sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-proposal-private-methods@^7.12.1", "@babel/plugin-proposal-private-methods@^7.16.11": version "7.16.11" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz#e8df108288555ff259f4527dbe84813aac3a1c50" @@ -521,6 +922,14 @@ "@babel/helper-create-class-features-plugin" "^7.16.10" "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-proposal-private-methods@^7.16.0", "@babel/plugin-proposal-private-methods@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz#5209de7d213457548a98436fa2882f52f4be6bea" + integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-proposal-private-property-in-object@^7.12.1": version "7.17.12" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.17.12.tgz#b02efb7f106d544667d91ae97405a9fd8c93952d" @@ -541,6 +950,16 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" +"@babel/plugin-proposal-private-property-in-object@^7.18.6": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz#309c7668f2263f1c711aa399b5a9a6291eef6135" + integrity sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-create-class-features-plugin" "^7.20.5" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-proposal-unicode-property-regex@^7.16.7", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz#635d18eb10c6214210ffc5ff4932552de08188a2" @@ -549,6 +968,14 @@ "@babel/helper-create-regexp-features-plugin" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-proposal-unicode-property-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz#af613d2cd5e643643b65cded64207b15c85cb78e" + integrity sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" @@ -584,6 +1011,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-syntax-decorators@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.19.0.tgz#5f13d1d8fce96951bea01a10424463c9a5b3a599" + integrity sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ== + dependencies: + "@babel/helper-plugin-utils" "^7.19.0" + "@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" @@ -612,6 +1046,20 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-syntax-flow@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz#774d825256f2379d06139be0c723c4dd444f3ca1" + integrity sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-syntax-import-assertions@^7.20.0": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz#bb50e0d4bea0957235390641209394e87bdb9cc4" + integrity sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ== + dependencies: + "@babel/helper-plugin-utils" "^7.19.0" + "@babel/plugin-syntax-import-meta@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" @@ -640,6 +1088,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-syntax-jsx@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" + integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" @@ -703,6 +1158,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-syntax-typescript@^7.20.0": + version "7.20.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz#4e9a0cfc769c85689b77a2e642d24e9f697fc8c7" + integrity sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.19.0" + "@babel/plugin-transform-arrow-functions@^7.12.1", "@babel/plugin-transform-arrow-functions@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz#44125e653d94b98db76369de9c396dc14bef4154" @@ -710,6 +1172,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-arrow-functions@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz#19063fcf8771ec7b31d742339dac62433d0611fe" + integrity sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-async-to-generator@^7.14.5", "@babel/plugin-transform-async-to-generator@^7.16.8": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz#b83dff4b970cf41f1b819f8b49cc0cfbaa53a808" @@ -719,6 +1188,15 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/helper-remap-async-to-generator" "^7.16.8" +"@babel/plugin-transform-async-to-generator@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz#ccda3d1ab9d5ced5265fdb13f1882d5476c71615" + integrity sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag== + dependencies: + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-remap-async-to-generator" "^7.18.6" + "@babel/plugin-transform-block-scoped-functions@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz#4d0d57d9632ef6062cdf354bb717102ee042a620" @@ -726,6 +1204,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-block-scoped-functions@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz#9187bf4ba302635b9d70d986ad70f038726216a8" + integrity sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-block-scoping@^7.12.12", "@babel/plugin-transform-block-scoping@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz#f50664ab99ddeaee5bc681b8f3a6ea9d72ab4f87" @@ -733,6 +1218,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-block-scoping@^7.20.2": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.5.tgz#401215f9dc13dc5262940e2e527c9536b3d7f237" + integrity sha512-WvpEIW9Cbj9ApF3yJCjIEEf1EiNJLtXagOrL5LNWEZOo3jv8pmPoYTSNJQvqej8OavVlgOoOPw6/htGZro6IkA== + dependencies: + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/plugin-transform-classes@^7.12.1", "@babel/plugin-transform-classes@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz#8f4b9562850cd973de3b498f1218796eb181ce00" @@ -747,6 +1239,21 @@ "@babel/helper-split-export-declaration" "^7.16.7" globals "^11.1.0" +"@babel/plugin-transform-classes@^7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.2.tgz#c0033cf1916ccf78202d04be4281d161f6709bb2" + integrity sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-compilation-targets" "^7.20.0" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-replace-supers" "^7.19.1" + "@babel/helper-split-export-declaration" "^7.18.6" + globals "^11.1.0" + "@babel/plugin-transform-computed-properties@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz#66dee12e46f61d2aae7a73710f591eb3df616470" @@ -754,6 +1261,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-computed-properties@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz#2357a8224d402dad623caf6259b611e56aec746e" + integrity sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-transform-destructuring@^7.12.1", "@babel/plugin-transform-destructuring@^7.16.7": version "7.17.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.17.3.tgz#c445f75819641788a27a0a3a759d9df911df6abc" @@ -761,6 +1275,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-destructuring@^7.20.2": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.2.tgz#c23741cfa44ddd35f5e53896e88c75331b8b2792" + integrity sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw== + dependencies: + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/plugin-transform-dotall-regex@^7.16.7", "@babel/plugin-transform-dotall-regex@^7.4.4": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz#6b2d67686fab15fb6a7fd4bd895d5982cfc81241" @@ -769,6 +1290,14 @@ "@babel/helper-create-regexp-features-plugin" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-dotall-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz#b286b3e7aae6c7b861e45bed0a2fafd6b1a4fef8" + integrity sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-duplicate-keys@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz#2207e9ca8f82a0d36a5a67b6536e7ef8b08823c9" @@ -776,6 +1305,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-duplicate-keys@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz#687f15ee3cdad6d85191eb2a372c4528eaa0ae0e" + integrity sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-transform-exponentiation-operator@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz#efa9862ef97e9e9e5f653f6ddc7b665e8536fe9b" @@ -784,6 +1320,22 @@ "@babel/helper-builder-binary-assignment-operator-visitor" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-exponentiation-operator@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz#421c705f4521888c65e91fdd1af951bfefd4dacd" + integrity sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-flow-strip-types@^7.16.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz#e9e8606633287488216028719638cbbb2f2dde8f" + integrity sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg== + dependencies: + "@babel/helper-plugin-utils" "^7.19.0" + "@babel/plugin-syntax-flow" "^7.18.6" + "@babel/plugin-transform-flow-strip-types@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.16.7.tgz#291fb140c78dabbf87f2427e7c7c332b126964b8" @@ -799,6 +1351,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-for-of@^7.18.8": + version "7.18.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz#6ef8a50b244eb6a0bdbad0c7c61877e4e30097c1" + integrity sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-function-name@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz#5ab34375c64d61d083d7d2f05c38d90b97ec65cf" @@ -808,6 +1367,15 @@ "@babel/helper-function-name" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-function-name@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz#cc354f8234e62968946c61a46d6365440fc764e0" + integrity sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ== + dependencies: + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-transform-literals@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz#254c9618c5ff749e87cb0c0cef1a0a050c0bdab1" @@ -815,6 +1383,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-literals@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz#72796fdbef80e56fba3c6a699d54f0de557444bc" + integrity sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-transform-member-expression-literals@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz#6e5dcf906ef8a098e630149d14c867dd28f92384" @@ -822,6 +1397,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-member-expression-literals@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz#ac9fdc1a118620ac49b7e7a5d2dc177a1bfee88e" + integrity sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-modules-amd@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz#b28d323016a7daaae8609781d1f8c9da42b13186" @@ -831,6 +1413,14 @@ "@babel/helper-plugin-utils" "^7.16.7" babel-plugin-dynamic-import-node "^2.3.3" +"@babel/plugin-transform-modules-amd@^7.19.6": + version "7.19.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.19.6.tgz#aca391801ae55d19c4d8d2ebfeaa33df5f2a2cbd" + integrity sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg== + dependencies: + "@babel/helper-module-transforms" "^7.19.6" + "@babel/helper-plugin-utils" "^7.19.0" + "@babel/plugin-transform-modules-commonjs@^7.16.8": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz#cdee19aae887b16b9d331009aa9a219af7c86afe" @@ -841,6 +1431,15 @@ "@babel/helper-simple-access" "^7.16.7" babel-plugin-dynamic-import-node "^2.3.3" +"@babel/plugin-transform-modules-commonjs@^7.19.6": + version "7.19.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz#25b32feef24df8038fc1ec56038917eacb0b730c" + integrity sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ== + dependencies: + "@babel/helper-module-transforms" "^7.19.6" + "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-simple-access" "^7.19.4" + "@babel/plugin-transform-modules-systemjs@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.7.tgz#887cefaef88e684d29558c2b13ee0563e287c2d7" @@ -852,6 +1451,16 @@ "@babel/helper-validator-identifier" "^7.16.7" babel-plugin-dynamic-import-node "^2.3.3" +"@babel/plugin-transform-modules-systemjs@^7.19.6": + version "7.19.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz#59e2a84064b5736a4471b1aa7b13d4431d327e0d" + integrity sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ== + dependencies: + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-module-transforms" "^7.19.6" + "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-validator-identifier" "^7.19.1" + "@babel/plugin-transform-modules-umd@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz#23dad479fa585283dbd22215bff12719171e7618" @@ -860,6 +1469,14 @@ "@babel/helper-module-transforms" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-modules-umd@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz#81d3832d6034b75b54e62821ba58f28ed0aab4b9" + integrity sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ== + dependencies: + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-named-capturing-groups-regex@^7.16.8": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz#7f860e0e40d844a02c9dcf9d84965e7dfd666252" @@ -867,6 +1484,14 @@ dependencies: "@babel/helper-create-regexp-features-plugin" "^7.16.7" +"@babel/plugin-transform-named-capturing-groups-regex@^7.19.1": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz#626298dd62ea51d452c3be58b285d23195ba69a8" + integrity sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.20.5" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/plugin-transform-new-target@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz#9967d89a5c243818e0800fdad89db22c5f514244" @@ -874,6 +1499,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-new-target@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz#d128f376ae200477f37c4ddfcc722a8a1b3246a8" + integrity sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-object-super@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz#ac359cf8d32cf4354d27a46867999490b6c32a94" @@ -882,6 +1514,14 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/helper-replace-supers" "^7.16.7" +"@babel/plugin-transform-object-super@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz#fb3c6ccdd15939b6ff7939944b51971ddc35912c" + integrity sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-replace-supers" "^7.18.6" + "@babel/plugin-transform-parameters@^7.12.1", "@babel/plugin-transform-parameters@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz#a1721f55b99b736511cb7e0152f61f17688f331f" @@ -889,6 +1529,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-parameters@^7.20.1": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.5.tgz#f8f9186c681d10c3de7620c916156d893c8a019e" + integrity sha512-h7plkOmcndIUWXZFLgpbrh2+fXAi47zcUX7IrOQuZdLD0I0KvjJ6cvo3BEcAOsDOcZhVKGJqv07mkSqK0y2isQ== + dependencies: + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/plugin-transform-property-literals@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz#2dadac85155436f22c696c4827730e0fe1057a55" @@ -896,6 +1543,20 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-property-literals@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz#e22498903a483448e94e032e9bbb9c5ccbfc93a3" + integrity sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-react-constant-elements@^7.12.1": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.20.2.tgz#3f02c784e0b711970d7d8ccc96c4359d64e27ac7" + integrity sha512-KS/G8YI8uwMGKErLFOHS/ekhqdHhpEloxs43NecQHVgo2QuQSyJhGIY1fL8UGl9wy5ItVwwoUL4YxVqsplGq2g== + dependencies: + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/plugin-transform-react-constant-elements@^7.14.5": version "7.17.6" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.17.6.tgz#6cc273c2f612a6a50cb657e63ee1303e5e68d10a" @@ -903,6 +1564,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-react-display-name@^7.16.0", "@babel/plugin-transform-react-display-name@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz#8b1125f919ef36ebdfff061d664e266c666b9415" + integrity sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-react-display-name@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.16.7.tgz#7b6d40d232f4c0f550ea348593db3b21e2404340" @@ -917,6 +1585,13 @@ dependencies: "@babel/plugin-transform-react-jsx" "^7.16.7" +"@babel/plugin-transform-react-jsx-development@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz#dbe5c972811e49c7405b630e4d0d2e1380c0ddc5" + integrity sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA== + dependencies: + "@babel/plugin-transform-react-jsx" "^7.18.6" + "@babel/plugin-transform-react-jsx@^7.12.12", "@babel/plugin-transform-react-jsx@^7.16.7": version "7.17.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.17.3.tgz#eac1565da176ccb1a715dae0b4609858808008c1" @@ -928,6 +1603,17 @@ "@babel/plugin-syntax-jsx" "^7.16.7" "@babel/types" "^7.17.0" +"@babel/plugin-transform-react-jsx@^7.18.6": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz#b3cbb7c3a00b92ec8ae1027910e331ba5c500eb9" + integrity sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-plugin-utils" "^7.19.0" + "@babel/plugin-syntax-jsx" "^7.18.6" + "@babel/types" "^7.19.0" + "@babel/plugin-transform-react-pure-annotations@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.16.7.tgz#232bfd2f12eb551d6d7d01d13fe3f86b45eb9c67" @@ -936,6 +1622,14 @@ "@babel/helper-annotate-as-pure" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-react-pure-annotations@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz#561af267f19f3e5d59291f9950fd7b9663d0d844" + integrity sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-regenerator@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.7.tgz#9e7576dc476cb89ccc5096fff7af659243b4adeb" @@ -943,6 +1637,14 @@ dependencies: regenerator-transform "^0.14.2" +"@babel/plugin-transform-regenerator@^7.18.6": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz#57cda588c7ffb7f4f8483cc83bdcea02a907f04d" + integrity sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ== + dependencies: + "@babel/helper-plugin-utils" "^7.20.2" + regenerator-transform "^0.15.1" + "@babel/plugin-transform-reserved-words@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz#1d798e078f7c5958eec952059c460b220a63f586" @@ -950,6 +1652,25 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-reserved-words@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz#b1abd8ebf8edaa5f7fe6bbb8d2133d23b6a6f76a" + integrity sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-runtime@^7.16.4": + version "7.19.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz#9d2a9dbf4e12644d6f46e5e75bfbf02b5d6e9194" + integrity sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw== + dependencies: + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-plugin-utils" "^7.19.0" + babel-plugin-polyfill-corejs2 "^0.3.3" + babel-plugin-polyfill-corejs3 "^0.6.0" + babel-plugin-polyfill-regenerator "^0.4.1" + semver "^6.3.0" + "@babel/plugin-transform-shorthand-properties@^7.12.1", "@babel/plugin-transform-shorthand-properties@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz#e8549ae4afcf8382f711794c0c7b6b934c5fbd2a" @@ -957,6 +1678,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-shorthand-properties@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz#6d6df7983d67b195289be24909e3f12a8f664dc9" + integrity sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-spread@^7.12.1", "@babel/plugin-transform-spread@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz#a303e2122f9f12e0105daeedd0f30fb197d8ff44" @@ -965,6 +1693,14 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" +"@babel/plugin-transform-spread@^7.19.0": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz#dd60b4620c2fec806d60cfaae364ec2188d593b6" + integrity sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w== + dependencies: + "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" + "@babel/plugin-transform-sticky-regex@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz#c84741d4f4a38072b9a1e2e3fd56d359552e8660" @@ -972,6 +1708,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-sticky-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz#c6706eb2b1524028e317720339583ad0f444adcc" + integrity sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-transform-template-literals@^7.12.1", "@babel/plugin-transform-template-literals@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz#f3d1c45d28967c8e80f53666fc9c3e50618217ab" @@ -979,6 +1722,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-template-literals@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz#04ec6f10acdaa81846689d63fae117dd9c243a5e" + integrity sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-transform-typeof-symbol@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz#9cdbe622582c21368bd482b660ba87d5545d4f7e" @@ -986,6 +1736,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-typeof-symbol@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz#c8cea68263e45addcd6afc9091429f80925762c0" + integrity sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-transform-typescript@^7.16.7": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.8.tgz#591ce9b6b83504903fa9dd3652c357c2ba7a1ee0" @@ -995,6 +1752,15 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-typescript" "^7.16.7" +"@babel/plugin-transform-typescript@^7.18.6": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.2.tgz#91515527b376fc122ba83b13d70b01af8fe98f3f" + integrity sha512-jvS+ngBfrnTUBfOQq8NfGnSbF9BrqlR6hjJ2yVxMkmO5nL/cdifNbI30EfjRlN4g5wYWNnMPyj5Sa6R1pbLeag== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.20.2" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/plugin-syntax-typescript" "^7.20.0" + "@babel/plugin-transform-unicode-escapes@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz#da8717de7b3287a2c6d659750c964f302b31ece3" @@ -1002,6 +1768,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-unicode-escapes@^7.18.10": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz#1ecfb0eda83d09bbcb77c09970c2dd55832aa246" + integrity sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-transform-unicode-regex@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz#0f7aa4a501198976e25e82702574c34cfebe9ef2" @@ -1010,6 +1783,95 @@ "@babel/helper-create-regexp-features-plugin" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-transform-unicode-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz#194317225d8c201bbae103364ffe9e2cea36cdca" + integrity sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/preset-env@^7.11.0", "@babel/preset-env@^7.12.1", "@babel/preset-env@^7.16.4": + version "7.20.2" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.20.2.tgz#9b1642aa47bb9f43a86f9630011780dab7f86506" + integrity sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg== + dependencies: + "@babel/compat-data" "^7.20.1" + "@babel/helper-compilation-targets" "^7.20.0" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-validator-option" "^7.18.6" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.18.9" + "@babel/plugin-proposal-async-generator-functions" "^7.20.1" + "@babel/plugin-proposal-class-properties" "^7.18.6" + "@babel/plugin-proposal-class-static-block" "^7.18.6" + "@babel/plugin-proposal-dynamic-import" "^7.18.6" + "@babel/plugin-proposal-export-namespace-from" "^7.18.9" + "@babel/plugin-proposal-json-strings" "^7.18.6" + "@babel/plugin-proposal-logical-assignment-operators" "^7.18.9" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.6" + "@babel/plugin-proposal-numeric-separator" "^7.18.6" + "@babel/plugin-proposal-object-rest-spread" "^7.20.2" + "@babel/plugin-proposal-optional-catch-binding" "^7.18.6" + "@babel/plugin-proposal-optional-chaining" "^7.18.9" + "@babel/plugin-proposal-private-methods" "^7.18.6" + "@babel/plugin-proposal-private-property-in-object" "^7.18.6" + "@babel/plugin-proposal-unicode-property-regex" "^7.18.6" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-import-assertions" "^7.20.0" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + "@babel/plugin-transform-arrow-functions" "^7.18.6" + "@babel/plugin-transform-async-to-generator" "^7.18.6" + "@babel/plugin-transform-block-scoped-functions" "^7.18.6" + "@babel/plugin-transform-block-scoping" "^7.20.2" + "@babel/plugin-transform-classes" "^7.20.2" + "@babel/plugin-transform-computed-properties" "^7.18.9" + "@babel/plugin-transform-destructuring" "^7.20.2" + "@babel/plugin-transform-dotall-regex" "^7.18.6" + "@babel/plugin-transform-duplicate-keys" "^7.18.9" + "@babel/plugin-transform-exponentiation-operator" "^7.18.6" + "@babel/plugin-transform-for-of" "^7.18.8" + "@babel/plugin-transform-function-name" "^7.18.9" + "@babel/plugin-transform-literals" "^7.18.9" + "@babel/plugin-transform-member-expression-literals" "^7.18.6" + "@babel/plugin-transform-modules-amd" "^7.19.6" + "@babel/plugin-transform-modules-commonjs" "^7.19.6" + "@babel/plugin-transform-modules-systemjs" "^7.19.6" + "@babel/plugin-transform-modules-umd" "^7.18.6" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.19.1" + "@babel/plugin-transform-new-target" "^7.18.6" + "@babel/plugin-transform-object-super" "^7.18.6" + "@babel/plugin-transform-parameters" "^7.20.1" + "@babel/plugin-transform-property-literals" "^7.18.6" + "@babel/plugin-transform-regenerator" "^7.18.6" + "@babel/plugin-transform-reserved-words" "^7.18.6" + "@babel/plugin-transform-shorthand-properties" "^7.18.6" + "@babel/plugin-transform-spread" "^7.19.0" + "@babel/plugin-transform-sticky-regex" "^7.18.6" + "@babel/plugin-transform-template-literals" "^7.18.9" + "@babel/plugin-transform-typeof-symbol" "^7.18.9" + "@babel/plugin-transform-unicode-escapes" "^7.18.10" + "@babel/plugin-transform-unicode-regex" "^7.18.6" + "@babel/preset-modules" "^0.1.5" + "@babel/types" "^7.20.2" + babel-plugin-polyfill-corejs2 "^0.3.3" + babel-plugin-polyfill-corejs3 "^0.6.0" + babel-plugin-polyfill-regenerator "^0.4.1" + core-js-compat "^3.25.1" + semver "^6.3.0" + "@babel/preset-env@^7.12.11", "@babel/preset-env@^7.15.0", "@babel/preset-env@^7.15.6": version "7.16.11" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.16.11.tgz#5dd88fd885fae36f88fd7c8342475c9f0abe2982" @@ -1122,6 +1984,18 @@ "@babel/plugin-transform-react-jsx-development" "^7.16.7" "@babel/plugin-transform-react-pure-annotations" "^7.16.7" +"@babel/preset-react@^7.12.5", "@babel/preset-react@^7.16.0": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.18.6.tgz#979f76d6277048dc19094c217b507f3ad517dd2d" + integrity sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-validator-option" "^7.18.6" + "@babel/plugin-transform-react-display-name" "^7.18.6" + "@babel/plugin-transform-react-jsx" "^7.18.6" + "@babel/plugin-transform-react-jsx-development" "^7.18.6" + "@babel/plugin-transform-react-pure-annotations" "^7.18.6" + "@babel/preset-typescript@^7.12.7", "@babel/preset-typescript@^7.15.0": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.16.7.tgz#ab114d68bb2020afc069cd51b37ff98a046a70b9" @@ -1131,6 +2005,15 @@ "@babel/helper-validator-option" "^7.16.7" "@babel/plugin-transform-typescript" "^7.16.7" +"@babel/preset-typescript@^7.16.0": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz#ce64be3e63eddc44240c6358daefac17b3186399" + integrity sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-validator-option" "^7.18.6" + "@babel/plugin-transform-typescript" "^7.18.6" + "@babel/register@^7.12.1": version "7.17.0" resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.17.0.tgz#8051e0b7cb71385be4909324f072599723a1f084" @@ -1208,6 +2091,15 @@ "@babel/parser" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/template@^7.18.10": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" + integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.18.10" + "@babel/types" "^7.18.10" + "@babel/traverse@^7.1.6", "@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.0", "@babel/traverse@^7.17.3", "@babel/traverse@^7.7.2": version "7.17.3" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.3.tgz#0ae0f15b27d9a92ba1f2263358ea7c4e7db47b57" @@ -1224,6 +2116,22 @@ debug "^4.1.0" globals "^11.1.0" +"@babel/traverse@^7.19.1", "@babel/traverse@^7.20.1", "@babel/traverse@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.5.tgz#78eb244bea8270fdda1ef9af22a5d5e5b7e57133" + integrity sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.20.5" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.20.5" + "@babel/types" "^7.20.5" + debug "^4.1.0" + globals "^11.1.0" + "@babel/types@^7.0.0", "@babel/types@^7.12.11", "@babel/types@^7.12.7", "@babel/types@^7.15.6", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": version "7.17.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" @@ -1232,6 +2140,15 @@ "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" +"@babel/types@^7.12.6", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.20.5": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.5.tgz#e206ae370b5393d94dfd1d04cd687cace53efa84" + integrity sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg== + dependencies: + "@babel/helper-string-parser" "^7.19.4" + "@babel/helper-validator-identifier" "^7.19.1" + to-fast-properties "^2.0.0" + "@base2/pretty-print-object@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz#371ba8be66d556812dc7fb169ebc3c08378f69d4" @@ -1553,6 +2470,137 @@ resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.25.6.tgz#934d9a967180baa66163847616a74358732227ca" integrity sha512-ofOYiuxVKNo238vCPPlaDzqPXy2AQ/5/nashBo5rvPZJkxt9LciGfUEQWPCOb1BIJDNx2Dzu0z4XCf/dwzl0Dg== +"@craco/craco@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@craco/craco/-/craco-7.0.0.tgz#4e9243e53fba6ed4d2bc08aa65aae9d1b63541ed" + integrity sha512-OyjL9zpURB6Ha1HO62Hlt27Xd7UYJ8DRiBNuE4DBB8Ue0iQ9q/xsv3ze7ROm6gCZqV6I2Gxjnq0EHCCye+4xDQ== + dependencies: + autoprefixer "^10.4.12" + cosmiconfig "^7.0.1" + cosmiconfig-typescript-loader "^1.0.0" + cross-spawn "^7.0.3" + lodash "^4.17.21" + semver "^7.3.7" + webpack-merge "^5.8.0" + +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + +"@csstools/normalize.css@*": + version "12.0.0" + resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-12.0.0.tgz#a9583a75c3f150667771f30b60d9f059473e62c4" + integrity sha512-M0qqxAcwCsIVfpFQSlGN5XjXWu8l5JDZN+fPt1LeW5SZexQTgnaEvgXAY+CeygRw0EeppWHi12JxESWiWrB0Sg== + +"@csstools/postcss-cascade-layers@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz#8a997edf97d34071dd2e37ea6022447dd9e795ad" + integrity sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA== + dependencies: + "@csstools/selector-specificity" "^2.0.2" + postcss-selector-parser "^6.0.10" + +"@csstools/postcss-color-function@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz#2bd36ab34f82d0497cfacdc9b18d34b5e6f64b6b" + integrity sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-font-format-keywords@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz#677b34e9e88ae997a67283311657973150e8b16a" + integrity sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-hwb-function@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz#ab54a9fce0ac102c754854769962f2422ae8aa8b" + integrity sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-ic-unit@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz#28237d812a124d1a16a5acc5c3832b040b303e58" + integrity sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-is-pseudo-class@^2.0.7": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz#846ae6c0d5a1eaa878fce352c544f9c295509cd1" + integrity sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA== + dependencies: + "@csstools/selector-specificity" "^2.0.0" + postcss-selector-parser "^6.0.10" + +"@csstools/postcss-nested-calc@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz#d7e9d1d0d3d15cf5ac891b16028af2a1044d0c26" + integrity sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-normalize-display-values@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz#15da54a36e867b3ac5163ee12c1d7f82d4d612c3" + integrity sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-oklab-function@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz#88cee0fbc8d6df27079ebd2fa016ee261eecf844" + integrity sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-progressive-custom-properties@^1.1.0", "@csstools/postcss-progressive-custom-properties@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz#542292558384361776b45c85226b9a3a34f276fa" + integrity sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-stepped-value-functions@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz#f8772c3681cc2befed695e2b0b1d68e22f08c4f4" + integrity sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-text-decoration-shorthand@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz#ea96cfbc87d921eca914d3ad29340d9bcc4c953f" + integrity sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-trigonometric-functions@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz#94d3e4774c36d35dcdc88ce091336cb770d32756" + integrity sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-unset-value@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz#c99bb70e2cdc7312948d1eb41df2412330b81f77" + integrity sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g== + +"@csstools/selector-specificity@^2.0.0", "@csstools/selector-specificity@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz#1bfafe4b7ed0f3e4105837e056e0a89b108ebe36" + integrity sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg== + "@date-io/core@^2.13.1": version "2.13.1" resolved "https://registry.yarnpkg.com/@date-io/core/-/core-2.13.1.tgz#f041765aff5c55fbc7e37fdd75fc1792733426d6" @@ -1856,6 +2904,21 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@eslint/eslintrc@^1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.3.tgz#2b044ab39fdfa75b4688184f9e573ce3c5b0ff95" + integrity sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.4.0" + globals "^13.15.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + "@gar/promisify@^1.0.1": version "1.1.3" resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" @@ -1866,6 +2929,15 @@ resolved "https://registry.yarnpkg.com/@hookform/resolvers/-/resolvers-2.8.8.tgz#17cf806485435877fdafce9f3bee6ff68f7f87b6" integrity sha512-meAEDur1IJBfKyTo9yPYAuzjIfrxA7m9Ov+1nxaW/YupsqMeseWifoUjWK03+hz/RJizsVQAaUjVxFEkyu0GWg== +"@humanwhocodes/config-array@^0.11.6": + version "0.11.7" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.7.tgz#38aec044c6c828f6ed51d5d7ae3d9b9faf6dbb0f" + integrity sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw== + dependencies: + "@humanwhocodes/object-schema" "^1.2.1" + debug "^4.1.1" + minimatch "^3.0.5" + "@humanwhocodes/config-array@^0.5.0": version "0.5.0" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" @@ -1884,6 +2956,11 @@ debug "^4.1.1" minimatch "^3.0.4" +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + "@humanwhocodes/object-schema@^1.2.0", "@humanwhocodes/object-schema@^1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" @@ -1922,6 +2999,18 @@ jest-util "^27.5.1" slash "^3.0.0" +"@jest/console@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-28.1.3.tgz#2030606ec03a18c31803b8a36382762e447655df" + integrity sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw== + dependencies: + "@jest/types" "^28.1.3" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + slash "^3.0.0" + "@jest/core@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.5.1.tgz#267ac5f704e09dc52de2922cbf3af9edcd64b626" @@ -2051,6 +3140,16 @@ "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" +"@jest/test-result@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-28.1.3.tgz#5eae945fd9f4b8fcfce74d239e6f725b6bf076c5" + integrity sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg== + dependencies: + "@jest/console" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + "@jest/test-sequencer@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz#4057e0e9cea4439e544c6353c6affe58d095745b" @@ -2137,16 +3236,56 @@ "@types/yargs" "^17.0.8" chalk "^4.0.0" +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + 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/resolve-uri@^3.0.3": version "3.0.5" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz#68eb521368db76d040a6315cdb24bf2483037b9c" integrity sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew== +"@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": + 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/sourcemap-codec@^1.4.10": version "1.4.11" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz#771a1d8d744eeb71b6adb35808e1a6c7b9b8c8ec" integrity sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg== +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping@^0.3.0": version "0.3.4" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz#f6a0832dffd5b8a6aaa633b7d9f8e8e94c83a0c3" @@ -2155,6 +3294,19 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@jridgewell/trace-mapping@^0.3.14", "@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== + "@lerna/add@4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@lerna/add/-/add-4.0.0.tgz#c36f57d132502a57b9e7058d1548b7a565ef183f" @@ -2826,6 +3978,14 @@ npmlog "^4.1.2" write-file-atomic "^3.0.3" +"@mdx-js/loader@^2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@mdx-js/loader/-/loader-2.1.5.tgz#4e764c65333530fd786dfe4f36e918dfeac0200b" + integrity sha512-oXjfTa/iAcMmW8DdQ+hQFodPCLqw5VKT2yoZkLwrZfPVVpUgKrI+5/ZePYq328xxtAUStZmR3ed0PWJrwd5Pkg== + dependencies: + "@mdx-js/mdx" "^2.0.0" + source-map "^0.7.0" + "@mdx-js/mdx@^1.6.22": version "1.6.22" resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-1.6.22.tgz#8a723157bf90e78f17dc0f27995398e6c731f1ba" @@ -2851,6 +4011,29 @@ unist-builder "2.0.3" unist-util-visit "2.0.3" +"@mdx-js/mdx@^2.0.0": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-2.1.5.tgz#577937349fd555154382c2f805f5f52834a64903" + integrity sha512-zEG0lt+Bl/r5U6e0TOS7qDbsXICtemfAPquxWFsMbdzrvlWaqMGemLl+sjVpqlyaaiCiGVQBSGdCk0t1qXjkQg== + dependencies: + "@types/estree-jsx" "^1.0.0" + "@types/mdx" "^2.0.0" + estree-util-build-jsx "^2.0.0" + estree-util-is-identifier-name "^2.0.0" + estree-util-to-js "^1.1.0" + estree-walker "^3.0.0" + hast-util-to-estree "^2.0.0" + markdown-extensions "^1.0.0" + periscopic "^3.0.0" + remark-mdx "^2.0.0" + remark-parse "^10.0.0" + remark-rehype "^10.0.0" + unified "^10.0.0" + unist-util-position-from-estree "^1.0.0" + unist-util-stringify-position "^3.0.0" + unist-util-visit "^4.0.0" + vfile "^5.0.0" + "@mdx-js/react@^1.6.22": version "1.6.22" resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-1.6.22.tgz#ae09b4744fddc74714ee9f9d6f17a66e77c43573" @@ -3052,6 +4235,13 @@ prop-types "^15.8.1" reselect "^4.1.5" +"@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1": + version "5.1.1-v1" + resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129" + integrity sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg== + dependencies: + eslint-scope "5.1.1" + "@noble/hashes@^1": version "1.1.2" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183" @@ -3080,7 +4270,7 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== -"@nodelib/fs.walk@^1.2.3": +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": 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== @@ -3164,6 +4354,11 @@ "@cosmjs/stargate" "^0.25.5" axios "^0.21.1" +"@nymproject/sdk@file:sdk/typescript/packages/sdk": + version "1.1.4" + dependencies: + comlink "^4.3.1" + "@octokit/auth-token@^2.4.4": version "2.5.0" resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-2.5.0.tgz#27c37ea26c205f28443402477ffd261311f21e36" @@ -3358,6 +4553,48 @@ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== +"@rollup/plugin-babel@^5.2.0": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283" + integrity sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q== + dependencies: + "@babel/helper-module-imports" "^7.10.4" + "@rollup/pluginutils" "^3.1.0" + +"@rollup/plugin-node-resolve@^11.2.1": + version "11.2.1" + resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz#82aa59397a29cd4e13248b106e6a4a1880362a60" + integrity sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg== + dependencies: + "@rollup/pluginutils" "^3.1.0" + "@types/resolve" "1.17.1" + builtin-modules "^3.1.0" + deepmerge "^4.2.2" + is-module "^1.0.0" + resolve "^1.19.0" + +"@rollup/plugin-replace@^2.4.1": + version "2.4.2" + resolved "https://registry.yarnpkg.com/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz#a2d539314fbc77c244858faa523012825068510a" + integrity sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg== + dependencies: + "@rollup/pluginutils" "^3.1.0" + magic-string "^0.25.7" + +"@rollup/pluginutils@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" + integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== + dependencies: + "@types/estree" "0.0.39" + estree-walker "^1.0.1" + picomatch "^2.2.2" + +"@rushstack/eslint-patch@^1.1.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz#8be36a1f66f3265389e90b5f9c9962146758f728" + integrity sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg== + "@sinclair/typebox@^0.24.1": version "0.24.19" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.19.tgz#5297278e0d8a1aea084685a3216074910ac6c113" @@ -4434,46 +5671,110 @@ regenerator-runtime "^0.13.7" resolve-from "^5.0.0" +"@surma/rollup-plugin-off-main-thread@^2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz#ee34985952ca21558ab0d952f00298ad2190c053" + integrity sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ== + dependencies: + ejs "^3.1.6" + json5 "^2.2.0" + magic-string "^0.25.0" + string.prototype.matchall "^4.0.6" + +"@svgr/babel-plugin-add-jsx-attribute@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz#81ef61947bb268eb9d50523446f9c638fb355906" + integrity sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg== + "@svgr/babel-plugin-add-jsx-attribute@^6.0.0": version "6.0.0" resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.0.0.tgz#bd6d1ff32a31b82b601e73672a789cc41e84fe18" integrity sha512-MdPdhdWLtQsjd29Wa4pABdhWbaRMACdM1h31BY+c6FghTZqNGT7pEYdBoaGeKtdTOBC/XNFQaKVj+r/Ei2ryWA== +"@svgr/babel-plugin-remove-jsx-attribute@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz#6b2c770c95c874654fd5e1d5ef475b78a0a962ef" + integrity sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg== + "@svgr/babel-plugin-remove-jsx-attribute@^6.0.0": version "6.0.0" resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-6.0.0.tgz#58654908beebfa069681a83332544b17e5237e89" integrity sha512-aVdtfx9jlaaxc3unA6l+M9YRnKIZjOhQPthLKqmTXC8UVkBLDRGwPKo+r8n3VZN8B34+yVajzPTZ+ptTSuZZCw== +"@svgr/babel-plugin-remove-jsx-empty-expression@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz#25621a8915ed7ad70da6cea3d0a6dbc2ea933efd" + integrity sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA== + "@svgr/babel-plugin-remove-jsx-empty-expression@^6.0.0": version "6.0.0" resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-6.0.0.tgz#d06dd6e8a8f603f92f9979bb9990a1f85a4f57ba" integrity sha512-Ccj42ApsePD451AZJJf1QzTD1B/BOU392URJTeXFxSK709i0KUsGtbwyiqsKu7vsYxpTM0IA5clAKDyf9RCZyA== +"@svgr/babel-plugin-replace-jsx-attribute-value@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz#0b221fc57f9fcd10e91fe219e2cd0dd03145a897" + integrity sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ== + "@svgr/babel-plugin-replace-jsx-attribute-value@^6.0.0": version "6.0.0" resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.0.0.tgz#0b85837577b02c31c09c758a12932820f5245cee" integrity sha512-88V26WGyt1Sfd1emBYmBJRWMmgarrExpKNVmI9vVozha4kqs6FzQJ/Kp5+EYli1apgX44518/0+t9+NU36lThQ== +"@svgr/babel-plugin-svg-dynamic-title@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz#139b546dd0c3186b6e5db4fefc26cb0baea729d7" + integrity sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg== + "@svgr/babel-plugin-svg-dynamic-title@^6.0.0": version "6.0.0" resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.0.0.tgz#28236ec26f7ab9d486a487d36ae52d58ba15676f" integrity sha512-F7YXNLfGze+xv0KMQxrl2vkNbI9kzT9oDK55/kUuymh1ACyXkMV+VZWX1zEhSTfEKh7VkHVZGmVtHg8eTZ6PRg== +"@svgr/babel-plugin-svg-em-dimensions@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz#6543f69526632a133ce5cabab965deeaea2234a0" + integrity sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw== + "@svgr/babel-plugin-svg-em-dimensions@^6.0.0": version "6.0.0" resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.0.0.tgz#40267c5dea1b43c4f83a0eb6169e08b43d8bafce" integrity sha512-+rghFXxdIqJNLQK08kwPBD3Z22/0b2tEZ9lKiL/yTfuyj1wW8HUXu4bo/XkogATIYuXSghVQOOCwURXzHGKyZA== +"@svgr/babel-plugin-transform-react-native-svg@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz#00bf9a7a73f1cad3948cdab1f8dfb774750f8c80" + integrity sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q== + "@svgr/babel-plugin-transform-react-native-svg@^6.0.0": version "6.0.0" resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.0.0.tgz#eb688d0a5f539e34d268d8a516e81f5d7fede7c9" integrity sha512-VaphyHZ+xIKv5v0K0HCzyfAaLhPGJXSk2HkpYfXIOKb7DjLBv0soHDxNv6X0vr2titsxE7klb++u7iOf7TSrFQ== +"@svgr/babel-plugin-transform-svg-component@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz#583a5e2a193e214da2f3afeb0b9e8d3250126b4a" + integrity sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ== + "@svgr/babel-plugin-transform-svg-component@^6.2.0": version "6.2.0" resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.2.0.tgz#7ba61d9fc1fb42b0ba1a04e4630019fa7e993c4f" integrity sha512-bhYIpsORb++wpsp91fymbFkf09Z/YEKR0DnFjxvN+8JHeCUD2unnh18jIMKnDJTWtvpTaGYPXELVe4OOzFI0xg== +"@svgr/babel-preset@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-5.5.0.tgz#8af54f3e0a8add7b1e2b0fcd5a882c55393df327" + integrity sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig== + dependencies: + "@svgr/babel-plugin-add-jsx-attribute" "^5.4.0" + "@svgr/babel-plugin-remove-jsx-attribute" "^5.4.0" + "@svgr/babel-plugin-remove-jsx-empty-expression" "^5.0.1" + "@svgr/babel-plugin-replace-jsx-attribute-value" "^5.0.1" + "@svgr/babel-plugin-svg-dynamic-title" "^5.4.0" + "@svgr/babel-plugin-svg-em-dimensions" "^5.4.0" + "@svgr/babel-plugin-transform-react-native-svg" "^5.4.0" + "@svgr/babel-plugin-transform-svg-component" "^5.5.0" + "@svgr/babel-preset@^6.2.0": version "6.2.0" resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-6.2.0.tgz#1d3ad8c7664253a4be8e4a0f0e6872f30d8af627" @@ -4488,6 +5789,15 @@ "@svgr/babel-plugin-transform-react-native-svg" "^6.0.0" "@svgr/babel-plugin-transform-svg-component" "^6.2.0" +"@svgr/core@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/core/-/core-5.5.0.tgz#82e826b8715d71083120fe8f2492ec7d7874a579" + integrity sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ== + dependencies: + "@svgr/plugin-jsx" "^5.5.0" + camelcase "^6.2.0" + cosmiconfig "^7.0.0" + "@svgr/core@^6.2.1": version "6.2.1" resolved "https://registry.yarnpkg.com/@svgr/core/-/core-6.2.1.tgz#195de807a9f27f9e0e0d678e01084b05c54fdf61" @@ -4497,6 +5807,13 @@ camelcase "^6.2.0" cosmiconfig "^7.0.1" +"@svgr/hast-util-to-babel-ast@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz#5ee52a9c2533f73e63f8f22b779f93cd432a5461" + integrity sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ== + dependencies: + "@babel/types" "^7.12.6" + "@svgr/hast-util-to-babel-ast@^6.2.1": version "6.2.1" resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.2.1.tgz#ae065567b74cbe745afae617053adf9a764bea25" @@ -4505,6 +5822,16 @@ "@babel/types" "^7.15.6" entities "^3.0.1" +"@svgr/plugin-jsx@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz#1aa8cd798a1db7173ac043466d7b52236b369000" + integrity sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA== + dependencies: + "@babel/core" "^7.12.3" + "@svgr/babel-preset" "^5.5.0" + "@svgr/hast-util-to-babel-ast" "^5.5.0" + svg-parser "^2.0.2" + "@svgr/plugin-jsx@^6.2.1": version "6.2.1" resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-6.2.1.tgz#5668f1d2aa18c2f1bb7a1fc9f682d3f9aed263bd" @@ -4515,6 +5842,15 @@ "@svgr/hast-util-to-babel-ast" "^6.2.1" svg-parser "^2.0.2" +"@svgr/plugin-svgo@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz#02da55d85320549324e201c7b2e53bf431fcc246" + integrity sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ== + dependencies: + cosmiconfig "^7.0.0" + deepmerge "^4.2.2" + svgo "^1.2.2" + "@svgr/plugin-svgo@^6.2.0": version "6.2.0" resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-6.2.0.tgz#4cbe6a33ccccdcae4e3b63ded64cc1cbe1faf48c" @@ -4524,6 +5860,20 @@ deepmerge "^4.2.2" svgo "^2.5.0" +"@svgr/webpack@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-5.5.0.tgz#aae858ee579f5fa8ce6c3166ef56c6a1b381b640" + integrity sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g== + dependencies: + "@babel/core" "^7.12.3" + "@babel/plugin-transform-react-constant-elements" "^7.12.1" + "@babel/preset-env" "^7.12.1" + "@babel/preset-react" "^7.12.5" + "@svgr/core" "^5.5.0" + "@svgr/plugin-jsx" "^5.5.0" + "@svgr/plugin-svgo" "^5.5.0" + loader-utils "^2.0.0" + "@svgr/webpack@^6.1.1": version "6.2.1" resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-6.2.1.tgz#ef5d51c1b6be4e7537fb9f76b3f2b2e22b63c58d" @@ -4538,105 +5888,100 @@ "@svgr/plugin-jsx" "^6.2.1" "@svgr/plugin-svgo" "^6.2.0" -"@tauri-apps/api@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@tauri-apps/api/-/api-1.0.2.tgz#5228720e35d50fd08df87067dc29e7306c1f7a10" - integrity sha512-yuNW0oeJ1/ZA7wNF1KgxhHrSu5viPVzY/UgUczzN5ptLM8dH15Juy5rEGkoHfeXGju90Y/l22hi3BtIrp/za+w== - -"@tauri-apps/api@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@tauri-apps/api/-/api-1.1.0.tgz#2c5756f6aeecd36f7683183eaba021690711bedf" - integrity sha512-n13pIqdPd3KtaMmmAcrU7BTfdMtIlGNnfZD0dNX8L4p8dgmuNyikm6JAA+yCpl9gqq6I8x5cV2Y0muqdgD0cWw== +"@tauri-apps/api@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@tauri-apps/api/-/api-1.2.0.tgz#1f196b3e012971227f41b98214c846430a4eb477" + integrity sha512-lsI54KI6HGf7VImuf/T9pnoejfgkNoXveP14pVV7XarrQ46rOejIVJLFqHI9sRReJMGdh2YuCoI3cc/yCWCsrw== "@tauri-apps/cli-darwin-arm64@1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-1.0.5.tgz#6fd17a8d9e0e7982b5c9887639407fdec783a744" integrity sha512-oxpFb9ZeMiC3xPUJ9NsXWCnnwFSVkPbJUvDKpc9IaoDIUpsMTV72W4P0Nh0uQRbyhx4modPpstt7+ONypNVYNg== -"@tauri-apps/cli-darwin-arm64@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-1.1.1.tgz#c6f4553cfb338f24131910a1ebbe9fe74d89b8ae" - integrity sha512-qBG11ig525/qf0f5OQxn0ON3hT8YdpTfpa4Y4kVqBJhdW50R5fadPv6tv5Dpl2TS2X7nWh/zg5mEXYoCK3HZ9w== +"@tauri-apps/cli-darwin-arm64@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-1.2.2.tgz#f18b0689b399b64dc67da41c0fd4da474be324fe" + integrity sha512-W+Cp2weUMlvmGkRJeUjypbz9Lpl6o98xkgKAtobZSum5SNwpsBQfawJTESakNoD+FXyVg/snIk5sRdHge+tAaA== "@tauri-apps/cli-darwin-x64@1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-1.0.5.tgz#6aaaadd68739c4c4f86546f3d17b2fb60a5a0c04" integrity sha512-hRNYC6L9edz2dEqK33tssPylF2ti6x6udidBlGWc5GSoeEb/05qKMEA1MESQYKBG+4q+wjJvACA2vvz6AfgJ3Q== -"@tauri-apps/cli-darwin-x64@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-1.1.1.tgz#11beb8b3dfc43725f0acd3736cd9d181f93526a2" - integrity sha512-M3dMsp78OdxisbTwAWGvy3jIb3uqThtQcUYVvqOu9LeEOHyldOBFDSht+6PTBpaJLAHFMQK2rmNxiWgigklJaA== +"@tauri-apps/cli-darwin-x64@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-1.2.2.tgz#4450bd244f586da346651f62a5a41686cee36db7" + integrity sha512-vmVAqt+ECH2d6cbcGJ7ddcCAZgmKe5xmxlL5r4xoaphu7OqU4gnv4VFURYkVltOfwzIFQVOPVSqwYyIDToCYNQ== "@tauri-apps/cli-linux-arm-gnueabihf@1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-1.0.5.tgz#d2d01c8b85ee3771656386bfda3852af8ed811da" integrity sha512-hc/Jp3TtFpxB8XVkLEwWy7MNcUBlS8rNCafQBUt4KSElXB+/oGo50jPO+wd5GSMSOR59UCzH08v11P0b+sAa/w== -"@tauri-apps/cli-linux-arm-gnueabihf@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-1.1.1.tgz#f4bd3f5839cfcd69132d213efee09ce5da5c6d90" - integrity sha512-LYlvdAd73cq+yTi6rw7j/DWIvDpeApwgQkIn+HYsNNeFhyFmABU7tmw+pekK3W3nHAkYAJ69Rl4ZdoxdNGKmHg== +"@tauri-apps/cli-linux-arm-gnueabihf@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-1.2.2.tgz#a4d5b95665620605fb0f54cb77f8134239b58370" + integrity sha512-yYTdQurgi4QZR8z+fANjl522jdQz/VtesFpw+C/A0+zXg7tiRjicsywBDdPsvNzCqFeGKKkmTR+Lny5qxhGaeQ== "@tauri-apps/cli-linux-arm64-gnu@1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-1.0.5.tgz#7ca848120c2e90b57188aaa9daee11cf29e2e2f4" integrity sha512-btFlkD2PG+yzJBZzWeJmyCy8ZV+iys2Jl66Fs4g9lSi3KrBDnyfQ26RpGZb2pRfkkcVP8/x1WSfByO+Rj+PTBA== -"@tauri-apps/cli-linux-arm64-gnu@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-1.1.1.tgz#2631b2a68e7901ea7281af022d8826c0d82b9edd" - integrity sha512-o/hbMQIKuFI7cTNpeQBHD/OCNJOBIci78faKms/t6AstLXx0QJuRHDk477Rg6VVy/I3BBKbyATALbmcTq+ti0A== +"@tauri-apps/cli-linux-arm64-gnu@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-1.2.2.tgz#c992907586b42e2085160d45b3a17316c99febea" + integrity sha512-ZSOVT6Eq1ay2+27B8KfA0MnpO7KYzONU6TjenH7DNcQki6eWGG5JoNu8QQ9Mdn3dAzY0XBP9i1ZHQOFu4iPtEg== "@tauri-apps/cli-linux-arm64-musl@1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.0.5.tgz#5ba65790849e0737f560f3ccd12f7a2a88c25b23" integrity sha512-p5JFdWab2AWhfgAZW/mgOLu+YiIJXKV0NdATGmdiBgQCMmz1k/FM8iOFApCgGbo3/zkR58cJ7Z7hyWmQ07M6Pw== -"@tauri-apps/cli-linux-arm64-musl@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.1.1.tgz#11a4bdc52696583152fc70ea373cf31717cb0f4c" - integrity sha512-8Ci4qlDnXIp93XqUrtzFCBDatUzPHpZq7L3bociUbWpvy/bnlzxp1C/C+vwdc4uS1MiAp9v3BFgrU4i0f0Z3QQ== +"@tauri-apps/cli-linux-arm64-musl@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.2.2.tgz#f8bd7901ce525b8433919e2cfe7ec22aace0f776" + integrity sha512-/NHSkqNQ+Pr4PshvyD1CeNFaPCaCpe1OeuAQgVi0rboSecC9fXN96G5dQbSBoxOUcCo6f8aTVE7zkZ4WchFVog== "@tauri-apps/cli-linux-x64-gnu@1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-1.0.5.tgz#d06430c608316cb5a29ec805d4c5d078a293c3ae" integrity sha512-fOXR635AXxwSO7MCfBhMLnGpcg1H83XGw9ocuyg4jjvtE8QoYPwC4ksfb5lLhDVMui9iIKY93NAK3EkQiSGGmQ== -"@tauri-apps/cli-linux-x64-gnu@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-1.1.1.tgz#11acbcc4743562cc8166c92ffc3bc12f68e0987f" - integrity sha512-ES4Bkx2JAI8+dDNDJswhLS3yqt+yT/4C6UfGOPIHFxcXUh6fe36eUllrTt+HLRS9xTZbYnteJy7ebq2TqMkaxw== +"@tauri-apps/cli-linux-x64-gnu@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-1.2.2.tgz#a558862d7101b0a641c5a994c9ee74edb8300fc5" + integrity sha512-4YTmfPuyvlHsvCkATDMwhklfuQm3HKxYXv/IOW9H0ra6pS9efVhrFYIC9Vfv6XaKN85Vnn/FYTEGMJLwCxZw2Q== "@tauri-apps/cli-linux-x64-musl@1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-1.0.5.tgz#813c90531f4001453e73b3ad2d4c75929412a249" integrity sha512-8be4zJVkuMs427JqONhFx5Ia5zWsQ5tbZXd80C3dHNL+5/3VIOK6nGQ0iijyZSLXiE9JKEH2jp1EHB+1TVJRcw== -"@tauri-apps/cli-linux-x64-musl@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-1.1.1.tgz#7dd81b8380d7e7183fb43a2ccbbc26931718204a" - integrity sha512-qrN1WOMAaDl+LE8P8iO0+DYlrWNTc9jIu/CsnVY/LImTn79ZPxEkcVBo0UGeKRI7f10TfvkVmLCBLxTz8QhEyA== +"@tauri-apps/cli-linux-x64-musl@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-1.2.2.tgz#573e965a638864a65b606783d3dbd34114939277" + integrity sha512-wr46tbscwFuCcA931R+ItOiUTT0djMmgKLd1HFCmFF82V9BKE2reIjr6O9l0NCXCo2WeD4pe3jA/Pt1dxDu+JA== "@tauri-apps/cli-win32-ia32-msvc@1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-1.0.5.tgz#a3eb6f56c3f4ba35f6311e1fb31bd30e6892b316" integrity sha512-WpnIfzS1e4InGhvd1IDSKC3w6kbI5c6oJgMmtkMTBlhjhiZXhZmQF4XA784A5Y13pzsbXnbNJKOp8DuPVkoTRQ== -"@tauri-apps/cli-win32-ia32-msvc@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-1.1.1.tgz#1d106ae1c3766f95d7f49bac51eba0d2cd2daf33" - integrity sha512-vw7VOmrQlywHhFV3pf54udf2FRNj9dg9WP1gL0My55FnB+w+PWS9Ipm871kX5qepmChdnZHKq9fsqE2uTjX//Q== +"@tauri-apps/cli-win32-ia32-msvc@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-1.2.2.tgz#0fe38283ffeb71acac6a6a317951dc75ec2d3dad" + integrity sha512-6VmbVJOWUZJK5/JKhb3mNFKrKGfq0KV7lJGumfN95WJgkHeyL61p8bZit+o6ZgUGUhrOabkAawhDkrRY+ZQhIw== "@tauri-apps/cli-win32-x64-msvc@1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-1.0.5.tgz#f1e0860166e8f86b550e35aaf22ef95d6da5a7c8" integrity sha512-8iEhVD3X4LZfrlxEPOV+mAj4QrJrEqKTICiJnwmgjvhYQOOsNHzg5kca7pcBbqcgorQOBydLpfGJtxWRusVPaw== -"@tauri-apps/cli-win32-x64-msvc@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-1.1.1.tgz#ce931d299fcc8c60aceec3f9e18b0987f9951c25" - integrity sha512-OukxlLLi3AoCN4ABnqCDTiiC7xJGWukAjrKCIx7wFISrLjNfsrnH7/UOzuopfGpZChSe2c+AamVmcpBfVsEmJA== +"@tauri-apps/cli-win32-x64-msvc@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-1.2.2.tgz#9b8ea7c63f2883af105e204fc4f1f11a83990a59" + integrity sha512-YRPJguJma+zSuRZpFoSZqls6+laggG1vqG0FPQWQTi+ywATgMpai2b2RZnffDlpHKp9mt4V/s2dtqOy6bpGZHg== "@tauri-apps/cli@^1.0.5": version "1.0.5" @@ -4653,20 +5998,20 @@ "@tauri-apps/cli-win32-ia32-msvc" "1.0.5" "@tauri-apps/cli-win32-x64-msvc" "1.0.5" -"@tauri-apps/cli@^1.1.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli/-/cli-1.1.1.tgz#480d5e1ab758aa1d7efcbf97d801bf9812b15cd4" - integrity sha512-80kjMEMPBwLYCp0tTKSquy90PHHGGBvZsneNr3B/mWxNsvjzA1C0vOyGJGFrJuT2OmkvrdvuJZ5mch5hL8O1Xg== +"@tauri-apps/cli@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli/-/cli-1.2.2.tgz#cf7cb90d11c3c3b757efe07b7e2c48abde045ada" + integrity sha512-D8zib3A0vWCvPPSyYLxww/OdDlVcY7fpcDVBH6qUvheOjj2aCyU7H9AYMRBwpgCfz8zY5+vomee+laLeB0H13w== optionalDependencies: - "@tauri-apps/cli-darwin-arm64" "1.1.1" - "@tauri-apps/cli-darwin-x64" "1.1.1" - "@tauri-apps/cli-linux-arm-gnueabihf" "1.1.1" - "@tauri-apps/cli-linux-arm64-gnu" "1.1.1" - "@tauri-apps/cli-linux-arm64-musl" "1.1.1" - "@tauri-apps/cli-linux-x64-gnu" "1.1.1" - "@tauri-apps/cli-linux-x64-musl" "1.1.1" - "@tauri-apps/cli-win32-ia32-msvc" "1.1.1" - "@tauri-apps/cli-win32-x64-msvc" "1.1.1" + "@tauri-apps/cli-darwin-arm64" "1.2.2" + "@tauri-apps/cli-darwin-x64" "1.2.2" + "@tauri-apps/cli-linux-arm-gnueabihf" "1.2.2" + "@tauri-apps/cli-linux-arm64-gnu" "1.2.2" + "@tauri-apps/cli-linux-arm64-musl" "1.2.2" + "@tauri-apps/cli-linux-x64-gnu" "1.2.2" + "@tauri-apps/cli-linux-x64-musl" "1.2.2" + "@tauri-apps/cli-win32-ia32-msvc" "1.2.2" + "@tauri-apps/cli-win32-x64-msvc" "1.2.2" "@tauri-apps/tauri-forage@^1.0.0-beta.2": version "1.0.0-beta.2" @@ -4692,6 +6037,20 @@ lz-string "^1.4.4" pretty-format "^27.0.2" +"@testing-library/dom@^8.5.0": + version "8.19.0" + resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.19.0.tgz#bd3f83c217ebac16694329e413d9ad5fdcfd785f" + integrity sha512-6YWYPPpxG3e/xOo6HIWwB/58HukkwIVTOaZ0VwdMVjhRUX/01E4FtQbck9GazOOj7MXHc5RBzMrU86iBJHbI+A== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/runtime" "^7.12.5" + "@types/aria-query" "^4.2.0" + aria-query "^5.0.0" + chalk "^4.1.0" + dom-accessibility-api "^0.5.9" + lz-string "^1.4.4" + pretty-format "^27.0.2" + "@testing-library/jest-dom@^5.14.1": version "5.16.2" resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.16.2.tgz#f329b36b44aa6149cd6ced9adf567f8b6aa1c959" @@ -4707,6 +6066,21 @@ lodash "^4.17.15" redent "^3.0.0" +"@testing-library/jest-dom@^5.16.5": + version "5.16.5" + resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz#3912846af19a29b2dbf32a6ae9c31ef52580074e" + integrity sha512-N5ixQ2qKpi5OLYfwQmUb/5mSV9LneAcaUfp32pn4yCnpb8r/Yz0pXFPck21dIicKmi+ta5WRAknkZCfA8refMA== + dependencies: + "@adobe/css-tools" "^4.0.1" + "@babel/runtime" "^7.9.2" + "@types/testing-library__jest-dom" "^5.9.1" + aria-query "^5.0.0" + chalk "^3.0.0" + css.escape "^1.5.1" + dom-accessibility-api "^0.5.6" + lodash "^4.17.15" + redent "^3.0.0" + "@testing-library/react@^12.0.0": version "12.1.3" resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-12.1.3.tgz#ef26c5f122661ea9b6f672b23dc6b328cadbbf26" @@ -4716,7 +6090,16 @@ "@testing-library/dom" "^8.0.0" "@types/react-dom" "*" -"@testing-library/user-event@^13.2.1": +"@testing-library/react@^13.4.0": + version "13.4.0" + resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-13.4.0.tgz#6a31e3bf5951615593ad984e96b9e5e2d9380966" + integrity sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw== + dependencies: + "@babel/runtime" "^7.12.5" + "@testing-library/dom" "^8.5.0" + "@types/react-dom" "^18.0.0" + +"@testing-library/user-event@^13.2.1", "@testing-library/user-event@^13.5.0": version "13.5.0" resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-13.5.0.tgz#69d77007f1e124d55314a2b73fd204b333b13295" integrity sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg== @@ -4733,6 +6116,33 @@ resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== +"@tsconfig/node10@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" + integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e" + integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== + +"@types/acorn@^4.0.0": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@types/acorn/-/acorn-4.0.6.tgz#d61ca5480300ac41a7d973dd5b84d0a591154a22" + integrity sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ== + dependencies: + "@types/estree" "*" + "@types/aria-query@^4.2.0": version "4.2.2" resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.2.tgz#ed4e0ad92306a704f9fb132a0cfcf77486dbe2bc" @@ -4876,6 +6286,13 @@ "@types/d3-interpolate" "^1" "@types/d3-selection" "^1" +"@types/debug@^4.0.0": + version "4.1.7" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82" + integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg== + dependencies: + "@types/ms" "*" + "@types/eslint-scope@^3.7.3": version "3.7.3" resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.3.tgz#125b88504b61e3c8bc6f870882003253005c3224" @@ -4892,11 +6309,36 @@ "@types/estree" "*" "@types/json-schema" "*" +"@types/eslint@^7.29.0 || ^8.4.1": + version "8.4.10" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.10.tgz#19731b9685c19ed1552da7052b6f668ed7eb64bb" + integrity sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree-jsx@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/estree-jsx/-/estree-jsx-1.0.0.tgz#7bfc979ab9f692b492017df42520f7f765e98df1" + integrity sha512-3qvGd0z8F2ENTGr/GG1yViqfiKmRfrXVx5sJyHGFu3z7m5g5utCQtGp/g29JnjflhtQJBv1WDQukHiT58xPcYQ== + dependencies: + "@types/estree" "*" + "@types/estree@*", "@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/estree@0.0.39": + version "0.0.39" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" + integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== + +"@types/estree@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" + integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== + "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": version "4.17.28" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz#c47def9f34ec81dc6328d0b1b5303d1ec98d86b8" @@ -5004,6 +6446,14 @@ jest-matcher-utils "^27.0.0" pretty-format "^27.0.0" +"@types/jest@^27.5.2": + version "27.5.2" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.5.2.tgz#ec49d29d926500ffb9fd22b84262e862049c026c" + integrity sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA== + dependencies: + jest-matcher-utils "^27.0.0" + pretty-format "^27.0.0" + "@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.9" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" @@ -5036,6 +6486,16 @@ dependencies: "@types/unist" "*" +"@types/mdx@^2.0.0": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/mdx/-/mdx-2.0.3.tgz#43fd32414f17fcbeced3578109a6edd877a2d96e" + integrity sha512-IgHxcT3RC8LzFLhKwP3gbMPeaK7BM9eBH46OdapPA7yvuIUJ8H6zHZV53J8hGZcTSnt95jANt+rTBNUUc22ACQ== + +"@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/mime@^1": version "1.3.2" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" @@ -5051,6 +6511,11 @@ resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== +"@types/ms@*": + version "0.7.31" + resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" + integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== + "@types/node-fetch@^2.5.7": version "2.6.1" resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.1.tgz#8f127c50481db65886800ef496f20bbf15518975" @@ -5079,6 +6544,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.39.tgz#07223cd2bc332ad9d92135e3a522eebdee3b060e" integrity sha512-K0MsdV42vPwm9L6UwhIxMAOmcvH/1OoVkZyCgEtVu4Wx7sElGloy/W7kMBNe/oJ7V/jW9BVt1F6RahH6e7tPXw== +"@types/node@^16.18.3": + version "16.18.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.3.tgz#d7f7ba828ad9e540270f01ce00d391c54e6e0abc" + integrity sha512-jh6m0QUhIRcZpNv7Z/rpN+ZWXOicUUQbSoWks7Htkbb9IjFQj4kzcX/xFCkjstCj5flMsN8FiSvt+q+Tcs4Llg== + "@types/normalize-package-data@^2.4.0": version "2.4.1" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" @@ -5114,11 +6584,16 @@ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11" integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ== -"@types/prop-types@^15.7.5": +"@types/prop-types@^15.0.0", "@types/prop-types@^15.7.5": version "15.7.5" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== +"@types/q@^1.5.1": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.5.tgz#75a2a8e7d8ab4b230414505d92335d1dcb53a6df" + integrity sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ== + "@types/qrcode.react@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@types/qrcode.react/-/qrcode.react-1.0.2.tgz#f892432cc41b5dac52e3ca8873b717c8bfea6002" @@ -5143,6 +6618,13 @@ dependencies: "@types/react" "*" +"@types/react-dom@^18.0.0", "@types/react-dom@^18.0.8": + version "18.0.9" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.9.tgz#ffee5e4bfc2a2f8774b15496474f8e7fe8d0b504" + integrity sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg== + dependencies: + "@types/react" "*" + "@types/react-is@^16.7.1 || ^17.0.0": version "17.0.3" resolved "https://registry.yarnpkg.com/@types/react-is/-/react-is-17.0.3.tgz#2d855ba575f2fc8d17ef9861f084acc4b90a137a" @@ -5190,6 +6672,22 @@ "@types/scheduler" "*" csstype "^3.0.2" +"@types/react@^18.0.25": + version "18.0.25" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.25.tgz#8b1dcd7e56fe7315535a4af25435e0bb55c8ae44" + integrity sha512-xD6c0KDT4m7n9uD4ZHi02lzskaiqcBxf4zi+tXZY98a04wvc0hi/TcCPC2FOESZi51Nd7tlUeOJY8RofL799/g== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/resolve@1.17.1": + version "1.17.1" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" + integrity sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw== + dependencies: + "@types/node" "*" + "@types/retry@^0.12.0": version "0.12.1" resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065" @@ -5200,6 +6698,11 @@ resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== +"@types/semver@^7.3.12": + version "7.3.13" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.13.tgz#da4bfd73f49bd541d28920ab0e2bf0ee80f71c91" + integrity sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw== + "@types/semver@^7.3.8": version "7.3.9" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.9.tgz#152c6c20a7688c30b967ec1841d31ace569863fc" @@ -5220,6 +6723,14 @@ "@types/mime" "^1" "@types/node" "*" +"@types/serve-static@^1.13.10": + version "1.15.0" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.0.tgz#c7930ff61afb334e121a9da780aac0d9b8f34155" + integrity sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg== + 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" @@ -5264,6 +6775,11 @@ dependencies: "@types/geojson" "*" +"@types/trusted-types@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756" + integrity sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg== + "@types/uglify-js@*": version "3.13.1" resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.13.1.tgz#5e889e9e81e94245c75b6450600e1c5ea2878aea" @@ -5314,6 +6830,13 @@ dependencies: "@types/node" "*" +"@types/ws@^8.5.1": + version "8.5.3" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" + integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== + dependencies: + "@types/node" "*" + "@types/yargs-parser@*": version "21.0.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" @@ -5355,6 +6878,21 @@ semver "^7.3.5" tsutils "^3.21.0" +"@typescript-eslint/eslint-plugin@^5.5.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.45.0.tgz#ffa505cf961d4844d38cfa19dcec4973a6039e41" + integrity sha512-CXXHNlf0oL+Yg021cxgOdMHNTXD17rHkq7iW6RFHoybdFgQBjU3yIXhhcPpGwr1CjZlo6ET8C6tzX5juQoXeGA== + dependencies: + "@typescript-eslint/scope-manager" "5.45.0" + "@typescript-eslint/type-utils" "5.45.0" + "@typescript-eslint/utils" "5.45.0" + debug "^4.3.4" + ignore "^5.2.0" + natural-compare-lite "^1.4.0" + regexpp "^3.2.0" + semver "^7.3.7" + tsutils "^3.21.0" + "@typescript-eslint/eslint-plugin@^5.7.0": version "5.30.6" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.30.6.tgz#9c6017b6c1d04894141b4a87816388967f64c359" @@ -5370,6 +6908,13 @@ semver "^7.3.7" tsutils "^3.21.0" +"@typescript-eslint/experimental-utils@^5.0.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.45.0.tgz#b59fea61a855cb2b1fdbd0fb45934a844f4bf870" + integrity sha512-DnRQg5+3uHHt/gaifTjwg9OKbg9/TWehfJzYHQIDJboPEbF897BKDE/qoqMhW7nf0jWRV1mwVXTaUvtB1/9Gwg== + dependencies: + "@typescript-eslint/utils" "5.45.0" + "@typescript-eslint/experimental-utils@^5.3.0": version "5.14.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.14.0.tgz#73a455cd975d52830360a5b4131b7c4f8f1ff06f" @@ -5387,6 +6932,16 @@ "@typescript-eslint/typescript-estree" "5.13.0" debug "^4.3.2" +"@typescript-eslint/parser@^5.5.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.45.0.tgz#b18a5f6b3cf1c2b3e399e9d2df4be40d6b0ddd0e" + integrity sha512-brvs/WSM4fKUmF5Ot/gEve6qYiCMjm6w4HkHPfS6ZNmxTS0m0iNN4yOChImaCkqc1hRwFGqUyanMXuGal6oyyQ== + dependencies: + "@typescript-eslint/scope-manager" "5.45.0" + "@typescript-eslint/types" "5.45.0" + "@typescript-eslint/typescript-estree" "5.45.0" + debug "^4.3.4" + "@typescript-eslint/parser@^5.7.0": version "5.30.6" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.30.6.tgz#add440db038fa9d777e4ebdaf66da9e7fb7abe92" @@ -5421,6 +6976,14 @@ "@typescript-eslint/types" "5.30.6" "@typescript-eslint/visitor-keys" "5.30.6" +"@typescript-eslint/scope-manager@5.45.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.45.0.tgz#7a4ac1bfa9544bff3f620ab85947945938319a96" + integrity sha512-noDMjr87Arp/PuVrtvN3dXiJstQR1+XlQ4R1EvzG+NMgXi8CuMCXpb8JqNtFHKceVSQ985BZhfRdowJzbv4yKw== + dependencies: + "@typescript-eslint/types" "5.45.0" + "@typescript-eslint/visitor-keys" "5.45.0" + "@typescript-eslint/type-utils@5.13.0": version "5.13.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.13.0.tgz#b0efd45c85b7bab1125c97b752cab3a86c7b615d" @@ -5439,6 +7002,16 @@ debug "^4.3.4" tsutils "^3.21.0" +"@typescript-eslint/type-utils@5.45.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.45.0.tgz#aefbc954c40878fcebeabfb77d20d84a3da3a8b2" + integrity sha512-DY7BXVFSIGRGFZ574hTEyLPRiQIvI/9oGcN8t1A7f6zIs6ftbrU0nhyV26ZW//6f85avkwrLag424n+fkuoJ1Q== + dependencies: + "@typescript-eslint/typescript-estree" "5.45.0" + "@typescript-eslint/utils" "5.45.0" + debug "^4.3.4" + tsutils "^3.21.0" + "@typescript-eslint/types@5.13.0": version "5.13.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.13.0.tgz#da1de4ae905b1b9ff682cab0bed6b2e3be9c04e5" @@ -5454,6 +7027,11 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.30.6.tgz#86369d0a7af8c67024115ac1da3e8fb2d38907e1" integrity sha512-HdnP8HioL1F7CwVmT4RaaMX57RrfqsOMclZc08wGMiDYJBsLGBM7JwXM4cZJmbWLzIR/pXg1kkrBBVpxTOwfUg== +"@typescript-eslint/types@5.45.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.45.0.tgz#794760b9037ee4154c09549ef5a96599621109c5" + integrity sha512-QQij+u/vgskA66azc9dCmx+rev79PzX8uDHpsqSjEFtfF2gBUTRCpvYMh2gw2ghkJabNkPlSUCimsyBEQZd1DA== + "@typescript-eslint/typescript-estree@5.13.0": version "5.13.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.13.0.tgz#b37c07b748ff030a3e93d87c842714e020b78141" @@ -5493,6 +7071,19 @@ semver "^7.3.7" tsutils "^3.21.0" +"@typescript-eslint/typescript-estree@5.45.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.45.0.tgz#f70a0d646d7f38c0dfd6936a5e171a77f1e5291d" + integrity sha512-maRhLGSzqUpFcZgXxg1qc/+H0bT36lHK4APhp0AEUVrpSwXiRAomm/JGjSG+kNUio5kAa3uekCYu/47cnGn5EQ== + dependencies: + "@typescript-eslint/types" "5.45.0" + "@typescript-eslint/visitor-keys" "5.45.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + "@typescript-eslint/utils@5.13.0", "@typescript-eslint/utils@^5.10.0": version "5.13.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.13.0.tgz#2328feca700eb02837298339a2e49c46b41bd0af" @@ -5529,6 +7120,20 @@ eslint-scope "^5.1.1" eslint-utils "^3.0.0" +"@typescript-eslint/utils@5.45.0", "@typescript-eslint/utils@^5.13.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.45.0.tgz#9cca2996eee1b8615485a6918a5c763629c7acf5" + integrity sha512-OUg2JvsVI1oIee/SwiejTot2OxwU8a7UfTFMOdlhD2y+Hl6memUSL4s98bpUTo8EpVEr0lmwlU7JSu/p2QpSvA== + dependencies: + "@types/json-schema" "^7.0.9" + "@types/semver" "^7.3.12" + "@typescript-eslint/scope-manager" "5.45.0" + "@typescript-eslint/types" "5.45.0" + "@typescript-eslint/typescript-estree" "5.45.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + semver "^7.3.7" + "@typescript-eslint/visitor-keys@5.13.0": version "5.13.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.13.0.tgz#f45ff55bcce16403b221ac9240fbeeae4764f0fd" @@ -5553,6 +7158,14 @@ "@typescript-eslint/types" "5.30.6" eslint-visitor-keys "^3.3.0" +"@typescript-eslint/visitor-keys@5.45.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.45.0.tgz#e0d160e9e7fdb7f8da697a5b78e7a14a22a70528" + integrity sha512-jc6Eccbn2RtQPr1s7th6jJWQHBHI6GBVQkCHoJFQ5UreaKm59Vxw+ynQUPPY2u2Amquc+7tmEoC2G52ApsGNNg== + dependencies: + "@typescript-eslint/types" "5.45.0" + eslint-visitor-keys "^3.3.0" + "@ungap/promise-all-settled@1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" @@ -5890,26 +7503,45 @@ acorn-import-assertions@^1.7.6: resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== -acorn-jsx@^5.3.1: +acorn-jsx@^5.0.0, acorn-jsx@^5.3.1, acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn-walk@^7.1.1, acorn-walk@^7.2.0: +acorn-node@^1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/acorn-node/-/acorn-node-1.8.2.tgz#114c95d64539e53dede23de8b9d96df7c7ae2af8" + integrity sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A== + dependencies: + acorn "^7.0.0" + acorn-walk "^7.0.0" + xtend "^4.0.2" + +acorn-walk@^7.0.0, acorn-walk@^7.1.1, acorn-walk@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== +acorn-walk@^8.1.1: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + acorn@^6.4.1: version "6.4.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== -acorn@^7.1.1, acorn@^7.4.0, acorn@^7.4.1: +acorn@^7.0.0, acorn@^7.1.1, acorn@^7.4.0, acorn@^7.4.1: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== +acorn@^8.0.0, acorn@^8.7.1, acorn@^8.8.0: + version "8.8.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" + integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== + acorn@^8.2.4, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.0: version "8.7.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" @@ -5925,6 +7557,19 @@ address@^1.0.1: resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== +address@^1.1.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/address/-/address-1.2.1.tgz#25bb61095b7522d65b357baa11bc05492d4c8acd" + integrity sha512-B+6bi5D34+fDYENiH5qOlA0cV2rAGKuWZ9LeyUUehbXy8e0VS9e498yO0Jeeh+iM+6KbfudHTFjXw2MmJD4QRA== + +adjust-sourcemap-loader@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz#fc4a0fd080f7d10471f30a7320f25560ade28c99" + integrity sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A== + dependencies: + loader-utils "^2.0.0" + regex-parser "^2.2.11" + agent-base@6, agent-base@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -6026,6 +7671,16 @@ ajv@^8.0.1: require-from-string "^2.0.2" uri-js "^4.2.2" +ajv@^8.6.0: + version "8.11.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.2.tgz#aecb20b50607acf2569b6382167b65a96008bb78" + integrity sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg== + 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-align@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" @@ -6048,7 +7703,7 @@ ansi-colors@^4.1.1: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== -ansi-escapes@^4.2.1: +ansi-escapes@^4.2.1, ansi-escapes@^4.3.1: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== @@ -6148,6 +7803,16 @@ are-we-there-yet@~1.1.2: delegates "^1.0.0" readable-stream "^2.0.6" +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +arg@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" + integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -6203,7 +7868,7 @@ array-flatten@1.1.1: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= -array-flatten@^2.1.0: +array-flatten@^2.1.0, 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== @@ -6224,6 +7889,17 @@ array-includes@^3.0.3, array-includes@^3.1.3, array-includes@^3.1.4: get-intrinsic "^1.1.1" is-string "^1.0.7" +array-includes@^3.1.6: + version "3.1.6" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.6.tgz#9e9e720e194f198266ba9e18c29e6a9b0e4b225f" + integrity sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + get-intrinsic "^1.1.3" + is-string "^1.0.7" + array-union@^1.0.1, array-union@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" @@ -6264,6 +7940,16 @@ array.prototype.flatmap@^1.2.1, array.prototype.flatmap@^1.2.5: define-properties "^1.1.3" es-abstract "^1.19.0" +array.prototype.flatmap@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz#1aae7903c2100433cb8261cd4ed310aab5c4a183" + integrity sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + es-shim-unscopables "^1.0.0" + array.prototype.map@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/array.prototype.map/-/array.prototype.map-1.0.4.tgz#0d97b640cfdd036c1b41cfe706a5e699aa0711f2" @@ -6275,6 +7961,28 @@ array.prototype.map@^1.0.4: es-array-method-boxes-properly "^1.0.0" is-string "^1.0.7" +array.prototype.reduce@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz#6b20b0daa9d9734dd6bc7ea66b5bbce395471eac" + integrity sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + es-array-method-boxes-properly "^1.0.0" + is-string "^1.0.7" + +array.prototype.tosorted@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz#ccf44738aa2b5ac56578ffda97c03fd3e23dd532" + integrity sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + es-shim-unscopables "^1.0.0" + get-intrinsic "^1.1.3" + arrify@^1.0.0, arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" @@ -6285,7 +7993,7 @@ arrify@^2.0.1: resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== -asap@^2.0.0: +asap@^2.0.0, asap@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= @@ -6342,6 +8050,11 @@ astral-regex@^2.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== +astring@^1.8.0: + version "1.8.3" + resolved "https://registry.yarnpkg.com/astring/-/astring-1.8.3.tgz#1a0ae738c7cc558f8e5ddc8e3120636f5cebcb85" + integrity sha512-sRpyiNrx2dEYIMmUXprS8nlpRg2Drs8m9ElX9vVEXaCB4XEAJhKfs7IcX0IwShjuOAjLR6wzIrgoptz1n19i1A== + async-each@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" @@ -6354,6 +8067,11 @@ async@^2.6.2: dependencies: lodash "^4.17.14" +async@^3.2.3: + version "3.2.4" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" + integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -6379,6 +8097,18 @@ author-regex@^1.0.0: resolved "https://registry.yarnpkg.com/author-regex/-/author-regex-1.0.0.tgz#d08885be6b9bbf9439fe087c76287245f0a81450" integrity sha1-0IiFvmubv5Q5/gh8dihyRfCoFFA= +autoprefixer@^10.4.12, autoprefixer@^10.4.13: + version "10.4.13" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.13.tgz#b5136b59930209a321e9fa3dca2e7c4d223e83a8" + integrity sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg== + dependencies: + browserslist "^4.21.4" + caniuse-lite "^1.0.30001426" + fraction.js "^4.2.0" + normalize-range "^0.1.2" + picocolors "^1.0.0" + postcss-value-parser "^4.2.0" + autoprefixer@^9.8.6: version "9.8.8" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.8.tgz#fd4bd4595385fa6f06599de749a4d5f7a474957a" @@ -6426,7 +8156,7 @@ axobject-query@^2.2.0: resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA== -babel-jest@^27.5.1: +babel-jest@^27.4.2, babel-jest@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.5.1.tgz#a1bf8d61928edfefd21da27eb86a695bfd691444" integrity sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg== @@ -6523,7 +8253,7 @@ babel-plugin-macros@^2.0.0, babel-plugin-macros@^2.6.1: cosmiconfig "^6.0.0" resolve "^1.12.0" -babel-plugin-macros@^3.0.1: +babel-plugin-macros@^3.0.1, babel-plugin-macros@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg== @@ -6532,6 +8262,11 @@ babel-plugin-macros@^3.0.1: cosmiconfig "^7.0.0" resolve "^1.19.0" +babel-plugin-named-asset-import@^0.3.8: + version "0.3.8" + resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz#6b7fa43c59229685368683c28bc9734f24524cc2" + integrity sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q== + babel-plugin-named-exports-order@^0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/babel-plugin-named-exports-order/-/babel-plugin-named-exports-order-0.0.2.tgz#ae14909521cf9606094a2048239d69847540cb09" @@ -6546,6 +8281,15 @@ babel-plugin-polyfill-corejs2@^0.3.0: "@babel/helper-define-polyfill-provider" "^0.3.1" semver "^6.1.1" +babel-plugin-polyfill-corejs2@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz#5d1bd3836d0a19e1b84bbf2d9640ccb6f951c122" + integrity sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q== + dependencies: + "@babel/compat-data" "^7.17.7" + "@babel/helper-define-polyfill-provider" "^0.3.3" + semver "^6.1.1" + babel-plugin-polyfill-corejs3@^0.1.0: version "0.1.7" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.1.7.tgz#80449d9d6f2274912e05d9e182b54816904befd0" @@ -6562,6 +8306,14 @@ babel-plugin-polyfill-corejs3@^0.5.0: "@babel/helper-define-polyfill-provider" "^0.3.1" core-js-compat "^3.21.0" +babel-plugin-polyfill-corejs3@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz#56ad88237137eade485a71b52f72dbed57c6230a" + integrity sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.3.3" + core-js-compat "^3.25.1" + babel-plugin-polyfill-regenerator@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz#2c0678ea47c75c8cc2fbb1852278d8fb68233990" @@ -6569,6 +8321,13 @@ babel-plugin-polyfill-regenerator@^0.3.0: dependencies: "@babel/helper-define-polyfill-provider" "^0.3.1" +babel-plugin-polyfill-regenerator@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz#390f91c38d90473592ed43351e801a9d3e0fd747" + integrity sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.3.3" + babel-plugin-react-docgen@^4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/babel-plugin-react-docgen/-/babel-plugin-react-docgen-4.2.1.tgz#7cc8e2f94e8dc057a06e953162f0810e4e72257b" @@ -6597,6 +8356,11 @@ babel-plugin-syntax-jsx@^6.18.0: resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY= +babel-plugin-transform-react-remove-prop-types@^0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz#f2edaf9b4c6a5fbe5c1d678bfb531078c1555f3a" + integrity sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA== + babel-preset-current-node-syntax@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" @@ -6623,11 +8387,38 @@ babel-preset-jest@^27.5.1: babel-plugin-jest-hoist "^27.5.1" babel-preset-current-node-syntax "^1.0.0" +babel-preset-react-app@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-react-app/-/babel-preset-react-app-10.0.1.tgz#ed6005a20a24f2c88521809fa9aea99903751584" + integrity sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg== + dependencies: + "@babel/core" "^7.16.0" + "@babel/plugin-proposal-class-properties" "^7.16.0" + "@babel/plugin-proposal-decorators" "^7.16.4" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.16.0" + "@babel/plugin-proposal-numeric-separator" "^7.16.0" + "@babel/plugin-proposal-optional-chaining" "^7.16.0" + "@babel/plugin-proposal-private-methods" "^7.16.0" + "@babel/plugin-transform-flow-strip-types" "^7.16.0" + "@babel/plugin-transform-react-display-name" "^7.16.0" + "@babel/plugin-transform-runtime" "^7.16.4" + "@babel/preset-env" "^7.16.4" + "@babel/preset-react" "^7.16.0" + "@babel/preset-typescript" "^7.16.0" + "@babel/runtime" "^7.16.3" + babel-plugin-macros "^3.1.0" + babel-plugin-transform-react-remove-prop-types "^0.4.24" + bail@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776" integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ== +bail@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/bail/-/bail-2.0.2.tgz#d26f5cd8fe5d6f832a31517b9f7c356040ba6d5d" + integrity sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw== + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" @@ -6687,6 +8478,16 @@ better-opn@^2.1.1: dependencies: open "^7.0.3" +bfj@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/bfj/-/bfj-7.0.2.tgz#1988ce76f3add9ac2913fd8ba47aad9e651bfbb2" + integrity sha512-+e/UqUzwmzJamNF50tBV6tZPTORow7gQ96iFow+8b562OdMpEK0BcJEq2OSPEDmAbSMBQ7PKZ87ubFkgxpYWgw== + dependencies: + bluebird "^3.5.5" + check-types "^11.1.1" + hoopy "^0.1.4" + tryer "^1.0.1" + big-integer@^1.6.7: version "1.6.51" resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" @@ -6774,6 +8575,34 @@ body-parser@1.19.2: raw-body "2.4.3" type-is "~1.6.18" +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.0.14" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.14.tgz#c346f5bc84e87802d08f8d5a60b93f758e514ee7" + integrity sha512-HIMbgLnk1Vqvs6B4Wq5ep7mxvj9sGz5d1JJyDNSGNIdA/w2MCz6GTjWTdjqOJV1bEPj+6IkxDvWNFKEBxNt4kQ== + dependencies: + array-flatten "^2.1.2" + dns-equal "^1.0.0" + fast-deep-equal "^3.1.3" + multicast-dns "^7.2.5" + bonjour@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" @@ -6786,7 +8615,7 @@ bonjour@^3.5.0: multicast-dns "^6.0.1" multicast-dns-service-types "^1.1.0" -boolbase@^1.0.0: +boolbase@^1.0.0, boolbase@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= @@ -6843,7 +8672,7 @@ braces@^2.3.1, braces@^2.3.2: split-string "^3.0.2" to-regex "^3.0.1" -braces@^3.0.1, braces@~3.0.2: +braces@^3.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== @@ -6953,6 +8782,16 @@ browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.17.5, browserslist@^ node-releases "^2.0.2" picocolors "^1.0.0" +browserslist@^4.18.1, browserslist@^4.21.3, browserslist@^4.21.4: + version "4.21.4" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" + integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== + dependencies: + caniuse-lite "^1.0.30001400" + electron-to-chromium "^1.4.251" + node-releases "^2.0.6" + update-browserslist-db "^1.0.9" + bs-logger@0.x: version "0.2.6" resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" @@ -7006,6 +8845,11 @@ buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" +builtin-modules@^3.1.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" + integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== + builtin-status-codes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" @@ -7140,7 +8984,7 @@ camel-case@^4.1.1, camel-case@^4.1.2: pascal-case "^3.1.2" tslib "^2.0.3" -camelcase-css@2.0.1: +camelcase-css@2.0.1, camelcase-css@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== @@ -7172,7 +9016,7 @@ camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -camelcase@^6.0.0, camelcase@^6.2.0: +camelcase@^6.0.0, camelcase@^6.2.0, camelcase@^6.2.1: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== @@ -7192,6 +9036,11 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001312, can resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001390.tgz" integrity sha512-sS4CaUM+/+vqQUlCvCJ2WtDlV81aWtHhqeEVkLokVJJa3ViN4zDxAGfq9R8i1m90uGHxo99cy10Od+lvn3hf0g== +caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001426: + version "1.0.30001435" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001435.tgz#502c93dbd2f493bee73a408fe98e98fb1dad10b2" + integrity sha512-kdCkUTjR+v4YAJelyiDTqiu82BDr4W4CP5sgTA0ZBmqn30XfS2ZghPLMowik9TPhS+psWJiUNxsqLyurDbmutA== + capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -7199,7 +9048,7 @@ capture-exit@^2.0.0: dependencies: rsvp "^4.8.4" -case-sensitive-paths-webpack-plugin@^2.3.0: +case-sensitive-paths-webpack-plugin@^2.3.0, case-sensitive-paths-webpack-plugin@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4" integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw== @@ -7214,6 +9063,11 @@ ccount@^1.0.0: resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043" integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg== +ccount@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5" + integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== + chalk@^2.0.0, chalk@^2.4.1: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -7231,7 +9085,7 @@ chalk@^3.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: +chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -7244,21 +9098,46 @@ char-regex@^1.0.2: resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== +char-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-2.0.1.tgz#6dafdb25f9d3349914079f010ba8d0e6ff9cd01e" + integrity sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw== + +character-entities-html4@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-2.1.0.tgz#1f1adb940c971a4b22ba39ddca6b618dc6e56b2b" + integrity sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA== + character-entities-legacy@^1.0.0: version "1.1.4" resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1" integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== +character-entities-legacy@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz#76bc83a90738901d7bc223a9e93759fdd560125b" + integrity sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ== + character-entities@^1.0.0: version "1.2.4" resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b" integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== +character-entities@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-2.0.2.tgz#2d09c2e72cd9523076ccb21157dff66ad43fcc22" + integrity sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ== + character-reference-invalid@^1.0.0: version "1.1.4" resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== +character-reference-invalid@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz#85c66b041e43b47210faf401278abf808ac45cb9" + integrity sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw== + charcodes@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/charcodes/-/charcodes-0.2.0.tgz#5208d327e6cc05f99eb80ffc814707572d1f14e4" @@ -7269,6 +9148,11 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== +check-types@^11.1.1: + version "11.2.2" + resolved "https://registry.yarnpkg.com/check-types/-/check-types-11.2.2.tgz#7afc0b6a860d686885062f2dba888ba5710335b4" + integrity sha512-HBiYvXvn9Z70Z88XKjz3AEKd4HJhBXsa3j7xFnITAzoS8+q6eIGi8qDB8FKPBAjtuxjI/zFpwuiCb8oDtKOYrA== + chokidar@3.5.3, chokidar@^3.4.1, chokidar@^3.4.2, chokidar@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" @@ -7487,6 +9371,15 @@ co@^4.6.0: resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= +coa@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" + integrity sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA== + dependencies: + "@types/q" "^1.5.1" + chalk "^2.4.1" + q "^1.1.2" + code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" @@ -7529,7 +9422,7 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -color-name@^1.0.0, color-name@~1.1.4: +color-name@^1.0.0, color-name@^1.1.4, color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== @@ -7613,6 +9506,11 @@ comma-separated-tokens@^1.0.0: resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== +comma-separated-tokens@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz#4e89c9458acb61bc8fef19f4529973b2392839ee" + integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg== + commander@2, commander@^2.19.0, commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -7643,6 +9541,11 @@ common-path-prefix@^3.0.0: resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0" integrity sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w== +common-tags@^1.8.0: + version "1.8.2" + resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.2.tgz#94ebb3c076d26032745fd54face7f688ef5ac9c6" + integrity sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA== + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -7714,7 +9617,7 @@ config-chain@^1.1.12: ini "^1.3.4" proto-list "~1.2.1" -confusing-browser-globals@^1.0.10: +confusing-browser-globals@^1.0.10, confusing-browser-globals@^1.0.11: version "1.0.11" resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81" integrity sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA== @@ -7724,6 +9627,11 @@ connect-history-api-fallback@^1.6.0: resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== +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== + console-browserify@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" @@ -7850,6 +9758,11 @@ cookie@0.4.2: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== +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-concurrently@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" @@ -7875,6 +9788,13 @@ core-js-compat@^3.20.2, core-js-compat@^3.21.0, core-js-compat@^3.8.1: browserslist "^4.19.1" semver "7.0.0" +core-js-compat@^3.25.1: + version "3.26.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.26.1.tgz#0e710b09ebf689d719545ac36e49041850f943df" + integrity sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A== + dependencies: + browserslist "^4.21.4" + core-js-pure@^3.20.2, core-js-pure@^3.8.1: version "3.21.1" resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.21.1.tgz#8c4d1e78839f5f46208de7230cebfb72bc3bdb51" @@ -7885,6 +9805,11 @@ core-js@^3.0.4, core-js@^3.6.5, core-js@^3.8.2: resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.21.1.tgz#f2e0ddc1fc43da6f904706e8e955bc19d06a0d94" integrity sha512-FRq5b/VMrWlrmCzwRrpDYNxyHP9BcAZC+xHJaqTgIE5091ZV1NTmyh0sGOg5XqpnHvR0svdy0sv1gWA1zmhxig== +core-js@^3.19.2: + version "3.26.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.26.1.tgz#7a9816dabd9ee846c1c0fe0e8fcad68f3709134e" + integrity sha512-21491RRQVzUn0GGM9Z1Jrpr6PNPxPi+Za8OM9q4tksTSnlbXXGKK1nXNg/QvwFYettXvSX6zWKCtHHfjN4puyA== + core-util-is@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -7895,6 +9820,14 @@ core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== +cosmiconfig-typescript-loader@^1.0.0: + version "1.0.9" + resolved "https://registry.yarnpkg.com/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-1.0.9.tgz#69c523f7e8c3d9f27f563d02bbeadaf2f27212d3" + integrity sha512-tRuMRhxN4m1Y8hP9SNYfz7jRwt8lZdWxdjg/ohg5esKmsndJIn4yT96oJVcf5x0eA11taXl+sIp+ielu529k6g== + dependencies: + cosmiconfig "^7" + ts-node "^10.7.0" + cosmiconfig@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" @@ -7906,6 +9839,17 @@ cosmiconfig@^6.0.0: path-type "^4.0.0" yaml "^1.7.2" +cosmiconfig@^7: + version "7.1.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" + integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + cosmiconfig@^7.0.0, cosmiconfig@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" @@ -7981,6 +9925,11 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: safe-buffer "^5.0.1" sha.js "^2.4.8" +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -8018,6 +9967,18 @@ crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" +crypto-random-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" + integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== + +css-blank-pseudo@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz#36523b01c12a25d812df343a32c322d2a2324561" + integrity sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ== + dependencies: + postcss-selector-parser "^6.0.9" + css-declaration-sorter@^6.0.3: version "6.1.4" resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.1.4.tgz#b9bfb4ed9a41f8dcca9bf7184d849ea94a8294b4" @@ -8025,6 +9986,13 @@ css-declaration-sorter@^6.0.3: dependencies: timsort "^0.3.0" +css-has-pseudo@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz#57f6be91ca242d5c9020ee3e51bbb5b89fc7af73" + integrity sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw== + dependencies: + postcss-selector-parser "^6.0.9" + css-loader@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645" @@ -8074,7 +10042,21 @@ css-loader@^6.2.0: postcss-value-parser "^4.2.0" semver "^7.3.5" -css-minimizer-webpack-plugin@^3.0.2: +css-loader@^6.5.1: + version "6.7.2" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.2.tgz#26bc22401b5921686a10fbeba75d124228302304" + integrity sha512-oqGbbVcBJkm8QwmnNzrFrWTnudnRZC+1eXikLJl0n4ljcfotgRifpg2a1lKy8jTrc4/d9A/ap1GFq1jDKG7J+Q== + dependencies: + icss-utils "^5.1.0" + postcss "^8.4.18" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.0" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.2.0" + semver "^7.3.8" + +css-minimizer-webpack-plugin@^3.0.2, css-minimizer-webpack-plugin@^3.2.0: version "3.4.1" resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz#ab78f781ced9181992fe7b6e4f3422e76429878f" integrity sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q== @@ -8086,6 +10068,26 @@ css-minimizer-webpack-plugin@^3.0.2: serialize-javascript "^6.0.0" source-map "^0.6.1" +css-prefers-color-scheme@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz#ca8a22e5992c10a5b9d315155e7caee625903349" + integrity sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA== + +css-select-base-adapter@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" + integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== + +css-select@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef" + integrity sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ== + dependencies: + boolbase "^1.0.0" + css-what "^3.2.1" + domutils "^1.7.0" + nth-check "^1.0.2" + css-select@^4.1.3: version "4.2.1" resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.2.1.tgz#9e665d6ae4c7f9d65dbe69d0316e3221fb274cdd" @@ -8097,6 +10099,14 @@ css-select@^4.1.3: domutils "^2.8.0" nth-check "^2.0.1" +css-tree@1.0.0-alpha.37: + version "1.0.0-alpha.37" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" + integrity sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg== + dependencies: + mdn-data "2.0.4" + source-map "^0.6.1" + css-tree@^1.1.2, css-tree@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" @@ -8118,6 +10128,11 @@ css-vendor@^2.0.8: "@babel/runtime" "^7.8.3" is-in-browser "^1.0.2" +css-what@^3.2.1: + version "3.4.2" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4" + integrity sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ== + css-what@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe" @@ -8137,6 +10152,11 @@ css@^3.0.0: source-map "^0.6.1" source-map-resolve "^0.6.0" +cssdb@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-7.2.0.tgz#f44bd4abc430f0ff7f4c64b8a1fb857a753f77a8" + integrity sha512-JYlIsE7eKHSi0UNuCyo96YuIDFqvhGgHw4Ck6lsN+DP0Tp8M64UTDT2trGbkMDqnCoEjks7CkS0XcjU0rkvBdg== + cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" @@ -8191,7 +10211,7 @@ cssnano@^5.0.6: lilconfig "^2.0.3" yaml "^1.10.2" -csso@^4.2.0: +csso@^4.0.2, csso@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== @@ -8429,7 +10449,7 @@ debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2: dependencies: ms "2.1.2" -debug@4.3.4, debug@^4.0.1, debug@^4.3.4: +debug@4.3.4, debug@^4.0.0, debug@^4.0.1, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -8476,6 +10496,13 @@ decimal.js@^10.2.1: resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== +decode-named-character-reference@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz#daabac9690874c394c81e4162a0304b35d824f0e" + integrity sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg== + dependencies: + character-entities "^2.0.0" + decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" @@ -8560,6 +10587,14 @@ define-properties@^1.1.2, define-properties@^1.1.3: dependencies: object-keys "^1.0.12" +define-properties@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" + integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== + dependencies: + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + define-property@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" @@ -8582,6 +10617,11 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" +defined@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.1.tgz#c0b9db27bfaffd95d6f61399419b893df0f91ebf" + integrity sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q== + del@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" @@ -8619,6 +10659,11 @@ delegates@^1.0.0: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= +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, depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" @@ -8629,6 +10674,11 @@ deprecation@^2.0.0, deprecation@^2.3.1: resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== +dequal@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" + integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== + des.js@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" @@ -8637,6 +10687,11 @@ des.js@^1.0.0: inherits "^2.0.1" minimalistic-assert "^1.0.0" +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" @@ -8686,6 +10741,14 @@ detect-package-manager@^2.0.1: dependencies: execa "^5.1.1" +detect-port-alt@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/detect-port-alt/-/detect-port-alt-1.1.6.tgz#24707deabe932d4a3cf621302027c2b266568275" + integrity sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q== + dependencies: + address "^1.0.1" + debug "^2.6.0" + detect-port@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.3.0.tgz#d9c40e9accadd4df5cac6a782aefd014d573d1f1" @@ -8694,6 +10757,15 @@ detect-port@^1.3.0: address "^1.0.1" debug "^2.6.0" +detective@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/detective/-/detective-5.2.1.tgz#6af01eeda11015acb0e73f933242b70f24f91034" + integrity sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw== + dependencies: + acorn-node "^1.8.2" + defined "^1.0.0" + minimist "^1.2.6" + dezalgo@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456" @@ -8707,6 +10779,11 @@ diacritics@1.3.0: resolved "https://registry.yarnpkg.com/diacritics/-/diacritics-1.3.0.tgz#3efa87323ebb863e6696cebb0082d48ff3d6f7a1" integrity sha1-PvqHMj67hj5mls67AILUj/PW96E= +didyoumean@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" + integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== + diff-sequences@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" @@ -8727,6 +10804,16 @@ diff@^3.1.0: resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +diff@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40" + integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw== + diffie-hellman@^5.0.0: version "5.0.3" resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" @@ -8750,6 +10837,11 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" +dlv@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" + integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== + dns-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" @@ -8763,6 +10855,13 @@ dns-packet@^1.3.1: ip "^1.1.0" safe-buffer "^5.0.1" +dns-packet@^5.2.2: + version "5.4.0" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.4.0.tgz#1f88477cf9f27e78a213fb6d118ae38e759a879b" + integrity sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g== + dependencies: + "@leichtgewicht/ip-codec" "^2.0.1" + dns-txt@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" @@ -8811,6 +10910,14 @@ dom-helpers@^5.0.1: "@babel/runtime" "^7.8.7" csstype "^3.0.2" +dom-serializer@0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" + integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== + dependencies: + domelementtype "^2.0.1" + entities "^2.0.0" + dom-serializer@^1.0.1: version "1.3.2" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91" @@ -8830,6 +10937,11 @@ domain-browser@^1.1.1: resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== +domelementtype@1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + domelementtype@^2.0.1, domelementtype@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" @@ -8849,6 +10961,14 @@ domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.0: dependencies: domelementtype "^2.2.0" +domutils@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + domutils@^2.5.2, domutils@^2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" @@ -8899,12 +11019,17 @@ dotenv-webpack@^7.0.3: dependencies: dotenv-defaults "^2.0.2" +dotenv@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" + integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== + dotenv@^8.0.0, dotenv@^8.2.0: version "8.6.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b" integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g== -duplexer@^0.1.1: +duplexer@^0.1.1, duplexer@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== @@ -8932,6 +11057,18 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= +ejs@^3.1.6: + version "3.1.8" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.8.tgz#758d32910c78047585c7ef1f92f9ee041c1c190b" + integrity sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ== + dependencies: + jake "^10.8.5" + +electron-to-chromium@^1.4.251: + version "1.4.284" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592" + integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== + electron-to-chromium@^1.4.71: version "1.4.75" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.75.tgz#d1ad9bb46f2f1bf432118c2be21d27ffeae82fdd" @@ -8955,6 +11092,11 @@ elliptic@^6.5.3: minimalistic-assert "^1.0.1" minimalistic-crypto-utils "^1.0.1" +emittery@^0.10.2: + version "0.10.2" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.2.tgz#902eec8aedb8c41938c46e9385e9db7e03182933" + integrity sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw== + emittery@^0.8.1: version "0.8.1" resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" @@ -9029,6 +11171,14 @@ enhanced-resolve@^5.0.0, enhanced-resolve@^5.7.0, enhanced-resolve@^5.8.3, enhan graceful-fs "^4.2.4" tapable "^2.2.0" +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" + enhanced-resolve@^5.9.3: version "5.9.3" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.9.3.tgz#44a342c012cbc473254af5cc6ae20ebd0aae5d88" @@ -9090,6 +11240,36 @@ error-stack-parser@^2.0.6: dependencies: stackframe "^1.1.1" +es-abstract@^1.17.2, es-abstract@^1.20.4: + version "1.20.4" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.4.tgz#1d103f9f8d78d4cf0713edcd6d0ed1a46eed5861" + integrity sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + function.prototype.name "^1.1.5" + get-intrinsic "^1.1.3" + get-symbol-description "^1.0.0" + has "^1.0.3" + has-property-descriptors "^1.0.0" + has-symbols "^1.0.3" + internal-slot "^1.0.3" + is-callable "^1.2.7" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-weakref "^1.0.2" + object-inspect "^1.12.2" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.4.3" + safe-regex-test "^1.0.0" + string.prototype.trimend "^1.0.5" + string.prototype.trimstart "^1.0.5" + unbox-primitive "^1.0.2" + es-abstract@^1.19.0, es-abstract@^1.19.1: version "1.19.1" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" @@ -9140,6 +11320,13 @@ es-module-lexer@^0.9.0: resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== +es-shim-unscopables@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" + integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== + dependencies: + has "^1.0.3" + es-to-primitive@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" @@ -9227,6 +11414,26 @@ eslint-config-prettier@^8.3.0, eslint-config-prettier@^8.5.0: resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== +eslint-config-react-app@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz#73ba3929978001c5c86274c017ea57eb5fa644b4" + integrity sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA== + dependencies: + "@babel/core" "^7.16.0" + "@babel/eslint-parser" "^7.16.3" + "@rushstack/eslint-patch" "^1.1.0" + "@typescript-eslint/eslint-plugin" "^5.5.0" + "@typescript-eslint/parser" "^5.5.0" + babel-preset-react-app "^10.0.1" + confusing-browser-globals "^1.0.11" + eslint-plugin-flowtype "^8.0.3" + eslint-plugin-import "^2.25.3" + eslint-plugin-jest "^25.3.0" + eslint-plugin-jsx-a11y "^6.5.1" + eslint-plugin-react "^7.27.1" + eslint-plugin-react-hooks "^4.3.0" + eslint-plugin-testing-library "^5.0.1" + eslint-import-resolver-node@^0.3.2, eslint-import-resolver-node@^0.3.6: version "0.3.6" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" @@ -9251,6 +11458,40 @@ eslint-module-utils@^2.7.2: debug "^3.2.7" find-up "^2.1.0" +eslint-module-utils@^2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz#4f3e41116aaf13a20792261e61d3a2e7e0583974" + integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA== + dependencies: + debug "^3.2.7" + +eslint-plugin-flowtype@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz#e1557e37118f24734aa3122e7536a038d34a4912" + integrity sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ== + dependencies: + lodash "^4.17.21" + string-natural-compare "^3.0.1" + +eslint-plugin-import@^2.25.3: + version "2.26.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz#f812dc47be4f2b72b478a021605a59fc6fe8b88b" + integrity sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA== + dependencies: + array-includes "^3.1.4" + array.prototype.flat "^1.2.5" + debug "^2.6.9" + doctrine "^2.1.0" + eslint-import-resolver-node "^0.3.6" + eslint-module-utils "^2.7.3" + has "^1.0.3" + is-core-module "^2.8.1" + is-glob "^4.0.3" + minimatch "^3.1.2" + object.values "^1.1.5" + resolve "^1.22.0" + tsconfig-paths "^3.14.1" + eslint-plugin-import@^2.25.4: version "2.25.4" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz#322f3f916a4e9e991ac7af32032c25ce313209f1" @@ -9270,6 +11511,13 @@ eslint-plugin-import@^2.25.4: resolve "^1.20.0" tsconfig-paths "^3.12.0" +eslint-plugin-jest@^25.3.0: + version "25.7.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz#ff4ac97520b53a96187bad9c9814e7d00de09a6a" + integrity sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ== + dependencies: + "@typescript-eslint/experimental-utils" "^5.0.0" + eslint-plugin-jest@^26.1.1: version "26.1.1" resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-26.1.1.tgz#7176dd745ef8bca3070263f62cdf112f2dfc9aa1" @@ -9315,6 +11563,27 @@ eslint-plugin-react-hooks@^4.3.0: resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz#318dbf312e06fab1c835a4abef00121751ac1172" integrity sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA== +eslint-plugin-react@^7.27.1: + version "7.31.11" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz#011521d2b16dcf95795df688a4770b4eaab364c8" + integrity sha512-TTvq5JsT5v56wPa9OYHzsrOlHzKZKjV+aLgS+55NJP/cuzdiQPC7PfYoUjMoxlffKtvijpk7vA/jmuqRb9nohw== + dependencies: + array-includes "^3.1.6" + array.prototype.flatmap "^1.3.1" + array.prototype.tosorted "^1.1.1" + doctrine "^2.1.0" + estraverse "^5.3.0" + jsx-ast-utils "^2.4.1 || ^3.0.0" + minimatch "^3.1.2" + object.entries "^1.1.6" + object.fromentries "^2.0.6" + object.hasown "^1.1.2" + object.values "^1.1.6" + prop-types "^15.8.1" + resolve "^2.0.0-next.3" + semver "^6.3.0" + string.prototype.matchall "^4.0.8" + eslint-plugin-react@^7.29.2: version "7.29.2" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.29.2.tgz#2d4da69d30d0a736efd30890dc6826f3e91f3f7c" @@ -9344,6 +11613,13 @@ eslint-plugin-storybook@^0.5.12: "@typescript-eslint/experimental-utils" "^5.3.0" requireindex "^1.1.0" +eslint-plugin-testing-library@^5.0.1: + version "5.9.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.9.1.tgz#12e4bd34c48683ee98af4df2e3318ec9f51dcf8a" + integrity sha512-6BQp3tmb79jLLasPHJmy8DnxREe+2Pgf7L+7o09TSWPfdqqtQfRZmZNetr5mOs3yqZk/MRNxpN3RUpJe0wB4LQ== + dependencies: + "@typescript-eslint/utils" "^5.13.0" + eslint-scope@5.1.1, eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" @@ -9387,7 +11663,7 @@ eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== -eslint-visitor-keys@^2.0.0: +eslint-visitor-keys@^2.0.0, eslint-visitor-keys@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== @@ -9397,6 +11673,17 @@ eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.3.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== +eslint-webpack-plugin@^3.1.1: + version "3.2.0" + resolved "https://registry.yarnpkg.com/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz#1978cdb9edc461e4b0195a20da950cf57988347c" + integrity sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w== + dependencies: + "@types/eslint" "^7.29.0 || ^8.4.1" + jest-worker "^28.0.2" + micromatch "^4.0.5" + normalize-path "^3.0.0" + schema-utils "^4.0.0" + eslint@^7.18.0: version "7.32.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" @@ -9484,6 +11771,51 @@ eslint@^8.10.0: text-table "^0.2.0" v8-compile-cache "^2.0.3" +eslint@^8.3.0: + version "8.28.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.28.0.tgz#81a680732634677cc890134bcdd9fdfea8e63d6e" + integrity sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ== + dependencies: + "@eslint/eslintrc" "^1.3.3" + "@humanwhocodes/config-array" "^0.11.6" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.1.1" + eslint-utils "^3.0.0" + eslint-visitor-keys "^3.3.0" + espree "^9.4.0" + esquery "^1.4.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.15.0" + grapheme-splitter "^1.0.4" + ignore "^5.2.0" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-sdsl "^4.1.4" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.1" + regexpp "^3.2.0" + strip-ansi "^6.0.1" + strip-json-comments "^3.1.0" + text-table "^0.2.0" + espree@^7.3.0, espree@^7.3.1: version "7.3.1" resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" @@ -9502,6 +11834,15 @@ espree@^9.3.1: acorn-jsx "^5.3.1" eslint-visitor-keys "^3.3.0" +espree@^9.4.0: + version "9.4.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.1.tgz#51d6092615567a2c2cff7833445e37c28c0065bd" + integrity sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg== + dependencies: + acorn "^8.8.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.3.0" + esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" @@ -9540,6 +11881,54 @@ estree-to-babel@^3.1.0: "@babel/types" "^7.2.0" c8 "^7.6.0" +estree-util-attach-comments@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/estree-util-attach-comments/-/estree-util-attach-comments-2.1.0.tgz#47d69900588bcbc6bf58c3798803ec5f1f3008de" + integrity sha512-rJz6I4L0GaXYtHpoMScgDIwM0/Vwbu5shbMeER596rB2D1EWF6+Gj0e0UKzJPZrpoOc87+Q2kgVFHfjAymIqmw== + dependencies: + "@types/estree" "^1.0.0" + +estree-util-build-jsx@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/estree-util-build-jsx/-/estree-util-build-jsx-2.2.0.tgz#d4307bbeee28c14eb4d63b75c9aad28fa61d84f5" + integrity sha512-apsfRxF9uLrqosApvHVtYZjISPvTJ+lBiIydpC+9wE6cF6ssbhnjyQLqaIjgzGxvC2Hbmec1M7g91PoBayYoQQ== + dependencies: + "@types/estree-jsx" "^1.0.0" + estree-util-is-identifier-name "^2.0.0" + estree-walker "^3.0.0" + +estree-util-is-identifier-name@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/estree-util-is-identifier-name/-/estree-util-is-identifier-name-2.0.1.tgz#cf07867f42705892718d9d89eb2d85eaa8f0fcb5" + integrity sha512-rxZj1GkQhY4x1j/CSnybK9cGuMFQYFPLq0iNyopqf14aOVLFtMv7Esika+ObJWPWiOHuMOAHz3YkWoLYYRnzWQ== + +estree-util-to-js@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/estree-util-to-js/-/estree-util-to-js-1.1.0.tgz#3bd9bb86354063537cc3d81259be2f0d4c3af39f" + integrity sha512-490lbfCcpLk+ofK6HCgqDfYs4KAfq6QVvDw3+Bm1YoKRgiOjKiKYGAVQE1uwh7zVxBgWhqp4FDtp5SqunpUk1A== + dependencies: + "@types/estree-jsx" "^1.0.0" + astring "^1.8.0" + source-map "^0.7.0" + +estree-util-visit@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/estree-util-visit/-/estree-util-visit-1.2.0.tgz#aa0311a9c2f2aa56e9ae5e8b9d87eac14e4ec8f8" + integrity sha512-wdsoqhWueuJKsh5hqLw3j8lwFqNStm92VcwtAOAny8g/KS/l5Y8RISjR4k5W6skCj3Nirag/WUCMS0Nfy3sgsg== + dependencies: + "@types/estree-jsx" "^1.0.0" + "@types/unist" "^2.0.0" + +estree-walker@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" + integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== + +estree-walker@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.1.tgz#c2a9fb4a30232f5039b7c030b37ead691932debd" + integrity sha512-woY0RUD87WzMBUiZLx8NsYr23N5BKsOMZHhu2hoNRVh6NXGfoiT1KOL8G3UHlJAnEDGmfa5ubNA/AacfG+Kb0g== + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" @@ -9681,6 +12070,43 @@ express@^4.17.1: utils-merge "1.0.1" vary "~1.1.2" +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" + extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" @@ -9761,6 +12187,17 @@ fast-glob@^2.2.6: merge2 "^1.2.3" micromatch "^3.1.10" +fast-glob@^3.2.12: + version "3.2.12" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" + integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== + 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-glob@^3.2.9: version "3.2.11" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" @@ -9777,7 +12214,7 @@ fast-json-parse@^1.0.3: resolved "https://registry.yarnpkg.com/fast-json-parse/-/fast-json-parse-1.0.3.tgz#43e5c61ee4efa9265633046b770fb682a7577c4d" integrity sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw== -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.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== @@ -9914,6 +12351,18 @@ file-uri-to-path@1.0.0: resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== +filelist@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" + integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== + dependencies: + minimatch "^5.0.1" + +filesize@^8.0.6: + version "8.0.7" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-8.0.7.tgz#695e70d80f4e47012c132d57a059e80c6b580bd8" + integrity sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ== + fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" @@ -9936,6 +12385,19 @@ filter-obj@^1.1.0: resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" integrity sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ== +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" + finalhandler@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" @@ -10103,6 +12565,25 @@ fork-ts-checker-webpack-plugin@^6.0.4: semver "^7.3.2" tapable "^1.0.0" +fork-ts-checker-webpack-plugin@^6.5.0: + version "6.5.2" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.2.tgz#4f67183f2f9eb8ba7df7177ce3cf3e75cdafb340" + integrity sha512-m5cUmF30xkZ7h4tWUgTAcEaKmUW7tfyUyTqNNOz7OxWJ0v1VWKTcOvH8FWHUwSjlW/356Ijc9vi3XfcPstpQKA== + dependencies: + "@babel/code-frame" "^7.8.3" + "@types/json-schema" "^7.0.5" + chalk "^4.1.0" + chokidar "^3.4.2" + cosmiconfig "^6.0.0" + deepmerge "^4.2.2" + fs-extra "^9.0.0" + glob "^7.1.6" + memfs "^3.1.2" + minimatch "^3.0.4" + schema-utils "2.7.0" + semver "^7.3.2" + tapable "^1.0.0" + fork-ts-checker-webpack-plugin@^7.2.1: version "7.2.1" resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.2.1.tgz#c37a538e12730fe11fd725bcf0fce29487950833" @@ -10148,6 +12629,11 @@ forwarded@0.2.0: resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== +fraction.js@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" + integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== + fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" @@ -10255,7 +12741,7 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -function.prototype.name@^1.1.0: +function.prototype.name@^1.1.0, function.prototype.name@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== @@ -10332,6 +12818,20 @@ get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: has "^1.0.3" has-symbols "^1.0.1" +get-intrinsic@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" + integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + +get-own-enumerable-property-symbols@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" + integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== + get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" @@ -10463,7 +12963,7 @@ glob-parent@^5.1.1, glob-parent@^5.1.2, glob-parent@~5.1.2: dependencies: is-glob "^4.0.1" -glob-parent@^6.0.1: +glob-parent@^6.0.1, glob-parent@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== @@ -10510,6 +13010,22 @@ glob@^8.0.3: minimatch "^5.0.1" once "^1.3.0" +global-modules@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" + integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== + dependencies: + global-prefix "^3.0.0" + +global-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" + integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== + dependencies: + ini "^1.3.5" + kind-of "^6.0.2" + which "^1.3.1" + global@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" @@ -10523,6 +13039,13 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== +globals@^13.15.0: + version "13.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.18.0.tgz#fb224daeeb2bb7d254cd2c640f003528b8d0c1dc" + integrity sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A== + dependencies: + type-fest "^0.20.2" + globals@^13.6.0, globals@^13.9.0: version "13.12.1" resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.1.tgz#ec206be932e6c77236677127577aa8e50bf1c5cb" @@ -10579,6 +13102,18 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== +grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + +gzip-size@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462" + integrity sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q== + dependencies: + duplexer "^0.1.2" + handle-thing@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" @@ -10614,11 +13149,21 @@ hard-rejection@^2.1.0: resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== +harmony-reflect@^1.4.6: + version "1.6.2" + resolved "https://registry.yarnpkg.com/harmony-reflect/-/harmony-reflect-1.6.2.tgz#31ecbd32e648a34d030d86adb67d4d47547fe710" + integrity sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g== + has-bigints@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== +has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -10636,6 +13181,13 @@ has-glob@^1.0.0: dependencies: is-glob "^3.0.0" +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" @@ -10754,6 +13306,27 @@ hast-util-raw@6.0.1: xtend "^4.0.0" zwitch "^1.0.0" +hast-util-to-estree@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/hast-util-to-estree/-/hast-util-to-estree-2.1.0.tgz#aeac70aad0102ae309570907b3f56a08231d5323" + integrity sha512-Vwch1etMRmm89xGgz+voWXvVHba2iiMdGMKmaMfYt35rbVtFDq8JNwwAIvi8zHMkO6Gvqo9oTMwJTmzVRfXh4g== + dependencies: + "@types/estree" "^1.0.0" + "@types/estree-jsx" "^1.0.0" + "@types/hast" "^2.0.0" + "@types/unist" "^2.0.0" + comma-separated-tokens "^2.0.0" + estree-util-attach-comments "^2.0.0" + estree-util-is-identifier-name "^2.0.0" + hast-util-whitespace "^2.0.0" + mdast-util-mdx-expression "^1.0.0" + mdast-util-mdxjs-esm "^1.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + style-to-object "^0.3.0" + unist-util-position "^4.0.0" + zwitch "^2.0.0" + hast-util-to-parse5@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz#1ec44650b631d72952066cea9b1445df699f8479" @@ -10765,6 +13338,11 @@ hast-util-to-parse5@^6.0.0: xtend "^4.0.0" zwitch "^1.0.0" +hast-util-whitespace@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-2.0.0.tgz#4fc1086467cc1ef5ba20673cb6b03cec3a970f1c" + integrity sha512-Pkw+xBHuV6xFeJprJe2BBEoDV+AvQySaz3pPDRUs5PNZEMQjpXJJueqrpcHIXxnWTcAGi/UOCgVShlkY6kLoqg== + hastscript@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640" @@ -10833,6 +13411,11 @@ hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react- dependencies: react-is "^16.7.0" +hoopy@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" + integrity sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ== + hosted-git-info@^2.1.4: version "2.8.9" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" @@ -10908,7 +13491,7 @@ html-void-elements@^1.0.0: resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.5.tgz#ce9159494e86d95e45795b166c2021c2cfca4483" integrity sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w== -html-webpack-plugin@>=5.0.0, html-webpack-plugin@^5.0.0, html-webpack-plugin@^5.3.2: +html-webpack-plugin@>=5.0.0, html-webpack-plugin@^5.0.0, html-webpack-plugin@^5.3.2, html-webpack-plugin@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz#c3911936f57681c1f9f4d8b68c158cd9dfe52f50" integrity sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw== @@ -10965,6 +13548,17 @@ http-errors@1.8.1: statuses ">= 1.5.0 < 2" toidentifier "1.0.1" +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" @@ -11000,6 +13594,17 @@ http-proxy-middleware@^2.0.0: is-plain-obj "^3.0.0" micromatch "^4.0.2" +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" @@ -11062,7 +13667,7 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@^0.6.2: +iconv-lite@^0.6.2, iconv-lite@^0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== @@ -11081,6 +13686,18 @@ icss-utils@^5.0.0, icss-utils@^5.1.0: resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== +idb@^7.0.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/idb/-/idb-7.1.1.tgz#d910ded866d32c7ced9befc5bfdf36f572ced72b" + integrity sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ== + +identity-obj-proxy@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz#94d2bda96084453ef36fbc5aaec37e0f79f1fc14" + integrity sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA== + dependencies: + harmony-reflect "^1.4.6" + ieee754@^1.1.13, ieee754@^1.1.4: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" @@ -11113,6 +13730,11 @@ immediate@~3.0.5: resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== +immer@^9.0.7: + version "9.0.16" + resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.16.tgz#8e7caab80118c2b54b37ad43e05758cdefad0198" + integrity sha512-qenGE7CstVm1NrHQbMh8YaSzTZTFNP3zPqr3YU0S0UY441j4bJTg4A2Hh5KAhwgaiU6ZZ1Ar6y/2f4TblnMReQ== + import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" @@ -11174,7 +13796,7 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -ini@^1.3.2, ini@^1.3.4, ini@~1.3.0: +ini@^1.3.2, ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: version "1.3.8" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== @@ -11284,6 +13906,11 @@ is-alphabetical@1.0.4, is-alphabetical@^1.0.0: resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d" integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg== +is-alphabetical@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-2.0.1.tgz#01072053ea7c1036df3c7d19a6daaec7f19e789b" + integrity sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ== + is-alphanumerical@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf" @@ -11292,6 +13919,14 @@ is-alphanumerical@^1.0.0: is-alphabetical "^1.0.0" is-decimal "^1.0.0" +is-alphanumerical@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz#7c03fbe96e3e931113e57f964b0a368cc2dfd875" + integrity sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw== + dependencies: + is-alphabetical "^2.0.0" + is-decimal "^2.0.0" + is-arguments@^1.0.4, is-arguments@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" @@ -11354,6 +13989,11 @@ is-callable@^1.1.4, is-callable@^1.2.4: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== +is-callable@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + is-ci@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" @@ -11368,6 +14008,13 @@ is-core-module@^2.2.0, is-core-module@^2.5.0, is-core-module@^2.8.0, is-core-mod dependencies: has "^1.0.3" +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-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -11394,6 +14041,11 @@ is-decimal@^1.0.0: resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== +is-decimal@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-2.0.1.tgz#9469d2dc190d0214fd87d78b78caecc0cc14eef7" + integrity sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A== + is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" @@ -11488,6 +14140,11 @@ is-hexadecimal@^1.0.0: resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== +is-hexadecimal@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz#86b5bf668fca307498d319dfc03289d781a90027" + integrity sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg== + is-in-browser@^1.0.2, is-in-browser@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/is-in-browser/-/is-in-browser-1.1.3.tgz#56ff4db683a078c6082eb95dad7dc62e1d04f835" @@ -11503,7 +14160,12 @@ is-map@^2.0.2: resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== -is-negative-zero@^2.0.1: +is-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" + integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g== + +is-negative-zero@^2.0.1, is-negative-zero@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== @@ -11527,6 +14189,11 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg== + is-obj@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" @@ -11556,7 +14223,7 @@ is-path-inside@^2.1.0: dependencies: path-is-inside "^1.0.2" -is-path-inside@^3.0.2: +is-path-inside@^3.0.2, is-path-inside@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== @@ -11576,6 +14243,11 @@ is-plain-obj@^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-obj@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0" + integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg== + is-plain-object@5.0.0, is-plain-object@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" @@ -11593,6 +14265,13 @@ is-potential-custom-element-name@^1.0.1: resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== +is-reference@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-3.0.0.tgz#b1380c03d96ddf7089709781e3208fceb0c92cd6" + integrity sha512-Eo1W3wUoHWoCoVM4GVl/a+K0IgiqE5aIo4kJABFyMum1ZORlPkC+UC357sSQUL5w5QCE5kCC9upl75b7+7CY/Q== + dependencies: + "@types/estree" "*" + is-regex@^1.0.4, is-regex@^1.1.2, is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" @@ -11601,6 +14280,16 @@ is-regex@^1.0.4, is-regex@^1.1.2, is-regex@^1.1.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + integrity sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA== + +is-root@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" + integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== + is-set@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" @@ -11611,6 +14300,13 @@ is-shared-array-buffer@^1.0.1: resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== +is-shared-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" + integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== + dependencies: + call-bind "^1.0.2" + is-ssh@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/is-ssh/-/is-ssh-1.4.0.tgz#4f8220601d2839d8fa624b3106f8e8884f01b8b2" @@ -11664,7 +14360,7 @@ is-utf8@^0.2.0: resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" integrity sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q== -is-weakref@^1.0.1: +is-weakref@^1.0.1, is-weakref@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== @@ -11813,6 +14509,21 @@ iterate-value@^1.0.2: es-get-iterator "^1.0.2" iterate-iterator "^1.0.1" +jake@^10.8.5: + version "10.8.5" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.5.tgz#f2183d2c59382cb274226034543b9c03b8164c46" + integrity sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw== + dependencies: + async "^3.2.3" + chalk "^4.0.2" + filelist "^1.0.1" + minimatch "^3.0.4" + +javascript-stringify@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/javascript-stringify/-/javascript-stringify-2.1.0.tgz#27c76539be14d8bd128219a2d731b09337904e79" + integrity sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg== + jest-changed-files@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz#a348aed00ec9bf671cc58a66fcbe7c3dfd6a68f5" @@ -12113,6 +14824,11 @@ jest-regex-util@^27.5.1: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== +jest-regex-util@^28.0.0: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-28.0.2.tgz#afdc377a3b25fb6e80825adcf76c854e5bf47ead" + integrity sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw== + jest-resolve-dependencies@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz#d811ecc8305e731cc86dd79741ee98fed06f1da8" @@ -12122,7 +14838,7 @@ jest-resolve-dependencies@^27.5.1: jest-regex-util "^27.5.1" jest-snapshot "^27.5.1" -jest-resolve@^27.5.1: +jest-resolve@^27.4.2, jest-resolve@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.5.1.tgz#a2f1c5a0796ec18fe9eb1536ac3814c23617b384" integrity sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw== @@ -12285,6 +15001,19 @@ jest-validate@^27.5.1: leven "^3.1.0" pretty-format "^27.5.1" +jest-watch-typeahead@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/jest-watch-typeahead/-/jest-watch-typeahead-1.1.0.tgz#b4a6826dfb9c9420da2f7bc900de59dad11266a9" + integrity sha512-Va5nLSJTN7YFtC2jd+7wsoe1pNe5K4ShLux/E5iHEwlB9AxaxmggY7to9KUqKojhaJw3aXqt5WAb4jGPOolpEw== + dependencies: + ansi-escapes "^4.3.1" + chalk "^4.0.0" + jest-regex-util "^28.0.0" + jest-watcher "^28.0.0" + slash "^4.0.0" + string-length "^5.0.1" + strip-ansi "^7.0.1" + jest-watcher@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.5.1.tgz#71bd85fb9bde3a2c2ec4dc353437971c43c642a2" @@ -12298,7 +15027,21 @@ jest-watcher@^27.5.1: jest-util "^27.5.1" string-length "^4.0.1" -jest-worker@^26.5.0, jest-worker@^26.6.2: +jest-watcher@^28.0.0: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-28.1.3.tgz#c6023a59ba2255e3b4c57179fc94164b3e73abd4" + integrity sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g== + dependencies: + "@jest/test-result" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.10.2" + jest-util "^28.1.3" + string-length "^4.0.1" + +jest-worker@^26.2.1, jest-worker@^26.5.0, jest-worker@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== @@ -12316,7 +15059,16 @@ jest-worker@^27.0.2, jest-worker@^27.4.5, jest-worker@^27.5.1: merge-stream "^2.0.0" supports-color "^8.0.0" -jest@^27.1.0: +jest-worker@^28.0.2: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-28.1.3.tgz#7e3c4ce3fa23d1bb6accb169e7f396f98ed4bb98" + integrity sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest@^27.1.0, jest@^27.4.3: version "27.5.1" resolved "https://registry.yarnpkg.com/jest/-/jest-27.5.1.tgz#dadf33ba70a779be7a6fc33015843b51494f63fc" integrity sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ== @@ -12325,6 +15077,11 @@ jest@^27.1.0: import-local "^3.0.2" jest-cli "^27.5.1" +js-sdsl@^4.1.4: + version "4.2.0" + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.2.0.tgz#278e98b7bea589b8baaf048c20aeb19eb7ad09d0" + integrity sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ== + js-sha3@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" @@ -12423,7 +15180,7 @@ json-schema-traverse@^1.0.0: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== -json-schema@0.4.0: +json-schema@0.4.0, json-schema@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== @@ -12452,6 +15209,11 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +json5@^2.2.0, json5@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" + integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + jsonc-parser@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.1.0.tgz#73b8f0e5c940b83d03476bc2e51a20ef0932615d" @@ -12478,6 +15240,11 @@ jsonparse@^1.2.0, jsonparse@^1.3.1: resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= +jsonpointer@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.1.tgz#2110e0af0900fd37467b5907ecd13a7884a1b559" + integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== + jsprim@^1.2.2: version "1.4.2" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" @@ -12607,7 +15374,12 @@ kleur@^3.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== -klona@^2.0.4: +kleur@^4.0.3: + version "4.1.5" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780" + integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== + +klona@^2.0.4, klona@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.5.tgz#d166574d90076395d9963aa7a928fabb8d76afbc" integrity sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ== @@ -12725,6 +15497,11 @@ lilconfig@^2.0.3: resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.4.tgz#f4507d043d7058b380b6a8f5cb7bcd4b34cee082" integrity sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA== +lilconfig@^2.0.5, lilconfig@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.6.tgz#32a384558bd58af3d4c6e077dd1ad1d397bc69d4" + integrity sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg== + lines-and-columns@^1.1.6: version "1.2.4" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" @@ -12789,6 +15566,11 @@ loader-utils@^2.0.0: emojis-list "^3.0.0" json5 "^2.1.2" +loader-utils@^3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-3.2.1.tgz#4fb104b599daafd82ef3e1a41fb9265f87e1f576" + integrity sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw== + localforage@^1.7.3: version "1.10.0" resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.10.0.tgz#5c465dc5f62b2807c3a84c0c6a1b1b3212781dd4" @@ -12866,6 +15648,11 @@ lodash.padend@^4.6.1: resolved "https://registry.yarnpkg.com/lodash.padend/-/lodash.padend-4.6.1.tgz#53ccba047d06e158d311f45da625f4e49e6f166e" integrity sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4= +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== + lodash.template@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" @@ -12919,6 +15706,11 @@ long@^4.0.0: resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== +longest-streak@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-3.1.0.tgz#62fa67cd958742a1574af9f39866364102d90cd4" + integrity sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g== + loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -12978,6 +15770,13 @@ lz-string@^1.4.4: resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26" integrity sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY= +magic-string@^0.25.0, magic-string@^0.25.7: + version "0.25.9" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" + integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== + dependencies: + sourcemap-codec "^1.4.8" + make-dir@^2.0.0, make-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" @@ -13087,6 +15886,11 @@ markdown-escapes@^1.0.0: resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535" integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg== +markdown-extensions@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/markdown-extensions/-/markdown-extensions-1.1.1.tgz#fea03b539faeaee9b4ef02a3769b455b189f7fc3" + integrity sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q== + marked@^4.0.16: version "4.0.18" resolved "https://registry.yarnpkg.com/marked/-/marked-4.0.18.tgz#cd0ac54b2e5610cfb90e8fd46ccaa8292c9ed569" @@ -13115,6 +15919,80 @@ mdast-util-definitions@^4.0.0: dependencies: unist-util-visit "^2.0.0" +mdast-util-definitions@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-5.1.1.tgz#2c1d684b28e53f84938bb06317944bee8efa79db" + integrity sha512-rQ+Gv7mHttxHOBx2dkF4HWTg+EE+UR78ptQWDylzPKaQuVGdG4HIoY3SrS/pCp80nZ04greFvXbVFHT+uf0JVQ== + dependencies: + "@types/mdast" "^3.0.0" + "@types/unist" "^2.0.0" + unist-util-visit "^4.0.0" + +mdast-util-from-markdown@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-1.2.0.tgz#84df2924ccc6c995dec1e2368b2b208ad0a76268" + integrity sha512-iZJyyvKD1+K7QX1b5jXdE7Sc5dtoTry1vzV28UZZe8Z1xVnB/czKntJ7ZAkG0tANqRnBF6p3p7GpU1y19DTf2Q== + dependencies: + "@types/mdast" "^3.0.0" + "@types/unist" "^2.0.0" + decode-named-character-reference "^1.0.0" + mdast-util-to-string "^3.1.0" + micromark "^3.0.0" + micromark-util-decode-numeric-character-reference "^1.0.0" + micromark-util-decode-string "^1.0.0" + micromark-util-normalize-identifier "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + unist-util-stringify-position "^3.0.0" + uvu "^0.5.0" + +mdast-util-mdx-expression@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mdast-util-mdx-expression/-/mdast-util-mdx-expression-1.3.1.tgz#2224cf0b5b150093704a3c225bd529d2de21f50f" + integrity sha512-TTb6cKyTA1RD+1su1iStZ5PAv3rFfOUKcoU5EstUpv/IZo63uDX03R8+jXjMEhcobXnNOiG6/ccekvVl4eV1zQ== + dependencies: + "@types/estree-jsx" "^1.0.0" + "@types/hast" "^2.0.0" + "@types/mdast" "^3.0.0" + mdast-util-from-markdown "^1.0.0" + mdast-util-to-markdown "^1.0.0" + +mdast-util-mdx-jsx@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-2.1.0.tgz#029f5a9c38485dbb5cf482059557ee7d788f1947" + integrity sha512-KzgzfWMhdteDkrY4mQtyvTU5bc/W4ppxhe9SzelO6QUUiwLAM+Et2Dnjjprik74a336kHdo0zKm7Tp+n6FFeRg== + dependencies: + "@types/estree-jsx" "^1.0.0" + "@types/hast" "^2.0.0" + "@types/mdast" "^3.0.0" + ccount "^2.0.0" + mdast-util-to-markdown "^1.3.0" + parse-entities "^4.0.0" + stringify-entities "^4.0.0" + unist-util-remove-position "^4.0.0" + unist-util-stringify-position "^3.0.0" + vfile-message "^3.0.0" + +mdast-util-mdx@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mdast-util-mdx/-/mdast-util-mdx-2.0.0.tgz#dd4f6c993cf27da32725e50a04874f595b7b63fb" + integrity sha512-M09lW0CcBT1VrJUaF/PYxemxxHa7SLDHdSn94Q9FhxjCQfuW7nMAWKWimTmA3OyDMSTH981NN1csW1X+HPSluw== + dependencies: + mdast-util-mdx-expression "^1.0.0" + mdast-util-mdx-jsx "^2.0.0" + mdast-util-mdxjs-esm "^1.0.0" + +mdast-util-mdxjs-esm@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-1.3.0.tgz#137345ef827169aeeeb6069277cd3e090830ce9a" + integrity sha512-7N5ihsOkAEGjFotIX9p/YPdl4TqUoMxL4ajNz7PbT89BqsdWJuBC9rvgt6wpbwTZqWWR0jKWqQbwsOWDBUZv4g== + dependencies: + "@types/estree-jsx" "^1.0.0" + "@types/hast" "^2.0.0" + "@types/mdast" "^3.0.0" + mdast-util-from-markdown "^1.0.0" + mdast-util-to-markdown "^1.0.0" + mdast-util-to-hast@10.0.1: version "10.0.1" resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-10.0.1.tgz#0cfc82089494c52d46eb0e3edb7a4eb2aea021eb" @@ -13129,16 +16007,54 @@ mdast-util-to-hast@10.0.1: unist-util-position "^3.0.0" unist-util-visit "^2.0.0" +mdast-util-to-hast@^12.1.0: + version "12.2.4" + resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-12.2.4.tgz#34c1ef2b6cf01c27b3e3504e2c977c76f722e7e1" + integrity sha512-a21xoxSef1l8VhHxS1Dnyioz6grrJkoaCUgGzMD/7dWHvboYX3VW53esRUfB5tgTyz4Yos1n25SPcj35dJqmAg== + dependencies: + "@types/hast" "^2.0.0" + "@types/mdast" "^3.0.0" + mdast-util-definitions "^5.0.0" + micromark-util-sanitize-uri "^1.1.0" + trim-lines "^3.0.0" + unist-builder "^3.0.0" + unist-util-generated "^2.0.0" + unist-util-position "^4.0.0" + unist-util-visit "^4.0.0" + +mdast-util-to-markdown@^1.0.0, mdast-util-to-markdown@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-markdown/-/mdast-util-to-markdown-1.3.0.tgz#38b6cdc8dc417de642a469c4fc2abdf8c931bd1e" + integrity sha512-6tUSs4r+KK4JGTTiQ7FfHmVOaDrLQJPmpjD6wPMlHGUVXoG9Vjc3jIeP+uyBWRf8clwB2blM+W7+KrlMYQnftA== + dependencies: + "@types/mdast" "^3.0.0" + "@types/unist" "^2.0.0" + longest-streak "^3.0.0" + mdast-util-to-string "^3.0.0" + micromark-util-decode-string "^1.0.0" + unist-util-visit "^4.0.0" + zwitch "^2.0.0" + mdast-util-to-string@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz#27055500103f51637bd07d01da01eb1967a43527" integrity sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A== +mdast-util-to-string@^3.0.0, mdast-util-to-string@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz#56c506d065fbf769515235e577b5a261552d56e9" + integrity sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA== + mdn-data@2.0.14: version "2.0.14" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== +mdn-data@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" + integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== + mdurl@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" @@ -13250,6 +16166,291 @@ microevent.ts@~0.1.1: resolved "https://registry.yarnpkg.com/microevent.ts/-/microevent.ts-0.1.1.tgz#70b09b83f43df5172d0205a63025bce0f7357fa0" integrity sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g== +micromark-core-commonmark@^1.0.0, micromark-core-commonmark@^1.0.1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-1.0.6.tgz#edff4c72e5993d93724a3c206970f5a15b0585ad" + integrity sha512-K+PkJTxqjFfSNkfAhp4GB+cZPfQd6dxtTXnf+RjZOV7T4EEXnvgzOcnp+eSTmpGk9d1S9sL6/lqrgSNn/s0HZA== + dependencies: + decode-named-character-reference "^1.0.0" + micromark-factory-destination "^1.0.0" + micromark-factory-label "^1.0.0" + micromark-factory-space "^1.0.0" + micromark-factory-title "^1.0.0" + micromark-factory-whitespace "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-chunked "^1.0.0" + micromark-util-classify-character "^1.0.0" + micromark-util-html-tag-name "^1.0.0" + micromark-util-normalize-identifier "^1.0.0" + micromark-util-resolve-all "^1.0.0" + micromark-util-subtokenize "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.1" + uvu "^0.5.0" + +micromark-extension-mdx-expression@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-1.0.3.tgz#cd3843573921bf55afcfff4ae0cd2e857a16dcfa" + integrity sha512-TjYtjEMszWze51NJCZmhv7MEBcgYRgb3tJeMAJ+HQCAaZHHRBaDCccqQzGizR/H4ODefP44wRTgOn2vE5I6nZA== + dependencies: + micromark-factory-mdx-expression "^1.0.0" + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-events-to-acorn "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + +micromark-extension-mdx-jsx@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-1.0.3.tgz#9f196be5f65eb09d2a49b237a7b3398bba2999be" + integrity sha512-VfA369RdqUISF0qGgv2FfV7gGjHDfn9+Qfiv5hEwpyr1xscRj/CiVRkU7rywGFCO7JwJ5L0e7CJz60lY52+qOA== + dependencies: + "@types/acorn" "^4.0.0" + estree-util-is-identifier-name "^2.0.0" + micromark-factory-mdx-expression "^1.0.0" + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + vfile-message "^3.0.0" + +micromark-extension-mdx-md@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-extension-mdx-md/-/micromark-extension-mdx-md-1.0.0.tgz#382f5df9ee3706dd120b51782a211f31f4760d22" + integrity sha512-xaRAMoSkKdqZXDAoSgp20Azm0aRQKGOl0RrS81yGu8Hr/JhMsBmfs4wR7m9kgVUIO36cMUQjNyiyDKPrsv8gOw== + dependencies: + micromark-util-types "^1.0.0" + +micromark-extension-mdxjs-esm@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-1.0.3.tgz#630d9dc9db2c2fd470cac8c1e7a824851267404d" + integrity sha512-2N13ol4KMoxb85rdDwTAC6uzs8lMX0zeqpcyx7FhS7PxXomOnLactu8WI8iBNXW8AVyea3KIJd/1CKnUmwrK9A== + dependencies: + micromark-core-commonmark "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-events-to-acorn "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + unist-util-position-from-estree "^1.1.0" + uvu "^0.5.0" + vfile-message "^3.0.0" + +micromark-extension-mdxjs@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-extension-mdxjs/-/micromark-extension-mdxjs-1.0.0.tgz#772644e12fc8299a33e50f59c5aa15727f6689dd" + integrity sha512-TZZRZgeHvtgm+IhtgC2+uDMR7h8eTKF0QUX9YsgoL9+bADBpBY6SiLvWqnBlLbCEevITmTqmEuY3FoxMKVs1rQ== + dependencies: + acorn "^8.0.0" + acorn-jsx "^5.0.0" + micromark-extension-mdx-expression "^1.0.0" + micromark-extension-mdx-jsx "^1.0.0" + micromark-extension-mdx-md "^1.0.0" + micromark-extension-mdxjs-esm "^1.0.0" + micromark-util-combine-extensions "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-factory-destination@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-factory-destination/-/micromark-factory-destination-1.0.0.tgz#fef1cb59ad4997c496f887b6977aa3034a5a277e" + integrity sha512-eUBA7Rs1/xtTVun9TmV3gjfPz2wEwgK5R5xcbIM5ZYAtvGF6JkyaDsj0agx8urXnO31tEO6Ug83iVH3tdedLnw== + dependencies: + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-factory-label@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/micromark-factory-label/-/micromark-factory-label-1.0.2.tgz#6be2551fa8d13542fcbbac478258fb7a20047137" + integrity sha512-CTIwxlOnU7dEshXDQ+dsr2n+yxpP0+fn271pu0bwDIS8uqfFcumXpj5mLn3hSC8iw2MUr6Gx8EcKng1dD7i6hg== + dependencies: + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + +micromark-factory-mdx-expression@^1.0.0: + version "1.0.6" + resolved "https://registry.yarnpkg.com/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-1.0.6.tgz#917e17d16e6e9c2551f3a862e6a9ebdd22056476" + integrity sha512-WRQIc78FV7KrCfjsEf/sETopbYjElh3xAmNpLkd1ODPqxEngP42eVRGbiPEQWpRV27LzqW+XVTvQAMIIRLPnNA== + dependencies: + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-events-to-acorn "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + unist-util-position-from-estree "^1.0.0" + uvu "^0.5.0" + vfile-message "^3.0.0" + +micromark-factory-space@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-factory-space/-/micromark-factory-space-1.0.0.tgz#cebff49968f2b9616c0fcb239e96685cb9497633" + integrity sha512-qUmqs4kj9a5yBnk3JMLyjtWYN6Mzfcx8uJfi5XAveBniDevmZasdGBba5b4QsvRcAkmvGo5ACmSUmyGiKTLZew== + dependencies: + micromark-util-character "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-factory-title@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/micromark-factory-title/-/micromark-factory-title-1.0.2.tgz#7e09287c3748ff1693930f176e1c4a328382494f" + integrity sha512-zily+Nr4yFqgMGRKLpTVsNl5L4PMu485fGFDOQJQBl2NFpjGte1e86zC0da93wf97jrc4+2G2GQudFMHn3IX+A== + dependencies: + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + +micromark-factory-whitespace@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-factory-whitespace/-/micromark-factory-whitespace-1.0.0.tgz#e991e043ad376c1ba52f4e49858ce0794678621c" + integrity sha512-Qx7uEyahU1lt1RnsECBiuEbfr9INjQTGa6Err+gF3g0Tx4YEviPbqqGKNv/NrBaE7dVHdn1bVZKM/n5I/Bak7A== + dependencies: + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-util-character@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-1.1.0.tgz#d97c54d5742a0d9611a68ca0cd4124331f264d86" + integrity sha512-agJ5B3unGNJ9rJvADMJ5ZiYjBRyDpzKAOk01Kpi1TKhlT1APx3XZk6eN7RtSz1erbWHC2L8T3xLZ81wdtGRZzg== + dependencies: + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-util-chunked@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-chunked/-/micromark-util-chunked-1.0.0.tgz#5b40d83f3d53b84c4c6bce30ed4257e9a4c79d06" + integrity sha512-5e8xTis5tEZKgesfbQMKRCyzvffRRUX+lK/y+DvsMFdabAicPkkZV6gO+FEWi9RfuKKoxxPwNL+dFF0SMImc1g== + dependencies: + micromark-util-symbol "^1.0.0" + +micromark-util-classify-character@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-classify-character/-/micromark-util-classify-character-1.0.0.tgz#cbd7b447cb79ee6997dd274a46fc4eb806460a20" + integrity sha512-F8oW2KKrQRb3vS5ud5HIqBVkCqQi224Nm55o5wYLzY/9PwHGXC01tr3d7+TqHHz6zrKQ72Okwtvm/xQm6OVNZA== + dependencies: + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-util-combine-extensions@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.0.0.tgz#91418e1e74fb893e3628b8d496085639124ff3d5" + integrity sha512-J8H058vFBdo/6+AsjHp2NF7AJ02SZtWaVUjsayNFeAiydTxUwViQPxN0Hf8dp4FmCQi0UUFovFsEyRSUmFH3MA== + dependencies: + micromark-util-chunked "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-util-decode-numeric-character-reference@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.0.0.tgz#dcc85f13b5bd93ff8d2868c3dba28039d490b946" + integrity sha512-OzO9AI5VUtrTD7KSdagf4MWgHMtET17Ua1fIpXTpuhclCqD8egFWo85GxSGvxgkGS74bEahvtM0WP0HjvV0e4w== + dependencies: + micromark-util-symbol "^1.0.0" + +micromark-util-decode-string@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/micromark-util-decode-string/-/micromark-util-decode-string-1.0.2.tgz#942252ab7a76dec2dbf089cc32505ee2bc3acf02" + integrity sha512-DLT5Ho02qr6QWVNYbRZ3RYOSSWWFuH3tJexd3dgN1odEuPNxCngTCXJum7+ViRAd9BbdxCvMToPOD/IvVhzG6Q== + dependencies: + decode-named-character-reference "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-decode-numeric-character-reference "^1.0.0" + micromark-util-symbol "^1.0.0" + +micromark-util-encode@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-1.0.1.tgz#2c1c22d3800870ad770ece5686ebca5920353383" + integrity sha512-U2s5YdnAYexjKDel31SVMPbfi+eF8y1U4pfiRW/Y8EFVCy/vgxk/2wWTxzcqE71LHtCuCzlBDRU2a5CQ5j+mQA== + +micromark-util-events-to-acorn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-1.2.0.tgz#65785cb77299d791bfefdc6a5213ab57ceead115" + integrity sha512-WWp3bf7xT9MppNuw3yPjpnOxa8cj5ACivEzXJKu0WwnjBYfzaBvIAT9KfeyI0Qkll+bfQtfftSwdgTH6QhTOKw== + dependencies: + "@types/acorn" "^4.0.0" + "@types/estree" "^1.0.0" + estree-util-visit "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + vfile-location "^4.0.0" + vfile-message "^3.0.0" + +micromark-util-html-tag-name@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.1.0.tgz#eb227118befd51f48858e879b7a419fc0df20497" + integrity sha512-BKlClMmYROy9UiV03SwNmckkjn8QHVaWkqoAqzivabvdGcwNGMMMH/5szAnywmsTBUzDsU57/mFi0sp4BQO6dA== + +micromark-util-normalize-identifier@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.0.0.tgz#4a3539cb8db954bbec5203952bfe8cedadae7828" + integrity sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg== + dependencies: + micromark-util-symbol "^1.0.0" + +micromark-util-resolve-all@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-resolve-all/-/micromark-util-resolve-all-1.0.0.tgz#a7c363f49a0162e931960c44f3127ab58f031d88" + integrity sha512-CB/AGk98u50k42kvgaMM94wzBqozSzDDaonKU7P7jwQIuH2RU0TeBqGYJz2WY1UdihhjweivStrJ2JdkdEmcfw== + dependencies: + micromark-util-types "^1.0.0" + +micromark-util-sanitize-uri@^1.0.0, micromark-util-sanitize-uri@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.1.0.tgz#f12e07a85106b902645e0364feb07cf253a85aee" + integrity sha512-RoxtuSCX6sUNtxhbmsEFQfWzs8VN7cTctmBPvYivo98xb/kDEoTCtJQX5wyzIYEmk/lvNFTat4hL8oW0KndFpg== + dependencies: + micromark-util-character "^1.0.0" + micromark-util-encode "^1.0.0" + micromark-util-symbol "^1.0.0" + +micromark-util-subtokenize@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/micromark-util-subtokenize/-/micromark-util-subtokenize-1.0.2.tgz#ff6f1af6ac836f8bfdbf9b02f40431760ad89105" + integrity sha512-d90uqCnXp/cy4G881Ub4psE57Sf8YD0pim9QdjCRNjfas2M1u6Lbt+XZK9gnHL2XFhnozZiEdCa9CNfXSfQ6xA== + dependencies: + micromark-util-chunked "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + +micromark-util-symbol@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-1.0.1.tgz#b90344db62042ce454f351cf0bebcc0a6da4920e" + integrity sha512-oKDEMK2u5qqAptasDAwWDXq0tG9AssVwAx3E9bBF3t/shRIGsWIRG+cGafs2p/SnDSOecnt6hZPCE2o6lHfFmQ== + +micromark-util-types@^1.0.0, micromark-util-types@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-1.0.2.tgz#f4220fdb319205812f99c40f8c87a9be83eded20" + integrity sha512-DCfg/T8fcrhrRKTPjRrw/5LLvdGV7BHySf/1LOZx7TzWZdYRjogNtyNq885z3nNallwr3QUKARjqvHqX1/7t+w== + +micromark@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/micromark/-/micromark-3.1.0.tgz#eeba0fe0ac1c9aaef675157b52c166f125e89f62" + integrity sha512-6Mj0yHLdUZjHnOPgr5xfWIMqMWS12zDN6iws9SLuSz76W8jTtAv24MN4/CL7gJrl5vtxGInkkqDv/JIoRsQOvA== + dependencies: + "@types/debug" "^4.0.0" + debug "^4.0.0" + decode-named-character-reference "^1.0.0" + micromark-core-commonmark "^1.0.1" + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-chunked "^1.0.0" + micromark-util-combine-extensions "^1.0.0" + micromark-util-decode-numeric-character-reference "^1.0.0" + micromark-util-encode "^1.0.0" + micromark-util-normalize-identifier "^1.0.0" + micromark-util-resolve-all "^1.0.0" + micromark-util-sanitize-uri "^1.0.0" + micromark-util-subtokenize "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.1" + uvu "^0.5.0" + micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -13277,6 +16478,14 @@ micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4: braces "^3.0.1" picomatch "^2.2.3" +micromatch@^4.0.5: + 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" + miller-rabin@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" @@ -13354,6 +16563,13 @@ mini-css-extract-plugin@^2.2.2: dependencies: schema-utils "^4.0.0" +mini-css-extract-plugin@^2.4.5: + version "2.7.1" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.1.tgz#ec924df783cff32ce6183fceb653028f70128643" + integrity sha512-viOoaUFy+Z2w43VsGPbtfwFrr0tKwDctK9dUofG5MBViYhD1noGFUzzDIVw0KPwCGUP+c7zqLxm+acuQs7zLzw== + dependencies: + schema-utils "^4.0.0" + minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" @@ -13371,7 +16587,7 @@ minimatch@5.0.1: dependencies: brace-expansion "^2.0.1" -minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.1.2: +minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -13526,6 +16742,13 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== +mkdirp@~0.5.1: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + mocha@^10.0.0: version "10.0.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.0.0.tgz#205447d8993ec755335c4b13deba3d3a13c4def9" @@ -13571,6 +16794,11 @@ move-concurrently@^1.0.1: rimraf "^2.5.4" run-queue "^1.0.3" +mri@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" + integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -13604,6 +16832,14 @@ multicast-dns@^6.0.1: dns-packet "^1.3.1" thunky "^1.0.2" +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" + multimatch@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-5.0.0.tgz#932b800963cea7a31a033328fa1e0c3a1874dbe6" @@ -13640,6 +16876,11 @@ nanoid@^3.3.1: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== +nanoid@^3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" + integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== + nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" @@ -13662,6 +16903,11 @@ napi-build-utils@^1.0.1: resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -13726,6 +16972,11 @@ node-fetch@^2.6.1, node-fetch@^2.6.7: dependencies: whatwg-url "^5.0.0" +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-forge@^1.2.0: version "1.3.0" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.0.tgz#37a874ea723855f37db091e6c186e5b67a01d4b2" @@ -13803,6 +17054,11 @@ node-releases@^2.0.2: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01" integrity sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg== +node-releases@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" + integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== + nopt@^4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" @@ -14005,6 +17261,13 @@ npmlog@^5.0.1: gauge "^3.0.0" set-blocking "^2.0.0" +nth-check@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== + dependencies: + boolbase "~1.0.0" + nth-check@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2" @@ -14046,12 +17309,17 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" +object-hash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" + integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== + object-inspect@^1.11.0: version "1.12.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== -object-inspect@^1.9.0: +object-inspect@^1.12.2, object-inspect@^1.9.0: version "1.12.2" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== @@ -14086,6 +17354,16 @@ object.assign@^4.1.0, object.assign@^4.1.2: has-symbols "^1.0.1" object-keys "^1.1.1" +object.assign@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" + integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + has-symbols "^1.0.3" + object-keys "^1.1.1" + object.entries@^1.1.0, object.entries@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861" @@ -14095,6 +17373,15 @@ object.entries@^1.1.0, object.entries@^1.1.5: define-properties "^1.1.3" es-abstract "^1.19.1" +object.entries@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.6.tgz#9737d0e5b8291edd340a3e3264bb8a3b00d5fa23" + integrity sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + "object.fromentries@^2.0.0 || ^1.0.0", object.fromentries@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.5.tgz#7b37b205109c21e741e605727fe8b0ad5fa08251" @@ -14104,6 +17391,15 @@ object.entries@^1.1.0, object.entries@^1.1.5: define-properties "^1.1.3" es-abstract "^1.19.1" +object.fromentries@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.6.tgz#cdb04da08c539cffa912dcd368b886e0904bfa73" + integrity sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.2: version "2.1.3" resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz#b223cf38e17fefb97a63c10c91df72ccb386df9e" @@ -14113,6 +17409,16 @@ object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.2 define-properties "^1.1.3" es-abstract "^1.19.1" +object.getownpropertydescriptors@^2.1.0: + version "2.1.5" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.5.tgz#db5a9002489b64eef903df81d6623c07e5b4b4d3" + integrity sha512-yDNzckpM6ntyQiGTik1fKV1DcVDRS+w8bvpWNCBanvH5LfRX9O8WTHqQzG4RZwRAM4I0oU7TV11Lj5v0g20ibw== + dependencies: + array.prototype.reduce "^1.0.5" + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + object.hasown@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.0.tgz#7232ed266f34d197d15cac5880232f7a4790afe5" @@ -14121,6 +17427,14 @@ object.hasown@^1.1.0: define-properties "^1.1.3" es-abstract "^1.19.1" +object.hasown@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.2.tgz#f919e21fad4eb38a57bc6345b3afd496515c3f92" + integrity sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw== + dependencies: + define-properties "^1.1.4" + es-abstract "^1.20.4" + object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" @@ -14137,6 +17451,15 @@ object.values@^1.1.0, object.values@^1.1.5: define-properties "^1.1.3" es-abstract "^1.19.1" +object.values@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.6.tgz#4abbaa71eba47d63589d402856f908243eea9b1d" + integrity sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + objectorarray@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/objectorarray/-/objectorarray-1.0.5.tgz#2c05248bbefabd8f43ad13b41085951aac5e68a5" @@ -14147,6 +17470,13 @@ obuf@^1.0.0, obuf@^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-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" @@ -14480,6 +17810,20 @@ parse-entities@^2.0.0: is-decimal "^1.0.0" is-hexadecimal "^1.0.0" +parse-entities@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-4.0.0.tgz#f67c856d4e3fe19b1a445c3fabe78dcdc1053eeb" + integrity sha512-5nk9Fn03x3rEhGaX1FU6IDwG/k+GxLXlFAkgrbM1asuAFl3BhdQWvASaIsmwWypRNcZKHPYnIuOSfIWEyEQnPQ== + dependencies: + "@types/unist" "^2.0.0" + character-entities "^2.0.0" + character-entities-legacy "^3.0.0" + character-reference-invalid "^2.0.0" + decode-named-character-reference "^1.0.0" + is-alphanumerical "^2.0.0" + is-decimal "^2.0.0" + is-hexadecimal "^2.0.0" + parse-json@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" @@ -14654,6 +17998,14 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= +periscopic@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/periscopic/-/periscopic-3.0.4.tgz#b3fbed0d1bc844976b977173ca2cd4a0ef4fa8d1" + integrity sha512-SFx68DxCv0Iyo6APZuw/AKewkkThGwssmU0QWtTlvov3VAtPX+QJ4CadwSaz8nrT5jPIuxdvJWB4PnD2KNDxQg== + dependencies: + estree-walker "^3.0.0" + is-reference "^3.0.0" + picocolors@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" @@ -14664,7 +18016,7 @@ picocolors@^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.2.3, picomatch@^2.3.0: +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3, picomatch@^2.3.0, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -14732,6 +18084,13 @@ pkg-dir@^5.0.0: dependencies: find-up "^5.0.0" +pkg-up@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" + integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== + dependencies: + find-up "^3.0.0" + pnp-webpack-plugin@1.6.4: version "1.6.4" resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" @@ -14767,6 +18126,18 @@ posix-character-classes@^0.1.0: resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= +postcss-attribute-case-insensitive@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz#03d761b24afc04c09e757e92ff53716ae8ea2741" + integrity sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ== + dependencies: + postcss-selector-parser "^6.0.10" + +postcss-browser-comments@^4: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz#bcfc86134df5807f5d3c0eefa191d42136b5e72a" + integrity sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg== + postcss-calc@^8.2.3: version "8.2.4" resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.2.4.tgz#77b9c29bfcbe8a07ff6693dc87050828889739a5" @@ -14775,6 +18146,34 @@ postcss-calc@^8.2.3: postcss-selector-parser "^6.0.9" postcss-value-parser "^4.2.0" +postcss-clamp@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-clamp/-/postcss-clamp-4.1.0.tgz#7263e95abadd8c2ba1bd911b0b5a5c9c93e02363" + integrity sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-color-functional-notation@^4.2.4: + version "4.2.4" + resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz#21a909e8d7454d3612d1659e471ce4696f28caec" + integrity sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-color-hex-alpha@^8.0.4: + version "8.0.4" + resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz#c66e2980f2fbc1a63f5b079663340ce8b55f25a5" + integrity sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-color-rebeccapurple@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz#63fdab91d878ebc4dd4b7c02619a0c3d6a56ced0" + integrity sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg== + dependencies: + postcss-value-parser "^4.2.0" + postcss-colormin@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.3.0.tgz#3cee9e5ca62b2c27e84fce63affc0cfb5901956a" @@ -14792,6 +18191,34 @@ postcss-convert-values@^5.1.0: dependencies: postcss-value-parser "^4.2.0" +postcss-custom-media@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz#c8f9637edf45fef761b014c024cee013f80529ea" + integrity sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-custom-properties@^12.1.10: + version "12.1.10" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-12.1.10.tgz#624517179fd4cf50078a7a60f628d5782e7d4903" + integrity sha512-U3BHdgrYhCrwTVcByFHs9EOBoqcKq4Lf3kXwbTi4hhq0qWhl/pDWq2THbv/ICX/Fl9KqeHBb8OVrTf2OaYF07A== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-custom-selectors@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz#1ab4684d65f30fed175520f82d223db0337239d9" + integrity sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-dir-pseudo-class@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz#2bf31de5de76added44e0a25ecf60ae9f7c7c26c" + integrity sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA== + dependencies: + postcss-selector-parser "^6.0.10" + postcss-discard-comments@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.1.0.tgz#87be4e0953bf599935837b940c701f8d4eca7d0b" @@ -14812,6 +18239,21 @@ postcss-discard-overridden@^5.1.0: resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz#7e8c5b53325747e9d90131bb88635282fb4a276e" integrity sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw== +postcss-double-position-gradients@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz#b96318fdb477be95997e86edd29c6e3557a49b91" + integrity sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +postcss-env-function@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/postcss-env-function/-/postcss-env-function-4.0.6.tgz#7b2d24c812f540ed6eda4c81f6090416722a8e7a" + integrity sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA== + dependencies: + postcss-value-parser "^4.2.0" + postcss-flexbugs-fixes@^4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.2.1.tgz#9218a65249f30897deab1033aced8578562a6690" @@ -14819,6 +18261,79 @@ postcss-flexbugs-fixes@^4.2.1: dependencies: postcss "^7.0.26" +postcss-flexbugs-fixes@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz#2028e145313074fc9abe276cb7ca14e5401eb49d" + integrity sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ== + +postcss-focus-visible@^6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz#50c9ea9afa0ee657fb75635fabad25e18d76bf9e" + integrity sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw== + dependencies: + postcss-selector-parser "^6.0.9" + +postcss-focus-within@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz#5b1d2ec603195f3344b716c0b75f61e44e8d2e20" + integrity sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ== + dependencies: + postcss-selector-parser "^6.0.9" + +postcss-font-variant@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz#efd59b4b7ea8bb06127f2d031bfbb7f24d32fa66" + integrity sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA== + +postcss-gap-properties@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz#f7e3cddcf73ee19e94ccf7cb77773f9560aa2fff" + integrity sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg== + +postcss-image-set-function@^4.0.7: + version "4.0.7" + resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz#08353bd756f1cbfb3b6e93182c7829879114481f" + integrity sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-import@^14.1.0: + version "14.1.0" + resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-14.1.0.tgz#a7333ffe32f0b8795303ee9e40215dac922781f0" + integrity sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw== + dependencies: + postcss-value-parser "^4.0.0" + read-cache "^1.0.0" + resolve "^1.1.7" + +postcss-initial@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-4.0.1.tgz#529f735f72c5724a0fb30527df6fb7ac54d7de42" + integrity sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ== + +postcss-js@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.0.tgz#31db79889531b80dc7bc9b0ad283e418dce0ac00" + integrity sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ== + dependencies: + camelcase-css "^2.0.1" + +postcss-lab-function@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz#6fe4c015102ff7cd27d1bd5385582f67ebdbdc98" + integrity sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +postcss-load-config@^3.1.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-3.1.4.tgz#1ab2571faf84bb078877e1d07905eabe9ebda855" + integrity sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg== + dependencies: + lilconfig "^2.0.5" + yaml "^1.10.2" + postcss-loader@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-4.3.0.tgz#2c4de9657cd4f07af5ab42bd60a673004da1b8cc" @@ -14830,6 +18345,25 @@ postcss-loader@^4.2.0: schema-utils "^3.0.0" semver "^7.3.4" +postcss-loader@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-6.2.1.tgz#0895f7346b1702103d30fdc66e4d494a93c008ef" + integrity sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q== + dependencies: + cosmiconfig "^7.0.0" + klona "^2.0.5" + semver "^7.3.5" + +postcss-logical@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-5.0.4.tgz#ec75b1ee54421acc04d5921576b7d8db6b0e6f73" + integrity sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g== + +postcss-media-minmax@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz#7140bddec173e2d6d657edbd8554a55794e2a5b5" + integrity sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ== + postcss-merge-longhand@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.0.tgz#f716bffbf0bdfbde6ea78c36088e21559f8a0a95" @@ -14941,6 +18475,21 @@ postcss-modules-values@^4.0.0: dependencies: icss-utils "^5.0.0" +postcss-nested@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.0.0.tgz#1572f1984736578f360cffc7eb7dca69e30d1735" + integrity sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w== + dependencies: + postcss-selector-parser "^6.0.10" + +postcss-nesting@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-10.2.0.tgz#0b12ce0db8edfd2d8ae0aaf86427370b898890be" + integrity sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA== + dependencies: + "@csstools/selector-specificity" "^2.0.0" + postcss-selector-parser "^6.0.10" + postcss-normalize-charset@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz#9302de0b29094b52c259e9b2cf8dc0879879f0ed" @@ -15004,6 +18553,20 @@ postcss-normalize-whitespace@^5.1.0: dependencies: postcss-value-parser "^4.2.0" +postcss-normalize@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/postcss-normalize/-/postcss-normalize-10.0.1.tgz#464692676b52792a06b06880a176279216540dd7" + integrity sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA== + dependencies: + "@csstools/normalize.css" "*" + postcss-browser-comments "^4" + sanitize.css "*" + +postcss-opacity-percentage@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.2.tgz#bd698bb3670a0a27f6d657cc16744b3ebf3b1145" + integrity sha512-lyUfF7miG+yewZ8EAk9XUBIlrHyUE6fijnesuz+Mj5zrIHIEw6KcIZSOk/elVMqzLvREmXB83Zi/5QpNRYd47w== + postcss-ordered-values@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.1.0.tgz#04ef429e0991b0292bc918b135cd4c038f7b889f" @@ -15012,6 +18575,87 @@ postcss-ordered-values@^5.1.0: cssnano-utils "^3.1.0" postcss-value-parser "^4.2.0" +postcss-overflow-shorthand@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz#7ed6486fec44b76f0eab15aa4866cda5d55d893e" + integrity sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-page-break@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-3.0.4.tgz#7fbf741c233621622b68d435babfb70dd8c1ee5f" + integrity sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ== + +postcss-place@^7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-7.0.5.tgz#95dbf85fd9656a3a6e60e832b5809914236986c4" + integrity sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-preset-env@^7.0.1: + version "7.8.3" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz#2a50f5e612c3149cc7af75634e202a5b2ad4f1e2" + integrity sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag== + dependencies: + "@csstools/postcss-cascade-layers" "^1.1.1" + "@csstools/postcss-color-function" "^1.1.1" + "@csstools/postcss-font-format-keywords" "^1.0.1" + "@csstools/postcss-hwb-function" "^1.0.2" + "@csstools/postcss-ic-unit" "^1.0.1" + "@csstools/postcss-is-pseudo-class" "^2.0.7" + "@csstools/postcss-nested-calc" "^1.0.0" + "@csstools/postcss-normalize-display-values" "^1.0.1" + "@csstools/postcss-oklab-function" "^1.1.1" + "@csstools/postcss-progressive-custom-properties" "^1.3.0" + "@csstools/postcss-stepped-value-functions" "^1.0.1" + "@csstools/postcss-text-decoration-shorthand" "^1.0.0" + "@csstools/postcss-trigonometric-functions" "^1.0.2" + "@csstools/postcss-unset-value" "^1.0.2" + autoprefixer "^10.4.13" + browserslist "^4.21.4" + css-blank-pseudo "^3.0.3" + css-has-pseudo "^3.0.4" + css-prefers-color-scheme "^6.0.3" + cssdb "^7.1.0" + postcss-attribute-case-insensitive "^5.0.2" + postcss-clamp "^4.1.0" + postcss-color-functional-notation "^4.2.4" + postcss-color-hex-alpha "^8.0.4" + postcss-color-rebeccapurple "^7.1.1" + postcss-custom-media "^8.0.2" + postcss-custom-properties "^12.1.10" + postcss-custom-selectors "^6.0.3" + postcss-dir-pseudo-class "^6.0.5" + postcss-double-position-gradients "^3.1.2" + postcss-env-function "^4.0.6" + postcss-focus-visible "^6.0.4" + postcss-focus-within "^5.0.4" + postcss-font-variant "^5.0.0" + postcss-gap-properties "^3.0.5" + postcss-image-set-function "^4.0.7" + postcss-initial "^4.0.1" + postcss-lab-function "^4.2.1" + postcss-logical "^5.0.4" + postcss-media-minmax "^5.0.0" + postcss-nesting "^10.2.0" + postcss-opacity-percentage "^1.1.2" + postcss-overflow-shorthand "^3.0.4" + postcss-page-break "^3.0.4" + postcss-place "^7.0.5" + postcss-pseudo-class-any-link "^7.1.6" + postcss-replace-overflow-wrap "^4.0.0" + postcss-selector-not "^6.0.1" + postcss-value-parser "^4.2.0" + +postcss-pseudo-class-any-link@^7.1.6: + version "7.1.6" + resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz#2693b221902da772c278def85a4d9a64b6e617ab" + integrity sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w== + dependencies: + postcss-selector-parser "^6.0.10" + postcss-reduce-initial@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.0.tgz#fc31659ea6e85c492fb2a7b545370c215822c5d6" @@ -15027,6 +18671,18 @@ postcss-reduce-transforms@^5.1.0: dependencies: postcss-value-parser "^4.2.0" +postcss-replace-overflow-wrap@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz#d2df6bed10b477bf9c52fab28c568b4b29ca4319" + integrity sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw== + +postcss-selector-not@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz#8f0a709bf7d4b45222793fc34409be407537556d" + integrity sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ== + dependencies: + postcss-selector-parser "^6.0.10" + postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: version "6.0.9" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz#ee71c3b9ff63d9cd130838876c13a2ec1a992b2f" @@ -15035,6 +18691,14 @@ postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2, postcss-selector cssesc "^3.0.0" util-deprecate "^1.0.2" +postcss-selector-parser@^6.0.10: + version "6.0.11" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz#2e41dc39b7ad74046e1615185185cd0b17d0c8dc" + integrity sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + postcss-svgo@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.1.0.tgz#0a317400ced789f233a28826e77523f15857d80d" @@ -15055,12 +18719,12 @@ postcss-value-parser@^3.3.0: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== -postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: +postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@^7.0.14, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.36, postcss@^7.0.5, postcss@^7.0.6: +postcss@^7.0.14, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.35, postcss@^7.0.36, postcss@^7.0.5, postcss@^7.0.6: version "7.0.39" resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== @@ -15077,6 +18741,15 @@ postcss@^8.2.15, postcss@^8.3.5: picocolors "^1.0.0" source-map-js "^1.0.2" +postcss@^8.4.18, postcss@^8.4.4: + version "8.4.19" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.19.tgz#61178e2add236b17351897c8bcc0b4c8ecab56fc" + integrity sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA== + dependencies: + nanoid "^3.3.4" + picocolors "^1.0.0" + source-map-js "^1.0.2" + postcss@^8.4.5: version "8.4.7" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.7.tgz#f99862069ec4541de386bf57f5660a6c7a0875a8" @@ -15155,6 +18828,11 @@ prettier@^2.5.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a" integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg== +pretty-bytes@^5.3.0, pretty-bytes@^5.4.1: + version "5.6.0" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" + integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== + pretty-bytes@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-6.0.0.tgz#928be2ad1f51a2e336add8ba764739f9776a8140" @@ -15259,7 +18937,14 @@ promise.prototype.finally@^3.1.0: define-properties "^1.1.3" es-abstract "^1.19.1" -prompts@^2.0.1, prompts@^2.4.0: +promise@^8.1.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/promise/-/promise-8.3.0.tgz#8cb333d1edeb61ef23869fbb8a4ea0279ab60e0a" + integrity sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg== + dependencies: + asap "~2.0.6" + +prompts@^2.0.1, prompts@^2.4.0, prompts@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== @@ -15295,6 +18980,11 @@ property-information@^5.0.0, property-information@^5.3.0: dependencies: xtend "^4.0.0" +property-information@^6.0.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.2.0.tgz#b74f522c31c097b5149e3c3cb8d7f3defd986a1d" + integrity sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg== + proto-list@~1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" @@ -15437,7 +19127,7 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -q@^1.5.1: +q@^1.1.2, q@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= @@ -15456,6 +19146,13 @@ qrcode.react@^1.0.1: prop-types "^15.6.0" qr.js "0.0.0" +qs@6.11.0, qs@^6.9.4: + 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" + qs@6.9.7: version "6.9.7" resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.7.tgz#4610846871485e1e048f44ae3b94033f0e675afe" @@ -15468,13 +19165,6 @@ qs@^6.10.0: dependencies: side-channel "^1.0.4" -qs@^6.9.4: - 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" - qs@~6.5.2: version "6.5.3" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" @@ -15515,6 +19205,18 @@ quick-lru@^4.0.1: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + +raf@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" + integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA== + dependencies: + performance-now "^2.1.0" + rambda@^7.1.0: version "7.1.4" resolved "https://registry.yarnpkg.com/rambda/-/rambda-7.1.4.tgz#7faa9665a54c5d81773975532a942b3113bb4a56" @@ -15560,6 +19262,16 @@ raw-body@2.4.3: iconv-lite "0.4.24" unpipe "1.0.0" +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" + raw-loader@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-4.0.2.tgz#1aac6b7d1ad1501e66efdac1522c73e59a584eb6" @@ -15578,6 +19290,48 @@ rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" +react-app-polyfill@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz#95221e0a9bd259e5ca6b177c7bb1cb6768f68fd7" + integrity sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w== + dependencies: + core-js "^3.19.2" + object-assign "^4.1.1" + promise "^8.1.0" + raf "^3.4.1" + regenerator-runtime "^0.13.9" + whatwg-fetch "^3.6.2" + +react-dev-utils@^12.0.1: + version "12.0.1" + resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-12.0.1.tgz#ba92edb4a1f379bd46ccd6bcd4e7bc398df33e73" + integrity sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ== + dependencies: + "@babel/code-frame" "^7.16.0" + address "^1.1.2" + browserslist "^4.18.1" + chalk "^4.1.2" + cross-spawn "^7.0.3" + detect-port-alt "^1.1.6" + escape-string-regexp "^4.0.0" + filesize "^8.0.6" + find-up "^5.0.0" + fork-ts-checker-webpack-plugin "^6.5.0" + global-modules "^2.0.0" + globby "^11.0.4" + gzip-size "^6.0.0" + immer "^9.0.7" + is-root "^2.1.0" + loader-utils "^3.2.0" + open "^8.4.0" + pkg-up "^3.1.0" + prompts "^2.4.2" + react-error-overlay "^6.0.11" + recursive-readdir "^2.2.2" + shell-quote "^1.7.3" + strip-ansi "^6.0.1" + text-table "^0.2.0" + react-docgen-typescript@^2.1.1: version "2.2.2" resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-2.2.2.tgz#4611055e569edc071204aadb20e1c93e1ab1659c" @@ -15608,6 +19362,14 @@ react-dom@^17.0.2: object-assign "^4.1.1" scheduler "^0.20.2" +react-dom@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" + integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== + dependencies: + loose-envify "^1.1.0" + scheduler "^0.23.0" + react-dropzone@^10.2.1: version "10.2.2" resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-10.2.2.tgz#67b4db7459589a42c3b891a82eaf9ade7650b815" @@ -15642,6 +19404,11 @@ react-error-boundary@^3.1.3, react-error-boundary@^3.1.4: dependencies: "@babel/runtime" "^7.12.5" +react-error-overlay@^6.0.11: + version "6.0.11" + resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.11.tgz#92835de5841c5cf08ba00ddd2d677b6d17ff9adb" + integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg== + react-google-charts@^3.0.15: version "3.0.15" resolved "https://registry.yarnpkg.com/react-google-charts/-/react-google-charts-3.0.15.tgz#30759a470f48336e744fd383d054122b039a1ff2" @@ -15693,6 +19460,27 @@ react-load-script@^0.0.6: resolved "https://registry.yarnpkg.com/react-load-script/-/react-load-script-0.0.6.tgz#db6851236aaa25bb622677a2eb51dad4f8d2c258" integrity sha512-aRGxDGP9VoLxcsaYvKWIW+LRrMOzz2eEcubTS4NvQPPugjk2VvMhow0wWTkSl7RxookomD1MwcP4l5UStg5ShQ== +react-markdown@^8.0.4: + version "8.0.4" + resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-8.0.4.tgz#b5ff1f0f29ead71a7a6f98815eb1a70bcc2a036e" + integrity sha512-2oxHa6oDxc1apg/Gnc1Goh06t3B617xeywqI/92wmDV9FELI6ayRkwge7w7DoEqM0gRpZGTNU6xQG+YpJISnVg== + dependencies: + "@types/hast" "^2.0.0" + "@types/prop-types" "^15.0.0" + "@types/unist" "^2.0.0" + comma-separated-tokens "^2.0.0" + hast-util-whitespace "^2.0.0" + prop-types "^15.0.0" + property-information "^6.0.0" + react-is "^18.0.0" + remark-parse "^10.0.0" + remark-rehype "^10.0.0" + space-separated-tokens "^2.0.0" + style-to-object "^0.3.0" + unified "^10.0.0" + unist-util-visit "^4.0.0" + vfile "^5.0.0" + react-merge-refs@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/react-merge-refs/-/react-merge-refs-1.1.0.tgz#73d88b892c6c68cbb7a66e0800faa374f4c38b06" @@ -15788,6 +19576,61 @@ react-router@6.3.0: dependencies: history "^5.2.0" +react-scripts@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-5.0.1.tgz#6285dbd65a8ba6e49ca8d651ce30645a6d980003" + integrity sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ== + dependencies: + "@babel/core" "^7.16.0" + "@pmmmwh/react-refresh-webpack-plugin" "^0.5.3" + "@svgr/webpack" "^5.5.0" + babel-jest "^27.4.2" + babel-loader "^8.2.3" + babel-plugin-named-asset-import "^0.3.8" + babel-preset-react-app "^10.0.1" + bfj "^7.0.2" + browserslist "^4.18.1" + camelcase "^6.2.1" + case-sensitive-paths-webpack-plugin "^2.4.0" + css-loader "^6.5.1" + css-minimizer-webpack-plugin "^3.2.0" + dotenv "^10.0.0" + dotenv-expand "^5.1.0" + eslint "^8.3.0" + eslint-config-react-app "^7.0.1" + eslint-webpack-plugin "^3.1.1" + file-loader "^6.2.0" + fs-extra "^10.0.0" + html-webpack-plugin "^5.5.0" + identity-obj-proxy "^3.0.0" + jest "^27.4.3" + jest-resolve "^27.4.2" + jest-watch-typeahead "^1.0.0" + mini-css-extract-plugin "^2.4.5" + postcss "^8.4.4" + postcss-flexbugs-fixes "^5.0.2" + postcss-loader "^6.2.1" + postcss-normalize "^10.0.1" + postcss-preset-env "^7.0.1" + prompts "^2.4.2" + react-app-polyfill "^3.0.0" + react-dev-utils "^12.0.1" + react-refresh "^0.11.0" + resolve "^1.20.0" + resolve-url-loader "^4.0.0" + sass-loader "^12.3.0" + semver "^7.3.5" + source-map-loader "^3.0.0" + style-loader "^3.3.1" + tailwindcss "^3.0.2" + terser-webpack-plugin "^5.2.5" + webpack "^5.64.4" + webpack-dev-server "^4.6.0" + webpack-manifest-plugin "^4.0.2" + workbox-webpack-plugin "^6.4.1" + optionalDependencies: + fsevents "^2.3.2" + react-simple-maps@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/react-simple-maps/-/react-simple-maps-2.3.0.tgz#7fdb55120335a9b1ef5bf62e0dcb669511705f3e" @@ -15853,6 +19696,20 @@ react@^17.0.2: loose-envify "^1.1.0" object-assign "^4.1.1" +react@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" + integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== + dependencies: + loose-envify "^1.1.0" + +read-cache@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" + integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== + dependencies: + pify "^2.3.0" + read-cmd-shim@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-2.0.0.tgz#4a50a71d6f0965364938e9038476f7eede3928d9" @@ -16049,6 +19906,13 @@ rechoir@^0.7.0: dependencies: resolve "^1.9.0" +recursive-readdir@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.3.tgz#e726f328c0d69153bcabd5c322d3195252379372" + integrity sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA== + dependencies: + minimatch "^3.0.5" + redent@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" @@ -16089,6 +19953,13 @@ regenerate-unicode-properties@^10.0.1: dependencies: regenerate "^1.4.2" +regenerate-unicode-properties@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz#7c3192cab6dd24e21cb4461e5ddd7dd24fa8374c" + integrity sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ== + dependencies: + regenerate "^1.4.2" + regenerate@^1.4.2: version "1.4.2" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" @@ -16104,6 +19975,11 @@ regenerator-runtime@^0.13.2, regenerator-runtime@^0.13.4, regenerator-runtime@^0 resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== +regenerator-runtime@^0.13.9: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + regenerator-transform@^0.14.2: version "0.14.5" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" @@ -16111,6 +19987,13 @@ regenerator-transform@^0.14.2: dependencies: "@babel/runtime" "^7.8.4" +regenerator-transform@^0.15.1: + version "0.15.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.1.tgz#f6c4e99fc1b4591f780db2586328e4d9a9d8dc56" + integrity sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg== + dependencies: + "@babel/runtime" "^7.8.4" + regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" @@ -16119,6 +20002,11 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" +regex-parser@^2.2.11: + version "2.2.11" + resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58" + integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== + regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.1: version "1.4.1" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz#b3f4c0059af9e47eca9f3f660e51d81307e72307" @@ -16127,6 +20015,15 @@ regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.1: call-bind "^1.0.2" define-properties "^1.1.3" +regexp.prototype.flags@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" + integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + functions-have-names "^1.2.2" + regexpp@^3.1.0, regexpp@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" @@ -16144,11 +20041,28 @@ regexpu-core@^5.0.1: unicode-match-property-ecmascript "^2.0.0" unicode-match-property-value-ecmascript "^2.0.0" +regexpu-core@^5.2.1: + version "5.2.2" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.2.2.tgz#3e4e5d12103b64748711c3aad69934d7718e75fc" + integrity sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw== + dependencies: + regenerate "^1.4.2" + regenerate-unicode-properties "^10.1.0" + regjsgen "^0.7.1" + regjsparser "^0.9.1" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.1.0" + regjsgen@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.6.0.tgz#83414c5354afd7d6627b16af5f10f41c4e71808d" integrity sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA== +regjsgen@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.7.1.tgz#ee5ef30e18d3f09b7c369b76e7c2373ed25546f6" + integrity sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA== + regjsparser@^0.8.2: version "0.8.4" resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.8.4.tgz#8a14285ffcc5de78c5b95d62bbf413b6bc132d5f" @@ -16156,6 +20070,13 @@ regjsparser@^0.8.2: dependencies: jsesc "~0.5.0" +regjsparser@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709" + integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== + dependencies: + jsesc "~0.5.0" + relateurl@^0.2.7: version "0.2.7" resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" @@ -16191,6 +20112,14 @@ remark-mdx@1.6.22: remark-parse "8.0.3" unified "9.2.0" +remark-mdx@^2.0.0: + version "2.1.5" + resolved "https://registry.yarnpkg.com/remark-mdx/-/remark-mdx-2.1.5.tgz#69b19ec42d30a289e0663c3fc7656ebdca0a8d8e" + integrity sha512-A8vw5s+BgOa968Irt8BO7DfWJTE0Fe7Ge3hX8zzDB1DnwMZTNdK6qF2IcFao+/7nzk1vSysKcFp+3ku4vhMpaQ== + dependencies: + mdast-util-mdx "^2.0.0" + micromark-extension-mdxjs "^1.0.0" + remark-parse@8.0.3: version "8.0.3" resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-8.0.3.tgz#9c62aa3b35b79a486454c690472906075f40c7e1" @@ -16213,6 +20142,25 @@ remark-parse@8.0.3: vfile-location "^3.0.0" xtend "^4.0.1" +remark-parse@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-10.0.1.tgz#6f60ae53edbf0cf38ea223fe643db64d112e0775" + integrity sha512-1fUyHr2jLsVOkhbvPRBJ5zTKZZyD6yZzYaWCS6BPBdQ8vEMBCH+9zNCDA6tET/zHCi/jLqjCWtlJZUPk+DbnFw== + dependencies: + "@types/mdast" "^3.0.0" + mdast-util-from-markdown "^1.0.0" + unified "^10.0.0" + +remark-rehype@^10.0.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/remark-rehype/-/remark-rehype-10.1.0.tgz#32dc99d2034c27ecaf2e0150d22a6dcccd9a6279" + integrity sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw== + dependencies: + "@types/hast" "^2.0.0" + "@types/mdast" "^3.0.0" + mdast-util-to-hast "^12.1.0" + unified "^10.0.0" + remark-slug@^6.0.0: version "6.1.0" resolved "https://registry.yarnpkg.com/remark-slug/-/remark-slug-6.1.0.tgz#0503268d5f0c4ecb1f33315c00465ccdd97923ce" @@ -16351,6 +20299,17 @@ resolve-pathname@^3.0.0: resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== +resolve-url-loader@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz#d50d4ddc746bb10468443167acf800dcd6c3ad57" + integrity sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA== + dependencies: + adjust-sourcemap-loader "^4.0.0" + convert-source-map "^1.7.0" + loader-utils "^2.0.0" + postcss "^7.0.35" + source-map "0.6.1" + resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" @@ -16361,6 +20320,15 @@ resolve.exports@^1.1.0: resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== +resolve@^1.1.7, resolve@^1.22.0, resolve@^1.22.1: + 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" + resolve@^1.10.0, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.3.2, resolve@^1.9.0: version "1.22.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" @@ -16438,6 +20406,23 @@ ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.2: hash-base "^3.0.0" inherits "^2.0.1" +rollup-plugin-terser@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz#e8fbba4869981b2dc35ae7e8a502d5c6c04d324d" + integrity sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ== + dependencies: + "@babel/code-frame" "^7.10.4" + jest-worker "^26.2.1" + serialize-javascript "^4.0.0" + terser "^5.0.0" + +rollup@^2.43.1: + version "2.79.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7" + integrity sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw== + optionalDependencies: + fsevents "~2.3.2" + rsvp@^4.8.4: version "4.8.5" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" @@ -16469,6 +20454,13 @@ rxjs@^6.6.0: dependencies: tslib "^1.9.0" +sade@^1.7.3: + version "1.8.1" + resolved "https://registry.yarnpkg.com/sade/-/sade-1.8.1.tgz#0a78e81d658d394887be57d2a409bf703a3b2701" + integrity sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A== + dependencies: + mri "^1.1.0" + safe-buffer@5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" @@ -16484,6 +20476,15 @@ safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-regex-test@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" + integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + is-regex "^1.1.4" + safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" @@ -16511,7 +20512,20 @@ sane@^4.0.3: minimist "^1.1.1" walker "~1.0.5" -sax@>=0.6.0: +sanitize.css@*: + version "13.0.0" + resolved "https://registry.yarnpkg.com/sanitize.css/-/sanitize.css-13.0.0.tgz#2675553974b27964c75562ade3bd85d79879f173" + integrity sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA== + +sass-loader@^12.3.0: + version "12.6.0" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-12.6.0.tgz#5148362c8e2cdd4b950f3c63ac5d16dbfed37bcb" + integrity sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA== + dependencies: + klona "^2.0.4" + neo-async "^2.6.2" + +sax@>=0.6.0, sax@~1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== @@ -16531,6 +20545,13 @@ scheduler@^0.20.2: loose-envify "^1.1.0" object-assign "^4.1.1" +scheduler@^0.23.0: + version "0.23.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" + integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== + dependencies: + loose-envify "^1.1.0" + schema-utils@2.7.0: version "2.7.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" @@ -16589,6 +20610,13 @@ selfsigned@^2.0.0: dependencies: node-forge "^1.2.0" +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" + "semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" @@ -16644,6 +20672,25 @@ send@0.17.2: range-parser "~1.2.1" statuses "~1.5.0" +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.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -16699,6 +20746,16 @@ serve-static@1.14.2: parseurl "~1.3.3" send "0.17.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" + set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -16801,6 +20858,11 @@ shell-quote@^1.6.1: resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw== +shell-quote@^1.7.3: + version "1.7.4" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.4.tgz#33fe15dee71ab2a81fcbd3a52106c5cfb9fb75d8" + integrity sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw== + shiki@^0.10.1: version "0.10.1" resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.10.1.tgz#6f9a16205a823b56c072d0f1a0bcd0f2646bef14" @@ -16865,6 +20927,11 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +slash@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" + integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== + slice-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" @@ -16914,7 +20981,7 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" -sockjs@^0.3.21: +sockjs@^0.3.21, 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== @@ -16963,16 +21030,25 @@ sort-keys@^4.0.0: dependencies: is-plain-obj "^2.0.0" -source-list-map@^2.0.0: +source-list-map@^2.0.0, source-list-map@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== -source-map-js@^1.0.2: +source-map-js@^1.0.1, source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== +source-map-loader@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.2.tgz#af23192f9b344daa729f6772933194cc5fa54fee" + integrity sha512-BokxPoLjyl3iOrgkWaakaxqnelAJSS+0V+De0kKIq6lyWrXuiPgYTGp6z3iHmqljKAaLXwZa+ctD8GccRJeVvg== + dependencies: + abab "^2.0.5" + iconv-lite "^0.6.3" + source-map-js "^1.0.1" + source-map-resolve@^0.5.0: version "0.5.3" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" @@ -17005,26 +21081,48 @@ source-map-url@^0.4.0: resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== +source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +source-map@^0.7.0: + version "0.7.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" + integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== source-map@^0.7.3, source-map@~0.7.2: version "0.7.3" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== +source-map@^0.8.0-beta.0: + version "0.8.0-beta.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" + integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== + dependencies: + whatwg-url "^7.0.0" + +sourcemap-codec@^1.4.8: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + space-separated-tokens@^1.0.0: version "1.1.5" resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== +space-separated-tokens@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz#1ecd9d2350a3844572c3f4a312bceb018348859f" + integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q== + spdx-correct@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" @@ -17164,6 +21262,11 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.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", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" @@ -17219,6 +21322,19 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" +string-length@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-5.0.1.tgz#3d647f497b6e8e8d41e422f7e0b23bc536c8381e" + integrity sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow== + dependencies: + char-regex "^2.0.0" + strip-ansi "^7.0.1" + +string-natural-compare@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4" + integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw== + string-to-color@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/string-to-color/-/string-to-color-2.2.2.tgz#46210bf7777dc9198dcdf997bd18ae6749cc9a73" @@ -17263,6 +21379,20 @@ string-width@^1.0.1: regexp.prototype.flags "^1.3.1" side-channel "^1.0.4" +string.prototype.matchall@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz#3bf85722021816dcd1bf38bb714915887ca79fd3" + integrity sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + get-intrinsic "^1.1.3" + has-symbols "^1.0.3" + internal-slot "^1.0.3" + regexp.prototype.flags "^1.4.3" + side-channel "^1.0.4" + string.prototype.padend@^3.0.0: version "3.1.3" resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.3.tgz#997a6de12c92c7cb34dc8a201a6c53d9bd88a5f1" @@ -17289,6 +21419,15 @@ string.prototype.trimend@^1.0.4: call-bind "^1.0.2" define-properties "^1.1.3" +string.prototype.trimend@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" + integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + string.prototype.trimstart@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" @@ -17297,6 +21436,15 @@ string.prototype.trimstart@^1.0.4: call-bind "^1.0.2" define-properties "^1.1.3" +string.prototype.trimstart@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" + integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + string_decoder@^1.0.0, string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -17311,6 +21459,23 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" +stringify-entities@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-4.0.3.tgz#cfabd7039d22ad30f3cc435b0ca2c1574fc88ef8" + integrity sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g== + dependencies: + character-entities-html4 "^2.0.0" + character-entities-legacy "^3.0.0" + +stringify-object@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== + dependencies: + get-own-enumerable-property-symbols "^3.0.0" + is-obj "^1.0.1" + is-regexp "^1.0.0" + strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" @@ -17325,7 +21490,7 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.0.0: +strip-ansi@^7.0.0, strip-ansi@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== @@ -17349,6 +21514,11 @@ strip-bom@^4.0.0: resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== +strip-comments@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-2.0.1.tgz#4ad11c3fbcac177a67a40ac224ca339ca1c1ba9b" + integrity sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw== + strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" @@ -17408,7 +21578,7 @@ style-loader@^2.0.0: loader-utils "^2.0.0" schema-utils "^3.0.0" -style-loader@^3.2.1: +style-loader@^3.2.1, style-loader@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575" integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ== @@ -17472,6 +21642,25 @@ svg-parser@^2.0.2: resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== +svgo@^1.2.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" + integrity sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw== + dependencies: + chalk "^2.4.1" + coa "^2.0.2" + css-select "^2.0.0" + css-select-base-adapter "^0.1.1" + css-tree "1.0.0-alpha.37" + csso "^4.0.2" + js-yaml "^3.13.1" + mkdirp "~0.5.1" + object.values "^1.1.0" + sax "~1.2.4" + stable "^0.1.8" + unquote "~1.1.1" + util.promisify "~1.0.0" + svgo@^2.5.0, svgo@^2.7.0: version "2.8.0" resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24" @@ -17521,6 +21710,35 @@ table@^6.0.9: string-width "^4.2.3" strip-ansi "^6.0.1" +tailwindcss@^3.0.2: + version "3.2.4" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.2.4.tgz#afe3477e7a19f3ceafb48e4b083e292ce0dc0250" + integrity sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ== + dependencies: + arg "^5.0.2" + chokidar "^3.5.3" + color-name "^1.1.4" + detective "^5.2.1" + didyoumean "^1.2.2" + dlv "^1.1.3" + fast-glob "^3.2.12" + glob-parent "^6.0.2" + is-glob "^4.0.3" + lilconfig "^2.0.6" + micromatch "^4.0.5" + normalize-path "^3.0.0" + object-hash "^3.0.0" + picocolors "^1.0.0" + postcss "^8.4.18" + postcss-import "^14.1.0" + postcss-js "^4.0.0" + postcss-load-config "^3.1.4" + postcss-nested "6.0.0" + postcss-selector-parser "^6.0.10" + postcss-value-parser "^4.2.0" + quick-lru "^5.1.1" + resolve "^1.22.1" + tapable@^1.0.0, tapable@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" @@ -17610,6 +21828,11 @@ temp-dir@^1.0.0: resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" integrity sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0= +temp-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e" + integrity sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg== + temp-write@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/temp-write/-/temp-write-4.0.0.tgz#cd2e0825fc826ae72d201dc26eef3bf7e6fc9320" @@ -17621,6 +21844,16 @@ temp-write@^4.0.0: temp-dir "^1.0.0" uuid "^3.3.2" +tempy@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tempy/-/tempy-0.6.0.tgz#65e2c35abc06f1124a97f387b08303442bde59f3" + integrity sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw== + dependencies: + is-stream "^2.0.0" + temp-dir "^2.0.0" + type-fest "^0.16.0" + unique-string "^2.0.0" + terminal-link@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" @@ -17670,6 +21903,17 @@ terser-webpack-plugin@^5.0.3, terser-webpack-plugin@^5.1.3: source-map "^0.6.1" terser "^5.7.2" +terser-webpack-plugin@^5.2.5: + version "5.3.6" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz#5590aec31aa3c6f771ce1b1acca60639eab3195c" + integrity sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ== + dependencies: + "@jridgewell/trace-mapping" "^0.3.14" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.0" + terser "^5.14.1" + terser@^4.1.2, terser@^4.6.3: version "4.8.1" resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.1.tgz#a00e5634562de2239fd404c649051bf6fc21144f" @@ -17679,6 +21923,16 @@ terser@^4.1.2, terser@^4.6.3: source-map "~0.6.1" source-map-support "~0.5.12" +terser@^5.0.0, terser@^5.14.1: + version "5.16.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.0.tgz#29362c6f5506e71545c73b069ccd199bb28f7f54" + integrity sha512-KjTV81QKStSfwbNiwlBXfcgMcOloyuRdb62/iLFPGBcVNF4EXjhdYBhYHmbJpiBrVxZhDvltE11j+LBQUxEEJg== + dependencies: + "@jridgewell/source-map" "^0.3.2" + acorn "^8.5.0" + commander "^2.20.0" + source-map-support "~0.5.20" + terser@^5.10.0, terser@^5.3.4, terser@^5.7.2: version "5.12.0" resolved "https://registry.yarnpkg.com/terser/-/terser-5.12.0.tgz#728c6bff05f7d1dcb687d8eace0644802a9dae8a" @@ -17859,6 +22113,13 @@ tough-cookie@~2.5.0: psl "^1.1.28" punycode "^2.1.1" +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA== + dependencies: + punycode "^2.1.0" + tr46@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" @@ -17871,6 +22132,11 @@ tr46@~0.0.3: resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= +trim-lines@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-3.0.1.tgz#d802e332a07df861c48802c04321017b1bd87338" + integrity sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg== + trim-newlines@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" @@ -17896,6 +22162,16 @@ trough@^1.0.0: resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== +trough@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/trough/-/trough-2.1.0.tgz#0f7b511a4fde65a46f18477ab38849b22c554876" + integrity sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g== + +tryer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" + integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== + ts-dedent@^2.0.0, ts-dedent@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5" @@ -17948,6 +22224,25 @@ ts-node@7.0.1: source-map-support "^0.5.6" yn "^2.0.0" +ts-node@^10.7.0: + version "10.9.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" + integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + ts-pnp@^1.1.6: version "1.2.0" resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" @@ -17972,7 +22267,7 @@ tsconfig-paths@^3.12.0: minimist "^1.2.0" strip-bom "^3.0.0" -tsconfig-paths@^3.5.0: +tsconfig-paths@^3.14.1, tsconfig-paths@^3.5.0: version "3.14.1" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== @@ -18060,6 +22355,11 @@ type-detect@4.0.8: resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== +type-fest@^0.16.0: + version "0.16.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.16.0.tgz#3240b891a78b0deae910dbeb86553e552a148860" + integrity sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg== + type-fest@^0.18.0: version "0.18.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.18.1.tgz#db4bc151a4a2cf4eebf9add5db75508db6cc841f" @@ -18156,6 +22456,16 @@ unbox-primitive@^1.0.1: has-symbols "^1.0.2" which-boxed-primitive "^1.0.2" +unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + dependencies: + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" + unfetch@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be" @@ -18187,6 +22497,11 @@ unicode-match-property-value-ecmascript@^2.0.0: resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== +unicode-match-property-value-ecmascript@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz#cb5fffdcd16a05124f5a4b0bf7c3770208acbbe0" + integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== + unicode-property-aliases-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" @@ -18204,6 +22519,19 @@ unified@9.2.0: trough "^1.0.0" vfile "^4.0.0" +unified@^10.0.0: + version "10.1.2" + resolved "https://registry.yarnpkg.com/unified/-/unified-10.1.2.tgz#b1d64e55dafe1f0b98bb6c719881103ecf6c86df" + integrity sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q== + dependencies: + "@types/unist" "^2.0.0" + bail "^2.0.0" + extend "^3.0.0" + is-buffer "^2.0.0" + is-plain-obj "^4.0.0" + trough "^2.0.0" + vfile "^5.0.0" + union-value@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" @@ -18228,26 +22556,64 @@ unique-slug@^2.0.0: dependencies: imurmurhash "^0.1.4" +unique-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" + integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== + dependencies: + crypto-random-string "^2.0.0" + unist-builder@2.0.3, unist-builder@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-2.0.3.tgz#77648711b5d86af0942f334397a33c5e91516436" integrity sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw== +unist-builder@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-3.0.0.tgz#728baca4767c0e784e1e64bb44b5a5a753021a04" + integrity sha512-GFxmfEAa0vi9i5sd0R2kcrI9ks0r82NasRq5QHh2ysGngrc6GiqD5CDf1FjPenY4vApmFASBIIlk/jj5J5YbmQ== + dependencies: + "@types/unist" "^2.0.0" + unist-util-generated@^1.0.0: version "1.1.6" resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.6.tgz#5ab51f689e2992a472beb1b35f2ce7ff2f324d4b" integrity sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg== +unist-util-generated@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-2.0.0.tgz#86fafb77eb6ce9bfa6b663c3f5ad4f8e56a60113" + integrity sha512-TiWE6DVtVe7Ye2QxOVW9kqybs6cZexNwTwSMVgkfjEReqy/xwGpAXb99OxktoWwmL+Z+Epb0Dn8/GNDYP1wnUw== + unist-util-is@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.1.0.tgz#976e5f462a7a5de73d94b706bac1b90671b57797" integrity sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg== +unist-util-is@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-5.1.1.tgz#e8aece0b102fa9bc097b0fef8f870c496d4a6236" + integrity sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ== + +unist-util-position-from-estree@^1.0.0, unist-util-position-from-estree@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unist-util-position-from-estree/-/unist-util-position-from-estree-1.1.1.tgz#96f4d543dfb0428edc01ebb928570b602d280c4c" + integrity sha512-xtoY50b5+7IH8tFbkw64gisG9tMSpxDjhX9TmaJJae/XuxQ9R/Kc8Nv1eOsf43Gt4KV/LkriMy9mptDr7XLcaw== + dependencies: + "@types/unist" "^2.0.0" + unist-util-position@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-3.1.0.tgz#1c42ee6301f8d52f47d14f62bbdb796571fa2d47" integrity sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA== +unist-util-position@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-4.0.3.tgz#5290547b014f6222dff95c48d5c3c13a88fadd07" + integrity sha512-p/5EMGIa1qwbXjA+QgcBXaPWjSnZfQ2Sc3yBEEfgPwsEmJd8Qh+DSk3LGnmOM4S1bY2C0AjmMnB8RuEYxpPwXQ== + dependencies: + "@types/unist" "^2.0.0" + unist-util-remove-position@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz#5d19ca79fdba712301999b2b73553ca8f3b352cc" @@ -18255,6 +22621,14 @@ unist-util-remove-position@^2.0.0: dependencies: unist-util-visit "^2.0.0" +unist-util-remove-position@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-4.0.1.tgz#d5b46a7304ac114c8d91990ece085ca7c2c135c8" + integrity sha512-0yDkppiIhDlPrfHELgB+NLQD5mfjup3a8UYclHruTJWmY74je8g+CIFr79x5f6AkmzSwlvKLbs63hC0meOMowQ== + dependencies: + "@types/unist" "^2.0.0" + unist-util-visit "^4.0.0" + unist-util-remove@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/unist-util-remove/-/unist-util-remove-2.1.0.tgz#b0b4738aa7ee445c402fda9328d604a02d010588" @@ -18269,6 +22643,13 @@ unist-util-stringify-position@^2.0.0: dependencies: "@types/unist" "^2.0.2" +unist-util-stringify-position@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-3.0.2.tgz#5c6aa07c90b1deffd9153be170dce628a869a447" + integrity sha512-7A6eiDCs9UtjcwZOcCpM4aPII3bAAGv13E96IkawkOAW0OhH+yRxtY0lzo8KiHpzEMfH7Q+FizUmwp8Iqy5EWg== + dependencies: + "@types/unist" "^2.0.0" + unist-util-visit-parents@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz#65a6ce698f78a6b0f56aa0e88f13801886cdaef6" @@ -18277,6 +22658,14 @@ unist-util-visit-parents@^3.0.0: "@types/unist" "^2.0.0" unist-util-is "^4.0.0" +unist-util-visit-parents@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-5.1.1.tgz#868f353e6fce6bf8fa875b251b0f4fec3be709bb" + integrity sha512-gks4baapT/kNRaWxuGkl5BIhoanZo7sC/cUT/JToSRNL1dYoXRFl75d++NkjYk4TAu2uv2Px+l8guMajogeuiw== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^5.0.0" + unist-util-visit@2.0.3, unist-util-visit@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.3.tgz#c3703893146df47203bb8a9795af47d7b971208c" @@ -18286,6 +22675,15 @@ unist-util-visit@2.0.3, unist-util-visit@^2.0.0: unist-util-is "^4.0.0" unist-util-visit-parents "^3.0.0" +unist-util-visit@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-4.1.1.tgz#1c4842d70bd3df6cc545276f5164f933390a9aad" + integrity sha512-n9KN3WV9k4h1DxYR1LoajgN93wpEi/7ZplVe02IoB4gH5ctI1AaF2670BLHQYbwj+pY83gFtyeySFiyMHJklrg== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^5.0.0" + unist-util-visit-parents "^5.1.1" + universal-user-agent@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" @@ -18306,6 +22704,11 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= +unquote@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" + integrity sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg== + unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" @@ -18321,7 +22724,7 @@ untildify@^2.0.0: dependencies: os-homedir "^1.0.0" -upath@^1.1.1: +upath@^1.1.1, upath@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== @@ -18331,6 +22734,14 @@ upath@^2.0.1: resolved "https://registry.yarnpkg.com/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b" integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w== +update-browserslist-db@^1.0.9: + 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" @@ -18392,6 +22803,16 @@ util.promisify@1.0.0: define-properties "^1.1.2" object.getownpropertydescriptors "^2.0.3" +util.promisify@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" + integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.2" + has-symbols "^1.0.1" + object.getownpropertydescriptors "^2.1.0" + util@0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" @@ -18436,6 +22857,21 @@ uuid@^8.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +uvu@^0.5.0: + version "0.5.6" + resolved "https://registry.yarnpkg.com/uvu/-/uvu-0.5.6.tgz#2754ca20bcb0bb59b64e9985e84d2e81058502df" + integrity sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA== + dependencies: + dequal "^2.0.0" + diff "^5.0.0" + kleur "^4.0.3" + sade "^1.7.3" + +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + v8-compile-cache@^2.0.3: version "2.3.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" @@ -18489,6 +22925,14 @@ vfile-location@^3.0.0, vfile-location@^3.2.0: resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-3.2.0.tgz#d8e41fbcbd406063669ebf6c33d56ae8721d0f3c" integrity sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA== +vfile-location@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-4.0.1.tgz#06f2b9244a3565bef91f099359486a08b10d3a95" + integrity sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw== + dependencies: + "@types/unist" "^2.0.0" + vfile "^5.0.0" + vfile-message@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a" @@ -18497,6 +22941,14 @@ vfile-message@^2.0.0: "@types/unist" "^2.0.0" unist-util-stringify-position "^2.0.0" +vfile-message@^3.0.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-3.1.3.tgz#1360c27a99234bebf7bddbbbca67807115e6b0dd" + integrity sha512-0yaU+rj2gKAyEk12ffdSbBfjnnj+b1zqTBv3OQCTn8yEB02bsPizwdBPrLJjHnK+cU9EMMcUnNv938XcZIkmdA== + dependencies: + "@types/unist" "^2.0.0" + unist-util-stringify-position "^3.0.0" + vfile@^4.0.0: version "4.2.1" resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.2.1.tgz#03f1dce28fc625c625bc6514350fbdb00fa9e624" @@ -18507,6 +22959,16 @@ vfile@^4.0.0: unist-util-stringify-position "^2.0.0" vfile-message "^2.0.0" +vfile@^5.0.0: + version "5.3.6" + resolved "https://registry.yarnpkg.com/vfile/-/vfile-5.3.6.tgz#61b2e70690cc835a5d0d0fd135beae74e5a39546" + integrity sha512-ADBsmerdGBs2WYckrLBEmuETSPyTD4TuLxTrw0DvjirxW1ra4ZwkbzG8ndsv3Q57smvHxo677MHaQrY9yxH8cA== + dependencies: + "@types/unist" "^2.0.0" + is-buffer "^2.0.0" + unist-util-stringify-position "^3.0.0" + vfile-message "^3.0.0" + vinyl@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.1.tgz#23cfb8bbab5ece3803aa2c0a1eb28af7cbba1974" @@ -18581,6 +23043,14 @@ watchpack@^2.2.0, watchpack@^2.3.1: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" +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" @@ -18600,11 +23070,21 @@ web-namespaces@^1.0.0: resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec" integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw== +web-vitals@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/web-vitals/-/web-vitals-2.1.4.tgz#76563175a475a5e835264d373704f9dde718290c" + integrity sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg== + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + webidl-conversions@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" @@ -18703,6 +23183,41 @@ webpack-dev-server@^4.5.0: webpack-dev-middleware "^5.3.1" ws "^8.4.2" +webpack-dev-server@^4.6.0: + version "4.11.1" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz#ae07f0d71ca0438cf88446f09029b92ce81380b5" + integrity sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw== + 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" + 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.4.2" + webpack-favicons@^1.3.8: version "1.3.8" resolved "https://registry.yarnpkg.com/webpack-favicons/-/webpack-favicons-1.3.8.tgz#cc986bf8f4cd7629af44a726ca142e14c66e7be5" @@ -18733,6 +23248,14 @@ webpack-log@^2.0.0: ansi-colors "^3.0.0" uuid "^3.3.2" +webpack-manifest-plugin@^4.0.2: + version "4.1.1" + resolved "https://registry.yarnpkg.com/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz#10f8dbf4714ff93a215d5a45bcc416d80506f94f" + integrity sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow== + dependencies: + tapable "^2.0.0" + webpack-sources "^2.2.0" + webpack-merge@^5.7.3, webpack-merge@^5.8.0: version "5.8.0" resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" @@ -18749,6 +23272,14 @@ webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: source-list-map "^2.0.0" source-map "~0.6.1" +webpack-sources@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.3.1.tgz#570de0af163949fe272233c2cefe1b56f74511fd" + integrity sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA== + dependencies: + source-list-map "^2.0.1" + source-map "^0.6.1" + webpack-sources@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" @@ -18855,6 +23386,36 @@ webpack@^5.64.3: watchpack "^2.3.1" webpack-sources "^3.2.3" +webpack@^5.64.4: + version "5.75.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.75.0.tgz#1e440468647b2505860e94c9ff3e44d5b582c152" + integrity sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ== + 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" + webpack@^5.9.0: version "5.70.0" resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.70.0.tgz#3461e6287a72b5e6e2f4872700bc8de0d7500e6d" @@ -18906,6 +23467,11 @@ whatwg-encoding@^1.0.5: dependencies: iconv-lite "0.4.24" +whatwg-fetch@^3.6.2: + version "3.6.2" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" + integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA== + whatwg-mimetype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" @@ -18919,6 +23485,15 @@ whatwg-url@^5.0.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" +whatwg-url@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" + integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-url@^8.0.0, whatwg-url@^8.4.0, whatwg-url@^8.5.0: version "8.7.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" @@ -18982,6 +23557,175 @@ wordwrap@^1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= +workbox-background-sync@6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-6.5.4.tgz#3141afba3cc8aa2ae14c24d0f6811374ba8ff6a9" + integrity sha512-0r4INQZMyPky/lj4Ou98qxcThrETucOde+7mRGJl13MPJugQNKeZQOdIJe/1AchOP23cTqHcN/YVpD6r8E6I8g== + dependencies: + idb "^7.0.1" + workbox-core "6.5.4" + +workbox-broadcast-update@6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/workbox-broadcast-update/-/workbox-broadcast-update-6.5.4.tgz#8441cff5417cd41f384ba7633ca960a7ffe40f66" + integrity sha512-I/lBERoH1u3zyBosnpPEtcAVe5lwykx9Yg1k6f8/BGEPGaMMgZrwVrqL1uA9QZ1NGGFoyE6t9i7lBjOlDhFEEw== + dependencies: + workbox-core "6.5.4" + +workbox-build@6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/workbox-build/-/workbox-build-6.5.4.tgz#7d06d31eb28a878817e1c991c05c5b93409f0389" + integrity sha512-kgRevLXEYvUW9WS4XoziYqZ8Q9j/2ziJYEtTrjdz5/L/cTUa2XfyMP2i7c3p34lgqJ03+mTiz13SdFef2POwbA== + dependencies: + "@apideck/better-ajv-errors" "^0.3.1" + "@babel/core" "^7.11.1" + "@babel/preset-env" "^7.11.0" + "@babel/runtime" "^7.11.2" + "@rollup/plugin-babel" "^5.2.0" + "@rollup/plugin-node-resolve" "^11.2.1" + "@rollup/plugin-replace" "^2.4.1" + "@surma/rollup-plugin-off-main-thread" "^2.2.3" + ajv "^8.6.0" + common-tags "^1.8.0" + fast-json-stable-stringify "^2.1.0" + fs-extra "^9.0.1" + glob "^7.1.6" + lodash "^4.17.20" + pretty-bytes "^5.3.0" + rollup "^2.43.1" + rollup-plugin-terser "^7.0.0" + source-map "^0.8.0-beta.0" + stringify-object "^3.3.0" + strip-comments "^2.0.1" + tempy "^0.6.0" + upath "^1.2.0" + workbox-background-sync "6.5.4" + workbox-broadcast-update "6.5.4" + workbox-cacheable-response "6.5.4" + workbox-core "6.5.4" + workbox-expiration "6.5.4" + workbox-google-analytics "6.5.4" + workbox-navigation-preload "6.5.4" + workbox-precaching "6.5.4" + workbox-range-requests "6.5.4" + workbox-recipes "6.5.4" + workbox-routing "6.5.4" + workbox-strategies "6.5.4" + workbox-streams "6.5.4" + workbox-sw "6.5.4" + workbox-window "6.5.4" + +workbox-cacheable-response@6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/workbox-cacheable-response/-/workbox-cacheable-response-6.5.4.tgz#a5c6ec0c6e2b6f037379198d4ef07d098f7cf137" + integrity sha512-DCR9uD0Fqj8oB2TSWQEm1hbFs/85hXXoayVwFKLVuIuxwJaihBsLsp4y7J9bvZbqtPJ1KlCkmYVGQKrBU4KAug== + dependencies: + workbox-core "6.5.4" + +workbox-core@6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-6.5.4.tgz#df48bf44cd58bb1d1726c49b883fb1dffa24c9ba" + integrity sha512-OXYb+m9wZm8GrORlV2vBbE5EC1FKu71GGp0H4rjmxmF4/HLbMCoTFws87M3dFwgpmg0v00K++PImpNQ6J5NQ6Q== + +workbox-expiration@6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-6.5.4.tgz#501056f81e87e1d296c76570bb483ce5e29b4539" + integrity sha512-jUP5qPOpH1nXtjGGh1fRBa1wJL2QlIb5mGpct3NzepjGG2uFFBn4iiEBiI9GUmfAFR2ApuRhDydjcRmYXddiEQ== + dependencies: + idb "^7.0.1" + workbox-core "6.5.4" + +workbox-google-analytics@6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/workbox-google-analytics/-/workbox-google-analytics-6.5.4.tgz#c74327f80dfa4c1954cbba93cd7ea640fe7ece7d" + integrity sha512-8AU1WuaXsD49249Wq0B2zn4a/vvFfHkpcFfqAFHNHwln3jK9QUYmzdkKXGIZl9wyKNP+RRX30vcgcyWMcZ9VAg== + dependencies: + workbox-background-sync "6.5.4" + workbox-core "6.5.4" + workbox-routing "6.5.4" + workbox-strategies "6.5.4" + +workbox-navigation-preload@6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/workbox-navigation-preload/-/workbox-navigation-preload-6.5.4.tgz#ede56dd5f6fc9e860a7e45b2c1a8f87c1c793212" + integrity sha512-IIwf80eO3cr8h6XSQJF+Hxj26rg2RPFVUmJLUlM0+A2GzB4HFbQyKkrgD5y2d84g2IbJzP4B4j5dPBRzamHrng== + dependencies: + workbox-core "6.5.4" + +workbox-precaching@6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/workbox-precaching/-/workbox-precaching-6.5.4.tgz#740e3561df92c6726ab5f7471e6aac89582cab72" + integrity sha512-hSMezMsW6btKnxHB4bFy2Qfwey/8SYdGWvVIKFaUm8vJ4E53JAY+U2JwLTRD8wbLWoP6OVUdFlXsTdKu9yoLTg== + dependencies: + workbox-core "6.5.4" + workbox-routing "6.5.4" + workbox-strategies "6.5.4" + +workbox-range-requests@6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/workbox-range-requests/-/workbox-range-requests-6.5.4.tgz#86b3d482e090433dab38d36ae031b2bb0bd74399" + integrity sha512-Je2qR1NXCFC8xVJ/Lux6saH6IrQGhMpDrPXWZWWS8n/RD+WZfKa6dSZwU+/QksfEadJEr/NfY+aP/CXFFK5JFg== + dependencies: + workbox-core "6.5.4" + +workbox-recipes@6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/workbox-recipes/-/workbox-recipes-6.5.4.tgz#cca809ee63b98b158b2702dcfb741b5cc3e24acb" + integrity sha512-QZNO8Ez708NNwzLNEXTG4QYSKQ1ochzEtRLGaq+mr2PyoEIC1xFW7MrWxrONUxBFOByksds9Z4//lKAX8tHyUA== + dependencies: + workbox-cacheable-response "6.5.4" + workbox-core "6.5.4" + workbox-expiration "6.5.4" + workbox-precaching "6.5.4" + workbox-routing "6.5.4" + workbox-strategies "6.5.4" + +workbox-routing@6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/workbox-routing/-/workbox-routing-6.5.4.tgz#6a7fbbd23f4ac801038d9a0298bc907ee26fe3da" + integrity sha512-apQswLsbrrOsBUWtr9Lf80F+P1sHnQdYodRo32SjiByYi36IDyL2r7BH1lJtFX8fwNHDa1QOVY74WKLLS6o5Pg== + dependencies: + workbox-core "6.5.4" + +workbox-strategies@6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-6.5.4.tgz#4edda035b3c010fc7f6152918370699334cd204d" + integrity sha512-DEtsxhx0LIYWkJBTQolRxG4EI0setTJkqR4m7r4YpBdxtWJH1Mbg01Cj8ZjNOO8etqfA3IZaOPHUxCs8cBsKLw== + dependencies: + workbox-core "6.5.4" + +workbox-streams@6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/workbox-streams/-/workbox-streams-6.5.4.tgz#1cb3c168a6101df7b5269d0353c19e36668d7d69" + integrity sha512-FXKVh87d2RFXkliAIheBojBELIPnWbQdyDvsH3t74Cwhg0fDheL1T8BqSM86hZvC0ZESLsznSYWw+Va+KVbUzg== + dependencies: + workbox-core "6.5.4" + workbox-routing "6.5.4" + +workbox-sw@6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/workbox-sw/-/workbox-sw-6.5.4.tgz#d93e9c67924dd153a61367a4656ff4d2ae2ed736" + integrity sha512-vo2RQo7DILVRoH5LjGqw3nphavEjK4Qk+FenXeUsknKn14eCNedHOXWbmnvP4ipKhlE35pvJ4yl4YYf6YsJArA== + +workbox-webpack-plugin@^6.4.1: + version "6.5.4" + resolved "https://registry.yarnpkg.com/workbox-webpack-plugin/-/workbox-webpack-plugin-6.5.4.tgz#baf2d3f4b8f435f3469887cf4fba2b7fac3d0fd7" + integrity sha512-LmWm/zoaahe0EGmMTrSLUi+BjyR3cdGEfU3fS6PN1zKFYbqAKuQ+Oy/27e4VSXsyIwAw8+QDfk1XHNGtZu9nQg== + dependencies: + fast-json-stable-stringify "^2.1.0" + pretty-bytes "^5.4.1" + upath "^1.2.0" + webpack-sources "^1.4.3" + workbox-build "6.5.4" + +workbox-window@6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/workbox-window/-/workbox-window-6.5.4.tgz#d991bc0a94dff3c2dbb6b84558cff155ca878e91" + integrity sha512-HnLZJDwYBE+hpG25AQBO8RUWBJRaCsI9ksQJEp3aCOFCaG5kqaToAYXFRAHxzRluM2cQbGzdQF5rjKPWPA1fug== + dependencies: + "@types/trusted-types" "^2.0.2" + workbox-core "6.5.4" + worker-farm@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" @@ -19115,7 +23859,7 @@ xstream@^11.14.0: globalthis "^1.0.1" symbol-observable "^2.0.3" -xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: +xtend@^4.0.0, xtend@^4.0.1, xtend@^4.0.2, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== @@ -19140,11 +23884,25 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yaml-loader@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/yaml-loader/-/yaml-loader-0.8.0.tgz#c839325e3fdee082b3768b2a21fe34fde5d96f61" + integrity sha512-LjeKnTzVBKWiQBeE2L9ssl6WprqaUIxCSNs5tle8PaDydgu3wVFXTbMfsvF2MSErpy9TDVa092n4q6adYwJaWg== + dependencies: + javascript-stringify "^2.0.1" + loader-utils "^2.0.0" + yaml "^2.0.0" + yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: version "1.10.2" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== +yaml@^2.0.0: + version "2.1.3" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.1.3.tgz#9b3a4c8aff9821b696275c79a8bee8399d945207" + integrity sha512-AacA8nRULjKMX2DvWvOAdBZMOfQlypSFkjcOcu9FalllIDJ1kvlREzcdIZmidQUqqeMv7jorHjq2HlLv/+c2lg== + yargs-parser@20.2.4: version "20.2.4" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" @@ -19178,6 +23936,11 @@ yargs@16.2.0, yargs@^16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + yn@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" @@ -19205,3 +23968,8 @@ zwitch@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw== + +zwitch@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-2.0.4.tgz#c827d4b0acb76fc3e685a4c6ec2902d51070e9d7" + integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A== From 0ed546b7397c3eb355d7748a6bf5d946864a7134 Mon Sep 17 00:00:00 2001 From: farbanas Date: Tue, 20 Dec 2022 12:04:24 +0100 Subject: [PATCH 34/39] fix: remove clear all settings button --- nym-connect/Cargo.lock | 6 +++--- nym-connect/src-tauri/src/menu.rs | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/nym-connect/Cargo.lock b/nym-connect/Cargo.lock index a9f80869be..427d578caf 100644 --- a/nym-connect/Cargo.lock +++ b/nym-connect/Cargo.lock @@ -632,7 +632,7 @@ dependencies = [ [[package]] name = "client-core" -version = "1.1.2" +version = "1.1.3" dependencies = [ "async-trait", "client-connections", @@ -3381,7 +3381,7 @@ dependencies = [ [[package]] name = "nym-connect" -version = "1.1.2" +version = "1.1.3" dependencies = [ "anyhow", "bip39", @@ -3423,7 +3423,7 @@ dependencies = [ [[package]] name = "nym-socks5-client" -version = "1.1.2" +version = "1.1.3" dependencies = [ "clap", "client-connections", diff --git a/nym-connect/src-tauri/src/menu.rs b/nym-connect/src-tauri/src/menu.rs index 4dac3ec540..fb6f88fb68 100644 --- a/nym-connect/src-tauri/src/menu.rs +++ b/nym-connect/src-tauri/src/menu.rs @@ -18,7 +18,6 @@ impl AddDefaultSubmenus for Menu { "Help", Menu::new() .add_item(CustomMenuItem::new(SHOW_LOG_WINDOW, "Show logs")) - .add_item(CustomMenuItem::new(CLEAR_STORAGE, "Clear all settings")), ); self.add_submenu(submenu) } From 08e6f3c4b7ef62b8da219c2c3b45390e1041a1fb Mon Sep 17 00:00:00 2001 From: farbanas Date: Tue, 20 Dec 2022 12:10:21 +0100 Subject: [PATCH 35/39] update binaries version --- clients/client-core/Cargo.toml | 2 +- clients/native/Cargo.toml | 2 +- clients/socks5/Cargo.toml | 2 +- gateway/Cargo.toml | 2 +- mixnode/Cargo.toml | 2 +- service-providers/network-requester/Cargo.toml | 2 +- service-providers/network-statistics/Cargo.toml | 2 +- tools/nym-cli/Cargo.toml | 2 +- validator-api/Cargo.toml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/clients/client-core/Cargo.toml b/clients/client-core/Cargo.toml index c28abe98ac..9965849481 100644 --- a/clients/client-core/Cargo.toml +++ b/clients/client-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "client-core" -version = "1.1.3" +version = "1.1.4" authors = ["Dave Hrycyszyn "] edition = "2021" diff --git a/clients/native/Cargo.toml b/clients/native/Cargo.toml index 13c5eef19a..d97f7748fb 100644 --- a/clients/native/Cargo.toml +++ b/clients/native/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-client" -version = "1.1.3" +version = "1.1.4" authors = ["Dave Hrycyszyn ", "Jędrzej Stuczyński "] description = "Implementation of the Nym Client" edition = "2021" diff --git a/clients/socks5/Cargo.toml b/clients/socks5/Cargo.toml index 316810b748..add5a3ee58 100644 --- a/clients/socks5/Cargo.toml +++ b/clients/socks5/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-socks5-client" -version = "1.1.3" +version = "1.1.4" authors = ["Dave Hrycyszyn "] description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address" edition = "2021" diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index ab26fccea7..528072ed96 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-gateway" -version = "1.1.3" +version = "1.1.4" authors = [ "Dave Hrycyszyn ", "Jędrzej Stuczyński ", diff --git a/mixnode/Cargo.toml b/mixnode/Cargo.toml index 70c1b439d0..776b7594f3 100644 --- a/mixnode/Cargo.toml +++ b/mixnode/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-mixnode" -version = "1.1.3" +version = "1.1.4" authors = [ "Dave Hrycyszyn ", "Jędrzej Stuczyński ", diff --git a/service-providers/network-requester/Cargo.toml b/service-providers/network-requester/Cargo.toml index 96d91d88ae..d693ed4422 100644 --- a/service-providers/network-requester/Cargo.toml +++ b/service-providers/network-requester/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-network-requester" -version = "1.1.3" +version = "1.1.4" authors = ["Dave Hrycyszyn ", "Jędrzej Stuczyński "] edition = "2021" rust-version = "1.65" diff --git a/service-providers/network-statistics/Cargo.toml b/service-providers/network-statistics/Cargo.toml index 7c2917a381..00b76f524e 100644 --- a/service-providers/network-statistics/Cargo.toml +++ b/service-providers/network-statistics/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-network-statistics" -version = "1.1.3" +version = "1.1.4" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/tools/nym-cli/Cargo.toml b/tools/nym-cli/Cargo.toml index d6ec40bb71..ddc21464ff 100644 --- a/tools/nym-cli/Cargo.toml +++ b/tools/nym-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-cli" -version = "1.1.3" +version = "1.1.4" authors = ["Nym Technologies SA"] edition = "2021" diff --git a/validator-api/Cargo.toml b/validator-api/Cargo.toml index ee2c169f65..2a8c510dd0 100644 --- a/validator-api/Cargo.toml +++ b/validator-api/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-validator-api" -version = "1.1.3" +version = "1.1.4" authors = [ "Dave Hrycyszyn ", "Jędrzej Stuczyński ", From 1133acd8bd1b4ce2fb66c30d5d091957d14b95ad Mon Sep 17 00:00:00 2001 From: farbanas Date: Tue, 20 Dec 2022 12:14:05 +0100 Subject: [PATCH 36/39] update nym-connect and nym-wallet version --- nym-connect/package.json | 2 +- nym-connect/src-tauri/Cargo.toml | 2 +- nym-wallet/package.json | 2 +- nym-wallet/src-tauri/Cargo.toml | 2 +- nym-wallet/src-tauri/tauri.conf.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/nym-connect/package.json b/nym-connect/package.json index 07134780ac..bff93c5a67 100644 --- a/nym-connect/package.json +++ b/nym-connect/package.json @@ -1,6 +1,6 @@ { "name": "@nym/nym-connect", - "version": "1.1.3", + "version": "1.1.4", "main": "index.js", "license": "MIT", "scripts": { diff --git a/nym-connect/src-tauri/Cargo.toml b/nym-connect/src-tauri/Cargo.toml index 8ddeba45bb..1ef082ea8d 100644 --- a/nym-connect/src-tauri/Cargo.toml +++ b/nym-connect/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-connect" -version = "1.1.3" +version = "1.1.4" description = "nym-connect" authors = ["Nym Technologies SA"] license = "" diff --git a/nym-wallet/package.json b/nym-wallet/package.json index a4cf864326..f2f827c098 100644 --- a/nym-wallet/package.json +++ b/nym-wallet/package.json @@ -1,6 +1,6 @@ { "name": "@nymproject/nym-wallet-app", - "version": "1.1.3", + "version": "1.1.4", "main": "index.js", "license": "MIT", "scripts": { diff --git a/nym-wallet/src-tauri/Cargo.toml b/nym-wallet/src-tauri/Cargo.toml index dc390aec7c..edbe2592b7 100644 --- a/nym-wallet/src-tauri/Cargo.toml +++ b/nym-wallet/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym_wallet" -version = "1.1.3" +version = "1.1.4" description = "Nym Native Wallet" authors = ["Nym Technologies SA"] license = "" diff --git a/nym-wallet/src-tauri/tauri.conf.json b/nym-wallet/src-tauri/tauri.conf.json index 13362f5060..e6c2dad6b9 100644 --- a/nym-wallet/src-tauri/tauri.conf.json +++ b/nym-wallet/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "package": { "productName": "nym-wallet", - "version": "1.1.3" + "version": "1.1.4" }, "build": { "distDir": "../dist", From 5e45f7d3a509a0f49cad19b3e0b6cce560f56f9f Mon Sep 17 00:00:00 2001 From: farbanas Date: Tue, 20 Dec 2022 12:28:13 +0100 Subject: [PATCH 37/39] updating changelogs --- CHANGELOG.md | 10 ++++++++++ nym-connect/CHANGELOG.md | 8 +++++++- nym-wallet/CHANGELOG.md | 6 ++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ddb76af927..9ce7038b4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,16 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// ## [Unreleased] +## [v1.1.4] (2022-12-20) + +### Changed + +- Feature/dkg contract threshold by @neacsu in https://github.com/nymtech/nym/pull/1885 +- Multi-surbs by @jstuczyn in https://github.com/nymtech/nym/pull/2667 +- Fix multi-surb backwards compatibility in pre 1.1.4 client config files by @jstuczyn in https://github.com/nymtech/nym/pull/2703 +- fix: ignore corrupted surb storage and instead create fresh one by @jstuczyn in https://github.com/nymtech/nym/pull/2711 +- socks5: rework waiting in inbound.rs by @octol in https://github.com/nymtech/nym/pull/1880 + ## [v1.1.3] (2022-12-13) ### Changed diff --git a/nym-connect/CHANGELOG.md b/nym-connect/CHANGELOG.md index 7b96eb019b..d791be7fc7 100644 --- a/nym-connect/CHANGELOG.md +++ b/nym-connect/CHANGELOG.md @@ -1,10 +1,16 @@ ## UNRELEASED +## [nym-connect-v1.1.4](https://github.com/nymtech/nym/tree/nym-connect-v1.1.4) (2022-12-20) + +- nym-connect: send status messages from socks5 task to tauri backend by @octol in https://github.com/nymtech/nym/pull/1882 +- socks5: rework waiting in inbound.rs by @octol in https://github.com/nymtech/nym/pull/1880 +- Test&Earn by @mmsinclair in https://github.com/nymtech/nym/pull/2729 + ## [nym-connect-v1.1.3](https://github.com/nymtech/nym/tree/nym-connect-v1.1.3) (2022-12-13) - socks5-client: added support for socks4a. -## [nym-connect-v1.1.2](https://github.com/nymtech/nym/tree/nym-connect-v1.1.2) (2022-11-29) +## [nym-connect-v1.1.2](https://github.com/nymtech/nym/tree/nym-connect-v1.1.2) (2022-12-06) - socks5-client: fix error with client failing and disconnecting unnecessarily. diff --git a/nym-wallet/CHANGELOG.md b/nym-wallet/CHANGELOG.md index ef1fb52d15..b94b8f3db5 100644 --- a/nym-wallet/CHANGELOG.md +++ b/nym-wallet/CHANGELOG.md @@ -2,7 +2,13 @@ ## UNRELEASED +## [nym-wallet-v1.1.4](https://github.com/nymtech/nym/releases/tag/nym-wallet-v1.1.4) (2022-12-20) + - wallet: present some cases of the more technical errors (abci, ..) in a more human readable form. +- Bug fix/hide display mnemonic by @fmtabbara in https://github.com/nymtech/nym/pull/1874 +- adding bity icon and wallet address by @gala1234 in https://github.com/nymtech/nym/pull/2689 +- remove warning error message by @gala1234 in https://github.com/nymtech/nym/pull/2694 +- ui and copy changes by @gala1234 in https://github.com/nymtech/nym/pull/2691 ## [nym-wallet-v1.1.3](https://github.com/nymtech/nym/releases/tag/nym-wallet-v1.1.3) (2022-12-13) From b9fed9f455887997c9a833b4d5008490a8825af7 Mon Sep 17 00:00:00 2001 From: farbanas Date: Tue, 20 Dec 2022 12:33:20 +0100 Subject: [PATCH 38/39] updating changelogs --- CHANGELOG.md | 6 ++++++ nym-connect/CHANGELOG.md | 2 ++ nym-wallet/CHANGELOG.md | 2 ++ 3 files changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ce7038b4a..a9f160260d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// ## [v1.1.4] (2022-12-20) +This release adds multiple Single Use Reply Blocks (SURBs) to allow arbitrarily-sized anonymized replies. +At the moment this is turned off by default, but available for use by application developers. +We will need to wait for network-requesters to upgrade to this new release, after which multi-SURB anonymization will become the default setting for the SOCKS proxy clients. + +The release also include some additional work for distributed key generation in the Coconut signing authority nodes. + ### Changed - Feature/dkg contract threshold by @neacsu in https://github.com/nymtech/nym/pull/1885 diff --git a/nym-connect/CHANGELOG.md b/nym-connect/CHANGELOG.md index d791be7fc7..8e6d4eb168 100644 --- a/nym-connect/CHANGELOG.md +++ b/nym-connect/CHANGELOG.md @@ -2,6 +2,8 @@ ## [nym-connect-v1.1.4](https://github.com/nymtech/nym/tree/nym-connect-v1.1.4) (2022-12-20) +This release contains the new opt-in Test & Earn program, and it uses a stress-tested directory of network requesters to improve reliability. It also has some bugfixes, performance improvements, and better error handling. + - nym-connect: send status messages from socks5 task to tauri backend by @octol in https://github.com/nymtech/nym/pull/1882 - socks5: rework waiting in inbound.rs by @octol in https://github.com/nymtech/nym/pull/1880 - Test&Earn by @mmsinclair in https://github.com/nymtech/nym/pull/2729 diff --git a/nym-wallet/CHANGELOG.md b/nym-wallet/CHANGELOG.md index b94b8f3db5..ae119b7749 100644 --- a/nym-wallet/CHANGELOG.md +++ b/nym-wallet/CHANGELOG.md @@ -4,6 +4,8 @@ ## [nym-wallet-v1.1.4](https://github.com/nymtech/nym/releases/tag/nym-wallet-v1.1.4) (2022-12-20) +This release contains a bugfix for hiding and displaying the mnemonic, and displays the Bity wallet address in the buy page, as well as better error handling. + - wallet: present some cases of the more technical errors (abci, ..) in a more human readable form. - Bug fix/hide display mnemonic by @fmtabbara in https://github.com/nymtech/nym/pull/1874 - adding bity icon and wallet address by @gala1234 in https://github.com/nymtech/nym/pull/2689 From eff1f383c3c8b9be5e67d2afaf441c211d2d939d Mon Sep 17 00:00:00 2001 From: Fouad Date: Wed, 21 Dec 2022 12:56:40 +0000 Subject: [PATCH 39/39] Feature/node settings apy playground (#1677) (#2738) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * initial ui for test my node use svg for node path add stories for test my node * add initial rewards calculation * update validation for rewards playground * init playground with default values * get node uptime * get mixnode reward estimation * calculate saturation calculate stake saturation * Make ComputeRewardEstParam derive Debug * set active set to be always true Co-authored-by: Jon Häggblad Co-authored-by: Jon Häggblad --- Cargo.lock | 18 +-- .../validator-client/src/validator_api/mod.rs | 28 +++- .../src/validator_api/routes.rs | 1 + nym-connect/src-tauri/src/menu.rs | 3 +- nym-wallet/Cargo.lock | 2 +- nym-wallet/src-tauri/src/main.rs | 3 + .../src-tauri/src/operations/mixnet/bond.rs | 15 ++ .../src/operations/mixnet/rewards.rs | 16 +- .../src/operations/validator_api/status.rs | 31 +++- nym-wallet/src/components/AppBar.tsx | 2 +- .../InclusionProbability.tsx | 19 +++ .../components/RewardsPlayground/Inputs.tsx | 91 ++++++++++++ .../RewardsPlayground/NodeDetail.tsx | 32 ++++ .../RewardsPlayground/ResultsTable.tsx | 75 ++++++++++ .../inputsValidationSchema.ts | 41 ++++++ nym-wallet/src/context/bonding.tsx | 15 +- nym-wallet/src/context/mocks/bonding.tsx | 4 +- .../bonding/node-settings/NodeSettings.tsx | 4 +- .../node-settings/apy-playground/index.tsx | 139 ++++++++++++++++++ .../node-settings/apy-playground/utils.tsx | 66 +++++++++ .../node-settings/node-settings.constant.tsx | 2 +- nym-wallet/src/requests/queries.ts | 15 ++ nym-wallet/src/requests/rewards.ts | 5 +- nym-wallet/src/types/rust/AppEnv.ts | 7 +- nym-wallet/src/types/rust/Network.ts | 3 +- nym-wallet/src/types/rust/StateParams.ts | 8 +- nym-wallet/src/types/rust/ValidatorUrl.ts | 6 +- nym-wallet/src/types/rust/ValidatorUrls.ts | 6 +- ts-packages/mui-theme/src/theme/theme.ts | 1 + ts-packages/types/src/types/rust/Account.ts | 1 + .../types/src/types/rust/AccountEntry.ts | 2 + .../src/types/rust/AccountWithMnemonic.ts | 1 + ts-packages/types/src/types/rust/Balance.ts | 1 + ts-packages/types/src/types/rust/Coin.ts | 2 + ts-packages/types/src/types/rust/CosmosFee.ts | 1 + .../types/src/types/rust/CurrencyDenom.ts | 2 + ts-packages/types/src/types/rust/DecCoin.ts | 1 + .../types/src/types/rust/Delegation.ts | 1 + .../types/src/types/rust/DelegationEvent.ts | 1 + .../src/types/rust/DelegationEventKind.ts | 2 + .../types/src/types/rust/DelegationResult.ts | 1 + .../types/rust/DelegationSummaryResponse.ts | 1 + .../types/rust/DelegationWithEverything.ts | 1 + ts-packages/types/src/types/rust/Fee.ts | 1 + .../types/src/types/rust/FeeDetails.ts | 1 + ts-packages/types/src/types/rust/Gas.ts | 2 + ts-packages/types/src/types/rust/GasInfo.ts | 1 + ts-packages/types/src/types/rust/Gateway.ts | 2 + .../types/src/types/rust/GatewayBond.ts | 1 + .../rust/InclusionProbabilityResponse.ts | 1 + ts-packages/types/src/types/rust/Interval.ts | 2 +- .../types/src/types/rust/MixNodeBond.ts | 1 + ts-packages/types/src/types/rust/Mixnode.ts | 2 + .../types/src/types/rust/MixnodeStatus.ts | 2 + .../src/types/rust/MixnodeStatusResponse.ts | 1 + .../src/types/rust/OriginalVestingResponse.ts | 1 + ts-packages/types/src/types/rust/Period.ts | 2 + .../types/src/types/rust/PledgeData.ts | 1 + .../src/types/rust/RewardedSetNodeStatus.ts | 2 + .../src/types/rust/RpcTransactionResponse.ts | 1 + .../types/src/types/rust/SendTxResult.ts | 1 + .../src/types/rust/StakeSaturationResponse.ts | 2 + .../src/types/rust/TransactionDetails.ts | 1 + .../types/rust/TransactionExecuteResult.ts | 1 + .../src/types/rust/VestingAccountInfo.ts | 1 + .../types/src/types/rust/VestingPeriod.ts | 2 + ts-packages/types/src/utils/decimal/index.ts | 3 + .../validator-api-requests/src/models.rs | 2 +- 68 files changed, 672 insertions(+), 41 deletions(-) create mode 100644 nym-wallet/src/components/RewardsPlayground/InclusionProbability.tsx create mode 100644 nym-wallet/src/components/RewardsPlayground/Inputs.tsx create mode 100644 nym-wallet/src/components/RewardsPlayground/NodeDetail.tsx create mode 100644 nym-wallet/src/components/RewardsPlayground/ResultsTable.tsx create mode 100644 nym-wallet/src/components/RewardsPlayground/inputsValidationSchema.ts create mode 100644 nym-wallet/src/pages/bonding/node-settings/apy-playground/index.tsx create mode 100644 nym-wallet/src/pages/bonding/node-settings/apy-playground/utils.tsx diff --git a/Cargo.lock b/Cargo.lock index 822fa26726..2256ba25f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -586,7 +586,7 @@ dependencies = [ [[package]] name = "client-core" -version = "1.1.2" +version = "1.1.4" dependencies = [ "async-trait", "client-connections", @@ -3106,7 +3106,7 @@ dependencies = [ [[package]] name = "nym-cli" -version = "1.1.2" +version = "1.1.4" dependencies = [ "anyhow", "base64", @@ -3160,7 +3160,7 @@ dependencies = [ [[package]] name = "nym-client" -version = "1.1.2" +version = "1.1.4" dependencies = [ "clap 3.2.8", "client-connections", @@ -3199,7 +3199,7 @@ dependencies = [ [[package]] name = "nym-gateway" -version = "1.1.2" +version = "1.1.4" dependencies = [ "anyhow", "async-trait", @@ -3246,7 +3246,7 @@ dependencies = [ [[package]] name = "nym-mixnode" -version = "1.1.2" +version = "1.1.4" dependencies = [ "anyhow", "bs58", @@ -3288,7 +3288,7 @@ dependencies = [ [[package]] name = "nym-network-requester" -version = "1.1.2" +version = "1.1.4" dependencies = [ "async-trait", "clap 3.2.8", @@ -3320,7 +3320,7 @@ dependencies = [ [[package]] name = "nym-network-statistics" -version = "1.1.2" +version = "1.1.4" dependencies = [ "dirs", "log", @@ -3336,7 +3336,7 @@ dependencies = [ [[package]] name = "nym-socks5-client" -version = "1.1.2" +version = "1.1.4" dependencies = [ "clap 3.2.8", "client-connections", @@ -3403,7 +3403,7 @@ dependencies = [ [[package]] name = "nym-validator-api" -version = "1.1.2" +version = "1.1.4" dependencies = [ "anyhow", "async-trait", diff --git a/common/client-libs/validator-client/src/validator_api/mod.rs b/common/client-libs/validator-client/src/validator_api/mod.rs index 3cb7ae2ce9..c0775b9971 100644 --- a/common/client-libs/validator-client/src/validator_api/mod.rs +++ b/common/client-libs/validator-client/src/validator_api/mod.rs @@ -12,10 +12,11 @@ use validator_api_requests::coconut::{ BlindSignRequestBody, BlindedSignatureResponse, VerifyCredentialBody, VerifyCredentialResponse, }; use validator_api_requests::models::{ - GatewayCoreStatusResponse, GatewayStatusReportResponse, GatewayUptimeHistoryResponse, - InclusionProbabilityResponse, MixNodeBondAnnotated, MixnodeCoreStatusResponse, - MixnodeStatusReportResponse, MixnodeStatusResponse, MixnodeUptimeHistoryResponse, RequestError, - RewardEstimationResponse, StakeSaturationResponse, UptimeResponse, + ComputeRewardEstParam, GatewayCoreStatusResponse, GatewayStatusReportResponse, + GatewayUptimeHistoryResponse, InclusionProbabilityResponse, MixNodeBondAnnotated, + MixnodeCoreStatusResponse, MixnodeStatusReportResponse, MixnodeStatusResponse, + MixnodeUptimeHistoryResponse, RequestError, RewardEstimationResponse, StakeSaturationResponse, + UptimeResponse, }; pub mod error; @@ -365,6 +366,25 @@ impl Client { .await } + pub async fn compute_mixnode_reward_estimation( + &self, + mix_id: MixId, + request_body: &ComputeRewardEstParam, + ) -> Result { + self.post_validator_api( + &[ + routes::API_VERSION, + routes::STATUS_ROUTES, + routes::MIXNODE, + &mix_id.to_string(), + routes::COMPUTE_REWARD_ESTIMATION, + ], + NO_PARAMS, + request_body, + ) + .await + } + pub async fn get_mixnode_stake_saturation( &self, mix_id: MixId, diff --git a/common/client-libs/validator-client/src/validator_api/routes.rs b/common/client-libs/validator-client/src/validator_api/routes.rs index 66a822b4fd..e98f2d295a 100644 --- a/common/client-libs/validator-client/src/validator_api/routes.rs +++ b/common/client-libs/validator-client/src/validator_api/routes.rs @@ -28,6 +28,7 @@ pub const STATUS: &str = "status"; pub const REPORT: &str = "report"; pub const HISTORY: &str = "history"; pub const REWARD_ESTIMATION: &str = "reward-estimation"; +pub const COMPUTE_REWARD_ESTIMATION: &str = "compute-reward-estimation"; pub const AVG_UPTIME: &str = "avg_uptime"; pub const STAKE_SATURATION: &str = "stake-saturation"; pub const INCLUSION_CHANCE: &str = "inclusion-probability"; diff --git a/nym-connect/src-tauri/src/menu.rs b/nym-connect/src-tauri/src/menu.rs index fb6f88fb68..2f9be83e07 100644 --- a/nym-connect/src-tauri/src/menu.rs +++ b/nym-connect/src-tauri/src/menu.rs @@ -16,8 +16,7 @@ impl AddDefaultSubmenus for Menu { fn add_default_app_submenus(self) -> Self { let submenu = Submenu::new( "Help", - Menu::new() - .add_item(CustomMenuItem::new(SHOW_LOG_WINDOW, "Show logs")) + Menu::new().add_item(CustomMenuItem::new(SHOW_LOG_WINDOW, "Show logs")), ); self.add_submenu(submenu) } diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 41db8105db..9112e7a45f 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -2862,7 +2862,7 @@ dependencies = [ [[package]] name = "nym_wallet" -version = "1.1.2" +version = "1.1.4" dependencies = [ "aes-gcm", "argon2 0.3.4", diff --git a/nym-wallet/src-tauri/src/main.rs b/nym-wallet/src-tauri/src/main.rs index d34a04f920..fff95fcb40 100644 --- a/nym-wallet/src-tauri/src/main.rs +++ b/nym-wallet/src-tauri/src/main.rs @@ -83,7 +83,9 @@ fn main() { mixnet::rewards::claim_delegator_reward, mixnet::rewards::claim_operator_reward, mixnet::rewards::claim_locked_and_unlocked_delegator_reward, + mixnet::rewards::get_current_rewarding_parameters, mixnet::send::send, + mixnet::bond::get_mixnode_uptime, network_config::add_validator, network_config::get_validator_api_urls, network_config::get_validator_nymd_urls, @@ -99,6 +101,7 @@ fn main() { utils::get_old_and_incorrect_hardcoded_fee, utils::try_convert_pubkey_to_mix_id, utils::default_mixnode_cost_params, + validator_api::status::compute_mixnode_reward_estimation, validator_api::status::gateway_core_node_status, validator_api::status::mixnode_core_node_status, validator_api::status::mixnode_inclusion_probability, diff --git a/nym-wallet/src-tauri/src/operations/mixnet/bond.rs b/nym-wallet/src-tauri/src/operations/mixnet/bond.rs index 567dc84290..c29e49b23c 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/bond.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/bond.rs @@ -341,3 +341,18 @@ pub async fn get_mix_node_description( .json() .await?) } + +#[tauri::command] +pub async fn get_mixnode_uptime( + mix_id: MixId, + state: tauri::State<'_, WalletState>, +) -> Result { + log::info!(">>> Get mixnode uptime"); + + let guard = state.read().await; + let client = guard.current_client()?; + let uptime = client.validator_api.get_mixnode_avg_uptime(mix_id).await?; + + log::info!(">>> Uptime response: {}", uptime.avg_uptime); + Ok(uptime.avg_uptime) +} diff --git a/nym-wallet/src-tauri/src/operations/mixnet/rewards.rs b/nym-wallet/src-tauri/src/operations/mixnet/rewards.rs index 6fb8893ee9..b4a048eeea 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/rewards.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/rewards.rs @@ -1,7 +1,7 @@ use crate::error::BackendError; use crate::state::WalletState; use crate::vesting::rewards::vesting_claim_delegator_reward; -use mixnet_contract_common::MixId; +use mixnet_contract_common::{MixId, RewardingParams}; use nym_types::transaction::TransactionExecuteResult; use validator_client::nymd::traits::{MixnetQueryClient, MixnetSigningClient}; use validator_client::nymd::Fee; @@ -95,3 +95,17 @@ pub async fn claim_locked_and_unlocked_delegator_reward( log::trace!("<<< {:?}", res); Ok(res) } + +#[tauri::command] +pub async fn get_current_rewarding_parameters( + state: tauri::State<'_, WalletState>, +) -> Result { + log::info!(">>> Get current rewarding params",); + + let guard = state.read().await; + let client = guard.current_client()?; + + let reward_params = client.nymd.get_rewarding_parameters().await?; + + Ok(reward_params) +} diff --git a/nym-wallet/src-tauri/src/operations/validator_api/status.rs b/nym-wallet/src-tauri/src/operations/validator_api/status.rs index 16c83cfb67..873a1fa0a4 100644 --- a/nym-wallet/src-tauri/src/operations/validator_api/status.rs +++ b/nym-wallet/src-tauri/src/operations/validator_api/status.rs @@ -4,11 +4,11 @@ use crate::api_client; use crate::error::BackendError; use crate::state::WalletState; -use mixnet_contract_common::{IdentityKeyRef, MixId}; +use mixnet_contract_common::{reward_params::Performance, Coin, IdentityKeyRef, MixId, Percent}; use validator_client::models::{ - GatewayCoreStatusResponse, GatewayStatusReportResponse, InclusionProbabilityResponse, - MixnodeCoreStatusResponse, MixnodeStatusResponse, RewardEstimationResponse, - StakeSaturationResponse, + ComputeRewardEstParam, GatewayCoreStatusResponse, GatewayStatusReportResponse, + InclusionProbabilityResponse, MixnodeCoreStatusResponse, MixnodeStatusResponse, + RewardEstimationResponse, StakeSaturationResponse, }; #[tauri::command] @@ -59,6 +59,29 @@ pub async fn mixnode_reward_estimation( .await?) } +#[tauri::command] +pub async fn compute_mixnode_reward_estimation( + mix_id: u32, + performance: Option, + pledge_amount: Option, + total_delegation: Option, + interval_operating_cost: Option, + profit_margin_percent: Option, + state: tauri::State<'_, WalletState>, +) -> Result { + let request_body = ComputeRewardEstParam { + performance, + active_in_rewarded_set: Some(true), + pledge_amount, + total_delegation, + interval_operating_cost, + profit_margin_percent, + }; + Ok(api_client!(state) + .compute_mixnode_reward_estimation(mix_id, &request_body) + .await?) +} + #[tauri::command] pub async fn mixnode_stake_saturation( mix_id: MixId, diff --git a/nym-wallet/src/components/AppBar.tsx b/nym-wallet/src/components/AppBar.tsx index 24b2f93942..3022646798 100644 --- a/nym-wallet/src/components/AppBar.tsx +++ b/nym-wallet/src/components/AppBar.tsx @@ -15,7 +15,7 @@ export const AppBar = () => { const navigate = useNavigate(); return ( - + diff --git a/nym-wallet/src/components/RewardsPlayground/InclusionProbability.tsx b/nym-wallet/src/components/RewardsPlayground/InclusionProbability.tsx new file mode 100644 index 0000000000..d60f7886c7 --- /dev/null +++ b/nym-wallet/src/components/RewardsPlayground/InclusionProbability.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { Typography } from '@mui/material'; +import { SelectionChance } from '@nymproject/types'; + +const colorMap: { [key in SelectionChance]: string } = { + Low: 'error.main', + Good: 'warning.main', + High: 'success.main', +}; + +const textMap: { [key in SelectionChance]: string } = { + Low: 'Low', + Good: 'Good', + High: 'High', +}; + +export const InclusionProbability = ({ probability }: { probability: SelectionChance }) => ( + {textMap[probability]} +); diff --git a/nym-wallet/src/components/RewardsPlayground/Inputs.tsx b/nym-wallet/src/components/RewardsPlayground/Inputs.tsx new file mode 100644 index 0000000000..1f1dbac935 --- /dev/null +++ b/nym-wallet/src/components/RewardsPlayground/Inputs.tsx @@ -0,0 +1,91 @@ +import React, { useCallback } from 'react'; +import { yupResolver } from '@hookform/resolvers/yup'; +import { Button, Grid, TextField, Typography } from '@mui/material'; +import { useForm } from 'react-hook-form'; +import { DefaultInputValues } from 'src/pages/bonding/node-settings/apy-playground'; +import { inputValidationSchema } from './inputsValidationSchema'; + +export type InputFields = { + label: string; + name: 'profitMargin' | 'uptime' | 'bond' | 'delegations' | 'operatorCost' | 'uptime'; + isPercentage?: boolean; +}[]; + +export type CalculateArgs = { + bond: string; + delegations: string; + uptime: string; + profitMargin: string; + operatorCost: string; +}; + +const inputFields: InputFields = [ + { label: 'Profit margin', name: 'profitMargin', isPercentage: true }, + { label: 'Operator cost', name: 'operatorCost' }, + { label: 'Bond', name: 'bond' }, + { label: 'Delegations', name: 'delegations' }, + { label: 'Uptime', name: 'uptime', isPercentage: true }, +]; + +export const Inputs = ({ + onCalculate, + defaultValues, +}: { + onCalculate: (args: CalculateArgs) => Promise; + defaultValues: DefaultInputValues; +}) => { + const handleCalculate = useCallback( + async (args: CalculateArgs) => { + onCalculate({ + bond: args.bond, + delegations: args.delegations, + uptime: args.uptime, + profitMargin: args.profitMargin, + operatorCost: args.operatorCost, + }); + }, + [onCalculate], + ); + + const { + register, + handleSubmit, + formState: { errors }, + } = useForm({ + resolver: yupResolver(inputValidationSchema), + defaultValues, + }); + + return ( + + {inputFields.map((field) => ( + + {field.isPercentage ? '%' : 'NYM'}, + }} + InputLabelProps={{ shrink: true }} + /> + + ))}{' '} + + + + + ); +}; diff --git a/nym-wallet/src/components/RewardsPlayground/NodeDetail.tsx b/nym-wallet/src/components/RewardsPlayground/NodeDetail.tsx new file mode 100644 index 0000000000..fb8a239be0 --- /dev/null +++ b/nym-wallet/src/components/RewardsPlayground/NodeDetail.tsx @@ -0,0 +1,32 @@ +import React from 'react'; +import { Card, CardContent, Divider, Stack, Typography } from '@mui/material'; +import { SelectionChance } from '@nymproject/types'; +import { InclusionProbability } from './InclusionProbability'; + +const computeSelectionProbability = (saturation: number): SelectionChance => { + if (saturation < 5) return 'Low'; + + if (saturation > 5 && saturation < 15) return 'Good'; + + return 'High'; +}; + +export const NodeDetails = ({ saturation }: { saturation?: string }) => { + if (!saturation) return null; + + return ( + + + + Stake saturation + {saturation || '- '}% + + + + Selection probability + + + + + ); +}; diff --git a/nym-wallet/src/components/RewardsPlayground/ResultsTable.tsx b/nym-wallet/src/components/RewardsPlayground/ResultsTable.tsx new file mode 100644 index 0000000000..19196c176d --- /dev/null +++ b/nym-wallet/src/components/RewardsPlayground/ResultsTable.tsx @@ -0,0 +1,75 @@ +import React from 'react'; +import { + Card, + CardContent, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + Typography, +} from '@mui/material'; + +export type Results = { + operator: { + daily: string; + monthly: string; + yearly: string; + }; + delegator: { + daily: string; + monthly: string; + yearly: string; + }; + total: { + daily: string; + monthly: string; + yearly: string; + }; +}; + +const tableHeader = [ + { title: 'Estimated rewards', bold: true }, + { title: 'Per day' }, + { title: 'Per month' }, + { title: 'Per year' }, +]; + +export const ResultsTable = ({ results }: { results: Results }) => { + const tableRows = [ + { title: 'Total node reward', ...results.total }, + { title: 'Operator rewards', ...results.operator }, + { title: 'Delegator rewards', ...results.delegator }, + ]; + + return ( + + + + + + + {tableHeader.map((header) => ( + + {header.title} + + ))} + + + + {tableRows.map((row) => ( + + {row.title} + {row.daily} + {row.monthly} + {row.yearly} + + ))} + +
    +
    +
    +
    + ); +}; diff --git a/nym-wallet/src/components/RewardsPlayground/inputsValidationSchema.ts b/nym-wallet/src/components/RewardsPlayground/inputsValidationSchema.ts new file mode 100644 index 0000000000..ef5d9ecc0d --- /dev/null +++ b/nym-wallet/src/components/RewardsPlayground/inputsValidationSchema.ts @@ -0,0 +1,41 @@ +import * as Yup from 'yup'; +import { isGreaterThan, isLessThan } from 'src/utils'; + +export const inputValidationSchema = Yup.object().shape({ + profitMargin: Yup.string() + .required('profit margin is a required field') + .test('Is valid profit margin value', (value, ctx) => { + const stringValueToNumber = Math.round(Number(value)); + + if (isGreaterThan(stringValueToNumber, -1) && isLessThan(stringValueToNumber, 101)) return true; + return ctx.createError({ message: 'Profit margin must be a number from 0 and 100' }); + }), + uptime: Yup.string() + .required() + .test('Is valid uptime value', (value, ctx) => { + const stringValueToNumber = Math.round(Number(value)); + if (stringValueToNumber && isGreaterThan(stringValueToNumber, 0) && isLessThan(stringValueToNumber, 101)) + return true; + return ctx.createError({ message: 'Uptime must be a number between 0 and 100' }); + }), + bond: Yup.string() + .required() + .test('Is valid bond value', (value, ctx) => { + if (Number(value)) return true; + return ctx.createError({ message: 'Bond must be a valid number' }); + }), + delegations: Yup.string() + .required() + .test('Is valid delegation value', (value, ctx) => { + if (Number(value)) return true; + return ctx.createError({ message: 'Delegations must be a valid number' }); + }), + operatorCost: Yup.string() + .required('operator cost is a required field') + .test('Is valid operator cost value', (value, ctx) => { + const stringValueToNumber = Math.round(Number(value)); + + if (isGreaterThan(stringValueToNumber, -1) && isLessThan(stringValueToNumber, 101)) return true; + return ctx.createError({ message: 'Operator cost must be a valid number' }); + }), +}); diff --git a/nym-wallet/src/context/bonding.tsx b/nym-wallet/src/context/bonding.tsx index 7225360456..94bf5271ca 100644 --- a/nym-wallet/src/context/bonding.tsx +++ b/nym-wallet/src/context/bonding.tsx @@ -24,7 +24,6 @@ import { vestingBondMixNode, vestingUnbondGateway, vestingUnbondMixnode, - getPendingEpochEvents, updateMixnodeCostParams as updateMixnodeCostParamsRequest, vestingUpdateMixnodeCostParams as updateMixnodeVestingCostParamsRequest, getNodeDescription as getNodeDescriptionRequest, @@ -36,6 +35,7 @@ import { getMixnodeAvgUptime, getMixnodeRewardEstimation, getGatewayReport, + getMixnodeUptime, } from '../requests'; import { useCheckOwnership } from '../hooks/useCheckOwnership'; import { AppContext } from './main'; @@ -71,10 +71,12 @@ export type TBondedMixnode = { verlocPort: number; version: string; isUnbonding: boolean; + uptime: number; }; export interface TBondedGateway { - name: string; + name?: string; + id: number; identityKey: string; ip: string; bond: DecCoin; @@ -154,14 +156,18 @@ export const BondingContextProvider = ({ children }: { children?: React.ReactNod status: MixnodeStatus; stakeSaturation: string; estimatedRewards?: DecCoin; + uptime: number; } = { status: 'not_found', stakeSaturation: '0', + uptime: 0, }; try { const statusResponse = await getMixnodeStatus(mixId); + const uptime = await getMixnodeUptime(mixId); additionalDetails.status = statusResponse.status; + additionalDetails.uptime = uptime; } catch (e) { Console.log('getMixnodeStatus fails', e); } @@ -259,7 +265,8 @@ export const BondingContextProvider = ({ children }: { children?: React.ReactNod rewarding_details, bond_information: { mix_id }, } = data; - const { status, stakeSaturation, estimatedRewards } = await getAdditionalMixnodeDetails(mix_id); + + const { status, stakeSaturation, estimatedRewards, uptime } = await getAdditionalMixnodeDetails(mix_id); const setProbabilities = await getSetProbabilities(mix_id); const nodeDescription = await getNodeDescription( bond_information.mix_node.host, @@ -267,6 +274,7 @@ export const BondingContextProvider = ({ children }: { children?: React.ReactNod ); const routingScore = await getAvgUptime(); setBondedNode({ + id: data.bond_information.mix_id, name: nodeDescription?.name, mixId: mix_id, identityKey: bond_information.mix_node.identity_key, @@ -279,6 +287,7 @@ export const BondingContextProvider = ({ children }: { children?: React.ReactNod delegators: rewarding_details.unique_delegations, proxy: bond_information.proxy, operatorRewards, + uptime, status, stakeSaturation, operatorCost: decCoinToDisplay(rewarding_details.cost_params.interval_operating_cost), diff --git a/nym-wallet/src/context/mocks/bonding.tsx b/nym-wallet/src/context/mocks/bonding.tsx index 95e770850b..f38168ee28 100644 --- a/nym-wallet/src/context/mocks/bonding.tsx +++ b/nym-wallet/src/context/mocks/bonding.tsx @@ -7,8 +7,8 @@ import { mockSleep } from './utils'; const SLEEP_MS = 1000; const bondedMixnodeMock: TBondedMixnode = { - name: 'Monster node', mixId: 1, + name: 'Monster node', identityKey: '7mjM2fYbtN6kxMwp1TrmQ4VwPks3URR5pBgWPWhzT98F', stake: { denom: 'nym', amount: '1234' }, bond: { denom: 'nym', amount: '1234' }, @@ -28,9 +28,11 @@ const bondedMixnodeMock: TBondedMixnode = { verlocPort: 1790, version: '1.0.2', isUnbonding: false, + uptime: 1, }; const bondedGatewayMock: TBondedGateway = { + id: 1, name: 'Monster node', identityKey: 'WayM2fYbtN6kxMwp1TrmQ4VwPks3URR5pBgWPWhzT98F', ip: '112.43.234.57', diff --git a/nym-wallet/src/pages/bonding/node-settings/NodeSettings.tsx b/nym-wallet/src/pages/bonding/node-settings/NodeSettings.tsx index da50bc2d2d..798993dc49 100644 --- a/nym-wallet/src/pages/bonding/node-settings/NodeSettings.tsx +++ b/nym-wallet/src/pages/bonding/node-settings/NodeSettings.tsx @@ -10,13 +10,14 @@ import { LoadingModal } from 'src/components/Modals/LoadingModal'; import { NymCard } from 'src/components'; import { PageLayout } from 'src/layouts'; import { Tabs } from 'src/components/Tabs'; -import { useBondingContext, BondingContextProvider } from 'src/context'; +import { useBondingContext, BondingContextProvider, TBondedMixnode } from 'src/context'; import { AppContext, urls } from 'src/context/main'; import { NodeGeneralSettings } from './settings-pages/general-settings'; import { NodeUnbondPage } from './settings-pages/NodeUnbondPage'; import { createNavItems } from './node-settings.constant'; import { isMixnode } from 'src/types'; +import { ApyPlayground } from './apy-playground'; export const NodeSettings = () => { const theme = useTheme(); @@ -123,6 +124,7 @@ export const NodeSettings = () => { {value === 'Unbond' && bondedNode && ( )} + {value === 'Playground' && bondedNode && } {confirmationDetails && confirmationDetails.status === 'success' && ( { + const { enqueueSnackbar } = useSnackbar(); + + const [results, setResults] = useState({ + total: { daily: '-', monthly: '-', yearly: '-' }, + operator: { daily: '-', monthly: '-', yearly: '-' }, + delegator: { daily: '-', monthly: '-', yearly: '-' }, + }); + + const [defaultInputValues, setDefaultInputValues] = useState(); + const [stakeSaturation, setStakeSaturation] = useState(); + const [isLoading, setIsLoading] = useState(true); + + const initialise = async (node: TBondedMixnode) => { + try { + const delegations = await getDelegationSummary(); + + const { estimation } = await computeEstimate({ + mixId: node.mixId, + uptime: node.uptime.toString(), + profitMargin: node.profitMargin, + operatorCost: node.operatorCost.amount, + totalDelegation: delegations.total_delegations.amount, + pledgeAmount: node.bond.amount, + }); + + setResults( + handleCalculatePeriodRewards({ + estimatedOperatorReward: estimation.operator, + estimatedDelegatorsReward: estimation.delegates, + }), + ); + + setStakeSaturation(node.stakeSaturation); + + setDefaultInputValues({ + profitMargin: node.profitMargin, + uptime: (node.uptime || 0).toString(), + bond: node.bond.amount || '', + delegations: delegations.total_delegations.amount, + operatorCost: node.operatorCost.amount, + }); + setIsLoading(false); + } catch (e) { + enqueueSnackbar(e as string, { variant: 'error' }); + } + }; + + useEffect(() => { + if (bondedNode) { + initialise(bondedNode); + } + }, []); + + if (isLoading) return ; + + const handleCalculateEstimate = async ({ bond, delegations, uptime, profitMargin, operatorCost }: CalculateArgs) => { + try { + const { estimation, reward_params } = await computeEstimate({ + mixId: bondedNode.mixId, + uptime: uptime, + profitMargin: profitMargin, + operatorCost: operatorCost, + totalDelegation: delegations, + pledgeAmount: bond, + }); + + const estimationResult = handleCalculatePeriodRewards({ + estimatedOperatorReward: estimation.operator, + estimatedDelegatorsReward: estimation.delegates, + }); + + const computedStakeSaturation = computeStakeSaturation( + bond, + delegations, + reward_params.interval.stake_saturation_point, + ); + + setStakeSaturation(computedStakeSaturation); + setResults(estimationResult); + } catch (e) { + console.log(e); + } + }; + + return ( + + + Playground + + + This is your parameters playground - change the parameters below to see the node specific estimations in the + table + + {defaultInputValues && ( + + + Estimation calculator + + } + /> + + + + + )} + + + + + + + + + + ); +}; diff --git a/nym-wallet/src/pages/bonding/node-settings/apy-playground/utils.tsx b/nym-wallet/src/pages/bonding/node-settings/apy-playground/utils.tsx new file mode 100644 index 0000000000..bc99898b45 --- /dev/null +++ b/nym-wallet/src/pages/bonding/node-settings/apy-playground/utils.tsx @@ -0,0 +1,66 @@ +import { decimalToPercentage, percentToDecimal } from '@nymproject/types'; +import { computeMixnodeRewardEstimation } from 'src/requests'; + +const SCALE_FACTOR = 1_000_000; + +export const computeStakeSaturation = (bond: string, delegations: string, stakeSaturationPoint: string) => { + const res = ((+bond + +delegations) * SCALE_FACTOR) / +stakeSaturationPoint; + return decimalToPercentage(res.toFixed(18).toString()); +}; + +export const computeEstimate = async ({ + mixId, + uptime, + pledgeAmount, + totalDelegation, + profitMargin, + operatorCost, +}: { + mixId: number; + uptime: string; + pledgeAmount: string; + totalDelegation: string; + profitMargin: string; + operatorCost: string; +}) => { + const computedEstimate = await computeMixnodeRewardEstimation({ + mixId: mixId, + performance: percentToDecimal(uptime), + pledgeAmount: Math.round(+pledgeAmount * SCALE_FACTOR), + totalDelegation: Math.round(+totalDelegation * SCALE_FACTOR), + profitMarginPercent: percentToDecimal(profitMargin), + intervalOperatingCost: { denom: 'unym', amount: Math.round(+operatorCost * SCALE_FACTOR).toString() }, + }); + + return computedEstimate; +}; + +export const handleCalculatePeriodRewards = ({ + estimatedOperatorReward, + estimatedDelegatorsReward, +}: { + estimatedOperatorReward: string; + estimatedDelegatorsReward: string; +}) => { + const dailyOperatorReward = (+estimatedOperatorReward / SCALE_FACTOR) * 24; // epoch_reward * 1 epoch_per_hour * 24 hours + const dailyDelegatorReward = (+estimatedDelegatorsReward / SCALE_FACTOR) * 24; + const dailyTotal = dailyOperatorReward + dailyDelegatorReward; + + return { + total: { + daily: dailyTotal.toFixed(3).toString(), + monthly: (dailyTotal * 30).toFixed(3).toString(), + yearly: (dailyTotal * 365).toFixed(3).toString(), + }, + operator: { + daily: dailyOperatorReward.toFixed(3).toString(), + monthly: (dailyOperatorReward * 30).toFixed(3).toString(), + yearly: (dailyOperatorReward * 365).toFixed(3).toString(), + }, + delegator: { + daily: dailyDelegatorReward.toFixed(3).toString(), + monthly: (dailyDelegatorReward * 30).toFixed(3).toString(), + yearly: (dailyDelegatorReward * 365).toFixed(3).toString(), + }, + }; +}; diff --git a/nym-wallet/src/pages/bonding/node-settings/node-settings.constant.tsx b/nym-wallet/src/pages/bonding/node-settings/node-settings.constant.tsx index f00409a182..0e8b6204fd 100644 --- a/nym-wallet/src/pages/bonding/node-settings/node-settings.constant.tsx +++ b/nym-wallet/src/pages/bonding/node-settings/node-settings.constant.tsx @@ -1,5 +1,5 @@ export const createNavItems = (isMixnode: boolean) => { const navItems = ['Unbond']; - if (isMixnode) return ['General', ...navItems]; + if (isMixnode) return ['General', 'Playground', ...navItems]; return navItems; }; diff --git a/nym-wallet/src/requests/queries.ts b/nym-wallet/src/requests/queries.ts index 5fba51beec..640fc79abb 100644 --- a/nym-wallet/src/requests/queries.ts +++ b/nym-wallet/src/requests/queries.ts @@ -8,6 +8,7 @@ import { RewardEstimationResponse, WrappedDelegationEvent, PendingIntervalEvent, + Coin, } from '@nymproject/types'; import { Interval, TGatewayReport, TNodeDescription } from 'src/types'; import { invokeWrapper } from './wrapper'; @@ -51,3 +52,17 @@ export const getPendingIntervalEvents = async () => export const getGatewayReport = async (identity: string) => invokeWrapper('gateway_report', { identity }); + +export const computeMixnodeRewardEstimation = async (args: { + mixId: number; + performance: string; + pledgeAmount: number; + totalDelegation: number; + profitMarginPercent: string; + intervalOperatingCost: { denom: 'unym'; amount: string }; +}) => { + console.log(args); + + return invokeWrapper('compute_mixnode_reward_estimation', args); +}; +export const getMixnodeUptime = async (mixId: number) => invokeWrapper('get_mixnode_uptime', { mixId }); diff --git a/nym-wallet/src/requests/rewards.ts b/nym-wallet/src/requests/rewards.ts index 5c8c63e34e..36b90838e7 100644 --- a/nym-wallet/src/requests/rewards.ts +++ b/nym-wallet/src/requests/rewards.ts @@ -1,4 +1,4 @@ -import { Fee, FeeDetails, TransactionExecuteResult } from '@nymproject/types'; +import { Fee, FeeDetails, RewardingParams, TransactionExecuteResult } from '@nymproject/types'; import { invokeWrapper } from './wrapper'; export const claimOperatorReward = async (fee?: Fee) => @@ -9,3 +9,6 @@ export const claimDelegatorRewards = async (mixId: number, fee?: FeeDetails) => mixId, fee: fee?.fee, }); + +export const getCurrentRewardingParameter = async () => + invokeWrapper('get_current_rewarding_parameters', {}); diff --git a/nym-wallet/src/types/rust/AppEnv.ts b/nym-wallet/src/types/rust/AppEnv.ts index 3f47419469..861ecd9ef5 100644 --- a/nym-wallet/src/types/rust/AppEnv.ts +++ b/nym-wallet/src/types/rust/AppEnv.ts @@ -1,2 +1,5 @@ - -export interface AppEnv { ADMIN_ADDRESS: string | null, SHOW_TERMINAL: string | null, ENABLE_QA_MODE: string | null, } \ No newline at end of file +export interface AppEnv { + ADMIN_ADDRESS: string | null; + SHOW_TERMINAL: string | null; + ENABLE_QA_MODE: string | null; +} diff --git a/nym-wallet/src/types/rust/Network.ts b/nym-wallet/src/types/rust/Network.ts index fd31bccafa..f8615cd992 100644 --- a/nym-wallet/src/types/rust/Network.ts +++ b/nym-wallet/src/types/rust/Network.ts @@ -1,2 +1 @@ - -export type Network = "QA" | "SANDBOX" | "MAINNET"; \ No newline at end of file +export type Network = 'QA' | 'SANDBOX' | 'MAINNET'; diff --git a/nym-wallet/src/types/rust/StateParams.ts b/nym-wallet/src/types/rust/StateParams.ts index 85c362a3b2..c9420f50dc 100644 --- a/nym-wallet/src/types/rust/StateParams.ts +++ b/nym-wallet/src/types/rust/StateParams.ts @@ -1,3 +1,7 @@ -import type { DecCoin } from "../../../../ts-packages/types/src/types/rust/DecCoin"; +import type { DecCoin } from '../../../../ts-packages/types/src/types/rust/DecCoin'; -export interface TauriContractStateParams { minimum_mixnode_pledge: DecCoin, minimum_gateway_pledge: DecCoin, minimum_mixnode_delegation: DecCoin | null, } \ No newline at end of file +export interface TauriContractStateParams { + minimum_mixnode_pledge: DecCoin; + minimum_gateway_pledge: DecCoin; + minimum_mixnode_delegation: DecCoin | null; +} diff --git a/nym-wallet/src/types/rust/ValidatorUrl.ts b/nym-wallet/src/types/rust/ValidatorUrl.ts index 9c74679bac..801e045a00 100644 --- a/nym-wallet/src/types/rust/ValidatorUrl.ts +++ b/nym-wallet/src/types/rust/ValidatorUrl.ts @@ -1,2 +1,4 @@ - -export interface ValidatorUrl { url: string, name: string | null, } \ No newline at end of file +export interface ValidatorUrl { + url: string; + name: string | null; +} diff --git a/nym-wallet/src/types/rust/ValidatorUrls.ts b/nym-wallet/src/types/rust/ValidatorUrls.ts index 3a104150b1..98ca799fb5 100644 --- a/nym-wallet/src/types/rust/ValidatorUrls.ts +++ b/nym-wallet/src/types/rust/ValidatorUrls.ts @@ -1,3 +1,5 @@ -import type { ValidatorUrl } from "./ValidatorUrl"; +import type { ValidatorUrl } from './ValidatorUrl'; -export interface ValidatorUrls { urls: Array, } \ No newline at end of file +export interface ValidatorUrls { + urls: Array; +} diff --git a/ts-packages/mui-theme/src/theme/theme.ts b/ts-packages/mui-theme/src/theme/theme.ts index a12e706e9e..bb4dcae533 100644 --- a/ts-packages/mui-theme/src/theme/theme.ts +++ b/ts-packages/mui-theme/src/theme/theme.ts @@ -84,6 +84,7 @@ export const getDesignTokens = (mode: PaletteMode): ThemeOptions => { ].join(','), fontSize: 14, fontWeightRegular: 500, + fontWeightMedium: 600, button: { textTransform: 'none', fontWeight: '600', diff --git a/ts-packages/types/src/types/rust/Account.ts b/ts-packages/types/src/types/rust/Account.ts index ea0586828f..da0afb666e 100644 --- a/ts-packages/types/src/types/rust/Account.ts +++ b/ts-packages/types/src/types/rust/Account.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { CurrencyDenom } from './CurrencyDenom'; export interface Account { diff --git a/ts-packages/types/src/types/rust/AccountEntry.ts b/ts-packages/types/src/types/rust/AccountEntry.ts index f6ad1b53a9..472a9befcd 100644 --- a/ts-packages/types/src/types/rust/AccountEntry.ts +++ b/ts-packages/types/src/types/rust/AccountEntry.ts @@ -1,3 +1,5 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + export interface AccountEntry { id: string; address: string; diff --git a/ts-packages/types/src/types/rust/AccountWithMnemonic.ts b/ts-packages/types/src/types/rust/AccountWithMnemonic.ts index 6b3757bdab..edbf9b9de6 100644 --- a/ts-packages/types/src/types/rust/AccountWithMnemonic.ts +++ b/ts-packages/types/src/types/rust/AccountWithMnemonic.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { Account } from './Account'; export interface AccountWithMnemonic { diff --git a/ts-packages/types/src/types/rust/Balance.ts b/ts-packages/types/src/types/rust/Balance.ts index ba6be26651..fe11917327 100644 --- a/ts-packages/types/src/types/rust/Balance.ts +++ b/ts-packages/types/src/types/rust/Balance.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { DecCoin } from './DecCoin'; export interface Balance { diff --git a/ts-packages/types/src/types/rust/Coin.ts b/ts-packages/types/src/types/rust/Coin.ts index dda00291d7..493c2e6b41 100644 --- a/ts-packages/types/src/types/rust/Coin.ts +++ b/ts-packages/types/src/types/rust/Coin.ts @@ -1,3 +1,5 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + export interface Coin { denom: string; amount: bigint; diff --git a/ts-packages/types/src/types/rust/CosmosFee.ts b/ts-packages/types/src/types/rust/CosmosFee.ts index 54c0f689bc..d77c4d3dd8 100644 --- a/ts-packages/types/src/types/rust/CosmosFee.ts +++ b/ts-packages/types/src/types/rust/CosmosFee.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { Coin } from './Coin'; export interface CosmosFee { diff --git a/ts-packages/types/src/types/rust/CurrencyDenom.ts b/ts-packages/types/src/types/rust/CurrencyDenom.ts index 04760b4fd7..3e7696c28d 100644 --- a/ts-packages/types/src/types/rust/CurrencyDenom.ts +++ b/ts-packages/types/src/types/rust/CurrencyDenom.ts @@ -1 +1,3 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + export type CurrencyDenom = 'unknown' | 'nym' | 'nymt' | 'nyx' | 'nyxt'; diff --git a/ts-packages/types/src/types/rust/DecCoin.ts b/ts-packages/types/src/types/rust/DecCoin.ts index d2b1b4dd69..9411bf358b 100644 --- a/ts-packages/types/src/types/rust/DecCoin.ts +++ b/ts-packages/types/src/types/rust/DecCoin.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { CurrencyDenom } from './CurrencyDenom'; export type DecCoin = { denom: CurrencyDenom; amount: string }; diff --git a/ts-packages/types/src/types/rust/Delegation.ts b/ts-packages/types/src/types/rust/Delegation.ts index 18d6df201f..58de13e6cc 100644 --- a/ts-packages/types/src/types/rust/Delegation.ts +++ b/ts-packages/types/src/types/rust/Delegation.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { DecCoin } from './DecCoin'; export interface Delegation { diff --git a/ts-packages/types/src/types/rust/DelegationEvent.ts b/ts-packages/types/src/types/rust/DelegationEvent.ts index d9e2c0a21d..30ff21943f 100644 --- a/ts-packages/types/src/types/rust/DelegationEvent.ts +++ b/ts-packages/types/src/types/rust/DelegationEvent.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { DecCoin } from './DecCoin'; import type { DelegationEventKind } from './DelegationEventKind'; diff --git a/ts-packages/types/src/types/rust/DelegationEventKind.ts b/ts-packages/types/src/types/rust/DelegationEventKind.ts index a1db5fac12..a242220102 100644 --- a/ts-packages/types/src/types/rust/DelegationEventKind.ts +++ b/ts-packages/types/src/types/rust/DelegationEventKind.ts @@ -1 +1,3 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + export type DelegationEventKind = 'Delegate' | 'Undelegate'; diff --git a/ts-packages/types/src/types/rust/DelegationResult.ts b/ts-packages/types/src/types/rust/DelegationResult.ts index f6d29d9435..d8f8a77ce3 100644 --- a/ts-packages/types/src/types/rust/DelegationResult.ts +++ b/ts-packages/types/src/types/rust/DelegationResult.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { DecCoin } from './DecCoin'; export interface DelegationResult { diff --git a/ts-packages/types/src/types/rust/DelegationSummaryResponse.ts b/ts-packages/types/src/types/rust/DelegationSummaryResponse.ts index 0cb9346c59..21e85d513b 100644 --- a/ts-packages/types/src/types/rust/DelegationSummaryResponse.ts +++ b/ts-packages/types/src/types/rust/DelegationSummaryResponse.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { DecCoin } from './DecCoin'; import type { DelegationWithEverything } from './DelegationWithEverything'; diff --git a/ts-packages/types/src/types/rust/DelegationWithEverything.ts b/ts-packages/types/src/types/rust/DelegationWithEverything.ts index 0d3423a133..ecf949c5ae 100644 --- a/ts-packages/types/src/types/rust/DelegationWithEverything.ts +++ b/ts-packages/types/src/types/rust/DelegationWithEverything.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { DecCoin } from './DecCoin'; import type { DelegationEvent } from './DelegationEvent'; import type { MixNodeCostParams } from './MixNodeCostParams'; diff --git a/ts-packages/types/src/types/rust/Fee.ts b/ts-packages/types/src/types/rust/Fee.ts index 5a7a0af56e..1e3f747e92 100644 --- a/ts-packages/types/src/types/rust/Fee.ts +++ b/ts-packages/types/src/types/rust/Fee.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { CosmosFee } from './CosmosFee'; export type Fee = { Manual: CosmosFee } | { Auto: number | null }; diff --git a/ts-packages/types/src/types/rust/FeeDetails.ts b/ts-packages/types/src/types/rust/FeeDetails.ts index 60bcd4cae5..7db283dbc1 100644 --- a/ts-packages/types/src/types/rust/FeeDetails.ts +++ b/ts-packages/types/src/types/rust/FeeDetails.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { DecCoin } from './DecCoin'; import type { Fee } from './Fee'; diff --git a/ts-packages/types/src/types/rust/Gas.ts b/ts-packages/types/src/types/rust/Gas.ts index e207dcb1e1..2b93e47509 100644 --- a/ts-packages/types/src/types/rust/Gas.ts +++ b/ts-packages/types/src/types/rust/Gas.ts @@ -1,3 +1,5 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + export interface Gas { gas_units: bigint; } diff --git a/ts-packages/types/src/types/rust/GasInfo.ts b/ts-packages/types/src/types/rust/GasInfo.ts index fd5b21e582..3e34323018 100644 --- a/ts-packages/types/src/types/rust/GasInfo.ts +++ b/ts-packages/types/src/types/rust/GasInfo.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { Gas } from './Gas'; export interface GasInfo { diff --git a/ts-packages/types/src/types/rust/Gateway.ts b/ts-packages/types/src/types/rust/Gateway.ts index 1dbba0e5ed..4c449b578d 100644 --- a/ts-packages/types/src/types/rust/Gateway.ts +++ b/ts-packages/types/src/types/rust/Gateway.ts @@ -1,3 +1,5 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + export interface Gateway { host: string; mix_port: number; diff --git a/ts-packages/types/src/types/rust/GatewayBond.ts b/ts-packages/types/src/types/rust/GatewayBond.ts index 277994efac..405c1cab92 100644 --- a/ts-packages/types/src/types/rust/GatewayBond.ts +++ b/ts-packages/types/src/types/rust/GatewayBond.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { DecCoin } from './DecCoin'; import type { Gateway } from './Gateway'; diff --git a/ts-packages/types/src/types/rust/InclusionProbabilityResponse.ts b/ts-packages/types/src/types/rust/InclusionProbabilityResponse.ts index 56d81bde41..3f80b794a0 100644 --- a/ts-packages/types/src/types/rust/InclusionProbabilityResponse.ts +++ b/ts-packages/types/src/types/rust/InclusionProbabilityResponse.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { SelectionChance } from './SelectionChance'; export interface InclusionProbabilityResponse { diff --git a/ts-packages/types/src/types/rust/Interval.ts b/ts-packages/types/src/types/rust/Interval.ts index b47687ae22..7a7fa7bb4d 100644 --- a/ts-packages/types/src/types/rust/Interval.ts +++ b/ts-packages/types/src/types/rust/Interval.ts @@ -3,6 +3,6 @@ export interface Interval { epochs_in_interval: number; current_epoch_start: string; current_epoch_id: number; - epoch_length: string; + epoch_length: { secs: number; nanos: number }; total_elapsed_epochs: number; } diff --git a/ts-packages/types/src/types/rust/MixNodeBond.ts b/ts-packages/types/src/types/rust/MixNodeBond.ts index 37059b9b61..173ce9599d 100644 --- a/ts-packages/types/src/types/rust/MixNodeBond.ts +++ b/ts-packages/types/src/types/rust/MixNodeBond.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { DecCoin } from './DecCoin'; import type { MixNode } from './Mixnode'; diff --git a/ts-packages/types/src/types/rust/Mixnode.ts b/ts-packages/types/src/types/rust/Mixnode.ts index 0deaa5b919..8dddce4eb2 100644 --- a/ts-packages/types/src/types/rust/Mixnode.ts +++ b/ts-packages/types/src/types/rust/Mixnode.ts @@ -1,3 +1,5 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + export interface MixNode { host: string; mix_port: number; diff --git a/ts-packages/types/src/types/rust/MixnodeStatus.ts b/ts-packages/types/src/types/rust/MixnodeStatus.ts index da89c7e8a7..6421988dce 100644 --- a/ts-packages/types/src/types/rust/MixnodeStatus.ts +++ b/ts-packages/types/src/types/rust/MixnodeStatus.ts @@ -1 +1,3 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + export type MixnodeStatus = 'active' | 'standby' | 'inactive' | 'not_found'; diff --git a/ts-packages/types/src/types/rust/MixnodeStatusResponse.ts b/ts-packages/types/src/types/rust/MixnodeStatusResponse.ts index 2225b26df3..2dd6bb6f54 100644 --- a/ts-packages/types/src/types/rust/MixnodeStatusResponse.ts +++ b/ts-packages/types/src/types/rust/MixnodeStatusResponse.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { MixnodeStatus } from './MixnodeStatus'; export interface MixnodeStatusResponse { diff --git a/ts-packages/types/src/types/rust/OriginalVestingResponse.ts b/ts-packages/types/src/types/rust/OriginalVestingResponse.ts index 8d781d5ad0..ea10cd24af 100644 --- a/ts-packages/types/src/types/rust/OriginalVestingResponse.ts +++ b/ts-packages/types/src/types/rust/OriginalVestingResponse.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { DecCoin } from './DecCoin'; export interface OriginalVestingResponse { diff --git a/ts-packages/types/src/types/rust/Period.ts b/ts-packages/types/src/types/rust/Period.ts index 05d9890d5f..76a8876b31 100644 --- a/ts-packages/types/src/types/rust/Period.ts +++ b/ts-packages/types/src/types/rust/Period.ts @@ -1 +1,3 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + export type Period = 'Before' | { In: number } | 'After'; diff --git a/ts-packages/types/src/types/rust/PledgeData.ts b/ts-packages/types/src/types/rust/PledgeData.ts index 9fb19f9aaf..76adc23018 100644 --- a/ts-packages/types/src/types/rust/PledgeData.ts +++ b/ts-packages/types/src/types/rust/PledgeData.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { DecCoin } from './DecCoin'; export interface PledgeData { diff --git a/ts-packages/types/src/types/rust/RewardedSetNodeStatus.ts b/ts-packages/types/src/types/rust/RewardedSetNodeStatus.ts index 8ddd13d047..5a8da8dbea 100644 --- a/ts-packages/types/src/types/rust/RewardedSetNodeStatus.ts +++ b/ts-packages/types/src/types/rust/RewardedSetNodeStatus.ts @@ -1 +1,3 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + export type RewardedSetNodeStatus = 'Active' | 'Standby'; diff --git a/ts-packages/types/src/types/rust/RpcTransactionResponse.ts b/ts-packages/types/src/types/rust/RpcTransactionResponse.ts index 2463e3dd20..2f9c3bdc8a 100644 --- a/ts-packages/types/src/types/rust/RpcTransactionResponse.ts +++ b/ts-packages/types/src/types/rust/RpcTransactionResponse.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { DecCoin } from './DecCoin'; import type { Gas } from './Gas'; diff --git a/ts-packages/types/src/types/rust/SendTxResult.ts b/ts-packages/types/src/types/rust/SendTxResult.ts index b44de3324d..02fb0b5b0c 100644 --- a/ts-packages/types/src/types/rust/SendTxResult.ts +++ b/ts-packages/types/src/types/rust/SendTxResult.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { DecCoin } from './DecCoin'; import type { Gas } from './Gas'; import type { TransactionDetails } from './TransactionDetails'; diff --git a/ts-packages/types/src/types/rust/StakeSaturationResponse.ts b/ts-packages/types/src/types/rust/StakeSaturationResponse.ts index 038d261c46..6be2ae0e0e 100644 --- a/ts-packages/types/src/types/rust/StakeSaturationResponse.ts +++ b/ts-packages/types/src/types/rust/StakeSaturationResponse.ts @@ -1,3 +1,5 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + export interface StakeSaturationResponse { saturation: string; uncapped_saturation: string; diff --git a/ts-packages/types/src/types/rust/TransactionDetails.ts b/ts-packages/types/src/types/rust/TransactionDetails.ts index 8de1cf9ec3..043db71473 100644 --- a/ts-packages/types/src/types/rust/TransactionDetails.ts +++ b/ts-packages/types/src/types/rust/TransactionDetails.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { DecCoin } from './DecCoin'; export interface TransactionDetails { diff --git a/ts-packages/types/src/types/rust/TransactionExecuteResult.ts b/ts-packages/types/src/types/rust/TransactionExecuteResult.ts index e6d93e8448..ce06484dd1 100644 --- a/ts-packages/types/src/types/rust/TransactionExecuteResult.ts +++ b/ts-packages/types/src/types/rust/TransactionExecuteResult.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { DecCoin } from './DecCoin'; import type { GasInfo } from './GasInfo'; diff --git a/ts-packages/types/src/types/rust/VestingAccountInfo.ts b/ts-packages/types/src/types/rust/VestingAccountInfo.ts index d317d045d1..538e941edb 100644 --- a/ts-packages/types/src/types/rust/VestingAccountInfo.ts +++ b/ts-packages/types/src/types/rust/VestingAccountInfo.ts @@ -1,3 +1,4 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { DecCoin } from './DecCoin'; import type { VestingPeriod } from './VestingPeriod'; diff --git a/ts-packages/types/src/types/rust/VestingPeriod.ts b/ts-packages/types/src/types/rust/VestingPeriod.ts index de1089005f..dae6901c10 100644 --- a/ts-packages/types/src/types/rust/VestingPeriod.ts +++ b/ts-packages/types/src/types/rust/VestingPeriod.ts @@ -1,3 +1,5 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + export interface VestingPeriod { start_time: bigint; period_seconds: bigint; diff --git a/ts-packages/types/src/utils/decimal/index.ts b/ts-packages/types/src/utils/decimal/index.ts index 2f58196372..62807f25d6 100644 --- a/ts-packages/types/src/utils/decimal/index.ts +++ b/ts-packages/types/src/utils/decimal/index.ts @@ -10,5 +10,8 @@ export const stringToDecimal = (raw: string): Decimal => Decimal.fromUserInput(r export const decimalToPercentage = (raw: string) => Math.round(Decimal.fromUserInput(raw, 18).toFloatApproximation() * 100).toString(); +export const percentToDecimal = (raw: string) => + (Decimal.fromUserInput(raw, 18).toFloatApproximation() / 100).toString(); + export const decimalToFloatApproximation = (raw: string): number => Decimal.fromUserInput(raw, 18).toFloatApproximation(); diff --git a/validator-api/validator-api-requests/src/models.rs b/validator-api/validator-api-requests/src/models.rs index eee713a701..df5fe07768 100644 --- a/validator-api/validator-api-requests/src/models.rs +++ b/validator-api/validator-api-requests/src/models.rs @@ -114,7 +114,7 @@ impl MixNodeBondAnnotated { } } -#[derive(Deserialize, JsonSchema)] +#[derive(Debug, Serialize, Deserialize, JsonSchema)] pub struct ComputeRewardEstParam { pub performance: Option, pub active_in_rewarded_set: Option,

    i7oJlPE&Nq*U_W;o}Y=vp5lP^QjkUnEpPy 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