From fd051540aa451cba0b63b87ca21a5ccdc8fe9f00 Mon Sep 17 00:00:00 2001 From: Mark Sinclair Date: Wed, 3 Dec 2025 13:37:00 +0000 Subject: [PATCH 01/56] remove nuke db cli args - only makes sense for sqlite and not pgsql --- nym-data-observatory/src/chain_scraper/mod.rs | 5 ----- nym-data-observatory/src/cli/commands/run/args.rs | 3 --- nym-data-observatory/src/cli/commands/run/mod.rs | 1 - nym-data-observatory/src/env.rs | 2 -- 4 files changed, 11 deletions(-) diff --git a/nym-data-observatory/src/chain_scraper/mod.rs b/nym-data-observatory/src/chain_scraper/mod.rs index a9cc9b9c21..4822947082 100644 --- a/nym-data-observatory/src/chain_scraper/mod.rs +++ b/nym-data-observatory/src/chain_scraper/mod.rs @@ -13,11 +13,6 @@ pub(crate) async fn run_chain_scraper( ) -> anyhow::Result { let use_best_effort_start_height = args.start_block_height.is_some(); - if args.nuke_db { - warn!("☢️☢️☢️ NUKING THE SCRAPER DATABASE"); - fs::remove_file(config.chain_scraper_connection_string())?; - } - let database_storage = config .chain_scraper_connection_string .clone() diff --git a/nym-data-observatory/src/cli/commands/run/args.rs b/nym-data-observatory/src/cli/commands/run/args.rs index 6d4f71b272..bd5322988e 100644 --- a/nym-data-observatory/src/cli/commands/run/args.rs +++ b/nym-data-observatory/src/cli/commands/run/args.rs @@ -15,9 +15,6 @@ pub(crate) struct Args { #[arg(long, env = NYXD_SCRAPER_START_HEIGHT)] pub(crate) start_block_height: Option, - #[arg(long, env = NYXD_SCRAPER_UNSAFE_NUKE_DB, default_value = "false")] - pub(crate) nuke_db: bool, - /// (Override) Postgres connection string for chain scraper history #[arg(long, env = NYM_DATA_OBSERVATORY_DB_URL, alias = "db_url")] pub(crate) db_connection_string: Option, diff --git a/nym-data-observatory/src/cli/commands/run/mod.rs b/nym-data-observatory/src/cli/commands/run/mod.rs index d6d3188cbf..4f4927d0d2 100644 --- a/nym-data-observatory/src/cli/commands/run/mod.rs +++ b/nym-data-observatory/src/cli/commands/run/mod.rs @@ -123,7 +123,6 @@ pub(crate) async fn execute(args: Args, http_port: u16) -> Result<(), NymDataObs w.watch_for_chain_message_types ); } - info!("nuke_db: {}", args.nuke_db); let storage = db::Storage::init(db_connection_string).await?; let watcher_pool = storage.pool_owned(); diff --git a/nym-data-observatory/src/env.rs b/nym-data-observatory/src/env.rs index cff2212b57..fe66aa492d 100644 --- a/nym-data-observatory/src/env.rs +++ b/nym-data-observatory/src/env.rs @@ -16,8 +16,6 @@ pub mod vars { pub const NYXD_SCRAPER_USE_BEST_EFFORT_START_HEIGHT: &str = "NYXD_SCRAPER_USE_BEST_EFFORT_START_HEIGHT"; - pub const NYXD_SCRAPER_UNSAFE_NUKE_DB: &str = "NYXD_SCRAPER_UNSAFE_NUKE_DB"; - pub const NYM_DATA_OBSERVATORY_ID_ARG: &str = "NYM_DATA_OBSERVATORY_ID"; pub const NYM_DATA_OBSERVATORY_OUTPUT_ARG: &str = "NYM_DATA_OBSERVATORY_OUTPUT"; From 18e72c90dfbd74d2d31dc7ab8e74b1003f805fbe Mon Sep 17 00:00:00 2001 From: Mark Sinclair Date: Thu, 4 Dec 2025 12:05:58 +0000 Subject: [PATCH 02/56] run the migrations from the data observatory and not the base chain scraper --- .../src/storage/block_storage.rs | 27 ++++++++++++------- common/nyxd-scraper-shared/src/scraper/mod.rs | 4 ++- common/nyxd-scraper-shared/src/storage/mod.rs | 5 +++- .../src/storage/block_storage.rs | 5 +++- nym-data-observatory/src/chain_scraper/mod.rs | 4 +-- nym-data-observatory/src/db/mod.rs | 12 ++++++++- nym-validator-rewarder/src/config/mod.rs | 1 + nyx-chain-watcher/src/chain_scraper/mod.rs | 1 + 8 files changed, 43 insertions(+), 16 deletions(-) diff --git a/common/nyxd-scraper-psql/src/storage/block_storage.rs b/common/nyxd-scraper-psql/src/storage/block_storage.rs index 49f2bab622..186de491b2 100644 --- a/common/nyxd-scraper-psql/src/storage/block_storage.rs +++ b/common/nyxd-scraper-psql/src/storage/block_storage.rs @@ -13,7 +13,7 @@ use nyxd_scraper_shared::storage::helpers::log_db_operation_time; use nyxd_scraper_shared::storage::{NyxdScraperStorage, NyxdScraperStorageError}; use sqlx::types::time::{OffsetDateTime, PrimitiveDateTime}; use tokio::time::Instant; -use tracing::{debug, error, info, instrument, warn}; +use tracing::{debug, error, info, instrument}; #[derive(Clone)] pub struct PostgresScraperStorage { @@ -22,7 +22,10 @@ pub struct PostgresScraperStorage { impl PostgresScraperStorage { #[instrument] - pub async fn init(connection_string: &str) -> Result { + pub async fn init( + connection_string: &str, + run_migrations: &bool, + ) -> Result { debug!("initialising scraper database with '{connection_string}'",); let connection_pool = match sqlx::PgPool::connect(connection_string).await { @@ -33,12 +36,13 @@ impl PostgresScraperStorage { } }; - if let Err(err) = sqlx::migrate!("./sql_migrations") - .run(&connection_pool) - .await - { - warn!("Failed to initialize SQLx database: {err}"); - // return Err(err.into()); + if *run_migrations { + if let Err(err) = sqlx::migrate!("./sql_migrations") + .run(&connection_pool) + .await + { + return Err(err.into()); + } } info!("Database migration finished!"); @@ -192,8 +196,11 @@ impl PostgresScraperStorage { impl NyxdScraperStorage for PostgresScraperStorage { type StorageTransaction = PostgresStorageTransaction; - async fn initialise(storage: &str) -> Result { - PostgresScraperStorage::init(storage) + async fn initialise( + storage: &str, + run_migrations: &bool, + ) -> Result { + PostgresScraperStorage::init(storage, run_migrations) .await .map_err(NyxdScraperStorageError::from) } diff --git a/common/nyxd-scraper-shared/src/scraper/mod.rs b/common/nyxd-scraper-shared/src/scraper/mod.rs index df9224ae22..76b17a2a54 100644 --- a/common/nyxd-scraper-shared/src/scraper/mod.rs +++ b/common/nyxd-scraper-shared/src/scraper/mod.rs @@ -48,6 +48,8 @@ pub struct Config { pub store_precommits: bool, pub start_block: StartingBlockOpts, + + pub run_migrations: bool, } pub struct NyxdScraperBuilder { @@ -161,7 +163,7 @@ where pub async fn new(config: Config) -> Result { config.pruning_options.validate()?; - let storage = S::initialise(&config.database_storage).await?; + let storage = S::initialise(&config.database_storage, &config.run_migrations).await?; let rpc_client = RpcClient::new(&config.rpc_url)?; Ok(NyxdScraper { diff --git a/common/nyxd-scraper-shared/src/storage/mod.rs b/common/nyxd-scraper-shared/src/storage/mod.rs index a847f2a6bf..c0564e343f 100644 --- a/common/nyxd-scraper-shared/src/storage/mod.rs +++ b/common/nyxd-scraper-shared/src/storage/mod.rs @@ -33,7 +33,10 @@ pub trait NyxdScraperStorage: Clone + Sized { type StorageTransaction: NyxdScraperTransaction; /// Either connection string (postgres) or storage path (sqlite) - async fn initialise(storage: &str) -> Result; + async fn initialise( + storage: &str, + run_migrations: &bool, + ) -> Result; async fn begin_processing_tx( &self, diff --git a/common/nyxd-scraper-sqlite/src/storage/block_storage.rs b/common/nyxd-scraper-sqlite/src/storage/block_storage.rs index 9a0a33d52a..f6d81f6f00 100644 --- a/common/nyxd-scraper-sqlite/src/storage/block_storage.rs +++ b/common/nyxd-scraper-sqlite/src/storage/block_storage.rs @@ -207,7 +207,10 @@ impl SqliteScraperStorage { impl NyxdScraperStorage for SqliteScraperStorage { type StorageTransaction = SqliteStorageTransaction; - async fn initialise(storage: &str) -> Result { + async fn initialise( + storage: &str, + _run_migrations: &bool, + ) -> Result { SqliteScraperStorage::init(storage) .await .map_err(NyxdScraperStorageError::from) diff --git a/nym-data-observatory/src/chain_scraper/mod.rs b/nym-data-observatory/src/chain_scraper/mod.rs index 4822947082..49623a5ecd 100644 --- a/nym-data-observatory/src/chain_scraper/mod.rs +++ b/nym-data-observatory/src/chain_scraper/mod.rs @@ -1,8 +1,7 @@ use crate::cli::commands::run::Args; use crate::db::DbPool; use nyxd_scraper_psql::{PostgresNyxdScraper, PruningOptions}; -use std::fs; -use tracing::{info, warn}; +use tracing::info; pub(crate) mod webhook; @@ -29,6 +28,7 @@ pub(crate) async fn run_chain_scraper( start_block_height: args.start_block_height, use_best_effort_start_height, }, + run_migrations: false, // ignore the base migrations }) .with_msg_module(crate::modules::wasm::WasmModule::new(connection_pool)) .with_tx_module(webhook::WebhookModule::new(config.clone())?); diff --git a/nym-data-observatory/src/db/mod.rs b/nym-data-observatory/src/db/mod.rs index 70c36a7b61..a8b7a7a952 100644 --- a/nym-data-observatory/src/db/mod.rs +++ b/nym-data-observatory/src/db/mod.rs @@ -1,6 +1,7 @@ use anyhow::{Result, anyhow}; -use sqlx::{Postgres, postgres::PgConnectOptions}; +use sqlx::{Postgres, migrate::Migrator, postgres::PgConnectOptions}; use std::str::FromStr; +use tracing::info; pub(crate) mod models; pub(crate) mod queries { @@ -8,6 +9,8 @@ pub(crate) mod queries { pub mod wasm; } +static MIGRATOR: Migrator = sqlx::migrate!("./migrations"); + pub(crate) type DbPool = sqlx::Pool; pub(crate) struct Storage { @@ -22,6 +25,13 @@ impl Storage { .await .map_err(|err| anyhow!("Failed to connect to {}: {}", &connection_url, err))?; + MIGRATOR + .run(&pool) + .await + .map_err(|err| anyhow!("Failed to run migrations: {}", err))?; + + info!("✅ Successfully migrated the database"); + Ok(Storage { pool }) } diff --git a/nym-validator-rewarder/src/config/mod.rs b/nym-validator-rewarder/src/config/mod.rs index 146f971bad..524cc7df9e 100644 --- a/nym-validator-rewarder/src/config/mod.rs +++ b/nym-validator-rewarder/src/config/mod.rs @@ -135,6 +135,7 @@ impl Config { start_block_height: None, use_best_effort_start_height: true, }, + run_migrations: true, }) } diff --git a/nyx-chain-watcher/src/chain_scraper/mod.rs b/nyx-chain-watcher/src/chain_scraper/mod.rs index c0db1b8e04..fe0d2187ff 100644 --- a/nyx-chain-watcher/src/chain_scraper/mod.rs +++ b/nyx-chain-watcher/src/chain_scraper/mod.rs @@ -60,6 +60,7 @@ pub(crate) async fn run_chain_scraper( start_block_height, use_best_effort_start_height, }, + run_migrations: true, }) .with_msg_module(BankScraperModule::new( db_pool, From 6e62e34ac8d2783c0e7868e16db397af7817ca39 Mon Sep 17 00:00:00 2001 From: Mark Sinclair Date: Thu, 4 Dec 2025 16:07:17 +0000 Subject: [PATCH 03/56] bump version to 1.0.1 --- Cargo.lock | 2 +- nym-data-observatory/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b9cd4c99d2..625ae5ddcf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5709,7 +5709,7 @@ dependencies = [ [[package]] name = "nym-data-observatory" -version = "1.0.0" +version = "1.0.1" dependencies = [ "anyhow", "async-trait", diff --git a/nym-data-observatory/Cargo.toml b/nym-data-observatory/Cargo.toml index d23b40f20d..995c4fec7d 100644 --- a/nym-data-observatory/Cargo.toml +++ b/nym-data-observatory/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-data-observatory" -version = "1.0.0" +version = "1.0.1" authors.workspace = true repository.workspace = true homepage.workspace = true From c55b215b6583e4f101e6bdfe74f53d9ceb8f7c0f Mon Sep 17 00:00:00 2001 From: Andrej Mihajlov Date: Mon, 2 Feb 2026 09:54:17 +0100 Subject: [PATCH 04/56] Update reqwest to v0.13.1, switch to using rustls (default); ring is no longer available --- Cargo.lock | 231 +++++++++++++++--- Cargo.toml | 2 +- .../client-libs/validator-client/Cargo.toml | 2 +- common/credential-proxy/Cargo.toml | 2 +- common/http-api-client/Cargo.toml | 2 +- common/http-api-client/src/dns.rs | 2 +- common/upgrade-mode-check/Cargo.toml | 2 +- .../nym-credential-proxy-requests/Cargo.toml | 2 +- .../nym-credential-proxy/Cargo.toml | 2 +- nym-data-observatory/Cargo.toml | 2 +- nyx-chain-watcher/Cargo.toml | 2 +- tools/nymvisor/Cargo.toml | 2 +- 12 files changed, 206 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2e041700b7..6a8548e25e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -571,6 +571,28 @@ dependencies = [ "log", ] +[[package]] +name = "aws-lc-rs" +version = "1.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b7b6141e96a8c160799cc2d5adecd5cbbe5054cb8c7c4af53da0f83bb7ad256" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c34dda4df7017c8db52132f0f8a2e0f8161649d15723ed63fc00c82d0f2081a" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", +] + [[package]] name = "axum" version = "0.7.9" @@ -1079,6 +1101,12 @@ dependencies = [ "serde", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + [[package]] name = "cfg-if" version = "1.0.4" @@ -1256,6 +1284,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "cmake" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" +dependencies = [ + "cc", +] + [[package]] name = "coarsetime" version = "0.1.36" @@ -1283,6 +1320,16 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "comfy-table" version = "7.2.1" @@ -1443,6 +1490,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -1866,7 +1923,7 @@ checksum = "79fc3b6dd0b87ba36e565715bf9a2ced221311db47bd18011676f24a6066edbc" dependencies = [ "curl-sys", "libc", - "openssl-probe", + "openssl-probe 0.1.6", "openssl-sys", "schannel", "socket2 0.6.1", @@ -2432,6 +2489,12 @@ dependencies = [ "dtoa", ] +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "dyn-clone" version = "1.0.20" @@ -2865,6 +2928,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "fsevent-sys" version = "4.1.0" @@ -3701,7 +3770,6 @@ dependencies = [ "tokio", "tokio-rustls 0.26.4", "tower-service", - "webpki-roots 1.0.5", ] [[package]] @@ -4282,6 +4350,28 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + [[package]] name = "jobserver" version = "0.1.34" @@ -5374,7 +5464,7 @@ dependencies = [ "pin-project", "rand 0.8.5", "rand_chacha 0.3.1", - "reqwest 0.12.28", + "reqwest 0.13.1", "schemars 0.8.22", "semver 1.0.27", "serde", @@ -5982,7 +6072,7 @@ dependencies = [ "nym-upgrade-mode-check", "nym-validator-client", "rand 0.8.5", - "reqwest 0.12.28", + "reqwest 0.13.1", "serde", "serde_json", "sqlx", @@ -6023,7 +6113,7 @@ dependencies = [ "nym-network-defaults", "nym-validator-client", "rand 0.8.5", - "reqwest 0.12.28", + "reqwest 0.13.1", "serde", "serde_json", "sqlx", @@ -6051,7 +6141,7 @@ dependencies = [ "nym-http-api-common", "nym-serde-helpers", "nym-upgrade-mode-check", - "reqwest 0.12.28", + "reqwest 0.13.1", "schemars 0.8.22", "serde", "serde_json", @@ -6229,7 +6319,7 @@ dependencies = [ "nym-validator-client", "nyxd-scraper-psql", "nyxd-scraper-shared", - "reqwest 0.12.28", + "reqwest 0.13.1", "schemars 0.8.22", "serde", "serde_json", @@ -6326,7 +6416,7 @@ dependencies = [ name = "nym-exit-policy" version = "1.20.1" dependencies = [ - "reqwest 0.12.28", + "reqwest 0.13.1", "serde", "serde_json", "thiserror 2.0.17", @@ -6489,7 +6579,7 @@ dependencies = [ "nym-validator-client", "pnet_packet", "rand 0.8.5", - "reqwest 0.12.28", + "reqwest 0.13.1", "serde", "serde_json", "thiserror 2.0.17", @@ -6618,7 +6708,7 @@ dependencies = [ "nym-http-api-common", "nym-network-defaults", "once_cell", - "reqwest 0.12.28", + "reqwest 0.13.1", "serde", "serde_json", "serde_plain", @@ -6639,7 +6729,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "reqwest 0.12.28", + "reqwest 0.13.1", "syn 2.0.114", "uuid", ] @@ -6767,7 +6857,7 @@ dependencies = [ "nym-wireguard", "nym-wireguard-types", "rand 0.8.5", - "reqwest 0.12.28", + "reqwest 0.13.1", "serde", "serde_json", "thiserror 2.0.17", @@ -7045,7 +7135,7 @@ dependencies = [ "petgraph", "rand 0.8.5", "rand_chacha 0.3.1", - "reqwest 0.12.28", + "reqwest 0.13.1", "serde", "serde_json", "tokio", @@ -7091,7 +7181,7 @@ dependencies = [ "publicsuffix", "rand 0.8.5", "regex", - "reqwest 0.12.28", + "reqwest 0.13.1", "serde", "serde_json", "sqlx", @@ -7292,7 +7382,7 @@ dependencies = [ "rand 0.8.5", "rand_chacha 0.3.1", "regex", - "reqwest 0.12.28", + "reqwest 0.13.1", "semver 1.0.27", "serde", "serde_json", @@ -7324,7 +7414,7 @@ dependencies = [ "bs58", "nym-credentials", "nym-crypto", - "reqwest 0.12.28", + "reqwest 0.13.1", "serde", "serde_json", "time", @@ -7578,7 +7668,7 @@ dependencies = [ "nym-validator-client", "parking_lot", "rand 0.8.5", - "reqwest 0.12.28", + "reqwest 0.13.1", "serde", "tap", "tempfile", @@ -7708,7 +7798,7 @@ dependencies = [ "nym-validator-client", "pin-project", "rand 0.8.5", - "reqwest 0.12.28", + "reqwest 0.13.1", "schemars 0.8.22", "serde", "tap", @@ -8055,7 +8145,7 @@ dependencies = [ "nym-sphinx-types", "nym-wasm-utils", "rand 0.8.5", - "reqwest 0.12.28", + "reqwest 0.13.1", "serde", "serde_json", "thiserror 2.0.17", @@ -8093,7 +8183,7 @@ dependencies = [ "nym-mixnet-contract-common", "nym-validator-client", "nym-vesting-contract-common", - "reqwest 0.12.28", + "reqwest 0.13.1", "schemars 0.8.22", "serde", "serde_json", @@ -8117,7 +8207,7 @@ dependencies = [ "nym-crypto", "nym-http-api-client", "nym-test-utils", - "reqwest 0.12.28", + "reqwest 0.13.1", "serde", "serde_json", "thiserror 2.0.17", @@ -8162,7 +8252,7 @@ dependencies = [ "nym-serde-helpers", "nym-vesting-contract-common", "prost", - "reqwest 0.12.28", + "reqwest 0.13.1", "serde", "serde_json", "sha2 0.10.9", @@ -8490,7 +8580,7 @@ dependencies = [ "nym-bin-common", "nym-config", "nym-task", - "reqwest 0.12.28", + "reqwest 0.13.1", "serde", "serde_json", "sha2 0.10.9", @@ -8517,7 +8607,7 @@ dependencies = [ "nym-task", "nym-validator-client", "nyxd-scraper-sqlite", - "reqwest 0.12.28", + "reqwest 0.13.1", "schemars 0.8.22", "serde", "sqlx", @@ -8650,6 +8740,12 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + [[package]] name = "openssl-sys" version = "0.9.111" @@ -9481,6 +9577,7 @@ version = "0.11.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" dependencies = [ + "aws-lc-rs", "bytes", "getrandom 0.3.4", "lru-slab", @@ -9741,9 +9838,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.28" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +checksum = "04e9018c9d814e5f30cc16a0f03271aeab3571e609612d9fe78c1aa8d11c2f62" dependencies = [ "base64 0.22.1", "bytes", @@ -9762,9 +9859,9 @@ dependencies = [ "quinn", "rustls 0.23.36", "rustls-pki-types", + "rustls-platform-verifier", "serde", "serde_json", - "serde_urlencoded", "sync_wrapper 1.0.2", "tokio", "tokio-rustls 0.26.4", @@ -9777,7 +9874,6 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 1.0.5", ] [[package]] @@ -9996,6 +10092,7 @@ version = "0.23.36" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" dependencies = [ + "aws-lc-rs", "log", "once_cell", "ring", @@ -10011,10 +10108,10 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ - "openssl-probe", + "openssl-probe 0.1.6", "rustls-pemfile 1.0.4", "schannel", - "security-framework", + "security-framework 2.11.1", ] [[package]] @@ -10023,11 +10120,23 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" dependencies = [ - "openssl-probe", + "openssl-probe 0.1.6", "rustls-pemfile 2.2.0", "rustls-pki-types", "schannel", - "security-framework", + "security-framework 2.11.1", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +dependencies = [ + "openssl-probe 0.2.1", + "rustls-pki-types", + "schannel", + "security-framework 3.5.1", ] [[package]] @@ -10058,6 +10167,33 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-platform-verifier" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" +dependencies = [ + "core-foundation 0.10.1", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls 0.23.36", + "rustls-native-certs 0.8.3", + "rustls-platform-verifier-android", + "rustls-webpki 0.103.8", + "security-framework 3.5.1", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -10085,6 +10221,7 @@ version = "0.103.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -10257,7 +10394,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags 2.10.0", - "core-foundation", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +dependencies = [ + "bitflags 2.10.0", + "core-foundation 0.10.1", "core-foundation-sys", "libc", "security-framework-sys", @@ -11224,7 +11374,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.4", "system-configuration-sys", ] @@ -13113,6 +13263,15 @@ dependencies = [ "string_cache_codegen", ] +[[package]] +name = "webpki-root-certs" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36a29fc0408b113f68cf32637857ab740edfafdf460c326cd2afaa2d84cc05dc" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webpki-roots" version = "0.24.0" @@ -13939,7 +14098,7 @@ dependencies = [ "nym-http-api-client", "nym-wasm-utils", "rand 0.8.5", - "reqwest 0.12.28", + "reqwest 0.13.1", "serde", "thiserror 2.0.17", "tokio", @@ -14003,7 +14162,7 @@ dependencies = [ "itertools 0.14.0", "nym-bin-common", "nym-http-api-client", - "reqwest 0.12.28", + "reqwest 0.13.1", "serde", "serde_json", "thiserror 2.0.17", diff --git a/Cargo.toml b/Cargo.toml index a9a240b504..b83ad953ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -324,7 +324,7 @@ rand_core = "0.6.3" rand_distr = "0.4" rayon = "1.5.1" regex = "1.10.6" -reqwest = { version = "0.12.15", default-features = false } +reqwest = { version = "0.13.1", default-features = false } rs_merkle = "1.5.0" schemars = "0.8.22" semver = "1.0.26" diff --git a/common/client-libs/validator-client/Cargo.toml b/common/client-libs/validator-client/Cargo.toml index 4faa1a0943..e7215d456b 100644 --- a/common/client-libs/validator-client/Cargo.toml +++ b/common/client-libs/validator-client/Cargo.toml @@ -76,7 +76,7 @@ features = ["json"] [target."cfg(not(target_arch = \"wasm32\"))".dependencies.reqwest] workspace = true -features = ["json", "rustls-tls"] +features = ["json", "rustls"] [dev-dependencies] anyhow = { workspace = true } diff --git a/common/credential-proxy/Cargo.toml b/common/credential-proxy/Cargo.toml index 2141e37c42..65549f2753 100644 --- a/common/credential-proxy/Cargo.toml +++ b/common/credential-proxy/Cargo.toml @@ -19,7 +19,7 @@ bs58 = { workspace = true } futures = { workspace = true } humantime = { workspace = true } rand = { workspace = true } -reqwest = { workspace = true, features = ["rustls-tls"] } +reqwest = { workspace = true, features = ["rustls"] } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } strum = { workspace = true, features = ["derive"] } diff --git a/common/http-api-client/Cargo.toml b/common/http-api-client/Cargo.toml index 43daed794f..cb297f004c 100644 --- a/common/http-api-client/Cargo.toml +++ b/common/http-api-client/Cargo.toml @@ -21,7 +21,7 @@ debug-inventory = ["nym-http-api-client-macro/debug-inventory"] async-trait = { workspace = true } bincode = { workspace = true } cfg-if = { workspace = true} -reqwest = { workspace = true, features = ["json", "gzip", "deflate", "brotli", "zstd", "rustls-tls"] } +reqwest = { workspace = true, features = ["json", "gzip", "deflate", "brotli", "zstd", "rustls"] } http.workspace = true url = { workspace = true } once_cell = { workspace = true } diff --git a/common/http-api-client/src/dns.rs b/common/http-api-client/src/dns.rs index db3424e8e6..0d61c75362 100644 --- a/common/http-api-client/src/dns.rs +++ b/common/http-api-client/src/dns.rs @@ -552,7 +552,7 @@ mod test { let var_name = HickoryDnsResolver::default(); let resolver = var_name; let client = reqwest::ClientBuilder::new() - .dns_resolver(resolver.into()) + .dns_resolver(resolver) .build() .unwrap(); diff --git a/common/upgrade-mode-check/Cargo.toml b/common/upgrade-mode-check/Cargo.toml index 8078ede9a4..d47d4ba5f9 100644 --- a/common/upgrade-mode-check/Cargo.toml +++ b/common/upgrade-mode-check/Cargo.toml @@ -13,7 +13,7 @@ description = "Functions and tests for checking Nym's Credential Proxy is being [dependencies] jwt-simple = { workspace = true } -reqwest = { workspace = true, features = ["rustls-tls"] } +reqwest = { workspace = true, features = ["rustls"] } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } time = { workspace = true, features = ["serde", "formatting", "parsing"] } diff --git a/nym-credential-proxy/nym-credential-proxy-requests/Cargo.toml b/nym-credential-proxy/nym-credential-proxy-requests/Cargo.toml index dbe84bf6f1..d81b35e70b 100644 --- a/nym-credential-proxy/nym-credential-proxy-requests/Cargo.toml +++ b/nym-credential-proxy/nym-credential-proxy-requests/Cargo.toml @@ -20,7 +20,7 @@ serde_json.workspace = true serde_with = { workspace = true } time = { workspace = true, features = ["serde", "formatting", "parsing"] } tsify = { workspace = true, optional = true } -reqwest = { workspace = true, features = ["json", "rustls-tls"] } +reqwest = { workspace = true, features = ["json", "rustls"] } wasm-bindgen = { workspace = true, optional = true } ## openapi: diff --git a/nym-credential-proxy/nym-credential-proxy/Cargo.toml b/nym-credential-proxy/nym-credential-proxy/Cargo.toml index 3d81b37f0f..9a680358a7 100644 --- a/nym-credential-proxy/nym-credential-proxy/Cargo.toml +++ b/nym-credential-proxy/nym-credential-proxy/Cargo.toml @@ -22,7 +22,7 @@ clap = { workspace = true, features = ["derive", "env"] } futures.workspace = true humantime.workspace = true rand.workspace = true -reqwest = { workspace = true, features = ["rustls-tls"] } +reqwest = { workspace = true, features = ["rustls"] } serde = { workspace = true, features = ["derive"] } serde_json.workspace = true sqlx = { workspace = true, features = [ diff --git a/nym-data-observatory/Cargo.toml b/nym-data-observatory/Cargo.toml index 2eefa881ef..fd6a7d9be1 100644 --- a/nym-data-observatory/Cargo.toml +++ b/nym-data-observatory/Cargo.toml @@ -27,7 +27,7 @@ nym-task = { workspace = true } nym-validator-client = { workspace = true } nyxd-scraper-psql = { path = "../common/nyxd-scraper-psql" } nyxd-scraper-shared = { workspace = true } -reqwest = { workspace = true, features = ["rustls-tls"] } +reqwest = { workspace = true, features = ["rustls"] } schemars = { workspace = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } diff --git a/nyx-chain-watcher/Cargo.toml b/nyx-chain-watcher/Cargo.toml index 479d24460e..7af5f4f20d 100644 --- a/nyx-chain-watcher/Cargo.toml +++ b/nyx-chain-watcher/Cargo.toml @@ -26,7 +26,7 @@ nym-network-defaults = { workspace = true } nym-task = { workspace = true } nym-validator-client = { workspace = true } nyxd-scraper-sqlite = { path = "../common/nyxd-scraper-sqlite" } -reqwest = { workspace = true, features = ["rustls-tls"] } +reqwest = { workspace = true, features = ["rustls"] } schemars = { workspace = true } serde = { workspace = true, features = ["derive"] } sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "time"] } diff --git a/tools/nymvisor/Cargo.toml b/tools/nymvisor/Cargo.toml index 668e532b98..c0327c321b 100644 --- a/tools/nymvisor/Cargo.toml +++ b/tools/nymvisor/Cargo.toml @@ -22,7 +22,7 @@ hex = { workspace = true } humantime = { workspace = true } humantime-serde = { workspace = true } nix = { workspace = true, features = ["signal", "fs"] } -reqwest = { workspace = true, features = ["json", "stream", "rustls-tls"] } +reqwest = { workspace = true, features = ["json", "stream", "rustls"] } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } sha2 = { workspace = true } From b4aee7a1d92e32aa5f327b4e0286caf45442454f Mon Sep 17 00:00:00 2001 From: Andrej Mihajlov Date: Mon, 2 Feb 2026 11:29:15 +0100 Subject: [PATCH 05/56] zulip-client: add form feat --- Cargo.lock | 1 + common/zulip-client/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 6a8548e25e..b3051e1b7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9862,6 +9862,7 @@ dependencies = [ "rustls-platform-verifier", "serde", "serde_json", + "serde_urlencoded", "sync_wrapper 1.0.2", "tokio", "tokio-rustls 0.26.4", diff --git a/common/zulip-client/Cargo.toml b/common/zulip-client/Cargo.toml index cc065e917c..8661cbe247 100644 --- a/common/zulip-client/Cargo.toml +++ b/common/zulip-client/Cargo.toml @@ -21,7 +21,7 @@ zeroize = { workspace = true } nym-bin-common = { workspace = true } nym-http-api-client = { workspace = true } -reqwest = { workspace = true } +reqwest = { workspace = true, features = ["form"] } tracing = { workspace = true } [dev-dependencies] From 63f158cccb9848d3f280feff0dd301e4117a7e4e Mon Sep 17 00:00:00 2001 From: Andrej Mihajlov Date: Mon, 2 Feb 2026 11:45:53 +0100 Subject: [PATCH 06/56] nym-api: add query feat --- nym-api/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index 39e7bd1cc2..b936025f42 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -27,7 +27,7 @@ moka = { workspace = true } pin-project = { workspace = true } rand = { workspace = true } rand_chacha = { workspace = true } -reqwest = { workspace = true, features = ["json"] } +reqwest = { workspace = true, features = ["json", "query"] } semver = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } From 52edfdcc2f89d35093500527b7e8fe5b5e263347 Mon Sep 17 00:00:00 2001 From: jmwample Date: Mon, 2 Feb 2026 08:11:59 -0700 Subject: [PATCH 07/56] move reqwest dep to dev only --- nym-api/Cargo.toml | 2 +- nym-api/src/node_status_api/models.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index b936025f42..be1e2edb7c 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -27,7 +27,6 @@ moka = { workspace = true } pin-project = { workspace = true } rand = { workspace = true } rand_chacha = { workspace = true } -reqwest = { workspace = true, features = ["json", "query"] } semver = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } @@ -124,6 +123,7 @@ sqlx = { workspace = true, features = [ [dev-dependencies] axum-test = { workspace = true } +reqwest = { workspace = true, features = ["json", "query"] } tempfile = { workspace = true } cw3 = { workspace = true } cw-utils = { workspace = true } diff --git a/nym-api/src/node_status_api/models.rs b/nym-api/src/node_status_api/models.rs index 76a9d0199b..77bfc91092 100644 --- a/nym-api/src/node_status_api/models.rs +++ b/nym-api/src/node_status_api/models.rs @@ -15,7 +15,7 @@ use nym_mixnet_contract_common::reward_params::Performance; use nym_mixnet_contract_common::{IdentityKey, NodeId}; use nym_serde_helpers::date::DATE_FORMAT; use nym_validator_client::nyxd::error::NyxdError; -use reqwest::StatusCode; +use axum::http::StatusCode; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use sqlx::Error; From 47af0b24f05f1fab08ab4976a03611bfd09f8ba3 Mon Sep 17 00:00:00 2001 From: jmwample Date: Mon, 2 Feb 2026 08:13:43 -0700 Subject: [PATCH 08/56] fmt --- nym-api/src/node_status_api/models.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nym-api/src/node_status_api/models.rs b/nym-api/src/node_status_api/models.rs index 77bfc91092..791582ce04 100644 --- a/nym-api/src/node_status_api/models.rs +++ b/nym-api/src/node_status_api/models.rs @@ -5,6 +5,7 @@ use crate::ecash::error::{EcashError, RedemptionError}; use crate::node_status_api::utils::NodeUptimes; use crate::storage::models::NodeStatus; use crate::support::caching::cache::UninitialisedCache; +use axum::http::StatusCode; use nym_api_requests::ecash::models::DepositId; use nym_api_requests::models::{ HistoricalPerformanceResponse, HistoricalUptimeResponse, NodePerformance, @@ -15,7 +16,6 @@ use nym_mixnet_contract_common::reward_params::Performance; use nym_mixnet_contract_common::{IdentityKey, NodeId}; use nym_serde_helpers::date::DATE_FORMAT; use nym_validator_client::nyxd::error::NyxdError; -use axum::http::StatusCode; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use sqlx::Error; From cfcf804b474f0e635fe33420fa2cfeba70f3c11f Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Tue, 3 Feb 2026 11:32:38 +0000 Subject: [PATCH 09/56] Max/crates publishing tweaks (#6343) * add semver validator action * update runner * update runner with sed for old version in CI * Add no commit to publish for the moment * fix version bump command * configure git bot * error check * make dryrun less opaque * Reintroduce error check - keep logging dryrun in for debug (commented out) * fix grep check * bring non-dry-run to parity * add node for npx semver check to action * updated sed command * revert erroneous version bump * added semver check to publish workflow * allow from other branches * allow from other branches again * publishing guide * update publication runner * Release 1.20.3 nym-api-requests@1.20.3 nym-async-file-watcher@1.20.3 nym-authenticator-requests@1.20.3 nym-bandwidth-controller@1.20.3 nym-bin-common@1.20.3 nym-cache@1.20.3 nym-cli-commands@1.20.3 nym-client-core@1.20.3 nym-client-core-config-types@1.20.3 nym-client-core-gateways-storage@1.20.3 nym-client-core-surb-storage@1.20.3 nym-client-websocket-requests@1.20.3 nym-coconut-dkg-common@1.20.3 nym-common@1.20.3 nym-compact-ecash@1.20.3 nym-config@1.20.3 nym-contracts-common@1.20.3 nym-contracts-common-testing@1.20.3 nym-cpp-ffi@1.20.3 nym-credential-proxy-lib@1.20.3 nym-credential-proxy-requests@1.20.3 nym-credential-storage@1.20.3 nym-credential-utils@1.20.3 nym-credential-verification@1.20.3 nym-credentials@1.20.3 nym-credentials-interface@1.20.3 nym-crypto@1.20.3 nym-dkg@1.20.3 nym-ecash-contract-common@1.20.3 nym-ecash-signer-check@1.20.3 nym-ecash-signer-check-types@1.20.3 nym-ecash-time@1.20.3 nym-exit-policy@1.20.3 nym-ffi-shared@1.20.3 nym-gateway-client@1.20.3 nym-gateway-requests@1.20.3 nym-gateway-stats-storage@1.20.3 nym-gateway-storage@1.20.3 nym-go-ffi@1.20.3 nym-group-contract-common@1.20.3 nym-http-api-client@1.20.3 nym-http-api-client-macro@1.20.3 nym-http-api-common@1.20.3 nym-id@1.20.3 nym-inclusion-probability@1.20.3 nym-ip-packet-client@1.20.3 nym-ip-packet-requests@1.20.3 nym-metrics@1.20.3 nym-mixnet-client@1.20.3 nym-mixnet-contract-common@1.20.3 nym-mixnode-common@1.20.3 nym-multisig-contract-common@1.20.3 nym-network-defaults@1.20.3 nym-node-metrics@1.20.3 nym-node-requests@1.20.3 nym-node-tester-utils@1.20.3 nym-noise@1.20.3 nym-noise-keys@1.20.3 nym-nonexhaustive-delayqueue@1.20.3 nym-ordered-buffer@1.20.3 nym-outfox@1.20.3 nym-pemstore@1.20.3 nym-performance-contract-common@1.20.3 nym-pool-contract-common@1.20.3 nym-registration-common@1.20.3 nym-sdk@1.20.3 nym-serde-helpers@1.20.3 nym-service-provider-requests-common@1.20.3 nym-service-providers-common@1.20.3 nym-socks5-client-core@1.20.3 nym-socks5-proxy-helpers@1.20.3 nym-socks5-requests@1.20.3 nym-sphinx@1.20.3 nym-sphinx-acknowledgements@1.20.3 nym-sphinx-addressing@1.20.3 nym-sphinx-anonymous-replies@1.20.3 nym-sphinx-chunking@1.20.3 nym-sphinx-cover@1.20.3 nym-sphinx-forwarding@1.20.3 nym-sphinx-framing@1.20.3 nym-sphinx-params@1.20.3 nym-sphinx-routing@1.20.3 nym-sphinx-types@1.20.3 nym-sqlx-pool-guard@1.20.3 nym-statistics-common@1.20.3 nym-store-cipher@1.20.3 nym-task@1.20.3 nym-test-utils@1.20.3 nym-ticketbooks-merkle@1.20.3 nym-topology@1.20.3 nym-tun@1.20.3 nym-types@1.20.3 nym-upgrade-mode-check@1.20.3 nym-validator-client@1.20.3 nym-verloc@1.20.3 nym-vesting-contract-common@1.20.3 nym-wasm-client-core@1.20.3 nym-wasm-storage@1.20.3 nym-wasm-utils@1.20.3 nym-wireguard@1.20.3 nym-wireguard-private-metadata-client@1.20.3 nym-wireguard-private-metadata-server@1.20.3 nym-wireguard-private-metadata-shared@1.20.3 nym-wireguard-private-metadata-tests@1.20.3 nym-wireguard-types@1.20.3 nyxd-scraper-shared@1.20.3 Generated by cargo-workspaces * remove --allow-branch ; no commit, doesn't need branch restrictions * remove another clashing flag * again * exclude build.rs from crate for crates.io * various in process scripts to pick up deployment where it left off * rename workflows * Version bump fix from borked publish run * add publishing doc + updated publish-resume ci * move example from service-providers to sdk examples/ to remove circular dev dependency for cargo publication * remove wildcard version import * Workflows and documentation for publication * add contracts/ patch + imports * Reintroduce missing kkt dep from rebase * fix borked rebase cargo lock --------- Co-authored-by: Nym bot --- .../workflows/ci-crates-publish-dry-run.yml | 79 ++++++ .../workflows/ci-crates-publish-resume.yml | 59 +++++ .github/workflows/ci-crates-publish.yml | 86 +++++++ .github/workflows/ci-crates-version-bump.yml | 74 ++++++ .../workflows/publish-crates-io-dry-run.yml | 43 ---- .github/workflows/publish-crates-io.yml | 47 ---- .../workflows/resume-publish-crates-io.yml | 41 +++ Cargo.lock | 238 +++++++++--------- Cargo.toml | 200 +++++++-------- common/network-defaults/Cargo.toml | 3 + common/nym-kcp/Cargo.toml | 1 + contracts/Cargo.lock | 58 +++-- contracts/Cargo.toml | 45 ++-- crate-publishing.md | 22 +- scripts/add-crates-owners.sh | 21 ++ .../nym-sdk}/examples/control_requests.rs | 0 service-providers/common/Cargo.toml | 7 - 17 files changed, 661 insertions(+), 363 deletions(-) create mode 100644 .github/workflows/ci-crates-publish-dry-run.yml create mode 100644 .github/workflows/ci-crates-publish-resume.yml create mode 100644 .github/workflows/ci-crates-publish.yml create mode 100644 .github/workflows/ci-crates-version-bump.yml delete mode 100644 .github/workflows/publish-crates-io-dry-run.yml delete mode 100644 .github/workflows/publish-crates-io.yml create mode 100644 .github/workflows/resume-publish-crates-io.yml create mode 100755 scripts/add-crates-owners.sh rename {service-providers/common => sdk/rust/nym-sdk}/examples/control_requests.rs (100%) diff --git a/.github/workflows/ci-crates-publish-dry-run.yml b/.github/workflows/ci-crates-publish-dry-run.yml new file mode 100644 index 0000000000..f57efbe87e --- /dev/null +++ b/.github/workflows/ci-crates-publish-dry-run.yml @@ -0,0 +1,79 @@ +name: Publish to crates.io (dry run) + +on: + workflow_dispatch: + inputs: + version: + description: "Version to publish (e.g. 1.21.0)" + required: true + type: string + +env: + CI_BOT_AUTHOR: "Nym bot" + CI_BOT_EMAIL: "nym-bot@users.noreply.github.com" + +jobs: + publish-dry-run: + runs-on: arc-linux-latest + steps: + - name: Checkout repo + uses: actions/checkout@v6 + + - name: Configure git identity + run: | + git config --global user.name "${{ env.CI_BOT_AUTHOR }}" + git config --global user.email "${{ env.CI_BOT_EMAIL }}" + + - name: Install rust toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + + - name: Install cargo-workspaces + run: cargo install cargo-workspaces + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + + - name: Validate version format + run: | + if ! npx semver "${{ inputs.version }}"; then + echo "Error: '${{ inputs.version }}' is not valid semver" + exit 1 + fi + + - name: Get current version + id: current_version + run: | + VERSION=$(grep -oP '^\s*version\s*=\s*"\K[0-9]+\.[0-9]+\.[0-9]+' Cargo.toml | head -1) + echo "version=$VERSION" >> $GITHUB_OUTPUT + + - name: Update workspace dependencies + run: | + sed -i '/path = /s/version = "${{ steps.current_version.outputs.version }}"/version = "${{ inputs.version }}"/g' Cargo.toml + + - name: Bump versions (local only) + run: | + cargo workspaces version custom ${{ inputs.version }} \ + --allow-branch ${{ github.ref_name }} \ + --no-git-commit \ + + # Dry run may show cascading dependency errors because packages aren't + # actually uploaded - these are expected and ignored. We check for real + # errors like packaging failures, missing metadata, or invalid Cargo.toml. + - name: Publish (dry run) + run: | + output=$(cargo workspaces publish --dry-run --allow-dirty 2>&1) || true + echo "$output" + + # Check for real errors (not cascading dependency errors) + # Cascading errors mention "crates.io index", real errors mention "Cargo.toml" + echo "$output" | grep -i "Cargo.toml" && exit 1 || true + + # Show the list of packages published + - name: Show package versions + run: cargo workspaces list --long diff --git a/.github/workflows/ci-crates-publish-resume.yml b/.github/workflows/ci-crates-publish-resume.yml new file mode 100644 index 0000000000..77f448a2b8 --- /dev/null +++ b/.github/workflows/ci-crates-publish-resume.yml @@ -0,0 +1,59 @@ +# This is in case, for whatever reason, a publication run fails, and we need to restart halfway down the list, of unbumped/unpublished crates. +name: Resume crates.io publish + +on: + workflow_dispatch: + inputs: + resume_after: + description: "Last successfully published crate (will start from the next one)" + required: true + type: string + publish_interval: + description: "Seconds to wait between publishes" + required: false + default: "600" + type: string + +jobs: + publish: + runs-on: arc-linux-latest + steps: + - name: Checkout repo + uses: actions/checkout@v6 + + - name: Install rust toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + + - name: Install cargo-workspaces + run: cargo install cargo-workspaces + + # Get crates in publish order, skip up to and including resume_after + - name: Publish remaining crates + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + run: | + CRATES=$(cargo workspaces plan 2>/dev/null | sed -n '/^${{ inputs.resume_after }}$/,$p' | tail -n +2) + + if [ -z "$CRATES" ]; then + echo "Error: No crates found after '${{ inputs.resume_after }}'" + echo "Check the crate name matches exactly from 'cargo workspaces plan'" + exit 1 + fi + + echo "Will publish the following crates:" + echo "$CRATES" + echo "" + + echo "$CRATES" | while read crate; do + echo "Publishing $crate..." + cargo publish -p "$crate" --allow-dirty + echo "Waiting ${{ inputs.publish_interval }}s before next publish..." + sleep ${{ inputs.publish_interval }} + done + + - name: Show package versions + run: cargo workspaces list --long diff --git a/.github/workflows/ci-crates-publish.yml b/.github/workflows/ci-crates-publish.yml new file mode 100644 index 0000000000..3c7250d241 --- /dev/null +++ b/.github/workflows/ci-crates-publish.yml @@ -0,0 +1,86 @@ +name: Publish crates to crates.io + +on: + workflow_dispatch: + inputs: + publish_interval: + description: "Seconds to wait between publishes (600 for first publish, 60 after)" + required: false + default: "600" + type: string + backup_author: + description: "Second team member added as owner of the crate" + required: false + default: "jstuczyn" + type: string + +jobs: + publish: + runs-on: arc-linux-latest + steps: + - name: Checkout repo + uses: actions/checkout@v6 + + - name: Install rust toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + + - name: Install cargo-workspaces + run: cargo install cargo-workspaces + + # `--publish-as-is` skips version bumping since that's done in a separate CI job. + - name: Publish + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + run: | + cargo workspaces publish \ + --publish-as-is \ + --publish-interval ${{ inputs.publish_interval }} + + - name: Show package versions + run: cargo workspaces list --long + + - name: Add team as crate owners + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + run: | + TEAM="github:nymtech:core" + echo "Checking and adding $TEAM as owner to workspace crates..." + + cargo workspaces list | while read crate; do + echo "Checking $crate..." + + if cargo owner --list "$crate" 2>/dev/null | grep -q "$TEAM"; then + echo " $TEAM already owns $crate, skipping" + else + echo " Adding $TEAM as owner of $crate..." + cargo owner --add "$TEAM" "$crate" + sleep 2 + fi + done + + echo "Done!" + + - name: Add secondary member as crate owner + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + run: | + TEAM_MEMBER="${{ inputs.backup_author }}" + echo "Checking and adding $TEAM_MEMBER as owner to workspace crates..." + + cargo workspaces list | while read crate; do + echo "Checking $crate..." + + if cargo owner --list "$crate" 2>/dev/null | grep -q "$TEAM_MEMBER"; then + echo " $TEAM_MEMBER already owns $crate, skipping" + else + echo " Adding $TEAM_MEMBER as owner of $crate..." + cargo owner --add "$TEAM_MEMBER" "$crate" + sleep 2 + fi + done + + echo "Done!" diff --git a/.github/workflows/ci-crates-version-bump.yml b/.github/workflows/ci-crates-version-bump.yml new file mode 100644 index 0000000000..790e2a062a --- /dev/null +++ b/.github/workflows/ci-crates-version-bump.yml @@ -0,0 +1,74 @@ +name: Bump crate versions + +on: + workflow_dispatch: + inputs: + version: + description: "Version to set (e.g. 1.21.0)" + required: true + type: string + +env: + CI_BOT_AUTHOR: "Nym bot" + CI_BOT_EMAIL: "nym-bot@users.noreply.github.com" + +jobs: + version-bump: + runs-on: arc-linux-latest + permissions: + contents: write + steps: + - name: Checkout repo + uses: actions/checkout@v6 + + - name: Configure git identity + run: | + git config --global user.name "${{ env.CI_BOT_AUTHOR }}" + git config --global user.email "${{ env.CI_BOT_EMAIL }}" + + - name: Install rust toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + + - name: Install cargo-workspaces + run: cargo install cargo-workspaces + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + + - name: Validate version format + run: | + if ! npx semver "${{ inputs.version }}"; then + echo "Error: '${{ inputs.version }}' is not valid semver" + exit 1 + fi + + - name: Get current version + id: current_version + run: | + VERSION=$(grep -oP '^\s*version\s*=\s*"\K[0-9]+\.[0-9]+\.[0-9]+' Cargo.toml | head -1) + echo "version=$VERSION" >> $GITHUB_OUTPUT + + - name: Update workspace dependencies + run: | + sed -i '/path = /s/version = "${{ steps.current_version.outputs.version }}"/version = "${{ inputs.version }}"/g' Cargo.toml + + - name: Bump versions + run: | + cargo workspaces version custom ${{ inputs.version }} \ + --no-git-commit \ + --yes + + - name: Commit and push version bump + run: | + git add -A + git commit -m "crates release: bump version to ${{ inputs.version }}" + git push + + - name: Show package versions + run: cargo workspaces list --long diff --git a/.github/workflows/publish-crates-io-dry-run.yml b/.github/workflows/publish-crates-io-dry-run.yml deleted file mode 100644 index 2025df7bc4..0000000000 --- a/.github/workflows/publish-crates-io-dry-run.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Publish to crates.io (dry run) - -on: - workflow_dispatch: - inputs: - version: - description: "Version to publish (e.g. 1.21.0)" - required: true - type: string - -jobs: - publish-dry-run: - runs-on: arc-ubuntu-22.04-dind - steps: - - name: Checkout repo - uses: actions/checkout@v6 - - - name: Install rust toolchain - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true - - - name: Install cargo-workspaces - run: cargo install cargo-workspaces - - - name: Bump versions (local only) - run: | - cargo workspaces version ${{ inputs.version }} \ - --no-git-commit \ - --no-git-tag \ - --no-git-push \ - --yes - - # Note: Dry run may show cascading dependency errors because packages - # aren't actually uploaded. Check if the missing dependency has an - # "aborting upload due to dry run" message earlier in the output - if so, - # it would succeed in a real publish since cargo-workspaces publishes in - # dependency order. cargo-workspaces doesn't fail on err, so there isn't - # a good way to check this at the moment. - - name: Publish (dry run) - run: cargo workspaces publish --from-git --dry-run --allow-dirty diff --git a/.github/workflows/publish-crates-io.yml b/.github/workflows/publish-crates-io.yml deleted file mode 100644 index 68a0cd064c..0000000000 --- a/.github/workflows/publish-crates-io.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: Publish to crates.io - -on: - workflow_dispatch: - inputs: - version: - description: "Version to publish (e.g. 1.21.0)" - required: true - type: string - -jobs: - publish: - runs-on: arc-ubuntu-22.04-dind - steps: - - name: Checkout repo - uses: actions/checkout@v6 - - - name: Install rust toolchain - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true - - - name: Install cargo-workspaces - run: cargo install cargo-workspaces - - # - name: Configure git - # run: | - # git config user.name "github-actions[bot]" - # git config user.email "github-actions[bot]@users.noreply.github.com" - - - name: Bump versions - run: | - cargo workspaces version ${{ inputs.version }} \ - --no-git-push \ - --no-git-tag \ - --yes - - - name: Publish - env: - CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} - run: cargo workspaces publish --from-git --no-git-commit - - # - name: Push version commit - # run: | - # git push origin HEAD diff --git a/.github/workflows/resume-publish-crates-io.yml b/.github/workflows/resume-publish-crates-io.yml new file mode 100644 index 0000000000..ef322790d7 --- /dev/null +++ b/.github/workflows/resume-publish-crates-io.yml @@ -0,0 +1,41 @@ +name: Resume publish to crates.io + +on: + workflow_dispatch: + inputs: + resume_after: + description: "Last successfully published crate (will start from the next one)" + required: true + type: string + +jobs: + publish: + runs-on: arc-linux-latest + steps: + - name: Checkout repo + uses: actions/checkout@v6 + + - name: Install rust toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + + - name: Install cargo-workspaces + run: cargo install cargo-workspaces + + - name: Publish remaining crates + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + run: | + # Get crates in publish order, skip up to and including resume_after + cargo workspaces plan 2>/dev/null | sed -n '/^${{ inputs.resume_after }}$/,$p' | tail -n +2 | while read crate; do + echo "Publishing $crate..." + cargo publish -p "$crate" --allow-dirty + echo "Waiting 600s before next publish..." + sleep 600 + done + + - name: Show package versions + run: cargo workspaces list --long diff --git a/Cargo.lock b/Cargo.lock index b3051e1b7b..e53cd9ddcb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2503,7 +2503,7 @@ checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "easy-addr" -version = "1.20.1" +version = "1.20.4" dependencies = [ "cosmwasm-std", "quote", @@ -5491,7 +5491,7 @@ dependencies = [ [[package]] name = "nym-api-requests" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bs58", "celes", @@ -5534,7 +5534,7 @@ dependencies = [ [[package]] name = "nym-async-file-watcher" -version = "1.20.1" +version = "1.20.4" dependencies = [ "futures", "log", @@ -5544,7 +5544,7 @@ dependencies = [ [[package]] name = "nym-authenticator-client" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bincode", "futures", @@ -5566,7 +5566,7 @@ dependencies = [ [[package]] name = "nym-authenticator-requests" -version = "1.20.1" +version = "1.20.4" dependencies = [ "base64 0.22.1", "bincode", @@ -5590,7 +5590,7 @@ dependencies = [ [[package]] name = "nym-bandwidth-controller" -version = "1.20.1" +version = "1.20.4" dependencies = [ "async-trait", "log", @@ -5607,7 +5607,7 @@ dependencies = [ [[package]] name = "nym-bin-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "clap", "clap_complete", @@ -5646,7 +5646,7 @@ dependencies = [ [[package]] name = "nym-cache" -version = "1.20.1" +version = "1.20.4" dependencies = [ "tokio", ] @@ -5677,7 +5677,7 @@ dependencies = [ [[package]] name = "nym-cli-commands" -version = "1.20.1" +version = "1.20.4" dependencies = [ "anyhow", "base64 0.22.1", @@ -5773,7 +5773,7 @@ dependencies = [ [[package]] name = "nym-client-core" -version = "1.20.1" +version = "1.20.4" dependencies = [ "async-trait", "base64 0.22.1", @@ -5834,7 +5834,7 @@ dependencies = [ [[package]] name = "nym-client-core-config-types" -version = "1.20.1" +version = "1.20.4" dependencies = [ "humantime-serde", "nym-config", @@ -5849,7 +5849,7 @@ dependencies = [ [[package]] name = "nym-client-core-gateways-storage" -version = "1.20.1" +version = "1.20.4" dependencies = [ "anyhow", "async-trait", @@ -5868,7 +5868,7 @@ dependencies = [ [[package]] name = "nym-client-core-surb-storage" -version = "1.20.1" +version = "1.20.4" dependencies = [ "anyhow", "async-trait", @@ -5914,7 +5914,7 @@ dependencies = [ [[package]] name = "nym-client-websocket-requests" -version = "1.20.1" +version = "1.20.4" dependencies = [ "nym-sphinx", "serde", @@ -5923,7 +5923,7 @@ dependencies = [ [[package]] name = "nym-coconut-dkg-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -5936,7 +5936,7 @@ dependencies = [ [[package]] name = "nym-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "tracing", "tracing-test", @@ -5944,7 +5944,7 @@ dependencies = [ [[package]] name = "nym-compact-ecash" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bincode", "bs58", @@ -5968,7 +5968,7 @@ dependencies = [ [[package]] name = "nym-config" -version = "1.20.1" +version = "1.20.4" dependencies = [ "dirs", "handlebars", @@ -6000,7 +6000,7 @@ dependencies = [ [[package]] name = "nym-contracts-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "anyhow", "bs58", @@ -6017,7 +6017,7 @@ dependencies = [ [[package]] name = "nym-contracts-common-testing" -version = "1.20.1" +version = "1.20.4" dependencies = [ "anyhow", "cosmwasm-std", @@ -6031,7 +6031,7 @@ dependencies = [ [[package]] name = "nym-cpp-ffi" -version = "1.20.1" +version = "1.20.4" dependencies = [ "anyhow", "bs58", @@ -6094,7 +6094,7 @@ dependencies = [ [[package]] name = "nym-credential-proxy-lib" -version = "1.20.1" +version = "1.20.4" dependencies = [ "anyhow", "axum", @@ -6132,7 +6132,7 @@ dependencies = [ [[package]] name = "nym-credential-proxy-requests" -version = "1.20.1" +version = "1.20.4" dependencies = [ "async-trait", "nym-credentials", @@ -6156,7 +6156,7 @@ dependencies = [ [[package]] name = "nym-credential-storage" -version = "1.20.1" +version = "1.20.4" dependencies = [ "anyhow", "async-trait", @@ -6179,7 +6179,7 @@ dependencies = [ [[package]] name = "nym-credential-utils" -version = "1.20.1" +version = "1.20.4" dependencies = [ "log", "nym-bandwidth-controller", @@ -6197,7 +6197,7 @@ dependencies = [ [[package]] name = "nym-credential-verification" -version = "1.20.1" +version = "1.20.4" dependencies = [ "async-trait", "bs58", @@ -6225,7 +6225,7 @@ dependencies = [ [[package]] name = "nym-credentials" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bincode", "cosmrs", @@ -6249,7 +6249,7 @@ dependencies = [ [[package]] name = "nym-credentials-interface" -version = "1.20.1" +version = "1.20.4" dependencies = [ "nym-bls12_381-fork", "nym-compact-ecash", @@ -6267,7 +6267,7 @@ dependencies = [ [[package]] name = "nym-crypto" -version = "1.20.1" +version = "1.20.4" dependencies = [ "aead", "aes 0.8.4", @@ -6339,7 +6339,7 @@ dependencies = [ [[package]] name = "nym-dkg" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bitvec", "bs58", @@ -6361,7 +6361,7 @@ dependencies = [ [[package]] name = "nym-ecash-contract-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bs58", "cosmwasm-schema", @@ -6375,7 +6375,7 @@ dependencies = [ [[package]] name = "nym-ecash-signer-check" -version = "1.20.1" +version = "1.20.4" dependencies = [ "futures", "nym-ecash-signer-check-types", @@ -6391,7 +6391,7 @@ dependencies = [ [[package]] name = "nym-ecash-signer-check-types" -version = "1.20.1" +version = "1.20.4" dependencies = [ "nym-coconut-dkg-common", "nym-crypto", @@ -6406,7 +6406,7 @@ dependencies = [ [[package]] name = "nym-ecash-time" -version = "1.20.1" +version = "1.20.4" dependencies = [ "nym-compact-ecash", "time", @@ -6414,7 +6414,7 @@ dependencies = [ [[package]] name = "nym-exit-policy" -version = "1.20.1" +version = "1.20.4" dependencies = [ "reqwest 0.13.1", "serde", @@ -6426,7 +6426,7 @@ dependencies = [ [[package]] name = "nym-ffi-shared" -version = "1.20.1" +version = "1.20.4" dependencies = [ "anyhow", "bs58", @@ -6502,7 +6502,7 @@ dependencies = [ [[package]] name = "nym-gateway-client" -version = "1.20.1" +version = "1.20.4" dependencies = [ "futures", "getrandom 0.2.16", @@ -6596,7 +6596,7 @@ dependencies = [ [[package]] name = "nym-gateway-requests" -version = "1.20.1" +version = "1.20.4" dependencies = [ "anyhow", "bs58", @@ -6628,7 +6628,7 @@ dependencies = [ [[package]] name = "nym-gateway-stats-storage" -version = "1.20.1" +version = "1.20.4" dependencies = [ "anyhow", "nym-node-metrics", @@ -6644,7 +6644,7 @@ dependencies = [ [[package]] name = "nym-gateway-storage" -version = "1.20.1" +version = "1.20.4" dependencies = [ "anyhow", "async-trait", @@ -6663,7 +6663,7 @@ dependencies = [ [[package]] name = "nym-go-ffi" -version = "1.20.1" +version = "1.20.4" dependencies = [ "anyhow", "lazy_static", @@ -6680,7 +6680,7 @@ dependencies = [ [[package]] name = "nym-group-contract-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "cosmwasm-schema", "cw-controllers", @@ -6691,7 +6691,7 @@ dependencies = [ [[package]] name = "nym-http-api-client" -version = "1.20.1" +version = "1.20.4" dependencies = [ "async-trait", "bincode", @@ -6723,7 +6723,7 @@ dependencies = [ [[package]] name = "nym-http-api-client-macro" -version = "1.20.1" +version = "1.20.4" dependencies = [ "nym-http-api-client", "proc-macro-crate", @@ -6736,7 +6736,7 @@ dependencies = [ [[package]] name = "nym-http-api-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "axum", "axum-client-ip", @@ -6758,7 +6758,7 @@ dependencies = [ [[package]] name = "nym-id" -version = "1.20.1" +version = "1.20.4" dependencies = [ "nym-credential-storage", "nym-credentials", @@ -6784,7 +6784,7 @@ dependencies = [ [[package]] name = "nym-inclusion-probability" -version = "1.20.1" +version = "1.20.4" dependencies = [ "log", "rand 0.8.5", @@ -6793,7 +6793,7 @@ dependencies = [ [[package]] name = "nym-ip-packet-client" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bincode", "bytes", @@ -6808,7 +6808,7 @@ dependencies = [ [[package]] name = "nym-ip-packet-requests" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bincode", "bytes", @@ -6826,7 +6826,7 @@ dependencies = [ [[package]] name = "nym-ip-packet-router" -version = "1.20.1" +version = "1.20.4" dependencies = [ "anyhow", "async-trait", @@ -6903,7 +6903,7 @@ dependencies = [ [[package]] name = "nym-kkt-ciphersuite" -version = "1.20.1" +version = "1.20.4" dependencies = [ "blake3", "libcrux-sha3", @@ -6915,7 +6915,7 @@ dependencies = [ [[package]] name = "nym-ledger" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bip32", "k256", @@ -7004,7 +7004,7 @@ dependencies = [ [[package]] name = "nym-metrics" -version = "1.20.1" +version = "1.20.4" dependencies = [ "dashmap", "lazy_static", @@ -7014,7 +7014,7 @@ dependencies = [ [[package]] name = "nym-mixnet-client" -version = "1.20.1" +version = "1.20.4" dependencies = [ "dashmap", "futures", @@ -7031,7 +7031,7 @@ dependencies = [ [[package]] name = "nym-mixnet-contract-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bs58", "cosmwasm-schema", @@ -7054,7 +7054,7 @@ dependencies = [ [[package]] name = "nym-mixnode-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bytes", "futures", @@ -7081,7 +7081,7 @@ dependencies = [ [[package]] name = "nym-multisig-contract-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -7096,7 +7096,7 @@ dependencies = [ [[package]] name = "nym-network-defaults" -version = "1.20.1" +version = "1.20.4" dependencies = [ "cargo_metadata 0.19.2", "dotenvy", @@ -7285,7 +7285,7 @@ dependencies = [ [[package]] name = "nym-node-metrics" -version = "1.20.1" +version = "1.20.4" dependencies = [ "dashmap", "futures", @@ -7299,7 +7299,7 @@ dependencies = [ [[package]] name = "nym-node-requests" -version = "1.20.1" +version = "1.20.4" dependencies = [ "async-trait", "celes", @@ -7423,7 +7423,7 @@ dependencies = [ [[package]] name = "nym-node-tester-utils" -version = "1.20.1" +version = "1.20.4" dependencies = [ "futures", "log", @@ -7463,7 +7463,7 @@ dependencies = [ [[package]] name = "nym-noise" -version = "1.20.1" +version = "1.20.4" dependencies = [ "anyhow", "arc-swap", @@ -7486,7 +7486,7 @@ dependencies = [ [[package]] name = "nym-noise-keys" -version = "1.20.1" +version = "1.20.4" dependencies = [ "nym-crypto", "schemars 0.8.22", @@ -7496,7 +7496,7 @@ dependencies = [ [[package]] name = "nym-nonexhaustive-delayqueue" -version = "1.20.1" +version = "1.20.4" dependencies = [ "tokio", "tokio-stream", @@ -7522,7 +7522,7 @@ dependencies = [ [[package]] name = "nym-ordered-buffer" -version = "1.20.1" +version = "1.20.4" dependencies = [ "log", "thiserror 2.0.17", @@ -7530,7 +7530,7 @@ dependencies = [ [[package]] name = "nym-outfox" -version = "1.20.1" +version = "1.20.4" dependencies = [ "blake3", "chacha20", @@ -7549,7 +7549,7 @@ dependencies = [ [[package]] name = "nym-pemstore" -version = "1.20.1" +version = "1.20.4" dependencies = [ "pem", "tracing", @@ -7558,7 +7558,7 @@ dependencies = [ [[package]] name = "nym-performance-contract-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -7571,7 +7571,7 @@ dependencies = [ [[package]] name = "nym-pool-contract-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -7584,7 +7584,7 @@ dependencies = [ [[package]] name = "nym-registration-client" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bytes", "futures", @@ -7611,7 +7611,7 @@ dependencies = [ [[package]] name = "nym-registration-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bincode", "nym-authenticator-requests", @@ -7628,7 +7628,7 @@ dependencies = [ [[package]] name = "nym-sdk" -version = "1.20.1" +version = "1.20.4" dependencies = [ "anyhow", "async-trait", @@ -7687,7 +7687,7 @@ dependencies = [ [[package]] name = "nym-serde-helpers" -version = "1.20.1" +version = "1.20.4" dependencies = [ "base64 0.22.1", "bs58", @@ -7698,7 +7698,7 @@ dependencies = [ [[package]] name = "nym-service-provider-requests-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bincode", "serde", @@ -7707,19 +7707,15 @@ dependencies = [ [[package]] name = "nym-service-providers-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ - "anyhow", "async-trait", "log", "nym-bin-common", - "nym-sdk", - "nym-socks5-requests", "nym-sphinx-anonymous-replies", "serde", "serde_json", "thiserror 2.0.17", - "tokio", ] [[package]] @@ -7777,7 +7773,7 @@ dependencies = [ [[package]] name = "nym-socks5-client-core" -version = "1.20.1" +version = "1.20.4" dependencies = [ "anyhow", "dirs", @@ -7809,7 +7805,7 @@ dependencies = [ [[package]] name = "nym-socks5-proxy-helpers" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bytes", "futures", @@ -7824,7 +7820,7 @@ dependencies = [ [[package]] name = "nym-socks5-requests" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bincode", "log", @@ -7839,7 +7835,7 @@ dependencies = [ [[package]] name = "nym-sphinx" -version = "1.20.1" +version = "1.20.4" dependencies = [ "nym-crypto", "nym-metrics", @@ -7865,7 +7861,7 @@ dependencies = [ [[package]] name = "nym-sphinx-acknowledgements" -version = "1.20.1" +version = "1.20.4" dependencies = [ "generic-array 0.14.7", "nym-crypto", @@ -7883,7 +7879,7 @@ dependencies = [ [[package]] name = "nym-sphinx-addressing" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bincode", "nym-crypto", @@ -7896,7 +7892,7 @@ dependencies = [ [[package]] name = "nym-sphinx-anonymous-replies" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bs58", "nym-crypto", @@ -7914,7 +7910,7 @@ dependencies = [ [[package]] name = "nym-sphinx-chunking" -version = "1.20.1" +version = "1.20.4" dependencies = [ "dashmap", "log", @@ -7932,7 +7928,7 @@ dependencies = [ [[package]] name = "nym-sphinx-cover" -version = "1.20.1" +version = "1.20.4" dependencies = [ "nym-crypto", "nym-sphinx-acknowledgements", @@ -7949,7 +7945,7 @@ dependencies = [ [[package]] name = "nym-sphinx-forwarding" -version = "1.20.1" +version = "1.20.4" dependencies = [ "nym-sphinx-addressing", "nym-sphinx-anonymous-replies", @@ -7960,7 +7956,7 @@ dependencies = [ [[package]] name = "nym-sphinx-framing" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bytes", "cfg-if", @@ -7977,7 +7973,7 @@ dependencies = [ [[package]] name = "nym-sphinx-params" -version = "1.20.1" +version = "1.20.4" dependencies = [ "nym-crypto", "nym-sphinx-types", @@ -7987,7 +7983,7 @@ dependencies = [ [[package]] name = "nym-sphinx-routing" -version = "1.20.1" +version = "1.20.4" dependencies = [ "nym-sphinx-addressing", "nym-sphinx-types", @@ -7996,7 +7992,7 @@ dependencies = [ [[package]] name = "nym-sphinx-types" -version = "1.20.1" +version = "1.20.4" dependencies = [ "nym-outfox", "sphinx-packet", @@ -8005,7 +8001,7 @@ dependencies = [ [[package]] name = "nym-sqlx-pool-guard" -version = "1.20.1" +version = "1.20.4" dependencies = [ "proc_pidinfo", "sqlx", @@ -8048,7 +8044,7 @@ dependencies = [ [[package]] name = "nym-statistics-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "futures", "log", @@ -8073,7 +8069,7 @@ dependencies = [ [[package]] name = "nym-store-cipher" -version = "1.20.1" +version = "1.20.4" dependencies = [ "aes-gcm", "argon2", @@ -8088,7 +8084,7 @@ dependencies = [ [[package]] name = "nym-task" -version = "1.20.1" +version = "1.20.4" dependencies = [ "anyhow", "cfg-if", @@ -8106,7 +8102,7 @@ dependencies = [ [[package]] name = "nym-test-utils" -version = "1.20.1" +version = "1.20.4" dependencies = [ "anyhow", "futures", @@ -8118,7 +8114,7 @@ dependencies = [ [[package]] name = "nym-ticketbooks-merkle" -version = "1.20.1" +version = "1.20.4" dependencies = [ "nym-credentials-interface", "nym-serde-helpers", @@ -8135,7 +8131,7 @@ dependencies = [ [[package]] name = "nym-topology" -version = "1.20.1" +version = "1.20.4" dependencies = [ "async-trait", "nym-api-requests", @@ -8157,7 +8153,7 @@ dependencies = [ [[package]] name = "nym-tun" -version = "1.20.1" +version = "1.20.4" dependencies = [ "etherparse", "log", @@ -8169,7 +8165,7 @@ dependencies = [ [[package]] name = "nym-types" -version = "1.20.1" +version = "1.20.4" dependencies = [ "base64 0.22.1", "cosmrs", @@ -8200,7 +8196,7 @@ dependencies = [ [[package]] name = "nym-upgrade-mode-check" -version = "1.20.1" +version = "1.20.4" dependencies = [ "anyhow", "jwt-simple", @@ -8218,7 +8214,7 @@ dependencies = [ [[package]] name = "nym-validator-client" -version = "1.20.1" +version = "1.20.4" dependencies = [ "anyhow", "async-trait", @@ -8312,7 +8308,7 @@ dependencies = [ [[package]] name = "nym-verloc" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bytes", "futures", @@ -8333,7 +8329,7 @@ dependencies = [ [[package]] name = "nym-vesting-contract-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -8347,7 +8343,7 @@ dependencies = [ [[package]] name = "nym-vpn-api-lib-wasm" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bs58", "getrandom 0.2.16", @@ -8392,7 +8388,7 @@ dependencies = [ [[package]] name = "nym-wasm-client-core" -version = "1.20.1" +version = "1.20.4" dependencies = [ "async-trait", "console_error_panic_hook", @@ -8426,7 +8422,7 @@ dependencies = [ [[package]] name = "nym-wasm-storage" -version = "1.20.1" +version = "1.20.4" dependencies = [ "async-trait", "getrandom 0.2.16", @@ -8442,7 +8438,7 @@ dependencies = [ [[package]] name = "nym-wasm-utils" -version = "1.20.1" +version = "1.20.4" dependencies = [ "console_error_panic_hook", "futures", @@ -8458,7 +8454,7 @@ dependencies = [ [[package]] name = "nym-wireguard" -version = "1.20.1" +version = "1.20.4" dependencies = [ "base64 0.22.1", "defguard_wireguard_rs", @@ -8485,7 +8481,7 @@ dependencies = [ [[package]] name = "nym-wireguard-private-metadata-client" -version = "1.20.1" +version = "1.20.4" dependencies = [ "async-trait", "nym-http-api-client", @@ -8495,7 +8491,7 @@ dependencies = [ [[package]] name = "nym-wireguard-private-metadata-server" -version = "1.20.1" +version = "1.20.4" dependencies = [ "anyhow", "async-trait", @@ -8515,7 +8511,7 @@ dependencies = [ [[package]] name = "nym-wireguard-private-metadata-shared" -version = "1.20.1" +version = "1.20.4" dependencies = [ "axum", "bincode", @@ -8528,7 +8524,7 @@ dependencies = [ [[package]] name = "nym-wireguard-private-metadata-tests" -version = "1.20.1" +version = "1.20.4" dependencies = [ "async-trait", "axum", @@ -8552,7 +8548,7 @@ dependencies = [ [[package]] name = "nym-wireguard-types" -version = "1.20.1" +version = "1.20.4" dependencies = [ "base64 0.22.1", "nym-crypto", @@ -8642,7 +8638,7 @@ dependencies = [ [[package]] name = "nyxd-scraper-shared" -version = "1.20.1" +version = "1.20.4" dependencies = [ "async-trait", "base64 0.22.1", @@ -12936,9 +12932,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" +checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" dependencies = [ "getrandom 0.3.4", "js-sys", @@ -14085,7 +14081,7 @@ dependencies = [ [[package]] name = "zknym-lib" -version = "1.20.1" +version = "1.20.4" dependencies = [ "anyhow", "async-trait", @@ -14158,7 +14154,7 @@ dependencies = [ [[package]] name = "zulip-client" -version = "1.20.1" +version = "1.20.4" dependencies = [ "itertools 0.14.0", "nym-bin-common", diff --git a/Cargo.toml b/Cargo.toml index b83ad953ae..7dbb4cd4f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -205,7 +205,7 @@ edition = "2024" license = "Apache-2.0" rust-version = "1.85" readme = "README.md" -version = "1.20.1" +version = "1.20.4" [workspace.dependencies] addr = "0.15.6" @@ -380,7 +380,7 @@ url = "2.5" utoipa = "5.2" utoipa-swagger-ui = "8.1" utoipauto = "0.2" -uuid = "*" +uuid = "1.19.0" vergen = { version = "=8.3.1", default-features = false } vergen-gitcl = { version = "1.0.8", default-features = false } walkdir = "2" @@ -390,106 +390,106 @@ zeroize = "1.7.0" prometheus = { version = "0.14.0" } # Workspace dep definitions required by crates.io publication - we need a workspace version since `cargo workspaces` doesn't work with path imports from crate manifests -nym-api-requests = { version = "1.20.1", path = "nym-api/nym-api-requests" } -nym-authenticator-requests = { version = "1.20.1", path = "common/authenticator-requests" } -nym-async-file-watcher = { version = "1.20.1", path = "common/async-file-watcher" } -nym-authenticator-client = { version = "1.20.1", path = "nym-authenticator-client" } -nym-bandwidth-controller = { version = "1.20.1", path = "common/bandwidth-controller" } -nym-bin-common = { version = "1.20.1", path = "common/bin-common" } -nym-cache = { version = "1.20.1", path = "common/nym-cache" } -nym-client-core = { version = "1.20.1", path = "common/client-core", default-features = false } -nym-client-core-config-types = { version = "1.20.1", path = "common/client-core/config-types" } -nym-client-core-gateways-storage = { version = "1.20.1", path = "common/client-core/gateways-storage" } -nym-client-core-surb-storage = { version = "1.20.1", path = "common/client-core/surb-storage" } -nym-client-websocket-requests = { version = "1.20.1", path = "clients/native/websocket-requests" } -nym-common = { version = "1.20.1", path = "common/nym-common" } -nym-compact-ecash = { version = "1.20.1", path = "common/nym_offline_compact_ecash" } -nym-config = { version = "1.20.1", path = "common/config" } -nym-contracts-common = { version = "1.20.1", path = "common/cosmwasm-smart-contracts/contracts-common" } -nym-coconut-dkg-common = { version = "1.20.1", path = "common/cosmwasm-smart-contracts/coconut-dkg" } -nym-credential-storage = { version = "1.20.1", path = "common/credential-storage" } -nym-credential-utils = { version = "1.20.1", path = "common/credential-utils" } -nym-credential-proxy-lib = { version = "1.20.1", path = "common/credential-proxy" } -nym-credentials = { version = "1.20.1", path = "common/credentials", default-features = false } -nym-credentials-interface = { version = "1.20.1", path = "common/credentials-interface" } -nym-credential-proxy-requests = { version = "1.20.1", path = "nym-credential-proxy/nym-credential-proxy-requests", default-features = false } -nym-credential-verification = { version = "1.20.1", path = "common/credential-verification" } -nym-crypto = { version = "1.20.1", path = "common/crypto", default-features = false } -nym-dkg = { version = "1.20.1", path = "common/dkg" } -nym-ecash-contract-common = { version = "1.20.1", path = "common/cosmwasm-smart-contracts/ecash-contract" } -nym-ecash-signer-check = { version = "1.20.1", path = "common/ecash-signer-check" } -nym-ecash-signer-check-types = { version = "1.20.1", path = "common/ecash-signer-check-types" } -nym-ecash-time = { version = "1.20.1", path = "common/ecash-time" } -nym-exit-policy = { version = "1.20.1", path = "common/exit-policy" } -nym-ffi-shared = { version = "1.20.1", path = "sdk/ffi/shared" } -nym-gateway-client = { version = "1.20.1", path = "common/client-libs/gateway-client", default-features = false } -nym-gateway-requests = { version = "1.20.1", path = "common/gateway-requests" } -nym-gateway-storage = { version = "1.20.1", path = "common/gateway-storage" } -nym-gateway-stats-storage = { version = "1.20.1", path = "common/gateway-stats-storage" } -nym-group-contract-common = { version = "1.20.1", path = "common/cosmwasm-smart-contracts/group-contract" } -nym-http-api-client = { version = "1.20.1", path = "common/http-api-client" } -nym-http-api-client-macro = { version = "1.20.1", path = "common/http-api-client-macro" } -nym-http-api-common = { version = "1.20.1", path = "common/http-api-common", default-features = false } -nym-id = { version = "1.20.1", path = "common/nym-id" } +nym-api-requests = { version = "1.20.4", path = "nym-api/nym-api-requests" } +nym-authenticator-requests = { version = "1.20.4", path = "common/authenticator-requests" } +nym-async-file-watcher = { version = "1.20.4", path = "common/async-file-watcher" } +nym-authenticator-client = { version = "1.20.4", path = "nym-authenticator-client" } +nym-bandwidth-controller = { version = "1.20.4", path = "common/bandwidth-controller" } +nym-bin-common = { version = "1.20.4", path = "common/bin-common" } +nym-cache = { version = "1.20.4", path = "common/nym-cache" } +nym-client-core = { version = "1.20.4", path = "common/client-core", default-features = false } +nym-client-core-config-types = { version = "1.20.4", path = "common/client-core/config-types" } +nym-client-core-gateways-storage = { version = "1.20.4", path = "common/client-core/gateways-storage" } +nym-client-core-surb-storage = { version = "1.20.4", path = "common/client-core/surb-storage" } +nym-client-websocket-requests = { version = "1.20.4", path = "clients/native/websocket-requests" } +nym-common = { version = "1.20.4", path = "common/nym-common" } +nym-compact-ecash = { version = "1.20.4", path = "common/nym_offline_compact_ecash" } +nym-config = { version = "1.20.4", path = "common/config" } +nym-contracts-common = { version = "1.20.4", path = "common/cosmwasm-smart-contracts/contracts-common" } +nym-coconut-dkg-common = { version = "1.20.4", path = "common/cosmwasm-smart-contracts/coconut-dkg" } +nym-credential-storage = { version = "1.20.4", path = "common/credential-storage" } +nym-credential-utils = { version = "1.20.4", path = "common/credential-utils" } +nym-credential-proxy-lib = { version = "1.20.4", path = "common/credential-proxy" } +nym-credentials = { version = "1.20.4", path = "common/credentials", default-features = false } +nym-credentials-interface = { version = "1.20.4", path = "common/credentials-interface" } +nym-credential-proxy-requests = { version = "1.20.4", path = "nym-credential-proxy/nym-credential-proxy-requests", default-features = false } +nym-credential-verification = { version = "1.20.4", path = "common/credential-verification" } +nym-crypto = { version = "1.20.4", path = "common/crypto", default-features = false } +nym-dkg = { version = "1.20.4", path = "common/dkg" } +nym-ecash-contract-common = { version = "1.20.4", path = "common/cosmwasm-smart-contracts/ecash-contract" } +nym-ecash-signer-check = { version = "1.20.4", path = "common/ecash-signer-check" } +nym-ecash-signer-check-types = { version = "1.20.4", path = "common/ecash-signer-check-types" } +nym-ecash-time = { version = "1.20.4", path = "common/ecash-time" } +nym-exit-policy = { version = "1.20.4", path = "common/exit-policy" } +nym-ffi-shared = { version = "1.20.4", path = "sdk/ffi/shared" } +nym-gateway-client = { version = "1.20.4", path = "common/client-libs/gateway-client", default-features = false } +nym-gateway-requests = { version = "1.20.4", path = "common/gateway-requests" } +nym-gateway-storage = { version = "1.20.4", path = "common/gateway-storage" } +nym-gateway-stats-storage = { version = "1.20.4", path = "common/gateway-stats-storage" } +nym-group-contract-common = { version = "1.20.4", path = "common/cosmwasm-smart-contracts/group-contract" } +nym-http-api-client = { version = "1.20.4", path = "common/http-api-client" } +nym-http-api-client-macro = { version = "1.20.4", path = "common/http-api-client-macro" } +nym-http-api-common = { version = "1.20.4", path = "common/http-api-common", default-features = false } +nym-id = { version = "1.20.4", path = "common/nym-id" } +nym-ip-packet-client = { version = "1.20.4", path = "nym-ip-packet-client" } +nym-ip-packet-requests = { version = "1.20.4", path = "common/ip-packet-requests" } nym-kkt-ciphersuite = { path = "common/nym-kkt-ciphersuite" } -nym-ip-packet-client = { version = "1.20.1", path = "nym-ip-packet-client" } -nym-ip-packet-requests = { version = "1.20.1", path = "common/ip-packet-requests" } -nym-metrics = { version = "1.20.1", path = "common/nym-metrics" } -nym-mixnet-client = { version = "1.20.1", path = "common/client-libs/mixnet-client" } -nym-mixnet-contract-common = { version = "1.20.1", path = "common/cosmwasm-smart-contracts/mixnet-contract" } -nym-multisig-contract-common = { version = "1.20.1", path = "common/cosmwasm-smart-contracts/multisig-contract" } -nym-network-defaults = { version = "1.20.1", path = "common/network-defaults" } -nym-node-tester-utils = { version = "1.20.1", path = "common/node-tester-utils" } -nym-noise = { version = "1.20.1", path = "common/nymnoise" } -nym-noise-keys = { version = "1.20.1", path = "common/nymnoise/keys" } -nym-nonexhaustive-delayqueue = { version = "1.20.1", path = "common/nonexhaustive-delayqueue" } -nym-node-requests = { version = "1.20.1", path = "nym-node/nym-node-requests", default-features = false } -nym-node-metrics = { version = "1.20.1", path = "nym-node/nym-node-metrics" } -nym-ordered-buffer = { version = "1.20.1", path = "common/socks5/ordered-buffer" } -nym-outfox = { version = "1.20.1", path = "nym-outfox" } -nym-registration-common = { version = "1.20.1", path = "common/registration" } -nym-pemstore = { version = "1.20.1", path = "common/pemstore" } -nym-performance-contract-common = { version = "1.20.1", path = "common/cosmwasm-smart-contracts/nym-performance-contract" } -nym-sdk = { version = "1.20.1", path = "sdk/rust/nym-sdk" } -nym-serde-helpers = { version = "1.20.1", path = "common/serde-helpers" } -nym-service-providers-common = { version = "1.20.1", path = "service-providers/common" } -nym-service-provider-requests-common = { version = "1.20.1", path = "common/service-provider-requests-common" } -nym-socks5-client-core = { version = "1.20.1", path = "common/socks5-client-core" } -nym-socks5-proxy-helpers = { version = "1.20.1", path = "common/socks5/proxy-helpers" } -nym-socks5-requests = { version = "1.20.1", path = "common/socks5/requests" } -nym-sphinx = { version = "1.20.1", path = "common/nymsphinx" } -nym-sphinx-acknowledgements = { version = "1.20.1", path = "common/nymsphinx/acknowledgements" } -nym-sphinx-addressing = { version = "1.20.1", path = "common/nymsphinx/addressing" } -nym-sphinx-anonymous-replies = { version = "1.20.1", path = "common/nymsphinx/anonymous-replies" } -nym-sphinx-chunking = { version = "1.20.1", path = "common/nymsphinx/chunking" } -nym-sphinx-cover = { version = "1.20.1", path = "common/nymsphinx/cover" } -nym-sphinx-forwarding = { version = "1.20.1", path = "common/nymsphinx/forwarding" } -nym-sphinx-framing = { version = "1.20.1", path = "common/nymsphinx/framing" } -nym-sphinx-params = { version = "1.20.1", path = "common/nymsphinx/params" } -nym-sphinx-routing = { version = "1.20.1", path = "common/nymsphinx/routing" } -nym-sphinx-types = { version = "1.20.1", path = "common/nymsphinx/types" } -nym-statistics-common = { version = "1.20.1", path = "common/statistics" } -nym-store-cipher = { version = "1.20.1", path = "common/store-cipher" } -nym-task = { version = "1.20.1", path = "common/task" } -nym-tun = { version = "1.20.1", path = "common/tun" } -nym-test-utils = { version = "1.20.1", path = "common/test-utils" } -nym-ticketbooks-merkle = { version = "1.20.1", path = "common/ticketbooks-merkle" } -nym-topology = { version = "1.20.1", path = "common/topology" } -nym-types = { version = "1.20.1", path = "common/types" } -nym-upgrade-mode-check = { version = "1.20.1", path = "common/upgrade-mode-check" } -nym-validator-client = { version = "1.20.1", path = "common/client-libs/validator-client", default-features = false } -nym-vesting-contract-common = { version = "1.20.1", path = "common/cosmwasm-smart-contracts/vesting-contract" } -nym-verloc = { version = "1.20.1", path = "common/verloc" } -nym-wireguard = { version = "1.20.1", path = "common/wireguard" } -nym-wireguard-types = { version = "1.20.1", path = "common/wireguard-types" } -nym-wireguard-private-metadata-shared = { version = "1.20.1", path = "common/wireguard-private-metadata/shared" } -nym-wireguard-private-metadata-client = { version = "1.20.1", path = "common/wireguard-private-metadata/client" } -nym-wireguard-private-metadata-server = { version = "1.20.1", path = "common/wireguard-private-metadata/server" } +nym-metrics = { version = "1.20.4", path = "common/nym-metrics" } +nym-mixnet-client = { version = "1.20.4", path = "common/client-libs/mixnet-client" } +nym-mixnet-contract-common = { version = "1.20.4", path = "common/cosmwasm-smart-contracts/mixnet-contract" } +nym-multisig-contract-common = { version = "1.20.4", path = "common/cosmwasm-smart-contracts/multisig-contract" } +nym-network-defaults = { version = "1.20.4", path = "common/network-defaults" } +nym-node-tester-utils = { version = "1.20.4", path = "common/node-tester-utils" } +nym-noise = { version = "1.20.4", path = "common/nymnoise" } +nym-noise-keys = { version = "1.20.4", path = "common/nymnoise/keys" } +nym-nonexhaustive-delayqueue = { version = "1.20.4", path = "common/nonexhaustive-delayqueue" } +nym-node-requests = { version = "1.20.4", path = "nym-node/nym-node-requests", default-features = false } +nym-node-metrics = { version = "1.20.4", path = "nym-node/nym-node-metrics" } +nym-ordered-buffer = { version = "1.20.4", path = "common/socks5/ordered-buffer" } +nym-outfox = { version = "1.20.4", path = "nym-outfox" } +nym-registration-common = { version = "1.20.4", path = "common/registration" } +nym-pemstore = { version = "1.20.4", path = "common/pemstore" } +nym-performance-contract-common = { version = "1.20.4", path = "common/cosmwasm-smart-contracts/nym-performance-contract" } +nym-sdk = { version = "1.20.4", path = "sdk/rust/nym-sdk" } +nym-serde-helpers = { version = "1.20.4", path = "common/serde-helpers" } +nym-service-providers-common = { version = "1.20.4", path = "service-providers/common" } +nym-service-provider-requests-common = { version = "1.20.4", path = "common/service-provider-requests-common" } +nym-socks5-client-core = { version = "1.20.4", path = "common/socks5-client-core" } +nym-socks5-proxy-helpers = { version = "1.20.4", path = "common/socks5/proxy-helpers" } +nym-socks5-requests = { version = "1.20.4", path = "common/socks5/requests" } +nym-sphinx = { version = "1.20.4", path = "common/nymsphinx" } +nym-sphinx-acknowledgements = { version = "1.20.4", path = "common/nymsphinx/acknowledgements" } +nym-sphinx-addressing = { version = "1.20.4", path = "common/nymsphinx/addressing" } +nym-sphinx-anonymous-replies = { version = "1.20.4", path = "common/nymsphinx/anonymous-replies" } +nym-sphinx-chunking = { version = "1.20.4", path = "common/nymsphinx/chunking" } +nym-sphinx-cover = { version = "1.20.4", path = "common/nymsphinx/cover" } +nym-sphinx-forwarding = { version = "1.20.4", path = "common/nymsphinx/forwarding" } +nym-sphinx-framing = { version = "1.20.4", path = "common/nymsphinx/framing" } +nym-sphinx-params = { version = "1.20.4", path = "common/nymsphinx/params" } +nym-sphinx-routing = { version = "1.20.4", path = "common/nymsphinx/routing" } +nym-sphinx-types = { version = "1.20.4", path = "common/nymsphinx/types" } +nym-statistics-common = { version = "1.20.4", path = "common/statistics" } +nym-store-cipher = { version = "1.20.4", path = "common/store-cipher" } +nym-task = { version = "1.20.4", path = "common/task" } +nym-tun = { version = "1.20.4", path = "common/tun" } +nym-test-utils = { version = "1.20.4", path = "common/test-utils" } +nym-ticketbooks-merkle = { version = "1.20.4", path = "common/ticketbooks-merkle" } +nym-topology = { version = "1.20.4", path = "common/topology" } +nym-types = { version = "1.20.4", path = "common/types" } +nym-upgrade-mode-check = { version = "1.20.4", path = "common/upgrade-mode-check" } +nym-validator-client = { version = "1.20.4", path = "common/client-libs/validator-client", default-features = false } +nym-vesting-contract-common = { version = "1.20.4", path = "common/cosmwasm-smart-contracts/vesting-contract" } +nym-verloc = { version = "1.20.4", path = "common/verloc" } +nym-wireguard = { version = "1.20.4", path = "common/wireguard" } +nym-wireguard-types = { version = "1.20.4", path = "common/wireguard-types" } +nym-wireguard-private-metadata-shared = { version = "1.20.4", path = "common/wireguard-private-metadata/shared" } +nym-wireguard-private-metadata-client = { version = "1.20.4", path = "common/wireguard-private-metadata/client" } +nym-wireguard-private-metadata-server = { version = "1.20.4", path = "common/wireguard-private-metadata/server" } nym-sqlx-pool-guard = { version = "1.2.0", path = "nym-sqlx-pool-guard" } -nym-wasm-client-core = { version = "1.20.1", path = "common/wasm/client-core" } -nym-wasm-storage = { version = "1.20.1", path = "common/wasm/storage" } -nym-wasm-utils = { version = "1.20.1", path = "common/wasm/utils", default-features = false } -nyxd-scraper-shared = { version = "1.20.1", path = "common/nyxd-scraper-shared" } +nym-wasm-client-core = { version = "1.20.4", path = "common/wasm/client-core" } +nym-wasm-storage = { version = "1.20.4", path = "common/wasm/storage" } +nym-wasm-utils = { version = "1.20.4", path = "common/wasm/utils", default-features = false } +nyxd-scraper-shared = { version = "1.20.4", path = "common/nyxd-scraper-shared" } # coconut/DKG related # unfortunately until https://github.com/zkcrypto/nym-bls12_381-fork/issues/10 is resolved, we have to rely on the fork diff --git a/common/network-defaults/Cargo.toml b/common/network-defaults/Cargo.toml index 924d09151f..305f31916f 100644 --- a/common/network-defaults/Cargo.toml +++ b/common/network-defaults/Cargo.toml @@ -6,6 +6,9 @@ edition.workspace = true authors.workspace = true license.workspace = true repository.workspace = true +# Exclude build.rs from published crate - it's only used for dev-time sync +# of env files and requires workspace context +exclude = ["build.rs"] [dependencies] dotenvy = { workspace = true, optional = true } diff --git a/common/nym-kcp/Cargo.toml b/common/nym-kcp/Cargo.toml index 488c9fff8a..3f435e94e5 100644 --- a/common/nym-kcp/Cargo.toml +++ b/common/nym-kcp/Cargo.toml @@ -6,6 +6,7 @@ edition = { workspace = true } authors = { workspace = true } license = { workspace = true } repository = { workspace = true } +publish = false [lib] name = "nym_kcp" diff --git a/contracts/Cargo.lock b/contracts/Cargo.lock index 92d73ca89e..f7f8f0ccfe 100644 --- a/contracts/Cargo.lock +++ b/contracts/Cargo.lock @@ -825,7 +825,7 @@ checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "easy-addr" -version = "1.20.1" +version = "1.20.4" dependencies = [ "cosmwasm-std", "quote", @@ -1248,7 +1248,9 @@ dependencies = [ [[package]] name = "nym-coconut-dkg-common" -version = "1.20.1" +version = "1.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a95dc43ef8954a4f79846e3224434cf389d4a9c14b77f526dae3cfd2221c6141" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1261,7 +1263,9 @@ dependencies = [ [[package]] name = "nym-contracts-common" -version = "1.20.1" +version = "1.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47bb3e8427c193cd500c802274b11879086863c3643525b6ece3e9ab1c77bddc" dependencies = [ "bs58", "cosmwasm-schema", @@ -1275,7 +1279,9 @@ dependencies = [ [[package]] name = "nym-contracts-common-testing" -version = "1.20.1" +version = "1.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3628aac6715e844f3ab20e3b8ae8c4684f144ccb78e205f002c1c3ae375e956" dependencies = [ "anyhow", "cosmwasm-std", @@ -1289,7 +1295,9 @@ dependencies = [ [[package]] name = "nym-crypto" -version = "1.20.1" +version = "1.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b710addc28c9950dd961e7dd3837ef3b479492d2b21b5f2437eb7d2899403027" dependencies = [ "base64 0.22.1", "bs58", @@ -1335,7 +1343,9 @@ dependencies = [ [[package]] name = "nym-ecash-contract-common" -version = "1.20.1" +version = "1.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d022e85291bf51877fbbf4688bc3762c605fdaee3b98c6407414f7c358bc5610" dependencies = [ "bs58", "cosmwasm-schema", @@ -1349,7 +1359,9 @@ dependencies = [ [[package]] name = "nym-group-contract-common" -version = "1.20.1" +version = "1.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb13102740426a4a2b683f54bbd6614fe9ecd745f5117bcf197c49c300b15edf" dependencies = [ "cosmwasm-schema", "cw-controllers", @@ -1384,7 +1396,9 @@ dependencies = [ [[package]] name = "nym-mixnet-contract-common" -version = "1.20.1" +version = "1.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41c21bceb3bb8ee2789851b3f381fc035485af825bf7290b7c99a5af4e8f6ba1" dependencies = [ "bs58", "cosmwasm-schema", @@ -1404,7 +1418,9 @@ dependencies = [ [[package]] name = "nym-multisig-contract-common" -version = "1.20.1" +version = "1.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a20b931ee849f6179ce2b387accd058720017f644ffbc8c2422f3e9ac3ff54" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1419,7 +1435,9 @@ dependencies = [ [[package]] name = "nym-network-defaults" -version = "1.20.1" +version = "1.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9834193b4641acdf9f360aea684a6bd841cad287930bc0d7c3241a133756464" dependencies = [ "cargo_metadata 0.19.2", "regex", @@ -1427,7 +1445,9 @@ dependencies = [ [[package]] name = "nym-pemstore" -version = "1.20.1" +version = "1.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03077f9ebeb40caf8aa8e6f7bf8728449f73733e7a246986e492fa34ad3e70ab" dependencies = [ "pem", "tracing", @@ -1455,7 +1475,9 @@ dependencies = [ [[package]] name = "nym-performance-contract-common" -version = "1.20.1" +version = "1.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42129a72f4b0dc0304a48b0ca1769b27694d913687ace5692d4c6924ca9f2a13" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1483,7 +1505,9 @@ dependencies = [ [[package]] name = "nym-pool-contract-common" -version = "1.20.1" +version = "1.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70239cc26beda3ad19289188c50d554522af29646d7d3f855bda6fc8ed332fe7" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1495,7 +1519,9 @@ dependencies = [ [[package]] name = "nym-sphinx-types" -version = "1.20.1" +version = "1.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ba662d39fd6da9e13166fa1162ff41c2cfaed78a77c70df72fbda6fef5eb4f5" dependencies = [ "sphinx-packet", "thiserror 2.0.12", @@ -1524,7 +1550,9 @@ dependencies = [ [[package]] name = "nym-vesting-contract-common" -version = "1.20.1" +version = "1.20.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "676c2793efbf9ccdf86bb788c903f778a2d5993a5174729303f9511a297f4ca8" dependencies = [ "cosmwasm-schema", "cosmwasm-std", diff --git a/contracts/Cargo.toml b/contracts/Cargo.toml index edcaf4b335..6659cb8804 100644 --- a/contracts/Cargo.toml +++ b/contracts/Cargo.toml @@ -57,34 +57,25 @@ schemars = "0.8.16" thiserror = "2.0.11" -# Common crates from parent workspace (paths relative to contracts/) -# -# TODO: Once these crates are published to crates.io, switch from path dependencies -# to crates.io versions. -# -# TODO add a [patch.crates-io] section at the bottom for local development if you need to use a modded version of common import instead e.g.: -# -# [patch.crates-io] -# nym-contracts-common = { path = "../common/cosmwasm-smart-contracts/contracts-common" } -# easy-addr = { version = "1.20.1", path = "../common/cosmwasm-smart-contracts/easy_addr" } -nym-coconut-dkg-common = { version = "1.20.1", path = "../common/cosmwasm-smart-contracts/coconut-dkg" } -nym-contracts-common = { version = "1.20.1", path = "../common/cosmwasm-smart-contracts/contracts-common" } -nym-contracts-common-testing = { version = "1.20.1", path = "../common/cosmwasm-smart-contracts/contracts-common-testing" } -nym-crypto = { version = "1.20.1", path = "../common/crypto", default-features = false } -nym-ecash-contract-common = { version = "1.20.1", path = "../common/cosmwasm-smart-contracts/ecash-contract" } -nym-group-contract-common = { version = "1.20.1", path = "../common/cosmwasm-smart-contracts/group-contract" } -nym-mixnet-contract-common = { version = "1.20.1", path = "../common/cosmwasm-smart-contracts/mixnet-contract" } -nym-multisig-contract-common = { version = "1.20.1", path = "../common/cosmwasm-smart-contracts/multisig-contract" } -nym-network-defaults = { version = "1.20.1", path = "../common/network-defaults", default-features = false } -nym-performance-contract-common = { version = "1.20.1", path = "../common/cosmwasm-smart-contracts/nym-performance-contract" } -nym-pool-contract-common = { version = "1.20.1", path = "../common/cosmwasm-smart-contracts/nym-pool-contract" } -nym-vesting-contract-common = { version = "1.20.1", path = "../common/cosmwasm-smart-contracts/vesting-contract" } +# For local development with modifications, add a [patch.crates-io] section (see bottom of file) +nym-coconut-dkg-common = "1.20.4" +nym-contracts-common = "1.20.4" +nym-contracts-common-testing = "1.20.4" +nym-crypto = { version = "1.20.4", default-features = false } +nym-ecash-contract-common = "1.20.4" +nym-group-contract-common = "1.20.4" +nym-mixnet-contract-common = "1.20.4" +nym-multisig-contract-common = "1.20.4" +nym-network-defaults = { version = "1.20.4", default-features = false } +nym-performance-contract-common = "1.20.4" +nym-pool-contract-common = "1.20.4" +nym-vesting-contract-common = "1.20.4" # Aliases for crates that some contracts import under different names -contracts-common = { version = "1.20.1", path = "../common/cosmwasm-smart-contracts/contracts-common", package = "nym-contracts-common" } -mixnet-contract-common = { version = "1.20.1", path = "../common/cosmwasm-smart-contracts/mixnet-contract", package = "nym-mixnet-contract-common" } -vesting-contract-common = { version = "1.20.1", path = "../common/cosmwasm-smart-contracts/vesting-contract", package = "nym-vesting-contract-common" } +contracts-common = { version = "1.20.4", package = "nym-contracts-common" } +mixnet-contract-common = { version = "1.20.4", package = "nym-mixnet-contract-common" } +vesting-contract-common = { version = "1.20.4", package = "nym-vesting-contract-common" } # Internal contract workspace members (for cross-contract testing) cw3-flex-multisig = { version = "2.0.0", path = "multisig/cw3-flex-multisig" } @@ -101,3 +92,7 @@ exit = "deny" panic = "deny" unimplemented = "deny" unreachable = "deny" + +# For local development, import via path instead of crates.io, e.g. +# [patch.crates-io] +# nym-coconut-dkg-common = { path = "../common/cosmwasm-smart-contracts/coconut-dkg" } diff --git a/crate-publishing.md b/crate-publishing.md index 780194e8b7..86dc0988d2 100644 --- a/crate-publishing.md +++ b/crate-publishing.md @@ -9,14 +9,26 @@ This version is defined in the `[workspace.package]` section of the root monorep ## When Developing If you add a workspace dependency to the SDK when developing, make sure to add this to the workspace dependencies in the root monorepo `Cargo.toml`. -## Publishing +## Check local publication ``` # List crates to publish cargo workspaces list -# Dry run - check for compilation or other problems +# Dry run locally - check for compilation or other problems cargo workspaces publish --no-git-commit --dry-run - -# Publish -TODO ``` + +## CI +There are several workflows that should be run in the following order: +- `ci-crates-publish-dry-run`: **run this first!** This is a remote dry-run on a runner. This greps for any errors that would be a problem when we're not dry-running. It doesn't catch all errors, as `dry-run` has a known issue where, assuming that 2 new crates are being uploaded, and crate B relies on crate A, if crate A isn't on crates.io (which it won't be, since you're dry-running publication), then since `cargo workspaces publish` only checks for available versions on crates.io, it will error. We don't want the CI to fail in that case. +- `ci-crates-version-bump`: this bumps the versions of the workspace + dependencies to the passed version, and then commits the change. This is its own CI job so that we don't get into sticky situations whereby the version bump + commit happens, but the publication step fails. +- `ci-crates-publish`: this publishes the crates. So long as you're not uploading more than 5 new crates, pass `60` as the `publish_interval`. This is to get around [crates.io rate limiting](https://github.com/rust-lang/crates.io/blob/ad7e58e1afd65b9137e58a7bca3e1fb7f5546682/src/rate_limiter.rs#L24). Pass the Github handle of whoever should be the backup author of the crate for security redundency (see the section below) as the second arg. + +> There is also `ci-crates-publish-resume` which is there in case a publication run fails and needs to be restarted part way through the list of unbumped/unpublished crates. Pass the previously bumped/published crate in the list output of `cargo workspaces list` + +## Crates.io Authors +Since Github teams have [limited ownership / mod rights](https://doc.rust-lang.org/cargo/reference/publishing.html#cargo-owner) of crates, and we cannot create a `CARGO_REGISTRY_TOKEN` on behalf of the Nym Github org. As such, we are currently using personal cargo tokens generated by team members (currently Max), and adding the Nym Github org as an owner in the CI job. + +However, since the Github org cannot add or modify owners, are also adding a second user author as a redundency, on the offchance that Max loses access to his Crates.io / Github account, gets struck by lightning, etc. This is the author passed as the second argument to the `ci-crates-publish` CI, and if none is passed, defaults to [https://github.com/jstuczyn](https://github.com/jstuczyn) since he is the Github org owner. + +Authors can also be changed by running `scripts/add-crates-owners.sh`. diff --git a/scripts/add-crates-owners.sh b/scripts/add-crates-owners.sh new file mode 100755 index 0000000000..813d2c9640 --- /dev/null +++ b/scripts/add-crates-owners.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# This is a local version of a script to add the nym github org as owners of a crate, aside from whoever's CI token is being used. +# If you want to add another team member as backup owner, comment out line 5 and use their github handle and they will be invited to be an owner on crates.io, e.g.: +# TEAM="jstuczyn" +TEAM="github:nymtech:core" + +echo "Checking and adding $TEAM as owner to workspace crates..." + +cargo workspaces list | while read crate; do + echo "Checking $crate..." + + if cargo owner --list "$crate" 2>/dev/null | grep -q "$TEAM"; then + echo " $TEAM already owns $crate, skipping" + else + echo " Adding $TEAM as owner of $crate..." + cargo owner --add "$TEAM" "$crate" + sleep 2 + fi +done + +echo "Done!" diff --git a/service-providers/common/examples/control_requests.rs b/sdk/rust/nym-sdk/examples/control_requests.rs similarity index 100% rename from service-providers/common/examples/control_requests.rs rename to sdk/rust/nym-sdk/examples/control_requests.rs diff --git a/service-providers/common/Cargo.toml b/service-providers/common/Cargo.toml index ad8b2b7574..93661af48f 100644 --- a/service-providers/common/Cargo.toml +++ b/service-providers/common/Cargo.toml @@ -20,10 +20,3 @@ thiserror = { workspace = true } serde = { workspace = true, features = ["derive"]} serde_json = { workspace = true } -[dev-dependencies] -# for the control requests example -anyhow = { workspace = true } -tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } - -nym-sdk = { workspace = true } -nym-socks5-requests = { workspace = true } From 660eff45dcadb6c5e5492f21834cbc1d031ae68b Mon Sep 17 00:00:00 2001 From: dynco-nym <173912580+dynco-nym@users.noreply.github.com> Date: Wed, 4 Feb 2026 22:14:46 +0100 Subject: [PATCH 10/56] Endpoint for exit GW IPs (#6418) --- Cargo.lock | 2 +- .../nym-node-status-api/Cargo.toml | 2 +- .../src/http/api/dvpn/exit.rs | 22 ++++++ .../nym-node-status-api/src/http/state.rs | 79 +++++++++++++++++-- 4 files changed, 95 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e53cd9ddcb..86ec8c1c56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7346,7 +7346,7 @@ dependencies = [ [[package]] name = "nym-node-status-api" -version = "4.0.14" +version = "4.1.0" dependencies = [ "ammonia", "anyhow", diff --git a/nym-node-status-api/nym-node-status-api/Cargo.toml b/nym-node-status-api/nym-node-status-api/Cargo.toml index 8d414c8817..8991b95e1c 100644 --- a/nym-node-status-api/nym-node-status-api/Cargo.toml +++ b/nym-node-status-api/nym-node-status-api/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-node-status-api" -version = "4.0.14" +version = "4.1.0" authors.workspace = true repository.workspace = true homepage.workspace = true diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/dvpn/exit.rs b/nym-node-status-api/nym-node-status-api/src/http/api/dvpn/exit.rs index 5d8b2918f4..02419a71a7 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/dvpn/exit.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/dvpn/exit.rs @@ -17,6 +17,7 @@ pub(crate) fn routes() -> Router { "/exit/countries", axum::routing::get(get_entry_gateway_countries), ) + .route("/exit/ips", axum::routing::get(get_exit_gateway_ips)) .route( "/exit/country/:two_letter_country_code", axum::routing::get(get_exit_gateways_by_country), @@ -70,6 +71,27 @@ pub async fn get_entry_gateway_countries(state: State) -> HttpResult) + ) +)] +#[instrument(level = tracing::Level::INFO, skip(state))] +pub async fn get_exit_gateway_ips(state: State) -> HttpResult>> { + Ok(Json( + state + .cache() + .get_exit_gateway_ips(state.db_pool(), &MIN_SUPPORTED_VERSION) + .await, + )) +} + #[utoipa::path( tag = "dVPN Directory Cache", get, diff --git a/nym-node-status-api/nym-node-status-api/src/http/state.rs b/nym-node-status-api/nym-node-status-api/src/http/state.rs index 14bfc99c8d..88ef86a75b 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/state.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/state.rs @@ -9,10 +9,10 @@ use nym_node_status_client::auth::VerifiableRequest; use nym_validator_client::nym_api::SkimmedNode; use semver::Version; use serde::{Deserialize, Serialize}; -use std::{collections::HashMap, sync::Arc, time::Duration}; +use std::{collections::HashMap, net::IpAddr, sync::Arc, time::Duration}; use time::UtcDateTime; use tokio::sync::RwLock; -use tracing::{error, instrument, warn}; +use tracing::{error, instrument, trace, warn}; use utoipa::ToSchema; use super::models::SessionStats; @@ -153,6 +153,7 @@ impl AppState { static GATEWAYS_LIST_KEY: &str = "gateways"; static DVPN_GATEWAYS_LIST_KEY: &str = "dvpn_gateways"; +static DVPN_EXIT_GATEWAY_IPS: &str = "dvpn_exit_gateway_ips"; static NYM_NODES_LIST_KEY: &str = "nym_nodes"; static MIXSTATS_LIST_KEY: &str = "mixstats"; static SUMMARY_HISTORY_LIST_KEY: &str = "summary-history"; @@ -164,6 +165,7 @@ const MIXNODE_STATS_HISTORY_DAYS: usize = 30; pub(crate) struct HttpCache { gateways: Cache>>>, dvpn_gateways: Cache>>>, + exit_gateway_ips: Cache>>>, nym_nodes: Cache>>>, mixstats: Cache>>>, history: Cache>>>, @@ -174,27 +176,31 @@ impl HttpCache { pub async fn new(ttl_seconds: u64) -> Self { HttpCache { gateways: Cache::builder() - .max_capacity(2) + .max_capacity(1) .time_to_live(Duration::from_secs(ttl_seconds)) .build(), dvpn_gateways: Cache::builder() - .max_capacity(6) + .max_capacity(1) + .time_to_live(Duration::from_secs(ttl_seconds)) + .build(), + exit_gateway_ips: Cache::builder() + .max_capacity(1) .time_to_live(Duration::from_secs(ttl_seconds)) .build(), nym_nodes: Cache::builder() - .max_capacity(2) + .max_capacity(1) .time_to_live(Duration::from_secs(ttl_seconds)) .build(), mixstats: Cache::builder() - .max_capacity(2) + .max_capacity(1) .time_to_live(Duration::from_secs(ttl_seconds)) .build(), history: Cache::builder() - .max_capacity(2) + .max_capacity(1) .time_to_live(Duration::from_secs(ttl_seconds)) .build(), session_stats: Cache::builder() - .max_capacity(2) + .max_capacity(1) .time_to_live(Duration::from_secs(ttl_seconds)) .build(), } @@ -436,6 +442,63 @@ impl HttpCache { .collect() } + pub async fn get_exit_gateway_ips( + &self, + db: &DbPool, + min_node_version: &Version, + ) -> Vec { + match self.exit_gateway_ips.get(DVPN_EXIT_GATEWAY_IPS).await { + Some(guard) => { + let read_lock = guard.read().await; + read_lock.clone() + } + None => { + trace!("No exit gateway IPs in cache, refreshing..."); + + let ips: Vec = self + .get_dvpn_gateway_list(db, min_node_version) + .await + .into_iter() + .filter_map(|gw| { + if gw.can_route_exit() { + Some(gw.ip_addresses) + } else { + None + } + }) + .flatten() + .filter(IpAddr::is_ipv4) + .map(|ip| ip.to_string()) + .sorted() + .dedup() + .collect(); + + self.upsert_exit_gateway_ips(ips.clone()).await; + + ips + } + } + } + + pub async fn upsert_exit_gateway_ips( + &self, + ip_list: Vec, + ) -> Entry>>> { + self.exit_gateway_ips + .entry_by_ref(DVPN_EXIT_GATEWAY_IPS) + .and_upsert_with(|maybe_entry| async { + if let Some(entry) = maybe_entry { + let v = entry.into_value(); + let mut guard = v.write().await; + *guard = ip_list; + v.clone() + } else { + Arc::new(RwLock::new(ip_list)) + } + }) + .await + } + pub async fn upsert_nym_node_list( &self, nym_node_list: Vec, From ded23a627100f9d889501a14c7c29d53caa09ccc Mon Sep 17 00:00:00 2001 From: Sachin Kamath Date: Mon, 9 Feb 2026 13:45:39 +0530 Subject: [PATCH 11/56] chore: add headers to coingecko fetch --- Cargo.lock | 2 +- nyx-chain-watcher/Cargo.toml | 2 +- nyx-chain-watcher/src/price_scraper/mod.rs | 8 +++++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f02486a236..e7b63d261c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8590,7 +8590,7 @@ dependencies = [ [[package]] name = "nyx-chain-watcher" -version = "0.1.14" +version = "0.1.15" dependencies = [ "anyhow", "async-trait", diff --git a/nyx-chain-watcher/Cargo.toml b/nyx-chain-watcher/Cargo.toml index 7af5f4f20d..e8f2b4b2e0 100644 --- a/nyx-chain-watcher/Cargo.toml +++ b/nyx-chain-watcher/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nyx-chain-watcher" -version = "0.1.14" +version = "0.1.15" authors.workspace = true repository.workspace = true homepage.workspace = true diff --git a/nyx-chain-watcher/src/price_scraper/mod.rs b/nyx-chain-watcher/src/price_scraper/mod.rs index 6442118579..160d699c03 100644 --- a/nyx-chain-watcher/src/price_scraper/mod.rs +++ b/nyx-chain-watcher/src/price_scraper/mod.rs @@ -29,7 +29,13 @@ impl PriceScraper { async fn get_coingecko_prices(&self) -> anyhow::Result { tracing::info!("💰 Fetching CoinGecko prices from {COINGECKO_API_URL}"); - let response = reqwest::get(COINGECKO_API_URL) + let client = reqwest::Client::new(); + let response = client + .get(COINGECKO_API_URL) + .header(reqwest::header::USER_AGENT, "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36") + .header(reqwest::header::ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7") + .header(reqwest::header::REFERER, "https://www.coingecko.com") + .send() .await? .json::() .await; From 51e5e7825d02a4d6695fc7a0edcfbfe6622d8118 Mon Sep 17 00:00:00 2001 From: Sachin Kamath Date: Mon, 9 Feb 2026 14:32:28 +0530 Subject: [PATCH 12/56] chore: update chain watcher push workflow --- .github/workflows/push-nyx-chain-watcher.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push-nyx-chain-watcher.yaml b/.github/workflows/push-nyx-chain-watcher.yaml index 3397742352..4d85e8e355 100644 --- a/.github/workflows/push-nyx-chain-watcher.yaml +++ b/.github/workflows/push-nyx-chain-watcher.yaml @@ -8,7 +8,7 @@ env: jobs: build-container: - runs-on: arc-ubuntu-22.04-dind + runs-on: arc-linux-latest steps: - name: Login to Harbor uses: docker/login-action@v3 From 49faa138558c9f108bb01a4d0efe62c277044adc Mon Sep 17 00:00:00 2001 From: Sachin Kamath Date: Mon, 9 Feb 2026 14:38:35 +0530 Subject: [PATCH 13/56] chore: update chain watcher workflow to hosted runner --- .github/workflows/push-nyx-chain-watcher.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push-nyx-chain-watcher.yaml b/.github/workflows/push-nyx-chain-watcher.yaml index 4d85e8e355..ff1dcf25ba 100644 --- a/.github/workflows/push-nyx-chain-watcher.yaml +++ b/.github/workflows/push-nyx-chain-watcher.yaml @@ -8,7 +8,7 @@ env: jobs: build-container: - runs-on: arc-linux-latest + runs-on: ubuntu-latest steps: - name: Login to Harbor uses: docker/login-action@v3 From 613d4961332d679cb9e5fbd852fb663c5830a4eb Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Tue, 10 Feb 2026 10:59:17 +0000 Subject: [PATCH 14/56] Add Lychee linkchecker for inter-doc links (#6438) * Add Lychee linkchecker for inter-doc links * Fix path to linkcheckr CI * Try fix path again * Update lychee config * Fix broken links * Add Lychee usage info to readme --- .github/workflows/ci-docs-linkcheck.yml | 21 ++++++++ documentation/docs/README.md | 8 ++- .../docs/pages/apis/cosmos-sdk-nyx.mdx | 2 +- documentation/docs/pages/apis/nym-api.mdx | 2 +- .../pages/developers/archive/nym-connect.md | 10 ++-- documentation/docs/pages/developers/chain.md | 2 +- .../pages/developers/clients/socks5/setup.mdx | 2 +- .../pages/developers/clients/socks5/usage.mdx | 2 +- .../developers/clients/websocket/usage.md | 2 +- .../rust/mixnet/troubleshooting.mdx | 4 +- .../pages/network/architecture/mixnet.mdx | 2 +- .../docs/pages/network/architecture/nyx.mdx | 6 +-- .../pages/network/cryptography/zk-nym.mdx | 2 +- .../cryptography/zk-nym/rerandomise.mdx | 2 +- .../cryptography/zk-nym/unlinkability.mdx | 4 +- .../cryptography/zk-nym/zk-nym-overview.mdx | 4 +- .../operators/archive/faq/smoosh-faq.mdx | 6 +-- .../pages/operators/binaries/building-nym.mdx | 4 +- .../docs/pages/operators/changelog.mdx | 52 +++++++++---------- .../pages/operators/community-counsel.mdx | 4 +- .../operators/community-counsel/isp-list.mdx | 2 +- .../operators/community-counsel/legal.mdx | 2 +- .../docs/pages/operators/introduction.mdx | 2 +- .../docs/pages/operators/misc/toc.md | 2 +- .../pages/operators/nodes/maintenance.mdx | 2 +- .../nodes/maintenance/manual-upgrade.mdx | 2 +- .../nymvisor-configuration.mdx | 2 +- .../pages/operators/nodes/nym-node/setup.mdx | 4 +- .../operators/nodes/preliminary-steps.mdx | 2 +- .../docs/pages/operators/sandbox.mdx | 2 +- .../docs/pages/operators/tokenomics.mdx | 2 +- .../operators/tokenomics/mixnet-rewards.mdx | 6 +-- .../pages/operators/troubleshooting/nodes.mdx | 6 +-- lychee.toml | 18 +++++++ 34 files changed, 120 insertions(+), 75 deletions(-) create mode 100644 .github/workflows/ci-docs-linkcheck.yml create mode 100644 lychee.toml diff --git a/.github/workflows/ci-docs-linkcheck.yml b/.github/workflows/ci-docs-linkcheck.yml new file mode 100644 index 0000000000..ba9411dd6b --- /dev/null +++ b/.github/workflows/ci-docs-linkcheck.yml @@ -0,0 +1,21 @@ +name: ci-docs-linkcheck + +on: + workflow_dispatch: + push: + paths: + - "documentation/docs/**" + - ".github/workflows/ci-docs-linkcheck.yml" + - "lychee.toml" + +jobs: + linkcheck: + runs-on: arc-linux-latest + steps: + - uses: actions/checkout@v6 + + - name: Check links + uses: lycheeverse/lychee-action@v2 + with: + args: ${{ github.workspace }}/documentation/docs/ --config ${{ github.workspace }}/lychee.toml --root-dir ${{ github.workspace }}/documentation/docs/pages/ + fail: true diff --git a/documentation/docs/README.md b/documentation/docs/README.md index 4bde3ebbda..b27ac7733d 100644 --- a/documentation/docs/README.md +++ b/documentation/docs/README.md @@ -22,6 +22,12 @@ Our `prebuild` script relies on the following: Otherwise make sure to have `node` installed. +### Link checking (optional) +We use [lychee](https://github.com/lycheeverse/lychee) to check for broken links. Install via your package manager or `cargo install lychee`, then run: +```sh +lychee documentation/docs/ --config lychee.toml --root-dir documentation/docs/pages/ +``` + ### Serve Local (Hot Reload) ```sh pnpm i @@ -48,7 +54,7 @@ pnpm run build > **Only run this script on branches where you want to push e.g. the build info of a binary to production docs**; it will build the monorepo binaries and use their command output for the produced markdown files. ## CI/CD -TODO +- **Link checking**: Runs on every push to `documentation/docs/` via `.github/workflows/ci-docs-linkcheck.yml` ## Licensing and copyright information This is a monorepo and components that make up Nym as a system are licensed individually, so for accurate information, please check individual files. diff --git a/documentation/docs/pages/apis/cosmos-sdk-nyx.mdx b/documentation/docs/pages/apis/cosmos-sdk-nyx.mdx index b43138fd3e..822f1a753f 100644 --- a/documentation/docs/pages/apis/cosmos-sdk-nyx.mdx +++ b/documentation/docs/pages/apis/cosmos-sdk-nyx.mdx @@ -1,3 +1,3 @@ # Validator REST API -Since the [Nyx validators](../../operators/nodes/validator-setup) are built with the Cosmos SDK, they by default expose a [REST API](https://docs.cosmos.network/api) which can be used to query the state of the chain. +Since the [Nyx validators](/operators/nodes/validator-setup) are built with the Cosmos SDK, they by default expose a [REST API](https://docs.cosmos.network/api) which can be used to query the state of the chain. diff --git a/documentation/docs/pages/apis/nym-api.mdx b/documentation/docs/pages/apis/nym-api.mdx index 15be469fc4..cf479a7a37 100644 --- a/documentation/docs/pages/apis/nym-api.mdx +++ b/documentation/docs/pages/apis/nym-api.mdx @@ -1,5 +1,5 @@ # NymAPI -The [NymAPI](../../operators/nodes/validator-setup/nym-api) is a sidecar binary operated by members of the Nym Validator set. Amongst other things, the API offers endpoints to query regarding circulating `NYM` supply, and global and ticketbook-specific [zk-nym](../../network/cryptography/zk-nym) data. This is all information contained in various smart contracts on the Nyx blockchain; the NymAPI caches this information periodically to make queries faster and more scalable. +The [NymAPI](/operators/nodes/validator-setup/nym-api) is a sidecar binary operated by members of the Nym Validator set. Amongst other things, the API offers endpoints to query regarding circulating `NYM` supply, and global and ticketbook-specific [zk-nym](/network/cryptography/zk-nym) data. This is all information contained in various smart contracts on the Nyx blockchain; the NymAPI caches this information periodically to make queries faster and more scalable. The code for this service can be found [in our monorepo](https://github.com/nymtech/nym/tree/develop/nym-api). diff --git a/documentation/docs/pages/developers/archive/nym-connect.md b/documentation/docs/pages/developers/archive/nym-connect.md index 78987b012e..bc2b720b16 100644 --- a/documentation/docs/pages/developers/archive/nym-connect.md +++ b/documentation/docs/pages/developers/archive/nym-connect.md @@ -2,7 +2,7 @@ ```admonish warning Since the beginning of 2024 NymConnect is no longer maintained. Nym is developing a new client called [NymVPN](https://nymvpn.com), an application routing all users traffic thorugh the mixnet. -If users want to route their traffic through socks5 we advice to use maintained [Nym Socks5 Client](../clients/socks5/setup.md). +If users want to route their traffic through socks5 we advice to use maintained [Nym Socks5 Client](../clients/socks5/setup). ``` In case you want to run deprecated NymConnect, follow these steps: @@ -27,7 +27,7 @@ Here are some examples of applications which will work behind Socks5 proxy (`nym To download Electrum visit the [official webpage](https://electrum.org/#download). To connect to the Mixnet follow these steps: -1. Start and connect NymConnect (or [`nym-socks5-client`](../clients/socks5/setup.md)) +1. Start and connect NymConnect (or [`nym-socks5-client`](../clients/socks5/setup)) 2. Start your Electrum Bitcoin wallet 3. Go to: *Tools* -> *Network* -> *Proxy* 4. Set *Use proxy* to ✅, choose `SOCKS5` from the drop-down and add (copy-paste) the values from your NymConnect application @@ -39,7 +39,7 @@ To download Electrum visit the [official webpage](https://electrum.org/#download To download Monero wallet visit [getmonero.org](https://www.getmonero.org/downloads/). To connect to the Mixnet follow these steps: -1. Start and connect NymConnect (or [`nym-socks5-client`](../clients/socks5/setup.md)) +1. Start and connect NymConnect (or [`nym-socks5-client`](../clients/socks5/setup)) 2. Start your Monero wallet 3. Go to: *Settings* -> *Interface* -> *Socks5 proxy* -> Add values: IP address `127.0.0.1`, Port `1080` (the values copied from NymConnect) 5. Now your Monero wallet runs through the Mixnet and it will be connected only if your NymConnect or `nym-socks5-client` are connected. @@ -49,7 +49,7 @@ To download Monero wallet visit [getmonero.org](https://www.getmonero.org/downlo To download Element (chat client for Matrix) visit [element.io](https://element.io/download). To connect to the Mixnet follow these steps: -1. Start and connect NymConnect (or [`nym-socks5-client`](../clients/socks5/setup.md)) +1. Start and connect NymConnect (or [`nym-socks5-client`](../clients/socks5/setup)) 2. Start `element-desktop` with `--proxy-server` argument: **Linux** @@ -68,7 +68,7 @@ To make the start of Element over NymConnect simplier, you can add this command ### Telegram via NymConnect -1. Start and connect NymConnect (or [`nym-socks5-client`](../clients/socks5/setup.md)) +1. Start and connect NymConnect (or [`nym-socks5-client`](../clients/socks5/setup)) 2. Start your Telegram chat application 3. Open the Telegram proxy settings. - Linux: *Settings* -> *Advanced* -> *Connection type* -> *Use custom proxy* diff --git a/documentation/docs/pages/developers/chain.md b/documentation/docs/pages/developers/chain.md index 03c83aeb0b..58eed5ecaf 100644 --- a/documentation/docs/pages/developers/chain.md +++ b/documentation/docs/pages/developers/chain.md @@ -1,7 +1,7 @@ # Interacting with Nyx Chain and Smart Contracts There are two options for interacting with the blockchain to send tokens or interact with deployed smart contracts: -* [`Nym-CLI`](../tools/nym-cli.md) tool +* [`Nym-CLI`](./tools/nym-cli) tool * `nyxd` binary ## Nym-CLI tool (recommended in most cases) diff --git a/documentation/docs/pages/developers/clients/socks5/setup.mdx b/documentation/docs/pages/developers/clients/socks5/setup.mdx index 59e46c2c19..207ed95329 100644 --- a/documentation/docs/pages/developers/clients/socks5/setup.mdx +++ b/documentation/docs/pages/developers/clients/socks5/setup.mdx @@ -28,7 +28,7 @@ Before you can use the client, you need to initalise a new instance of it, which The `--id` in the example above is a local identifier so that you can name your clients and keep track of them on your local system; it is **never** transmitted over the network. -The `--use-reply-surbs` field denotes whether you wish to send [SURBs](../../network/concepts/anonymous-replies) along with your request. It defaults to `false`, we are explicitly setting it as `true`. It defaults to `false` for compatibility with versions of the pre-smoosh `nym-network-requester` binary which will soon be deprecated. +The `--use-reply-surbs` field denotes whether you wish to send [SURBs](/network/concepts/anonymous-replies) along with your request. It defaults to `false`, we are explicitly setting it as `true`. It defaults to `false` for compatibility with versions of the pre-smoosh `nym-network-requester` binary which will soon be deprecated. The `--provider` field needs to be filled with the Nym address of an Exit Gateway that can make network requests on your behalf. You can select one from the [mixnet explorer](https://nym.com/explorer) by copying its `Client ID` and using this as the value of the `--provider` flag. Alternatively, you could use [Harbourmaster](https://harbourmaster.nymtech.net/). diff --git a/documentation/docs/pages/developers/clients/socks5/usage.mdx b/documentation/docs/pages/developers/clients/socks5/usage.mdx index 1f19f9d166..ac76276eb0 100644 --- a/documentation/docs/pages/developers/clients/socks5/usage.mdx +++ b/documentation/docs/pages/developers/clients/socks5/usage.mdx @@ -44,7 +44,7 @@ When trying to connect your app, generally the proxy settings are found in `sett Here is an example of setting the proxy connecting in Blockstream Green: -![Blockstream Green settings](/images/wallet-proxy-settings/blockstream-green.gif) +![Blockstream Green settings](/images/developers/blockstream-green.gif) Most wallets and other applications will work basically the same way: find the network proxy settings, enter the proxy url (host: **localhost**, port: **1080**). diff --git a/documentation/docs/pages/developers/clients/websocket/usage.md b/documentation/docs/pages/developers/clients/websocket/usage.md index c258d45abb..333875b716 100644 --- a/documentation/docs/pages/developers/clients/websocket/usage.md +++ b/documentation/docs/pages/developers/clients/websocket/usage.md @@ -54,7 +54,7 @@ In some applications, e.g. where people are chatting with friends who they know, **If that fits your security model, good. However, will probably be the case that you want to send anonymous replies using Single Use Reply Blocks (SURBs)**. -You can read more about SURBs [here](../../network/concepts/anonymous-replies) but in short they are ways for the receiver of this message to anonymously reply to you - the sender - **without them having to know your client address**. +You can read more about SURBs [here](/network/concepts/anonymous-replies) but in short they are ways for the receiver of this message to anonymously reply to you - the sender - **without them having to know your client address**. Your client will send along a number of `replySurbs` to the recipient of the message. These are pre-addressed Sphinx packets that the recipient can write to the payload of (i.e. write response data to), but not view the final destination of. If the recipient is unable to fit the response data into the bucket of SURBs sent to it, it will use a SURB to request more SURBs be sent to it from your client. diff --git a/documentation/docs/pages/developers/rust/mixnet/troubleshooting.mdx b/documentation/docs/pages/developers/rust/mixnet/troubleshooting.mdx index 719cda58f3..8ad5135a0e 100644 --- a/documentation/docs/pages/developers/rust/mixnet/troubleshooting.mdx +++ b/documentation/docs/pages/developers/rust/mixnet/troubleshooting.mdx @@ -111,7 +111,7 @@ However, this is not true. **This will only block until the message is put into client's internal queue**. Therefore in the above example, the client is being shut down before the message is _actually sent to the mixnet_; after being placed in the client's internal queue, there is still work to be done under the hood, such as route encrypting the message and placing it amongst the stream of cover traffic. -The simple solution? Make sure the program/client stays active, either by calling `sleep`, or listening out for new messages. As sending a one-shot message without listening out for a response is likely not what you'll be doing, then you will be then awaiting a response (see the [message helpers page](./message-helpers.md) for an example of this). +The simple solution? Make sure the program/client stays active, either by calling `sleep`, or listening out for new messages. As sending a one-shot message without listening out for a response is likely not what you'll be doing, then you will be then awaiting a response (see the [message helpers page](./message-helpers) for an example of this). Furthermore, you should always **manually disconnect your client** with `client.disconnect().await` as seen in the code examples. This is important as your client is writing to a local DB and dealing with SURB storage. @@ -122,7 +122,7 @@ You might however be receiving messages without data attached to them / empty pa Whether the `data` of a SURB request being empty is a feature or a bug is to be decided - there is some discussion surrounding whether we can use SURB requests to send additional data to streamline the process of sending large replies across the mixnet. -You can find a few helper functions [here](./message-helpers.md) to help deal with this issue in the meantime. +You can find a few helper functions [here](./message-helpers) to help deal with this issue in the meantime. > If you can think of a more succinct or different way of handling this do reach out - we're happy to hear other opinions diff --git a/documentation/docs/pages/network/architecture/mixnet.mdx b/documentation/docs/pages/network/architecture/mixnet.mdx index 4843a292a6..bd86fb6774 100644 --- a/documentation/docs/pages/network/architecture/mixnet.mdx +++ b/documentation/docs/pages/network/architecture/mixnet.mdx @@ -6,7 +6,7 @@ import { Callout } from 'nextra/components' -If you want to run a node, the setup and maintenance guides can be found in the [Operator Docs](../../../operators/introduction). +If you want to run a node, the setup and maintenance guides can be found in the [Operator Docs](/operators/introduction). diff --git a/documentation/docs/pages/network/architecture/nyx.mdx b/documentation/docs/pages/network/architecture/nyx.mdx index 5795e76f77..69ec52b06e 100644 --- a/documentation/docs/pages/network/architecture/nyx.mdx +++ b/documentation/docs/pages/network/architecture/nyx.mdx @@ -6,7 +6,7 @@ import { Callout } from 'nextra/components' If you want to interact with the chain please check the [interacting with Nyx](../../developers/chain) section of the developer docs. -If you want to run a Validator node, check the [Operator guides](../../../operators/nodes/validator-setup). +If you want to run a Validator node, check the [Operator guides](/operators/nodes/validator-setup). @@ -14,7 +14,7 @@ Nyx is a Cosmos SDK blockchain. The blockchain plays a supporting but fundamenta ## Validators - The validator setup and maintenance guide can be found in the [Operator Docs](../../../operators/nodes/validator-setup). + The validator setup and maintenance guide can be found in the [Operator Docs](/operators/nodes/validator-setup). Validators secure the Nyx blockchain via Proof of Stake consensus. The Nyx blockchain records the ledger of `NYM` transactions and executes the smart contracts for distributing `NYM` rewards. The Nyx validators are run via the `nyxd` binary ([codebase](https://github.com/nymtech/nyxd)), maintaining a CosmWasm- and IBC-enabled blockchain. @@ -23,7 +23,7 @@ Detailed info on Nyx Validators and token flow can be found in [Nym Reward Shari ## NymAPI - The Nym API setup and maintenance guide has moved to the [Operator Guides book](../../../operators/nodes/validator-setup/nym-api). + The Nym API setup and maintenance guide has moved to the [Operator Guides book](/operators/nodes/validator-setup/nym-api). The NymAPI is a binary operated by a subset of the Nyx validator set. This binary can be run in several different modes, and has two main bits of functionality: diff --git a/documentation/docs/pages/network/cryptography/zk-nym.mdx b/documentation/docs/pages/network/cryptography/zk-nym.mdx index b2570e24e9..720373fcd8 100644 --- a/documentation/docs/pages/network/cryptography/zk-nym.mdx +++ b/documentation/docs/pages/network/cryptography/zk-nym.mdx @@ -2,7 +2,7 @@ The zk-nym scheme enables the creation and use of unlinkable, rerandomisable anonymous access credentials that are 'spent' with Gateways in order to anonymously prove that someone has paid for Mixnet access. This implementation incorporates elements of both the [Coconut Credential](https://arxiv.org/pdf/1802.07344) and [Offline Ecash](https://arxiv.org/pdf/2303.08221) schemes. -As outlined in the [overview](./zk-nym/zk-nym-overview.md) on the next page, zk-nyms allow for users to pay for Mixnet access in a manner that is **unlinkable to their payment account**; even with pseudonymous cryptocurrencies or fiat. This solves one of the fundamental privacy problems with the majority of VPNs and dVPNs in production today: the linkability of a user's session with their payment information, which can in the majority of cases be easily used to deanonymise them, either at the behest of an authority or by the service operators themselves. +As outlined in the [overview](./zk-nym/zk-nym-overview) on the next page, zk-nyms allow for users to pay for Mixnet access in a manner that is **unlinkable to their payment account**; even with pseudonymous cryptocurrencies or fiat. This solves one of the fundamental privacy problems with the majority of VPNs and dVPNs in production today: the linkability of a user's session with their payment information, which can in the majority of cases be easily used to deanonymise them, either at the behest of an authority or by the service operators themselves. > The current zk-nym scheme is non-generic in that it is only used for gating Mixnet access. A generic scheme based on zk-nyms is being actively researched in order to facilitate more generic and customisable anonymous credentials for other applications and services. diff --git a/documentation/docs/pages/network/cryptography/zk-nym/rerandomise.mdx b/documentation/docs/pages/network/cryptography/zk-nym/rerandomise.mdx index 3b4a296eff..e82d4f510d 100644 --- a/documentation/docs/pages/network/cryptography/zk-nym/rerandomise.mdx +++ b/documentation/docs/pages/network/cryptography/zk-nym/rerandomise.mdx @@ -5,7 +5,7 @@ import { Callout } from 'nextra/components' Each ticket will not be valid for the entire amount of data that the ticketbook aggregated from the PSCs is; if the aggregated ticketbook is worth (e.g.) 10GB of Mixnet data, each ticket will be worth far less (e.g. 100MB). This amount will be globally uniform in order to avoid situations where differently sized tickets allow for patterns to emerge. - The functionality included in the following code block examples were added to the [nym-cli tool](../tools/nym-cli.md) for illustrative purposes only: this is not necessarily how credentials will be accessed in the future. + The functionality included in the following code block examples were added to the [nym-cli tool](/developers/tools/nym-cli) for illustrative purposes only: this is not necessarily how credentials will be accessed in the future. The numbers used in this high level overview are for illustration purposes only. The figures used in production will potentially vary. Note that individual ticket sizes will be uniform across the Network. diff --git a/documentation/docs/pages/network/cryptography/zk-nym/unlinkability.mdx b/documentation/docs/pages/network/cryptography/zk-nym/unlinkability.mdx index e6554299b6..d2c7768b49 100644 --- a/documentation/docs/pages/network/cryptography/zk-nym/unlinkability.mdx +++ b/documentation/docs/pages/network/cryptography/zk-nym/unlinkability.mdx @@ -1,11 +1,11 @@ import { Callout } from 'nextra/components' # Unlinkability -Each time a credential is requested by an ingress Gateway to prove that a client has purchased data to send through the Mixnet the Requester's device will produce a ticket. This is a rereandomised value that is able to be verified as being legitimate (in that it was created by a valid root ticketbook) but **not linked to any other tickets**, either previously generated or to be generated in the future. This feature also allows for a single ticketbook to allow access to be split across multiple ingress Gateways / connections and [incrementally spent](./rerandomise.md) over time. +Each time a credential is requested by an ingress Gateway to prove that a client has purchased data to send through the Mixnet the Requester's device will produce a ticket. This is a rereandomised value that is able to be verified as being legitimate (in that it was created by a valid root ticketbook) but **not linked to any other tickets**, either previously generated or to be generated in the future. This feature also allows for a single ticketbook to allow access to be split across multiple ingress Gateways / connections and [incrementally spent](./rerandomise) over time. -The functionality included in the following code block examples were added to the [nym-cli tool](../tools/nym-cli.md) for illustrative purposes only: this is not necessarily how credentials will be accessed in the future. +The functionality included in the following code block examples were added to the [nym-cli tool](/developers/tools/nym-cli) for illustrative purposes only: this is not necessarily how credentials will be accessed in the future. The numbers used in this high level overview are for illustration purposes only. The figures used in production will potentially vary. Note that individual zkNym sizes will be uniform across the Network. diff --git a/documentation/docs/pages/network/cryptography/zk-nym/zk-nym-overview.mdx b/documentation/docs/pages/network/cryptography/zk-nym/zk-nym-overview.mdx index fa63e9602c..61ab6d3895 100644 --- a/documentation/docs/pages/network/cryptography/zk-nym/zk-nym-overview.mdx +++ b/documentation/docs/pages/network/cryptography/zk-nym/zk-nym-overview.mdx @@ -51,8 +51,8 @@ Once the Requester has received over the threshold number of PSCs they can assem ## Spend zk-nym to Access Mixnet -- Once the ticketbook has been aggregated from the PSCs returned from > threshold of Quorum members, smaller 'ticket' credentials can be generated from it, accounting for smaller chunks of bandwidth which can be 'spent' with ingress Gateways. This occurs entirely offline, on the device of the zk-nym Requester. See pages on the scheme's [unlinkability](unlinkability.md) and [rerandomisation and incremental spending](./rerandomise.md) features for further information on this. -- This ticket is later presented to the Quorum by the Gateway that collected it, which is used to calculate reward percentages given to Nym Network infrastructure operators by the Quorum, with payouts triggered by their multisig wallet. Both ingress Gateways and the Quorum use spent tickets when engaging in [double spending protection](./double-spend-prot.md). +- Once the ticketbook has been aggregated from the PSCs returned from > threshold of Quorum members, smaller 'ticket' credentials can be generated from it, accounting for smaller chunks of bandwidth which can be 'spent' with ingress Gateways. This occurs entirely offline, on the device of the zk-nym Requester. See pages on the scheme's [unlinkability](unlinkability) and [rerandomisation and incremental spending](./rerandomise) features for further information on this. +- This ticket is later presented to the Quorum by the Gateway that collected it, which is used to calculate reward percentages given to Nym Network infrastructure operators by the Quorum, with payouts triggered by their multisig wallet. Both ingress Gateways and the Quorum use spent tickets when engaging in [double spending protection](./double-spend-prot). ![](/images/network/use-zknym.png) diff --git a/documentation/docs/pages/operators/archive/faq/smoosh-faq.mdx b/documentation/docs/pages/operators/archive/faq/smoosh-faq.mdx index c7d5c843bb..b26c3ba5db 100644 --- a/documentation/docs/pages/operators/archive/faq/smoosh-faq.mdx +++ b/documentation/docs/pages/operators/archive/faq/smoosh-faq.mdx @@ -10,7 +10,7 @@ import { Callout } from 'nextra/components'; > -- Harry Halpin, Nym CEO -This page refer to the changes which are planned to take place over Q3 and Q4 2023. As this is a transition period in the beginning (Q3 2023) the [Mix Nodes FAQ page](mixnodes-faq.md) holds more answers to the current setup as project Smoosh refers to the eventual setup. As project Smoosh gets progressively implemented the answers on this page will become to be more relevant to the current state and eventually this FAQ page will be merged with the still relevant parts of the main Mix Nodes FAQ page. +This page refer to the changes which are planned to take place over Q3 and Q4 2023. As this is a transition period in the beginning (Q3 2023) the Mix Nodes FAQ page holds more answers to the current setup as project Smoosh refers to the eventual setup. As project Smoosh gets progressively implemented the answers on this page will become to be more relevant to the current state and eventually this FAQ page will be merged with the still relevant parts of the main Mix Nodes FAQ page. If any questions are not answered or it's not clear for you in which stage project Smoosh is right now, please reach out in Node Operators [Matrix room](https://matrix.to/#/#operators:nymtech.chat). @@ -22,7 +22,7 @@ Project Smoosh will have four steps, please follow the table below to track the | **Step** | **Status** | | :--- | :--- | | **1.** Combine the `nym-gateway` and `nym-network-requester` into one binary | ✅ done | -| **2.** Create [Exit Gateway](../../legal/exit-gateway.md): Take the `nym-gateway` binary including `nym-network-requester` combined in \#1 and switch from [`allowed.list`](https://nymtech.net/.wellknown/network-requester/standard-allowed-list.txt) to a new [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) | ✅ done | +| **2.** Create [Exit Gateway](/operators/community-counsel/exit-gateway): Take the `nym-gateway` binary including `nym-network-requester` combined in \#1 and switch from [`allowed.list`](https://nymtech.net/.wellknown/network-requester/standard-allowed-list.txt) to a new [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) | ✅ done | | **3.** Combine all the nodes in the Nym Mixnet into one binary, that is `nym-mixnode`, `nym-gateway` (entry and exit) and `nym-network-requester`. | ✅ done | | **4.** Adjust reward scheme to incentivise and reward Exit Gateways as a part of `nym-node` binary, implementing [zkNym credentials](https://youtu.be/nLmdsZ1BsQg?t=1717). | 🛠️ in progress | | **5.** Implement multiple node functionalities into one `nym-node` connected to one Nyx account. | 🛠️ in progress | @@ -40,7 +40,7 @@ We are exploring two potential methods for implementing binary functionality in ### Where can I read more about the Exit Gateway setup? -We created an [entire page](../../legal/exit-gateway.md) about the technical and legal questions around Exit Gateway. +We created an [entire page](/operators/community-counsel/exit-gateway) about the technical and legal questions around Exit Gateway. ### What is the change from allow list to deny list? diff --git a/documentation/docs/pages/operators/binaries/building-nym.mdx b/documentation/docs/pages/operators/binaries/building-nym.mdx index 2bda63a905..f730cfcdd8 100644 --- a/documentation/docs/pages/operators/binaries/building-nym.mdx +++ b/documentation/docs/pages/operators/binaries/building-nym.mdx @@ -12,7 +12,7 @@ Nym has two main codebases: - the [Nym platform](https://github.com/nymtech/nym), written in Rust. This contains all of our code _except_ for the validators. - the [Nym validators](https://github.com/nymtech/nyxd), written in Go. -> This page details how to build the main Nym platform code. **If you want to build and run a validator, [go here](../nodes/validator-setup.md) instead.** +> This page details how to build the main Nym platform code. **If you want to build and run a validator, [go here](../nodes/validator-setup) instead.** ## Prerequisites @@ -64,7 +64,7 @@ cargo build --release # build your binaries with **mainnet** configuration Quite a bit of stuff gets built. The key working parts are: -* [Nym Node](../nodes/nym-node/nym-node.mdx): `nym-node` +* [Nym Node](../nodes/nym-node): `nym-node` * [Validator](../nodes/validator-setup.mdx) * [websocket client](../../developers/clients/websocket): `nym-client` * [socks5 client](../../developers/clients/socks5): `nym-socks5-client` diff --git a/documentation/docs/pages/operators/changelog.mdx b/documentation/docs/pages/operators/changelog.mdx index 9ea5885dd6..3bb0c47815 100644 --- a/documentation/docs/pages/operators/changelog.mdx +++ b/documentation/docs/pages/operators/changelog.mdx @@ -72,7 +72,7 @@ cargo Profile: release **This release comes with breaking changes - please follow the [steps below](#oscypek-special-update) before upgrading!** -Secondly, the outcome of [NIP-7: Nym Exit Policy Update - Opening Ports for Steam, Discord & SSH](https://governator.nym.com/proposal/prop-281e9ec1-8e10-4e97-848c-311823e83f61), is added to the [Network tunnel manager (NTM)](https://github.com/nymtech/nym/blob/develop/scripts/nym-node-setup/network-tunnel-manager.sh) and operators are required to rerun the tool on their servers as [documented here](update-nym-exit-policy). +Secondly, the outcome of [NIP-7: Nym Exit Policy Update - Opening Ports for Steam, Discord & SSH](https://governator.nym.com/proposal/prop-281e9ec1-8e10-4e97-848c-311823e83f61), is added to the [Network tunnel manager (NTM)](https://github.com/nymtech/nym/blob/develop/scripts/nym-node-setup/network-tunnel-manager.sh) and operators are required to rerun the tool on their servers. #### `oscypek` special update @@ -4080,7 +4080,7 @@ Here are the aims of these tests: Meanwhile we started to research pricing of stronger servers with unlimited bandwidth and higher (and stable) port speed, to arrive to a better understanding of needed rewards and grants to bootstrap the network before NymVPN launch. -More info about testing and tools for performance monitoring can be found in [this chapter](testing/performance.md). +More info about testing and tools for performance monitoring can be found in [this chapter](performance-and-testing). > We would like to call out to operators to join the efforts and reach out to us if they know of solid ISPs who offer reliable dedicated services for good price or may even be interested in partnership. @@ -4641,11 +4641,11 @@ done ### Operators Guide, Tooling & Updates -- More explicit [setup for `nym-node`](nodes/setup.md#initialise--run) with a new [option explanation](nodes/setup.md#essential-parameters--variables), including syntax examples +- More explicit [setup for `nym-node`](nodes/nym-node/setup#initialise--run) with a new [option explanation](nodes/nym-node/setup#essential-parameters--variables), including syntax examples -- New [VPS networking configuration steps for Wireguard](nodes/configuration.md#routing-configuration) +- New [VPS networking configuration steps for Wireguard](nodes/nym-node/configuration#routing-configuration) -- Wireguard [builds from source](binaries/building-nym.md) together with `nym-node`, no need to specify with a feature flag anymore +- Wireguard [builds from source](binaries/building-nym) together with `nym-node`, no need to specify with a feature flag anymore - Wireguard peers stay connected for longer time, re-connections are also faster @@ -4684,12 +4684,12 @@ Every `nym-node` should be upgraded to the latest version! Operators can test us **`nym-node`** - Make sure to fill in basic description info, into the file located at `.nym/nym-nodes//data/description.toml` (all nodes) -- Configure wireguard routing with new [`network_tunnel_manager.sh`](https://github.com/nymtech/nym/blob/develop/scripts/network_tunnel_manager.sh) following [these steps](nodes/configuration.md#routing-configuration) (Gateways only for the time being) +- Configure wireguard routing with new [`network_tunnel_manager.sh`](https://github.com/nymtech/nym/blob/develop/scripts/network_tunnel_manager.sh) following [these steps](nodes/nym-node/configuration#routing-configuration) (Gateways only for the time being) - Enable Wireguard with `--wireguard-enabled true` flag included in your run command (Gateways only for the time being) - Note: On some VPS this setup may not be enough to get the correct results as some ISPs have their own security groups setup below the individual VPS. In that case a ticket to ISP will have to be issued to open the needed settings. We are working on a template for such ticket. -- Setup [reverse proxy and WSS](nodes/proxy-configuration.md) on `nym-node` (Gateways only for the time being) +- Setup [reverse proxy and WSS](nodes/nym-node/configuration/proxy-configuration) on `nym-node` (Gateways only for the time being) - Don't forget to restart your node - or (preferably using [systemd automation](nodes/nym-node/configuration.mdx#systemd)) reload daemon and restart the service -- Optional: Use [`nym-gateway-probe`](testing/gateway-probe.html) and [NymVPN CLI](https://nymtech.net/developers/nymvpn/cli.html) to test your own Gateway +- Optional: Use [`nym-gateway-probe`](performance-and-testing/gateway-probe) and [NymVPN CLI](https://nymtech.net/developers/nymvpn/cli.html) to test your own Gateway - Optional: Run the script below to measure ping speed of your Gateway and share your results in [Nym Operators channel](https://matrix.to/#/#operators:nymtech.chat) @@ -4878,7 +4878,7 @@ sudo -E ./nym-vpn-cli -c ../qa.env run --entry-gateway-id $entry_gateway --exit- ### Operators Guide updates -* [WireGuard tunnel configuration guide](nodes/configuration.md#routing-configuration) for `nym-node` (currently Gateways functionalities). For simplicity we made a detailed step by step guide to upgrade an existing `nym-node` to the latest version and configure your VPS routing for WireGuard. Open by clicking on the example block below. +* [WireGuard tunnel configuration guide](nodes/nym-node/configuration#routing-configuration) for `nym-node` (currently Gateways functionalities). For simplicity we made a detailed step by step guide to upgrade an existing `nym-node` to the latest version and configure your VPS routing for WireGuard. Open by clicking on the example block below. **Prerequisites** @@ -4943,7 +4943,7 @@ chmod u+x network_tunnel_manager.sh **Step 3: Update the Nym Node Service File** -1. Modify your [`nym-node` service file](nodes/configuration.md#systemd) to enable WireGuard. Open the file (usually located at `/etc/systemd/system/nym-node.service`) and update the `[Service]` section as follows: +1. Modify your [`nym-node` service file](nodes/nym-node/configuration#systemd) to enable WireGuard. Open the file (usually located at `/etc/systemd/system/nym-node.service`) and update the `[Service]` section as follows: ```ini [Service] @@ -4989,7 +4989,7 @@ Finally, run the following command to initiate our favorite routing test - run t - **Note:** Wireguard will return only IPv4 joke, not IPv6. WG IPv6 is under development. Running IPR joke through the mixnet with `./network_tunnel_manager.sh joke_through_the_mixnet` should work with both IPv4 and IPv6! -* [Change `--wireguard-enabled` flag to `true`](nodes/setup.md#-initialise--run): With a proper [routing configuration](nodes/configuration.md#routing-configuration) `nym-nodes` running as Gateways can now enable WG. See the example below: +* [Change `--wireguard-enabled` flag to `true`](nodes/nym-node/setup#initialise--run): With a proper [routing configuration](nodes/nym-node/configuration#routing-configuration) `nym-nodes` running as Gateways can now enable WG. See the example below: For Exit Gateway: @@ -5350,8 +5350,8 @@ bind_address = '0.0.0.0:9000' ### Operators Guide updates -- [Node description guide](nodes/configuration.md#node-description): Steps to add self-description to `nym-node` and query this information from any node. -- [Web Secure Socket (WSS) guide and reverse proxy update](nodes/proxy-configuration.md), PR [here](https://github.com/nymtech/nym/pull/4694): A guide to setup `nym-node` in a secure fashion, using WSS via Nginx and Certbot. Landing page (reversed proxy) is updated and simplified. +- [Node description guide](nodes/nym-node/configuration#node-description): Steps to add self-description to `nym-node` and query this information from any node. +- [Web Secure Socket (WSS) guide and reverse proxy update](nodes/nym-node/configuration/proxy-configuration), PR [here](https://github.com/nymtech/nym/pull/4694): A guide to setup `nym-node` in a secure fashion, using WSS via Nginx and Certbot. Landing page (reversed proxy) is updated and simplified. --- @@ -5551,16 +5551,16 @@ warning: /home/alice/src/nym/nym/common/dkg/Cargo.toml: `default-features` is ig ### Operators Guide updates -- [New Release Cycle](release-cycle.md) introduced: a transparent release flow, including: +- [New Release Cycle](release-cycle) introduced: a transparent release flow, including: - New environments - Stable testnet - [Testnet token faucet](https://nymtech.net/operators/sandbox.html#sandbox-token-faucet) - - Flow [chart](release-cycle.md#release-flow) -- [Sandbox testnet](sandbox.md) guide: teaching Nym node operators how to run their nodes in Nym Sandbox testnet environment. -- [Terms & Conditions flag](nodes/setup.md#terms--conditions) + - Flow [chart](release-cycle#release-flow) +- [Sandbox testnet](sandbox) guide: teaching Nym node operators how to run their nodes in Nym Sandbox testnet environment. +- [Terms & Conditions flag](nodes/nym-node/setup#terms--conditions) - Node API Check CLI -- [Pruning VPS `syslog` scripts](troubleshooting/vps-isp.md#pruning-logs) -- [Black-xit: Exiting the blacklist](troubleshooting/nodes.md#my-gateway-is-blacklisted) +- [Pruning VPS `syslog` scripts](troubleshooting/vps-isp#pruning-logs) +- [Black-xit: Exiting the blacklist](troubleshooting/nodes#my-gateway-is-blacklisted) --- @@ -5712,9 +5712,9 @@ called Result::unwrap() on an Err value: ClientCoreError(ValidatorClientError(Ny ### Operators Guide updates -- [`nym-gateway-probe`](testing/gateway-probe.md): A CLI tool to check in-real-time networking status of any Gateway locally. -- [Where to host your `nym-node`?](legal/isp-list.md): A list of Internet Service Providers (ISPs) by Nym Operators community. We invite all operators to add their experiences with different ISPs to strengthen the community knowledge and Nym mixnet performance. -- Make sure you run `nym-node` with `--wireguard-enabled false` and add a location description to your `config.toml`, both documented in [`nym-node` setup manual](nodes/setup.md#mode-exit-gateway). +- [`nym-gateway-probe`](performance-and-testing/gateway-probe): A CLI tool to check in-real-time networking status of any Gateway locally. +- [Where to host your `nym-node`?](community-counsel/isp-list): A list of Internet Service Providers (ISPs) by Nym Operators community. We invite all operators to add their experiences with different ISPs to strengthen the community knowledge and Nym mixnet performance. +- Make sure you run `nym-node` with `--wireguard-enabled false` and add a location description to your `config.toml`, both documented in [`nym-node` setup manual](nodes/nym-node/setup#mode-exit-gateway). --- @@ -5728,8 +5728,8 @@ called Result::unwrap() on an Err value: ClientCoreError(ValidatorClientError(Ny - Nym wallet changes: - Adding `nym-node` command to bonding screens - Fixed the delegation issues with fixing RPC -- [Network configuration](nodes/configuration.md#connectivity-test-and-configuration) section updates, in particular for `--mode mixnode` operators -- [VPS IPv6 troubleshooting](troubleshooting/vps-isp.md#ipv6-troubleshooting) updates +- [Network configuration](nodes/nym-node/configuration#connectivity-test-and-configuration) section updates, in particular for `--mode mixnode` operators +- [VPS IPv6 troubleshooting](troubleshooting/vps-isp#ipv6-troubleshooting) updates --- @@ -5740,8 +5740,8 @@ called Result::unwrap() on an Err value: ClientCoreError(ValidatorClientError(Ny - [`nym-node`](nodes/nym-node.mdx) initial release - New tool for monitoring Gateways performance [harbourmaster.nymtech.net](https://harbourmaster.nymtech.net) - New versioning `1.1.0+nymnode` mainly for internal migration testing, not essential for operational use. We aim to correct this in a future release to ensure mixnodes feature correctly in the main API -- New [VPS specs & configuration](nodes/vps-setup.md) page -- New [configuration page](nodes/configuration.md) with [connectivity setup guide](nodes/configuration.md#connectivity-test-and-configuration) - a new requirement for `exit-gateway` +- New [VPS specs & configuration](nodes/preliminary-steps/vps-setup) page +- New [configuration page](nodes/nym-node/configuration) with [connectivity setup guide](nodes/nym-node/configuration#connectivity-test-and-configuration) - a new requirement for `exit-gateway` - API endpoints redirection: Nym-mixnode and nym-gateway endpoints will eventually be deprecated; due to this, their endpoints will be redirected to new routes once the `nym-node` has been migrated and is running **API endpoints redirection** diff --git a/documentation/docs/pages/operators/community-counsel.mdx b/documentation/docs/pages/operators/community-counsel.mdx index c79555493c..46b46eacab 100644 --- a/documentation/docs/pages/operators/community-counsel.mdx +++ b/documentation/docs/pages/operators/community-counsel.mdx @@ -10,8 +10,8 @@ import { MyTab } from 'components/generic-tabs.tsx'; **The entire content of this section is under [Creative Commons Attribution 4.0 International Public License](https://creativecommons.org/licenses/by/4.0/).** -Running an Exit Gateway is a commitment and as such is exposed to various challenges. Besides different legal regulations typical difficulties may be dealing with VPS or ISP providers. Our strength lies in decentralised community of squads and individuals supporting each other. Sharing examples of [landing pages](landing-pages.md), templates for communication and FAQs is a great way to empower other operators sharing the mission of liberating internet. Below is a simple way how to create a pull request directly to Nym Operator Guide docs. +Running an Exit Gateway is a commitment and as such is exposed to various challenges. Besides different legal regulations typical difficulties may be dealing with VPS or ISP providers. Our strength lies in decentralised community of squads and individuals supporting each other. Sharing examples of [landing pages](community-counsel/landing-pages), templates for communication and FAQs is a great way to empower other operators sharing the mission of liberating internet. Below is a simple way how to create a pull request directly to Nym Operator Guide docs. ## How to add content -Our aim is to establish a strong community network, sharing legal findings and other suggestions with each other. We would like to encourage all of the current and future operators to do research about the situation in the jurisdiction they operate in as well as solutions to any challenges when running an Exit Gateway and add those through a pull request (PR). Please check out the [steps to make a pull request](add-content.md). +Our aim is to establish a strong community network, sharing legal findings and other suggestions with each other. We would like to encourage all of the current and future operators to do research about the situation in the jurisdiction they operate in as well as solutions to any challenges when running an Exit Gateway and add those through a pull request (PR). Please check out the [steps to make a pull request](community-counsel/add-content). diff --git a/documentation/docs/pages/operators/community-counsel/isp-list.mdx b/documentation/docs/pages/operators/community-counsel/isp-list.mdx index e3affcaabc..55a1f0e8fd 100644 --- a/documentation/docs/pages/operators/community-counsel/isp-list.mdx +++ b/documentation/docs/pages/operators/community-counsel/isp-list.mdx @@ -10,7 +10,7 @@ This ISP list is fully managed by Nym operator community and it serves as a spac Please share any experiences running a node like policies, complains, legal issues and solutions, discrepancy between offers and reality (bandwidth, IP range, locations) or anything regarding pricing or customer support. -If you came across any legal findings, please share them in our [list of jurisdictions](jurisdictions.md). +If you came across any legal findings, please share them in our [list of jurisdictions](jurisdictions). While we trust that Nym node operators are honest, we would like to ask everyone to do your own research. diff --git a/documentation/docs/pages/operators/community-counsel/legal.mdx b/documentation/docs/pages/operators/community-counsel/legal.mdx index f2f0d114d9..6edc156904 100644 --- a/documentation/docs/pages/operators/community-counsel/legal.mdx +++ b/documentation/docs/pages/operators/community-counsel/legal.mdx @@ -24,7 +24,7 @@ Write a message to your provider telling them about your intention to run a `nym #### Join Operators Legal Forum -This [Matrix channel]((https://matrix.to/#/!YfoUFsJjsXbWmijbPG:nymtech.chat?via=nymtech.chat&via=matrix.org&via=matrix.su4ka.icu)) is the best place to ask questions and share your experience with others. You can share screen prints of abuse reports and ask for support. +This [Matrix channel](https://matrix.to/#/!YfoUFsJjsXbWmijbPG:nymtech.chat?via=nymtech.chat&via=matrix.org&via=matrix.su4ka.icu) is the best place to ask questions and share your experience with others. You can share screen prints of abuse reports and ask for support. #### Join Operators Legal Clinic Do you have any questions directed for lawyers? Come and chat with Nym COO Alexis Roussel, every Wednesday 14:30 UTC for 60min in our [Operator Legal Forum channel on Matrix](https://matrix.to/#/!YfoUFsJjsXbWmijbPG:nymtech.chat?via=nymtech.chat&via=matrix.org&via=matrix.su4ka.icu). diff --git a/documentation/docs/pages/operators/introduction.mdx b/documentation/docs/pages/operators/introduction.mdx index 1ed3c1ffd5..8a564662fe 100644 --- a/documentation/docs/pages/operators/introduction.mdx +++ b/documentation/docs/pages/operators/introduction.mdx @@ -35,7 +35,7 @@ If you want to explore kickstart options and examples, learn how to integrate wi **Node setup and usage guides:** -* [Nym Node](nodes/nym-node/nym-node.mdx) +* [Nym Node](nodes/nym-node) * [Nymvisor](nodes/maintenance/nymvisor-upgrade.mdx) * [Validators](nodes/validator-setup.mdx) * [Nym API Setup](nodes/validator-setup/nym-api.mdx) diff --git a/documentation/docs/pages/operators/misc/toc.md b/documentation/docs/pages/operators/misc/toc.md index 298a297c1e..94e9e3f64e 100644 --- a/documentation/docs/pages/operators/misc/toc.md +++ b/documentation/docs/pages/operators/misc/toc.md @@ -6,4 +6,4 @@ There has been a long ongoing discussion whether and how to apply Terms and Cond Accepting T&Cs is done via an explicit flag `--accept-operator-terms-and-conditions` added to `nym-node run` command. -More information on how to setup your node or check whether any node has T&C accepted can be found in [`nym-node` setup guide](nodes/setup.md#terms--conditions). +More information on how to setup your node or check whether any node has T&C accepted can be found in [`nym-node` setup guide](/operators/nodes/nym-node/setup#terms--conditions). diff --git a/documentation/docs/pages/operators/nodes/maintenance.mdx b/documentation/docs/pages/operators/nodes/maintenance.mdx index a825b3ab32..fa3d902a61 100644 --- a/documentation/docs/pages/operators/nodes/maintenance.mdx +++ b/documentation/docs/pages/operators/nodes/maintenance.mdx @@ -448,7 +448,7 @@ scp -r -3 @:/etc/systemd/system/nym-node. Local node identifier, denoted as `` accross the documentation (not the identity key) is a name chosen by operators which defines where the nodes configuration data will be stored, where the ID determines the path to `~/.nym/nym-nodes//`. This ID is never shared on the network. -When running a [`nym-node`](nym-node/nym-node.mdx), a local identifier specified with a flag `--ID ` is no longer necessary. Nodes without a specified ID will be assigned a default ID `default-nym-node`. This streamlines node management, particularly for operators handling multiple nodes via ansible and other automation scripts, as all data is stored at `~/.nym/nym-nodes/default-nym-node`. +When running a [`nym-node`](nym-node), a local identifier specified with a flag `--ID ` is no longer necessary. Nodes without a specified ID will be assigned a default ID `default-nym-node`. This streamlines node management, particularly for operators handling multiple nodes via ansible and other automation scripts, as all data is stored at `~/.nym/nym-nodes/default-nym-node`. If you already operate a `nym-node` and wish to change the local ID to `default-nym-node` or anything else, follow the steps below to do so. diff --git a/documentation/docs/pages/operators/nodes/maintenance/manual-upgrade.mdx b/documentation/docs/pages/operators/nodes/maintenance/manual-upgrade.mdx index d2a99e5cbe..ed622d4ea1 100644 --- a/documentation/docs/pages/operators/nodes/maintenance/manual-upgrade.mdx +++ b/documentation/docs/pages/operators/nodes/maintenance/manual-upgrade.mdx @@ -8,7 +8,7 @@ import CliUpdate from 'components/operators/snippets/update-cli-steps.mdx' # Manual Node Upgrade -This page explains how to upgrade [`nym-node`](#nym-node-upgrade) or [`validator`](#validator-upgrade) to the latest version in a few steps. If you prefer to automate the process, try to setup your flow with [Nymvisor](nymvisor-upgrade.md). +This page explains how to upgrade [`nym-node`](#nym-node-upgrade) or [`validator`](#validator-upgrade) to the latest version in a few steps. If you prefer to automate the process, try to setup your flow with [Nymvisor](nymvisor-upgrade). diff --git a/documentation/docs/pages/operators/nodes/maintenance/nymvisor-upgrade/nymvisor-configuration.mdx b/documentation/docs/pages/operators/nodes/maintenance/nymvisor-upgrade/nymvisor-configuration.mdx index 3863c379d2..83488f1eeb 100644 --- a/documentation/docs/pages/operators/nodes/maintenance/nymvisor-upgrade/nymvisor-configuration.mdx +++ b/documentation/docs/pages/operators/nodes/maintenance/nymvisor-upgrade/nymvisor-configuration.mdx @@ -10,7 +10,7 @@ import { Steps } from 'nextra/components'; ## Nymvisor Automation with `systemd` -This section contains guide how to setup `systemd` automation for Nymvisor. If you are looking for other chapters, visit these pages: [VPS setup](../../../preliminrary-steps/vps-setup.mdx), advanced terminal tools like [tmux and nohup setup](../../nym-node/configuration.mdx#vps-setup-and-automation), [`nym-node` automation](../../nym-node/configuration.mdx#systemd) or [`validator` automation](../../validator-setup/nyx-configuration#automation). +This section contains guide how to setup `systemd` automation for Nymvisor. If you are looking for other chapters, visit these pages: [VPS setup](../../preliminary-steps/vps-setup), advanced terminal tools like [tmux and nohup setup](../../nym-node/configuration.mdx#vps-setup-and-automation), [`nym-node` automation](../../nym-node/configuration.mdx#systemd) or [`validator` automation](../../validator-setup/nyx-configuration#automation). Since you're planning to run your node via a Nymvisor instance, as well as creating a Nymvisor `.service` file, you will also want to **stop any previous node automation process you already have running**. diff --git a/documentation/docs/pages/operators/nodes/nym-node/setup.mdx b/documentation/docs/pages/operators/nodes/nym-node/setup.mdx index 971a629c0f..1f367a85fc 100644 --- a/documentation/docs/pages/operators/nodes/nym-node/setup.mdx +++ b/documentation/docs/pages/operators/nodes/nym-node/setup.mdx @@ -133,7 +133,7 @@ curl -X 'GET' \ #### Essential Parameters & Variables -Running a `nym-node` in a `mixnode` mode requires less configuration than a full `exit-gateway` setup, we recommend operators to still follow through with all documented [configuration](configuration.md). Before you scroll down to syntax examples for the mode of your choice please familiarise yourself with the essential [paramters and variables](../../variables.mdx) convention we use in the guide. +Running a `nym-node` in a `mixnode` mode requires less configuration than a full `exit-gateway` setup, we recommend operators to still follow through with all documented [configuration](configuration). Before you scroll down to syntax examples for the mode of your choice please familiarise yourself with the essential [paramters and variables](../../variables) convention we use in the guide. To prevent over-flooding of our documentation we cannot provide with every single command syntax as there is a large combination of possibilities. Please read the [variables and parameters page](../../variables.mdx), use the explanation in `--help` option and common sence. @@ -172,7 +172,7 @@ From `2024.14-crunch` release (`nym-node v1.2.0`) onward, `nym-node` binary does Furthermore, giving that legacy nodes had been deprecated for several months, Nym cannot promise 100% serialisation for operators migrating from long outdated versions. If you are about to migrate, start with [`nym-node v1.1.0`](https://github.com/nymtech/nym/releases/tag/nym-binaries-v2024.3-eclipse) and keep upgrading version by version all the way to the latest one. -Operators who are about to migrate their nodes need to configure their [VPS](vps-setup.md) and setup `nym-node` which can be downloaded as a [pre-built binary](../binaries/pre-built-binaries.md) or compiled from [source](../binaries/building-nym.md). +Operators who are about to migrate their nodes need to configure their [VPS](../preliminary-steps/vps-setup) and setup `nym-node` which can be downloaded as a [pre-built binary](../../binaries/pre-built-binaries) or compiled from [source](../../binaries/building-nym). To migrate a `nym-mixnode` or a `nym-gateway` to `nym-node` use, the `migrate` command with `--config-file` flag pointing to the original `config.toml` file, with a conditional argument defining which type of node this configuration belongs to. The exact steps are below. diff --git a/documentation/docs/pages/operators/nodes/preliminary-steps.mdx b/documentation/docs/pages/operators/nodes/preliminary-steps.mdx index 9a628d5810..ec460eefdc 100644 --- a/documentation/docs/pages/operators/nodes/preliminary-steps.mdx +++ b/documentation/docs/pages/operators/nodes/preliminary-steps.mdx @@ -1,6 +1,6 @@ # Preliminary Steps -> The `nym-node` binary was built in the [building nym](../binaries/building-nym.md) section. If you haven't yet built Nym and want to run the code, go there first. +> The `nym-node` binary was built in the [building nym](../binaries/building-nym) section. If you haven't yet built Nym and want to run the code, go there first. There are a couple of steps that need completing before starting to set up your `nym-node`: diff --git a/documentation/docs/pages/operators/sandbox.mdx b/documentation/docs/pages/operators/sandbox.mdx index 188c42541b..a46d76a35c 100644 --- a/documentation/docs/pages/operators/sandbox.mdx +++ b/documentation/docs/pages/operators/sandbox.mdx @@ -56,7 +56,7 @@ curl -o sandbox.env -L https://raw.githubusercontent.com/nymtech/nym/develop/env -1. If you [built Nym from source](../binaries/building-nym.md), you already have `sandbox.env` as a part of the monorepo (`nym/envs/sandbox.env`). Giving that you are likely to run `nym-node` from `nym/target/release`, the flag will look like this `--config-env-file ../../envs/sandbox.env` +1. If you [built Nym from source](binaries/building-nym), you already have `sandbox.env` as a part of the monorepo (`nym/envs/sandbox.env`). Giving that you are likely to run `nym-node` from `nym/target/release`, the flag will look like this `--config-env-file ../../envs/sandbox.env` 2. You can export the path to `sandbox.env` to your environmental variables: ```sh diff --git a/documentation/docs/pages/operators/tokenomics.mdx b/documentation/docs/pages/operators/tokenomics.mdx index 23f9e00517..c6235273de 100644 --- a/documentation/docs/pages/operators/tokenomics.mdx +++ b/documentation/docs/pages/operators/tokenomics.mdx @@ -21,7 +21,7 @@ import { AccordionTemplate } from 'components/accordion-template.tsx'; -Nym Network is composed of two main elements, the Mixnet represented by [Nym Nodes](nodes/nym-node/nym-node.mdx) routing and mixing the data packets, and Nyx blockchain distributted accros [validator set](tokenomics/validator-rewards.mdx), using smart contracts (based on [cosmwasm](https://cosmwasm.com/)) to monitor and reward Nym Nodes by querying API endpoints and distributing NYM token to operators according to work done by their nodes. All Nym nodes and validators are run by decentralised community of operators. +Nym Network is composed of two main elements, the Mixnet represented by [Nym Nodes](nodes/nym-node) routing and mixing the data packets, and Nyx blockchain distributted accros [validator set](tokenomics/validator-rewards.mdx), using smart contracts (based on [cosmwasm](https://cosmwasm.com/)) to monitor and reward Nym Nodes by querying API endpoints and distributing NYM token to operators according to work done by their nodes. All Nym nodes and validators are run by decentralised community of operators. * Nym tokenomics are based on the research paper [*Reward Sharing for Mixnets*](https://nym.com/nym-cryptoecon-paper.pdf) * For a more comprehensive overview, token live data and graphs, visit a community managed dashboard [*explorer.nym.spectredao.net/token*](https://explorer.nym.spectredao.net/dashboard) diff --git a/documentation/docs/pages/operators/tokenomics/mixnet-rewards.mdx b/documentation/docs/pages/operators/tokenomics/mixnet-rewards.mdx index ee1cd26ae6..86fd14f212 100644 --- a/documentation/docs/pages/operators/tokenomics/mixnet-rewards.mdx +++ b/documentation/docs/pages/operators/tokenomics/mixnet-rewards.mdx @@ -61,8 +61,8 @@ Nodes bonded with vesting tokens are [not allowed to join rewarded set](https:// This is a quick summary, to understand the logic behind fundamentals like [rewarded set selection](#rewarded-set-selection), [node performance](#mixnet-node-performance-calculation), [stake saturation](#stake-saturation), or [rewards calculation](#rewards-calculation), please read the chapters below. * **The current reward system is called [*Naive rewarding*](#naive-rewarding) - an intermediate step - where the operators of `nym-node` get rewarded from [Mixmining pool](https://validator.nymtech.net/api/v1/epoch/reward_params), which emits NYM per hour** -* **Only nodes selected to [rewarded set](../tokenomics.mdx#active-set) of Mixnet receive rewards** -* The [rewarded set](../tokenomics.mdx#active-set) of the Mixnet is currently **240 nodes in total and it's selected for each new epoch (60 min)**, from all the nodes registered (bonded) in the network +* **Only nodes selected to [rewarded set](../tokenomics#rewarded-set) of Mixnet receive rewards** +* The [rewarded set](../tokenomics#rewarded-set) of the Mixnet is currently **240 nodes in total and it's selected for each new epoch (60 min)**, from all the nodes registered (bonded) in the network * Each node gets the same proportion of work factor because of the *naive* distribution of work * In the [final model](#roadmap), nodes will get rewarded based on their layer position and the work they do (collected user tickets), where the work factor distribution per layer will be according to a [decision made by the operators](https://forum.nymtech.net/t/poll-what-should-be-the-split-of-mixmining-rewards-among-the-layers-of-the-nym-mixnet/407) as [listed below](#nym-network-rewarded-set-distribution) * If a node is selected to the rewarded set, it will be rewarded in the end of the epoch, based on this reward calculation formula: @@ -146,7 +146,7 @@ In reality there is a an additional value called **α**, giving a premium t | **Network layer** | **1** | **2** | | :-- | :---: | :---: | | Node functionality in layer | Entry Gateway | Exit Gateway | -| Naive rewarding: Nodes in [active set](tokenomics.mdx#active-set) | only Mixnet mode | only Mixnet mode | +| Naive rewarding: Nodes in [active set](../tokenomics#rewarded-set) | only Mixnet mode | only Mixnet mode | | Naive rewarding\*: Maximum work fraction per node | only Mixnet mode | only Mixnet mode | | Final model\*\*: Layer multiplier | 0.33 | 0.67 | diff --git a/documentation/docs/pages/operators/troubleshooting/nodes.mdx b/documentation/docs/pages/operators/troubleshooting/nodes.mdx index 0011a9a6b4..45b7b9793e 100644 --- a/documentation/docs/pages/operators/troubleshooting/nodes.mdx +++ b/documentation/docs/pages/operators/troubleshooting/nodes.mdx @@ -31,7 +31,7 @@ We have scripts which automatically include the Git commit hash and Git tag in t What to do? -* Follow the instructions in the Binaries section to [build nym from source](../binaries/building-nym.mdx) or [download precompiled binaries](../binaries/pre-build-binaries.mdx) +* Follow the instructions in the Binaries section to [build nym from source](../binaries/building-nym.mdx) or [download precompiled binaries](../binaries/pre-built-binaries.mdx) * To upgrade, follow the [upgrade instructions](../nodes/maintenance/manual-upgrade.mdx) ## General Node Config @@ -343,7 +343,7 @@ In case your Gateway appeared on the [blacklist](https://validator.nymtech.net/a **What to do** -Begin with a sanity check by opening [harbourmaster.nymtech.net](https://harbourmaster.nymtech.net) and check your node there. To see IPv4 and IPv6 routing in real time (harbourmaster can have a cache up to 90 min), run [Gateway Probe CLI](../testing/gateway-probe.mdx). +Begin with a sanity check by opening [harbourmaster.nymtech.net](https://harbourmaster.nymtech.net) and check your node there. To see IPv4 and IPv6 routing in real time (harbourmaster can have a cache up to 90 min), run [Gateway Probe CLI](../performance-and-testing/gateway-probe.mdx). Then follow these steps: @@ -412,7 +412,7 @@ https:///api/v1/swagger/#/ ###### 2. Configure IPv4 and IPv6 tables and rules -In case you haven't lately, follow the steps in the node [configuration](../nodes/nym-node/configuration.mdx) chapter [connectivity test and configurastion](../nodes/nym-nodes/configuration.mdx#connectivity-test-and-configuration). +In case you haven't lately, follow the steps in the node [configuration](../nodes/nym-node/configuration.mdx) chapter [connectivity test and configuration](../nodes/nym-node/configuration.mdx#connectivity-test-and-configuration). ###### 3. Test connectivity diff --git a/lychee.toml b/lychee.toml new file mode 100644 index 0000000000..42ea21812d --- /dev/null +++ b/lychee.toml @@ -0,0 +1,18 @@ +# This is a pre-commit linkchecker for the docs site +# +# Lychee is explicit with links, whereas NextJS resolves links w/out extensions to md(x) +fallback_extensions = ["mdx", "md"] + +# Root directory for resolving absolute paths (pages for content) +# Note: root_dir must be passed via CLI with absolute path in CI +# root_dir = "documentation/docs/pages/" + +# Remap /images to public/images for NextJS static assets +# Lychee resolves /images to pages/images, but Next.js serves from public/images +remap = ["pages/images public/images"] + +# Exclude component snippets (TODO: verify which are still in use) +exclude_path = ["components/"] + +# Only check local file links (skip external URLs for pre-commit speed) +scheme = ["file"] From 32402d64e8e9f1429eeda5763af6008e85b339cf Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Tue, 10 Feb 2026 12:00:02 +0000 Subject: [PATCH 15/56] remove doubled and bring up to date (#6443) * remove doubled and bring up to date * update readme * update build --- documentation/README.md | 26 ++++--- documentation/docs/README.md | 68 ------------------- .../circulating-supply.json | 4 +- .../nyx-outputs/circulating-supply.md | 2 +- .../nyx-outputs/epoch-reward-budget.md | 2 +- .../nyx-outputs/stake-saturation.md | 2 +- .../nyx-outputs/staking-target.md | 2 +- .../nyx-outputs/staking_supply.md | 2 +- .../nyx-outputs/token-table.md | 6 +- .../api-scraping-outputs/reward-params.json | 8 +-- .../outputs/api-scraping-outputs/time-now.md | 1 - .../node-api-check-query-help.md | 2 +- .../nym-node-cli-install-help.md | 3 +- .../command-outputs/nym-node-run-help.md | 4 ++ 14 files changed, 32 insertions(+), 100 deletions(-) delete mode 100644 documentation/docs/README.md delete mode 100644 documentation/docs/components/outputs/api-scraping-outputs/time-now.md diff --git a/documentation/README.md b/documentation/README.md index 776db65a21..b27ac7733d 100644 --- a/documentation/README.md +++ b/documentation/README.md @@ -2,7 +2,7 @@ This is v2 of the nym docs, condensed from various mdbooks projects that we had previously. -These docs are hosted at [nymtech.net/docs](www.nymtech.net/docs). +These docs are hosted at [nym.com/docs](https://nym.com/docs). ## Doc projects `docs/pages/` contains several subdirs, each hosting a subsection of the docs: @@ -11,6 +11,7 @@ These docs are hosted at [nymtech.net/docs](www.nymtech.net/docs). * `operators` contains node setup and maintenance guides. ## Local development + ### Dependencies Our `prebuild` script relies on the following: - `python` @@ -21,13 +22,10 @@ Our `prebuild` script relies on the following: Otherwise make sure to have `node` installed. -#### Binary dependencies -If you don't want/need build our binaries in Rust localy you can download them from latest Release page on [github](https://github.com/nymtech/nym/releases) into target/release in root of this repo. -{'nym-node', 'nym-api', 'nymvisor'} - -Make them executable -```bash -chmod +x target/release/* +### Link checking (optional) +We use [lychee](https://github.com/lycheeverse/lychee) to check for broken links. Install via your package manager or `cargo install lychee`, then run: +```sh +lychee documentation/docs/ --config lychee.toml --root-dir documentation/docs/pages/ ``` ### Serve Local (Hot Reload) @@ -43,27 +41,27 @@ Open `http://localhost:3000`. pnpm run build ``` -The static output will be in `./out`; - ## Contribution * If you wish to add to the documentation please create a PR against this repo, with a `patch` against `develop`. ## Scripts -* There are several autogenerated command files for clients and binaries. These are generated with `generate:commands`, which runs the `autodoc` rust binary, moves the files to their required places, and then if there is an update, commits them to git. This is for remote deployments. -* Python scripts TODO +* `generate:commands`: generates command output files for clients and binaries. This script runs the `autodoc` rust binary, moves the files to their required places, and then if there is an update, commits them to git. We commit the files as our remote deployments pull from a git repo. **Only run this script on branches where you want to push e.g. the build info of a binary to production docs**; it will build the monorepo binaries and use their command output for the produced markdown files. +* `generate:tables`: generates various information tables containing some repo-wide variables and information about ISPs. ### Autodoc `autodoc` is a script that generates markdown files containing commands and their output (both command and `--help` output). For the moment the binaries and their commands are manually configured in the script. +> **Only run this script on branches where you want to push e.g. the build info of a binary to production docs**; it will build the monorepo binaries and use their command output for the produced markdown files. + ## CI/CD -TODO +- **Link checking**: Runs on every push to `documentation/docs/` via `.github/workflows/ci-docs-linkcheck.yml` ## Licensing and copyright information This is a monorepo and components that make up Nym as a system are licensed individually, so for accurate information, please check individual files. As a general approach, licensing is as follows this pattern: -*

Nym Documentation by Nym Technologies is licensed under CC BY-NC-SA 4.0

+*

Nym Documentation by Nym Technologies is licensed under CC BY-NC-SA 4.0

* Nym applications and binaries are [GPL-3.0-only](https://www.gnu.org/licenses/) diff --git a/documentation/docs/README.md b/documentation/docs/README.md deleted file mode 100644 index b27ac7733d..0000000000 --- a/documentation/docs/README.md +++ /dev/null @@ -1,68 +0,0 @@ -# Nym Docs v2 - -This is v2 of the nym docs, condensed from various mdbooks projects that we had previously. - -These docs are hosted at [nym.com/docs](https://nym.com/docs). - -## Doc projects -`docs/pages/` contains several subdirs, each hosting a subsection of the docs: -* `network` contains key concepts, cryptosystems, architecture. -* `developers` contains key concepts for developers, required architecture, and Rust/Typescript SDK docs. -* `operators` contains node setup and maintenance guides. - -## Local development - -### Dependencies -Our `prebuild` script relies on the following: -- `python` -- `pip` -- [`pandas`](https://pandas.pydata.org/) -- [`tabulate`](https://pypi.org/project/tabulate/) -- `jq` - -Otherwise make sure to have `node` installed. - -### Link checking (optional) -We use [lychee](https://github.com/lycheeverse/lychee) to check for broken links. Install via your package manager or `cargo install lychee`, then run: -```sh -lychee documentation/docs/ --config lychee.toml --root-dir documentation/docs/pages/ -``` - -### Serve Local (Hot Reload) -```sh -pnpm i -pnpm run dev -``` - -Open `http://localhost:3000`. - -## Build -```sh -pnpm run build -``` - -## Contribution -* If you wish to add to the documentation please create a PR against this repo, with a `patch` against `develop`. - -## Scripts -* `generate:commands`: generates command output files for clients and binaries. This script runs the `autodoc` rust binary, moves the files to their required places, and then if there is an update, commits them to git. We commit the files as our remote deployments pull from a git repo. **Only run this script on branches where you want to push e.g. the build info of a binary to production docs**; it will build the monorepo binaries and use their command output for the produced markdown files. -* `generate:tables`: generates various information tables containing some repo-wide variables and information about ISPs. - -### Autodoc -`autodoc` is a script that generates markdown files containing commands and their output (both command and `--help` output). For the moment the binaries and their commands are manually configured in the script. - -> **Only run this script on branches where you want to push e.g. the build info of a binary to production docs**; it will build the monorepo binaries and use their command output for the produced markdown files. - -## CI/CD -- **Link checking**: Runs on every push to `documentation/docs/` via `.github/workflows/ci-docs-linkcheck.yml` - -## Licensing and copyright information -This is a monorepo and components that make up Nym as a system are licensed individually, so for accurate information, please check individual files. - -As a general approach, licensing is as follows this pattern: - -*

Nym Documentation by Nym Technologies is licensed under CC BY-NC-SA 4.0

- -* Nym applications and binaries are [GPL-3.0-only](https://www.gnu.org/licenses/) - -* Used libraries and different components are [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0.html) or [MIT](https://mit-license.org/) diff --git a/documentation/docs/components/outputs/api-scraping-outputs/circulating-supply.json b/documentation/docs/components/outputs/api-scraping-outputs/circulating-supply.json index df7471adde..1d29b76edf 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/circulating-supply.json +++ b/documentation/docs/components/outputs/api-scraping-outputs/circulating-supply.json @@ -5,7 +5,7 @@ }, "mixmining_reserve": { "denom": "unym", - "amount": "174592308324894" + "amount": "172542733168986" }, "vesting_tokens": { "denom": "unym", @@ -13,6 +13,6 @@ }, "circulating_supply": { "denom": "unym", - "amount": "825407691675106" + "amount": "827457266831014" } } diff --git a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/circulating-supply.md b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/circulating-supply.md index 91ff277f75..3747ac3017 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/circulating-supply.md +++ b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/circulating-supply.md @@ -1 +1 @@ -825_407_691 +827_457_266 diff --git a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/epoch-reward-budget.md b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/epoch-reward-budget.md index 5ef2576ddb..d38a8f0ca0 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/epoch-reward-budget.md +++ b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/epoch-reward-budget.md @@ -1 +1 @@ -4_849 +4_792 diff --git a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/stake-saturation.md b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/stake-saturation.md index 24d0944fa1..ed8f9dc9fe 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/stake-saturation.md +++ b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/stake-saturation.md @@ -1 +1 @@ -252_536 +253_163 diff --git a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/staking-target.md b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/staking-target.md index ffd684c3fa..dc4c855ff0 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/staking-target.md +++ b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/staking-target.md @@ -1 +1 @@ -60_608_795 +60_759_293 diff --git a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/staking_supply.md b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/staking_supply.md index 555068ef86..762d44b4ee 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/staking_supply.md +++ b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/staking_supply.md @@ -1 +1 @@ -60_608_794 +60_759_292 diff --git a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/token-table.md b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/token-table.md index c81a077a17..deab11591f 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/token-table.md +++ b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/token-table.md @@ -1,7 +1,7 @@ | **Item** | **Description** | **Amount in NYM** | |:-------------------|:------------------------------------------------------|--------------------:| | Total Supply | Maximum amount of NYM token in existence | 1_000_000_000 | -| Mixmining Reserve | Tokens releasing for operators rewards | 174_592_308 | +| Mixmining Reserve | Tokens releasing for operators rewards | 172_542_733 | | Vesting Tokens | Tokens locked outside of cicrulation for future claim | 0 | -| Circulating Supply | Amount of unlocked tokens | 825_407_691 | -| Stake Saturation | Optimal size of node self-bond + delegation | 252_536 | +| Circulating Supply | Amount of unlocked tokens | 827_457_266 | +| Stake Saturation | Optimal size of node self-bond + delegation | 253_163 | diff --git a/documentation/docs/components/outputs/api-scraping-outputs/reward-params.json b/documentation/docs/components/outputs/api-scraping-outputs/reward-params.json index ae0a8aa8aa..1092b27856 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/reward-params.json +++ b/documentation/docs/components/outputs/api-scraping-outputs/reward-params.json @@ -1,10 +1,10 @@ { "interval": { - "reward_pool": "174592308324894.719164125613282609", - "staking_supply": "60608794397902.33807512267258462", + "reward_pool": "172542733168986.886192478589145223", + "staking_supply": "60759292488059.481869771104188242", "staking_supply_scale_factor": "0.07342892", - "epoch_reward_budget": "4849786342.358186643447933702", - "stake_saturation_point": "252536643324.593075313011135769", + "epoch_reward_budget": "4792853699.138524616457738587", + "stake_saturation_point": "253163718700.247841124046267451", "sybil_resistance": "0.3", "active_set_work_factor": "10", "interval_pool_emission": "0.02" diff --git a/documentation/docs/components/outputs/api-scraping-outputs/time-now.md b/documentation/docs/components/outputs/api-scraping-outputs/time-now.md deleted file mode 100644 index 8e121587e5..0000000000 --- a/documentation/docs/components/outputs/api-scraping-outputs/time-now.md +++ /dev/null @@ -1 +0,0 @@ -Wednesday, January 28th 2026, 09:28:07 UTC diff --git a/documentation/docs/components/outputs/command-outputs/node-api-check-query-help.md b/documentation/docs/components/outputs/command-outputs/node-api-check-query-help.md index bfa068ddb0..999f3d4a6f 100644 --- a/documentation/docs/components/outputs/command-outputs/node-api-check-query-help.md +++ b/documentation/docs/components/outputs/command-outputs/node-api-check-query-help.md @@ -11,7 +11,7 @@ options: --no_routing_history Display node stats without routing history --no_verloc_metrics Display node stats without verloc metrics -m, --markdown Display results in markdown format - -o [OUTPUT], --output [OUTPUT] + -o, --output [OUTPUT] Save results to file (in current dir or supply with path without filename) ``` diff --git a/documentation/docs/components/outputs/command-outputs/nym-node-cli-install-help.md b/documentation/docs/components/outputs/command-outputs/nym-node-cli-install-help.md index 70baf6f736..ddc7c867b3 100644 --- a/documentation/docs/components/outputs/command-outputs/nym-node-cli-install-help.md +++ b/documentation/docs/components/outputs/command-outputs/nym-node-cli-install-help.md @@ -12,8 +12,7 @@ usage: nym-node-cli install [-h] [-V] [-d BRANCH] [-v] options: -h, --help show this help message and exit -V, --version show program's version number and exit - -d BRANCH, --dev BRANCH - Define github branch (default: develop) + -d, --dev BRANCH Define github branch (default: develop) -v, --verbose Show full error tracebacks --mode {mixnode,entry-gateway,exit-gateway} Node mode: 'mixnode', 'entry-gateway', or 'exit- diff --git a/documentation/docs/components/outputs/command-outputs/nym-node-run-help.md b/documentation/docs/components/outputs/command-outputs/nym-node-run-help.md index ab11bb896e..1d0b089b38 100644 --- a/documentation/docs/components/outputs/command-outputs/nym-node-run-help.md +++ b/documentation/docs/components/outputs/command-outputs/nym-node-run-help.md @@ -62,6 +62,8 @@ Options: Tunnel port announced to external clients wishing to connect to the wireguard interface. Useful in the instances where the node is behind a proxy [env: NYMNODE_WG_ANNOUNCED_PORT=] --wireguard-private-network-prefix The prefix denoting the maximum number of the clients that can be connected via Wireguard. The maximum value for IPv4 is 32 and for IPv6 is 128 [env: NYMNODE_WG_PRIVATE_NETWORK_PREFIX=] + --wireguard-userspace + Use userspace implementation of WireGuard (wireguard-go) instead of kernel module. Useful in containerized environments without kernel WireGuard support [env: NYMNODE_WG_USERSPACE=] [possible values: true, false] --verloc-bind-address Socket address this node will use for binding its verloc API. default: `[::]:1790` [env: NYMNODE_VERLOC_BIND_ADDRESS=] --verloc-announce-port @@ -80,6 +82,8 @@ Options: Endpoint to query to retrieve current upgrade mode attestation. This argument should never be set outside testnets and local networks [env: NYMNODE_UPGRADE_MODE_ATTESTATION_URL=] --upgrade-mode-attester-public-key Expected public key of the entity signing the published attestation. This argument should never be set outside testnets and local networks [env: NYMNODE_UPGRADE_MODE_ATTESTER_PUBKEY=] + --lp-use-mock-ecash + Use mock ecash manager for LP testing. WARNING: Only use this for local testing! Never enable in production. When enabled, the LP listener will accept any credential without blockchain verification [env: NYMNODE_LP_USE_MOCK_ECASH=] [possible values: true, false] --upstream-exit-policy-url Specifies the url for an upstream source of the exit policy used by this node [env: NYMNODE_UPSTREAM_EXIT_POLICY=] --open-proxy From 73bc746cd69572ad0118f10d6854eb582c401b14 Mon Sep 17 00:00:00 2001 From: merve Date: Tue, 10 Feb 2026 15:31:06 +0300 Subject: [PATCH 16/56] Update changelog for v2026.3-parmigiano --- .../docs/pages/operators/changelog.mdx | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/documentation/docs/pages/operators/changelog.mdx b/documentation/docs/pages/operators/changelog.mdx index 3bb0c47815..a1df2a43c0 100644 --- a/documentation/docs/pages/operators/changelog.mdx +++ b/documentation/docs/pages/operators/changelog.mdx @@ -49,6 +49,63 @@ This page displays a full list of all the changes during our release cycle from +## `v2026.3-parmigiano` +- [Release Binaries](https://github.com/nymtech/nym/releases/tag/nym-binaries-v2026.3-parmigiano) +- [`nym-node`](nodes/nym-node.mdx) version `1.25.0` + +```sh +nym-node +Binary Name: nym-node +Build Timestamp: 2026-01-27T14:54:15.579821601Z +Build Version: 1.25.0 +Commit SHA: 1ecb457c66ccabc4877e3822566f266c7331d29e +Commit Date: 2026-02-10T15:46:52.000000000+01:00 +Commit Branch: HEAD +rustc Version: 1.91.1 +rustc Channel: stable +cargo Profile: release +``` + +### Operators Updates & Tools + + **This release contains several important fixes and improvements for mixnet gateway probes, LP clients, and registration flows. Operators are encouraged to review the LP and gateway probe changes to ensure smooth node operation.** + +NOTE: Some LP configuration and registration fixes may require operator attention to maintain compatibility with the latest nym-node and VPN clients. Monitor your nodes closely after updating. + + +### Key updates for operators include: + +LP Gateway and Client fixes: + +- [Registration client now properly supports fallback](https://github.com/nymtech/nym/pull/6419) +- [Exposed WireGuard PSK for vpn-client](https://github.com/nymtech/nym/pull/6411) +- [Configurable LP timeouts](https://github.com/nymtech/nym/pull/6409) +- [LP x25519 key added to descriptions](https://github.com/nymtech/nym/pull/6408) +- [Improved CLI and behavior for LP Gateway Probe](https://github.com/nymtech/nym/pull/6400) + +Mixnet & Networking Enhancements: + +- [NS API Socks5 support](https://github.com/nymtech/nym/pull/6361) +- [Two-step dvpn registration flow](https://github.com/nymtech/nym/pull/6386) +- [DVPN PSK injection](https://github.com/nymtech/nym/pull/6378) + +Security & Encoding Improvements: + +- [Hex-encoding for LP key digests](https://github.com/nymtech/nym/pull/6394) +- [Encrypted KKT](https://github.com/nymtech/nym/pull/6331) +- [Reject packets with incompatible versions](https://github.com/nymtech/nym/pull/6326) + +Bugfixes & Quality-of-Life: + +- [Share IP allocation fixes](https://github.com/nymtech/nym/pull/6395) +- [Mixnet registration fixes](https://github.com/nymtech/nym/pull/6356) +- [Small QoL changes](https://github.com/nymtech/nym/pull/6340) + +Chores & Maintenance: + +- [Cleanup x25519/ed22519 usage](https://github.com/nymtech/nym/pull/6335) +- [Upgrade to def_guard_wireguard v0.8.0](https://github.com/nymtech/nym/pull/6315) + ## `v2026.2-oscypek` - [Release Binaries](https://github.com/nymtech/nym/releases/tag/nym-binaries-v2026.2-oscypek) From 4222a7b684455498db2e2434037da6a1be814b6a Mon Sep 17 00:00:00 2001 From: Merve <111695676+merve64@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:50:01 +0300 Subject: [PATCH 17/56] Update changelog.mdx --- documentation/docs/pages/operators/changelog.mdx | 1 - 1 file changed, 1 deletion(-) diff --git a/documentation/docs/pages/operators/changelog.mdx b/documentation/docs/pages/operators/changelog.mdx index a1df2a43c0..630790c04c 100644 --- a/documentation/docs/pages/operators/changelog.mdx +++ b/documentation/docs/pages/operators/changelog.mdx @@ -80,7 +80,6 @@ LP Gateway and Client fixes: - [Registration client now properly supports fallback](https://github.com/nymtech/nym/pull/6419) - [Exposed WireGuard PSK for vpn-client](https://github.com/nymtech/nym/pull/6411) - [Configurable LP timeouts](https://github.com/nymtech/nym/pull/6409) -- [LP x25519 key added to descriptions](https://github.com/nymtech/nym/pull/6408) - [Improved CLI and behavior for LP Gateway Probe](https://github.com/nymtech/nym/pull/6400) Mixnet & Networking Enhancements: From bb24b5e91d7fc8ccd801ae77571e4f8562b301fc Mon Sep 17 00:00:00 2001 From: Merve <111695676+merve64@users.noreply.github.com> Date: Tue, 10 Feb 2026 16:23:52 +0300 Subject: [PATCH 18/56] Update changelog.mdx --- documentation/docs/pages/operators/changelog.mdx | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/documentation/docs/pages/operators/changelog.mdx b/documentation/docs/pages/operators/changelog.mdx index 630790c04c..21cdcfa2d5 100644 --- a/documentation/docs/pages/operators/changelog.mdx +++ b/documentation/docs/pages/operators/changelog.mdx @@ -56,23 +56,16 @@ This page displays a full list of all the changes during our release cycle from ```sh nym-node Binary Name: nym-node -Build Timestamp: 2026-01-27T14:54:15.579821601Z +Build Timestamp: 2026-02-10T10:41:14.958988176Z Build Version: 1.25.0 Commit SHA: 1ecb457c66ccabc4877e3822566f266c7331d29e -Commit Date: 2026-02-10T15:46:52.000000000+01:00 +Commit Date: 2026-02-10T10:30:45.000000000+01:00 Commit Branch: HEAD rustc Version: 1.91.1 rustc Channel: stable cargo Profile: release ``` -### Operators Updates & Tools - - **This release contains several important fixes and improvements for mixnet gateway probes, LP clients, and registration flows. Operators are encouraged to review the LP and gateway probe changes to ensure smooth node operation.** - -NOTE: Some LP configuration and registration fixes may require operator attention to maintain compatibility with the latest nym-node and VPN clients. Monitor your nodes closely after updating. - - ### Key updates for operators include: LP Gateway and Client fixes: From 470282612b4dbb3d4db812a3f24f7e15fc830fd3 Mon Sep 17 00:00:00 2001 From: Merve <111695676+merve64@users.noreply.github.com> Date: Tue, 10 Feb 2026 16:34:31 +0300 Subject: [PATCH 19/56] Update changelog.mdx --- documentation/docs/pages/operators/changelog.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/documentation/docs/pages/operators/changelog.mdx b/documentation/docs/pages/operators/changelog.mdx index 21cdcfa2d5..677cdaafc9 100644 --- a/documentation/docs/pages/operators/changelog.mdx +++ b/documentation/docs/pages/operators/changelog.mdx @@ -75,6 +75,8 @@ LP Gateway and Client fixes: - [Configurable LP timeouts](https://github.com/nymtech/nym/pull/6409) - [Improved CLI and behavior for LP Gateway Probe](https://github.com/nymtech/nym/pull/6400) +Note: This code is currently deactivated and doesn’t involve any changes for operators right now, but it will in the future. + Mixnet & Networking Enhancements: - [NS API Socks5 support](https://github.com/nymtech/nym/pull/6361) From b0d01ec12a1b619156028ae4ae505a7cbb0afc7c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:48:30 +0000 Subject: [PATCH 20/56] build(deps-dev): bump webpack in /wasm/client/internal-dev (#6435) Bumps [webpack](https://github.com/webpack/webpack) from 5.98.0 to 5.105.0. - [Release notes](https://github.com/webpack/webpack/releases) - [Changelog](https://github.com/webpack/webpack/blob/main/CHANGELOG.md) - [Commits](https://github.com/webpack/webpack/compare/v5.98.0...v5.105.0) --- updated-dependencies: - dependency-name: webpack dependency-version: 5.105.0 dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- wasm/client/internal-dev/package-lock.json | 220 +++++++++++---------- wasm/client/internal-dev/yarn.lock | 179 +++++++++-------- 2 files changed, 214 insertions(+), 185 deletions(-) diff --git a/wasm/client/internal-dev/package-lock.json b/wasm/client/internal-dev/package-lock.json index b098c510c6..5652306177 100644 --- a/wasm/client/internal-dev/package-lock.json +++ b/wasm/client/internal-dev/package-lock.json @@ -37,18 +37,14 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", - "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { @@ -61,20 +57,10 @@ "node": ">=6.0.0" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", "dev": true, "license": "MIT", "dependencies": { @@ -83,16 +69,16 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", "dependencies": { @@ -214,9 +200,9 @@ } }, "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true, "license": "MIT" }, @@ -256,9 +242,9 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true, "license": "MIT" }, @@ -567,9 +553,9 @@ } }, "node_modules/acorn": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", - "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", "bin": { @@ -579,13 +565,25 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, "node_modules/ajv": { "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -669,6 +667,16 @@ "dev": true, "license": "MIT" }, + "node_modules/baseline-browser-mapping": { + "version": "2.9.19", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", + "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, "node_modules/batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", @@ -759,9 +767,9 @@ } }, "node_modules/browserslist": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", - "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "dev": true, "funding": [ { @@ -778,12 +786,12 @@ } ], "license": "MIT", - "peer": true, "dependencies": { - "caniuse-lite": "^1.0.30001688", - "electron-to-chromium": "^1.5.73", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.1" + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" @@ -841,9 +849,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001704", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001704.tgz", - "integrity": "sha512-+L2IgBbV6gXB4ETf0keSvLr7JUrRVbIaB/lrQ1+z8mRcQiisG5k+lG6O4n6Y5q6f5EuNfaYXKgymucphlEXQew==", + "version": "1.0.30001769", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz", + "integrity": "sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==", "dev": true, "funding": [ { @@ -1201,9 +1209,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.116", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.116.tgz", - "integrity": "sha512-mufxTCJzLBQVvSdZzX1s5YAuXsN1M4tTyYxOOL1TcSKtIzQ9rjIrm7yFK80rN5dwGTePgdoABDSHpuVtRQh0Zw==", + "version": "1.5.286", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz", + "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==", "dev": true, "license": "ISC" }, @@ -1218,14 +1226,14 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.18.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", - "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "version": "5.19.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz", + "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==", "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "tapable": "^2.3.0" }, "engines": { "node": ">=10.13.0" @@ -1265,9 +1273,9 @@ } }, "node_modules/es-module-lexer": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", - "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", + "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", "dev": true, "license": "MIT" }, @@ -2263,13 +2271,17 @@ } }, "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", "dev": true, "license": "MIT", "engines": { "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/locate-path": { @@ -2484,9 +2496,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", "dev": true, "license": "MIT" }, @@ -3064,9 +3076,9 @@ "license": "MIT" }, "node_modules/schema-utils": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", - "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", "dev": true, "license": "MIT", "dependencies": { @@ -3564,24 +3576,28 @@ } }, "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", "dev": true, "license": "MIT", "engines": { "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/terser": { - "version": "5.39.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz", - "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==", + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", + "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", + "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -3593,9 +3609,9 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.14", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", - "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", + "version": "5.3.16", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", + "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", "dev": true, "license": "MIT", "dependencies": { @@ -3682,9 +3698,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { @@ -3760,9 +3776,9 @@ } }, "node_modules/watchpack": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", - "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", + "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", "dev": true, "license": "MIT", "dependencies": { @@ -3784,36 +3800,37 @@ } }, "node_modules/webpack": { - "version": "5.98.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.98.0.tgz", - "integrity": "sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==", + "version": "5.105.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.0.tgz", + "integrity": "sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", - "@types/estree": "^1.0.6", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.14.0", - "browserslist": "^4.24.0", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.1", - "es-module-lexer": "^1.2.1", + "enhanced-resolve": "^5.19.0", + "es-module-lexer": "^2.0.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", + "loader-runner": "^4.3.1", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^4.3.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.11", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.16", + "watchpack": "^2.5.1", + "webpack-sources": "^3.3.3" }, "bin": { "webpack": "bin/webpack.js" @@ -3837,7 +3854,6 @@ "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/configtest": "^1.2.0", @@ -3989,9 +4005,9 @@ } }, "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", "dev": true, "license": "MIT", "engines": { diff --git a/wasm/client/internal-dev/yarn.lock b/wasm/client/internal-dev/yarn.lock index c736c8af03..844562e88a 100644 --- a/wasm/client/internal-dev/yarn.lock +++ b/wasm/client/internal-dev/yarn.lock @@ -122,10 +122,10 @@ "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*", "@types/estree@^1.0.6": - version "1.0.6" - resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz" - integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== +"@types/estree@*", "@types/estree@^1.0.8": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" + integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": version "4.17.33" @@ -153,10 +153,10 @@ dependencies: "@types/node" "*" -"@types/json-schema@*", "@types/json-schema@^7.0.9": - version "7.0.11" - resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz" - integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== +"@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.9": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== "@types/mime@*": version "3.0.1" @@ -368,10 +368,15 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: mime-types "~2.1.34" negotiator "0.6.3" -acorn@^8.14.0, acorn@^8.8.2: - version "8.14.1" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz" - integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg== +acorn-import-phases@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz#16eb850ba99a056cb7cbfe872ffb8972e18c8bd7" + integrity sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ== + +acorn@^8.15.0, acorn@^8.8.2: + version "8.15.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" + integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== ajv-formats@^2.1.1: version "2.1.1" @@ -425,6 +430,11 @@ balanced-match@^1.0.0: resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +baseline-browser-mapping@^2.9.0: + version "2.9.19" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz#3e508c43c46d961eb4d7d2e5b8d1dd0f9ee4f488" + integrity sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg== + batch@0.6.1: version "0.6.1" resolved "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz" @@ -478,15 +488,16 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.24.0: - version "4.24.4" - resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz" - integrity sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A== +browserslist@^4.28.1: + version "4.28.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.1.tgz#7f534594628c53c63101079e27e40de490456a95" + integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA== dependencies: - caniuse-lite "^1.0.30001688" - electron-to-chromium "^1.5.73" - node-releases "^2.0.19" - update-browserslist-db "^1.1.1" + baseline-browser-mapping "^2.9.0" + caniuse-lite "^1.0.30001759" + electron-to-chromium "^1.5.263" + node-releases "^2.0.27" + update-browserslist-db "^1.2.0" buffer-from@^1.0.0: version "1.1.2" @@ -519,10 +530,10 @@ call-bound@^1.0.2: call-bind-apply-helpers "^1.0.2" get-intrinsic "^1.3.0" -caniuse-lite@^1.0.30001688: - version "1.0.30001704" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001704.tgz" - integrity sha512-+L2IgBbV6gXB4ETf0keSvLr7JUrRVbIaB/lrQ1+z8mRcQiisG5k+lG6O4n6Y5q6f5EuNfaYXKgymucphlEXQew== +caniuse-lite@^1.0.30001759: + version "1.0.30001769" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz#1ad91594fad7dc233777c2781879ab5409f7d9c2" + integrity sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg== chokidar@^3.5.3: version "3.5.3" @@ -725,10 +736,10 @@ ee-first@1.1.1: resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -electron-to-chromium@^1.5.73: - version "1.5.116" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.116.tgz" - integrity sha512-mufxTCJzLBQVvSdZzX1s5YAuXsN1M4tTyYxOOL1TcSKtIzQ9rjIrm7yFK80rN5dwGTePgdoABDSHpuVtRQh0Zw== +electron-to-chromium@^1.5.263: + version "1.5.286" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz#142be1ab5e1cd5044954db0e5898f60a4960384e" + integrity sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A== encodeurl@~1.0.2: version "1.0.2" @@ -740,13 +751,13 @@ encodeurl@~2.0.0: resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz" integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== -enhanced-resolve@^5.17.1: - version "5.18.1" - resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz" - integrity sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg== +enhanced-resolve@^5.19.0: + version "5.19.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz#6687446a15e969eaa63c2fa2694510e17ae6d97c" + integrity sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg== dependencies: graceful-fs "^4.2.4" - tapable "^2.2.0" + tapable "^2.3.0" envinfo@^7.7.3: version "7.8.1" @@ -763,10 +774,10 @@ es-errors@^1.3.0: resolved "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz" integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== -es-module-lexer@^1.2.1: - version "1.6.0" - resolved "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz" - integrity sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ== +es-module-lexer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-2.0.0.tgz#f657cd7a9448dcdda9c070a3cb75e5dc1e85f5b1" + integrity sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw== es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: version "1.1.1" @@ -1321,10 +1332,10 @@ launch-editor@^2.6.0: picocolors "^1.0.0" shell-quote "^1.7.3" -loader-runner@^4.2.0: - version "4.3.0" - resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz" - integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== +loader-runner@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.1.tgz#6c76ed29b0ccce9af379208299f07f876de737e3" + integrity sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q== locate-path@^5.0.0: version "5.0.0" @@ -1450,10 +1461,10 @@ node-forge@^1: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.2.tgz#d0d2659a26eef778bf84d73e7f55c08144ee7750" integrity sha512-6xKiQ+cph9KImrRh0VsjH2d8/GXA4FIMlgU4B757iI1ApvcyA9VlouP0yZJha01V+huImO+kKMU7ih+2+E14fw== -node-releases@^2.0.19: - version "2.0.19" - resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz" - integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw== +node-releases@^2.0.27: + version "2.0.27" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e" + integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" @@ -1749,10 +1760,10 @@ safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -schema-utils@^4.0.0, schema-utils@^4.3.0: - version "4.3.0" - resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz" - integrity sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g== +schema-utils@^4.0.0, schema-utils@^4.3.0, schema-utils@^4.3.3: + version "4.3.3" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.3.tgz#5b1850912fa31df90716963d45d9121fdfc09f46" + integrity sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA== dependencies: "@types/json-schema" "^7.0.9" ajv "^8.9.0" @@ -1990,15 +2001,15 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -tapable@^2.1.1, tapable@^2.2.0: - version "2.2.1" - resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz" - integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== +tapable@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.0.tgz#7e3ea6d5ca31ba8e078b560f0d83ce9a14aa8be6" + integrity sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg== -terser-webpack-plugin@^5.3.11: - version "5.3.14" - resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz" - integrity sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw== +terser-webpack-plugin@^5.3.16: + version "5.3.16" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz#741e448cc3f93d8026ebe4f7ef9e4afacfd56330" + integrity sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q== dependencies: "@jridgewell/trace-mapping" "^0.3.25" jest-worker "^27.4.5" @@ -2046,10 +2057,10 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== -update-browserslist-db@^1.1.1: - version "1.1.3" - resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz" - integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw== +update-browserslist-db@^1.2.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz#64d76db58713136acbeb4c49114366cc6cc2e80d" + integrity sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w== dependencies: escalade "^3.2.0" picocolors "^1.1.1" @@ -2081,10 +2092,10 @@ vary@~1.1.2: resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== -watchpack@^2.4.1: - version "2.4.2" - resolved "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz" - integrity sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw== +watchpack@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.5.1.tgz#dd38b601f669e0cbf567cb802e75cead82cde102" + integrity sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg== dependencies: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" @@ -2169,39 +2180,41 @@ webpack-merge@^5.7.3: clone-deep "^4.0.1" wildcard "^2.0.0" -webpack-sources@^3.2.3: - version "3.2.3" - resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz" - integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== +webpack-sources@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.3.tgz#d4bf7f9909675d7a070ff14d0ef2a4f3c982c723" + integrity sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg== webpack@^5.70.0: - version "5.98.0" - resolved "https://registry.npmjs.org/webpack/-/webpack-5.98.0.tgz" - integrity sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA== + version "5.105.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.105.0.tgz#38b5e6c5db8cbe81debbd16e089335ada05ea23a" + integrity sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw== dependencies: "@types/eslint-scope" "^3.7.7" - "@types/estree" "^1.0.6" + "@types/estree" "^1.0.8" + "@types/json-schema" "^7.0.15" "@webassemblyjs/ast" "^1.14.1" "@webassemblyjs/wasm-edit" "^1.14.1" "@webassemblyjs/wasm-parser" "^1.14.1" - acorn "^8.14.0" - browserslist "^4.24.0" + acorn "^8.15.0" + acorn-import-phases "^1.0.3" + browserslist "^4.28.1" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.17.1" - es-module-lexer "^1.2.1" + enhanced-resolve "^5.19.0" + es-module-lexer "^2.0.0" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" graceful-fs "^4.2.11" json-parse-even-better-errors "^2.3.1" - loader-runner "^4.2.0" + loader-runner "^4.3.1" mime-types "^2.1.27" neo-async "^2.6.2" - schema-utils "^4.3.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.3.11" - watchpack "^2.4.1" - webpack-sources "^3.2.3" + schema-utils "^4.3.3" + tapable "^2.3.0" + terser-webpack-plugin "^5.3.16" + watchpack "^2.5.1" + webpack-sources "^3.3.3" websocket-driver@>=0.5.1, websocket-driver@^0.7.4: version "0.7.4" From fd47ebfad095f02eefccb2c1ddd158852d57fe69 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:48:56 +0000 Subject: [PATCH 21/56] build(deps): bump time from 0.3.41 to 0.3.47 in /nym-wallet (#6433) Bumps [time](https://github.com/time-rs/time) from 0.3.41 to 0.3.47. - [Release notes](https://github.com/time-rs/time/releases) - [Changelog](https://github.com/time-rs/time/blob/main/CHANGELOG.md) - [Commits](https://github.com/time-rs/time/compare/v0.3.41...v0.3.47) --- updated-dependencies: - dependency-name: time dependency-version: 0.3.47 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.toml | 2 +- nym-wallet/Cargo.lock | 377 ++++++++++++++++++++++++-------- nym-wallet/src-tauri/Cargo.toml | 2 +- 3 files changed, 290 insertions(+), 91 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3d3a7636d7..2bf995abc0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -353,7 +353,7 @@ tar = "0.4.44" test-with = { version = "0.15.4", default-features = false } tempfile = "3.20" thiserror = "2.0" -time = "0.3.41" +time = "0.3.47" tls_codec = "0.4.1" tokio = "1.47" tokio-postgres = "0.7" diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 6f4ebfbc81..f18537b669 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -602,6 +602,28 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "aws-lc-rs" +version = "1.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b7b6141e96a8c160799cc2d5adecd5cbbe5054cb8c7c4af53da0f83bb7ad256" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c34dda4df7017c8db52132f0f8a2e0f8161649d15723ed63fc00c82d0f2081a" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", +] + [[package]] name = "backtrace" version = "0.3.74" @@ -970,10 +992,11 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.17" +version = "1.2.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" +checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29" dependencies = [ + "find-msvc-tools", "jobserver", "libc", "shlex", @@ -1110,6 +1133,15 @@ dependencies = [ "error-code", ] +[[package]] +name = "cmake" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" +dependencies = [ + "cc", +] + [[package]] name = "coarsetime" version = "0.1.36" @@ -1704,12 +1736,12 @@ dependencies = [ [[package]] name = "deranged" -version = "0.4.1" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cfac68e08048ae1883171632c2aef3ebc555621ae56fbccce1cbf22dd7f058" +checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" dependencies = [ "powerfmt", - "serde", + "serde_core", ] [[package]] @@ -2241,6 +2273,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + [[package]] name = "fixedbitset" version = "0.4.2" @@ -2324,6 +2362,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "futf" version = "0.1.5" @@ -2957,7 +3001,7 @@ dependencies = [ "once_cell", "rand 0.9.0", "ring", - "rustls 0.23.25", + "rustls 0.23.36", "thiserror 2.0.12", "tinyvec", "tokio", @@ -2982,7 +3026,7 @@ dependencies = [ "parking_lot", "rand 0.9.0", "resolv-conf", - "rustls 0.23.25", + "rustls 0.23.36", "smallvec", "thiserror 2.0.12", "tokio", @@ -3177,19 +3221,21 @@ dependencies = [ [[package]] name = "hyper" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" dependencies = [ + "atomic-waker", "bytes", "futures-channel", - "futures-util", + "futures-core", "h2 0.4.8", "http 1.3.1", "http-body 1.0.1", "httparse", "itoa 1.0.15", "pin-project-lite", + "pin-utils", "smallvec", "tokio", "want", @@ -3217,9 +3263,9 @@ checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" dependencies = [ "futures-util", "http 1.3.1", - "hyper 1.6.0", + "hyper 1.8.1", "hyper-util", - "rustls 0.23.25", + "rustls 0.23.36", "rustls-pki-types", "tokio", "tokio-rustls 0.26.2", @@ -3235,7 +3281,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.6.0", + "hyper 1.8.1", "hyper-util", "native-tls", "tokio", @@ -3245,19 +3291,22 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.11" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ + "base64 0.22.1", "bytes", "futures-channel", "futures-util", "http 1.3.1", "http-body 1.0.1", - "hyper 1.6.0", + "hyper 1.8.1", + "ipnet", "libc", + "percent-encoding", "pin-project-lite", - "socket2 0.5.9", + "socket2 0.6.0", "tokio", "tower-service", "tracing", @@ -3539,6 +3588,16 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +[[package]] +name = "iri-string" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "is-docker" version = "0.2.0" @@ -4034,10 +4093,10 @@ dependencies = [ "libc", "log", "openssl", - "openssl-probe", + "openssl-probe 0.1.6", "openssl-sys", "schannel", - "security-framework", + "security-framework 2.11.1", "security-framework-sys", "tempfile", ] @@ -4145,9 +4204,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" [[package]] name = "num-integer" @@ -4212,7 +4271,7 @@ dependencies = [ [[package]] name = "nym-api-requests" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bs58", "celes", @@ -4252,7 +4311,7 @@ dependencies = [ [[package]] name = "nym-bin-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "const-str", "log", @@ -4283,7 +4342,7 @@ dependencies = [ [[package]] name = "nym-coconut-dkg-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -4296,7 +4355,7 @@ dependencies = [ [[package]] name = "nym-compact-ecash" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bincode", "bs58", @@ -4318,7 +4377,7 @@ dependencies = [ [[package]] name = "nym-config" -version = "1.20.1" +version = "1.20.4" dependencies = [ "dirs 6.0.0", "handlebars", @@ -4332,7 +4391,7 @@ dependencies = [ [[package]] name = "nym-contracts-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bs58", "cosmwasm-schema", @@ -4346,7 +4405,7 @@ dependencies = [ [[package]] name = "nym-credentials-interface" -version = "1.20.1" +version = "1.20.4" dependencies = [ "nym-bls12_381-fork", "nym-compact-ecash", @@ -4364,7 +4423,7 @@ dependencies = [ [[package]] name = "nym-crypto" -version = "1.20.1" +version = "1.20.4" dependencies = [ "base64 0.22.1", "bs58", @@ -4385,7 +4444,7 @@ dependencies = [ [[package]] name = "nym-ecash-contract-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bs58", "cosmwasm-schema", @@ -4398,7 +4457,7 @@ dependencies = [ [[package]] name = "nym-ecash-signer-check-types" -version = "1.20.1" +version = "1.20.4" dependencies = [ "nym-coconut-dkg-common", "nym-crypto", @@ -4413,14 +4472,14 @@ dependencies = [ [[package]] name = "nym-ecash-time" -version = "1.20.1" +version = "1.20.4" dependencies = [ "time", ] [[package]] name = "nym-exit-policy" -version = "1.20.1" +version = "1.20.4" dependencies = [ "serde", "serde_json", @@ -4431,7 +4490,7 @@ dependencies = [ [[package]] name = "nym-group-contract-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "cosmwasm-schema", "cw-controllers", @@ -4442,7 +4501,7 @@ dependencies = [ [[package]] name = "nym-http-api-client" -version = "1.20.1" +version = "1.20.4" dependencies = [ "async-trait", "bincode", @@ -4458,7 +4517,7 @@ dependencies = [ "nym-http-api-client-macro", "nym-http-api-common", "once_cell", - "reqwest 0.12.15", + "reqwest 0.13.2", "serde", "serde_json", "serde_plain", @@ -4472,7 +4531,7 @@ dependencies = [ [[package]] name = "nym-http-api-client-macro" -version = "1.20.1" +version = "1.20.4" dependencies = [ "proc-macro-crate 3.3.0", "proc-macro2", @@ -4483,7 +4542,7 @@ dependencies = [ [[package]] name = "nym-http-api-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bincode", "serde", @@ -4493,7 +4552,7 @@ dependencies = [ [[package]] name = "nym-kkt-ciphersuite" -version = "1.20.1" +version = "1.20.4" dependencies = [ "num_enum", "strum", @@ -4503,7 +4562,7 @@ dependencies = [ [[package]] name = "nym-mixnet-contract-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "bs58", "cosmwasm-schema", @@ -4524,7 +4583,7 @@ dependencies = [ [[package]] name = "nym-multisig-contract-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -4539,7 +4598,7 @@ dependencies = [ [[package]] name = "nym-network-defaults" -version = "1.20.1" +version = "1.20.4" dependencies = [ "cargo_metadata 0.19.2", "dotenvy", @@ -4555,7 +4614,7 @@ dependencies = [ [[package]] name = "nym-node-requests" -version = "1.20.1" +version = "1.20.4" dependencies = [ "async-trait", "celes", @@ -4581,7 +4640,7 @@ dependencies = [ [[package]] name = "nym-noise-keys" -version = "1.20.1" +version = "1.20.4" dependencies = [ "nym-crypto", "schemars", @@ -4591,7 +4650,7 @@ dependencies = [ [[package]] name = "nym-pemstore" -version = "1.20.1" +version = "1.20.4" dependencies = [ "pem", "tracing", @@ -4600,7 +4659,7 @@ dependencies = [ [[package]] name = "nym-performance-contract-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -4613,7 +4672,7 @@ dependencies = [ [[package]] name = "nym-serde-helpers" -version = "1.20.1" +version = "1.20.4" dependencies = [ "base64 0.22.1", "bs58", @@ -4624,7 +4683,7 @@ dependencies = [ [[package]] name = "nym-sphinx-types" -version = "1.20.1" +version = "1.20.4" dependencies = [ "sphinx-packet", "thiserror 2.0.12", @@ -4632,7 +4691,7 @@ dependencies = [ [[package]] name = "nym-store-cipher" -version = "1.20.1" +version = "1.20.4" dependencies = [ "aes-gcm", "argon2", @@ -4647,7 +4706,7 @@ dependencies = [ [[package]] name = "nym-ticketbooks-merkle" -version = "1.20.1" +version = "1.20.4" dependencies = [ "nym-credentials-interface", "nym-serde-helpers", @@ -4661,7 +4720,7 @@ dependencies = [ [[package]] name = "nym-types" -version = "1.20.1" +version = "1.20.4" dependencies = [ "base64 0.22.1", "cosmrs", @@ -4675,7 +4734,7 @@ dependencies = [ "nym-mixnet-contract-common", "nym-validator-client", "nym-vesting-contract-common", - "reqwest 0.12.15", + "reqwest 0.13.2", "schemars", "serde", "serde_json", @@ -4691,12 +4750,12 @@ dependencies = [ [[package]] name = "nym-upgrade-mode-check" -version = "1.20.1" +version = "1.20.4" dependencies = [ "jwt-simple", "nym-crypto", "nym-http-api-client", - "reqwest 0.12.15", + "reqwest 0.13.2", "serde", "serde_json", "thiserror 2.0.12", @@ -4707,7 +4766,7 @@ dependencies = [ [[package]] name = "nym-validator-client" -version = "1.20.1" +version = "1.20.4" dependencies = [ "async-trait", "base64 0.22.1", @@ -4740,7 +4799,7 @@ dependencies = [ "nym-serde-helpers", "nym-vesting-contract-common", "prost", - "reqwest 0.12.15", + "reqwest 0.13.2", "serde", "serde_json", "sha2 0.10.9", @@ -4756,7 +4815,7 @@ dependencies = [ [[package]] name = "nym-vesting-contract-common" -version = "1.20.1" +version = "1.20.4" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -4802,7 +4861,7 @@ dependencies = [ [[package]] name = "nym-wireguard-types" -version = "1.20.1" +version = "1.20.4" dependencies = [ "base64 0.22.1", "nym-crypto", @@ -5110,6 +5169,12 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + [[package]] name = "openssl-sys" version = "0.9.107" @@ -5815,7 +5880,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.25", + "rustls 0.23.36", "socket2 0.5.9", "thiserror 2.0.12", "tokio", @@ -5829,12 +5894,13 @@ version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b820744eb4dc9b57a3398183639c511b5a26d2ed702cedd3febaa1393caa22cc" dependencies = [ + "aws-lc-rs", "bytes", "getrandom 0.3.2", "rand 0.9.0", "ring", "rustc-hash", - "rustls 0.23.25", + "rustls 0.23.36", "rustls-pki-types", "slab", "thiserror 2.0.12", @@ -6103,7 +6169,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "rustls 0.21.12", - "rustls-native-certs", + "rustls-native-certs 0.6.3", "rustls-pemfile 1.0.4", "serde", "serde_json", @@ -6126,7 +6192,6 @@ version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" dependencies = [ - "async-compression", "base64 0.22.1", "bytes", "encoding_rs", @@ -6136,7 +6201,7 @@ dependencies = [ "http 1.3.1", "http-body 1.0.1", "http-body-util", - "hyper 1.6.0", + "hyper 1.8.1", "hyper-rustls 0.27.5", "hyper-tls", "hyper-util", @@ -6149,7 +6214,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.25", + "rustls 0.23.36", "rustls-pemfile 2.2.0", "rustls-pki-types", "serde", @@ -6172,6 +6237,43 @@ dependencies = [ "windows-registry", ] +[[package]] +name = "reqwest" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-core", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.8.1", + "hyper-rustls 0.27.5", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls 0.23.36", + "rustls-pki-types", + "rustls-platform-verifier", + "serde", + "serde_json", + "sync_wrapper 1.0.2", + "tokio", + "tokio-rustls 0.26.2", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "resolv-conf" version = "0.7.1" @@ -6327,15 +6429,16 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.25" +version = "0.23.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" +checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" dependencies = [ + "aws-lc-rs", "log", "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.103.1", + "rustls-webpki 0.103.9", "subtle 2.6.1", "zeroize", ] @@ -6346,10 +6449,22 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ - "openssl-probe", + "openssl-probe 0.1.6", "rustls-pemfile 1.0.4", "schannel", - "security-framework", + "security-framework 2.11.1", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +dependencies = [ + "openssl-probe 0.2.1", + "rustls-pki-types", + "schannel", + "security-framework 3.5.1", ] [[package]] @@ -6372,13 +6487,41 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.11.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" dependencies = [ "web-time", + "zeroize", ] +[[package]] +name = "rustls-platform-verifier" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" +dependencies = [ + "core-foundation 0.10.0", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls 0.23.36", + "rustls-native-certs 0.8.3", + "rustls-platform-verifier-android", + "rustls-webpki 0.103.9", + "security-framework 3.5.1", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -6391,10 +6534,11 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.1" +version = "0.103.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -6526,10 +6670,23 @@ dependencies = [ ] [[package]] -name = "security-framework-sys" -version = "2.14.0" +name = "security-framework" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +dependencies = [ + "bitflags 2.9.0", + "core-foundation 0.10.0", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" dependencies = [ "core-foundation-sys", "libc", @@ -6566,10 +6723,11 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ + "serde_core", "serde_derive", ] @@ -6603,10 +6761,19 @@ dependencies = [ ] [[package]] -name = "serde_derive" -version = "1.0.219" +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -7799,9 +7966,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.41" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "itoa 1.0.15", @@ -7809,22 +7976,22 @@ dependencies = [ "num-conv", "num_threads", "powerfmt", - "serde", + "serde_core", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.4" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "time-macros" -version = "0.2.22" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" dependencies = [ "num-conv", "time-core", @@ -7912,7 +8079,7 @@ version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" dependencies = [ - "rustls 0.23.25", + "rustls 0.23.36", "tokio", ] @@ -8016,6 +8183,29 @@ dependencies = [ "tower-service", ] +[[package]] +name = "tower-http" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +dependencies = [ + "async-compression", + "bitflags 2.9.0", + "bytes", + "futures-core", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "iri-string", + "pin-project-lite", + "tokio", + "tokio-util", + "tower", + "tower-layer", + "tower-service", +] + [[package]] name = "tower-layer" version = "0.3.3" @@ -8693,6 +8883,15 @@ dependencies = [ "system-deps", ] +[[package]] +name = "webpki-root-certs" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webpki-roots" version = "0.26.8" diff --git a/nym-wallet/src-tauri/Cargo.toml b/nym-wallet/src-tauri/Cargo.toml index 6327991107..abac9b8a70 100644 --- a/nym-wallet/src-tauri/Cargo.toml +++ b/nym-wallet/src-tauri/Cargo.toml @@ -43,7 +43,7 @@ strum = { version = "0.27.2", features = ["derive"] } tap = "1" tauri = { version = "2", features = [] } #tendermint-rpc = "0.23.0" -time = { version = "0.3.30", features = ["local-offset"] } +time = { version = "0.3.47", features = ["local-offset"] } thiserror = "1.0" tokio = { version = "1.44", features = ["full"] } toml = "0.5.8" From 89ab2630cdbb5567c96df3f1431e807662c75073 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:49:15 +0000 Subject: [PATCH 22/56] build(deps-dev): bump webpack from 5.102.1 to 5.104.1 (#6432) Bumps [webpack](https://github.com/webpack/webpack) from 5.102.1 to 5.104.1. - [Release notes](https://github.com/webpack/webpack/releases) - [Changelog](https://github.com/webpack/webpack/blob/main/CHANGELOG.md) - [Commits](https://github.com/webpack/webpack/compare/v5.102.1...v5.104.1) --- updated-dependencies: - dependency-name: webpack dependency-version: 5.104.1 dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 103 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 54 insertions(+), 49 deletions(-) diff --git a/yarn.lock b/yarn.lock index df46d7fbca..542f2e8951 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8428,10 +8428,10 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" -baseline-browser-mapping@^2.8.19: - version "2.8.20" - resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.8.20.tgz#6766cf270f3668d20b6712b9c54cc911b87da714" - integrity sha512-JMWsdF+O8Orq3EMukbUN1QfbLK9mX2CkUmQBcW2T0s8OmdAUL5LLM/6wFwSrqXzlXB13yhyK9gTKS1rIizOduQ== +baseline-browser-mapping@^2.9.0: + version "2.9.19" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz#3e508c43c46d961eb4d7d2e5b8d1dd0f9ee4f488" + integrity sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg== batch@0.6.1: version "0.6.1" @@ -8725,16 +8725,16 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.21.4, browserslist@^4.23.0, browserslist@^4.24.0, browserslist@^4.26.3: - version "4.27.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.27.0.tgz#755654744feae978fbb123718b2f139bc0fa6697" - integrity sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw== +browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.21.4, browserslist@^4.23.0, browserslist@^4.24.0, browserslist@^4.26.3, browserslist@^4.28.1: + version "4.28.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.1.tgz#7f534594628c53c63101079e27e40de490456a95" + integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA== dependencies: - baseline-browser-mapping "^2.8.19" - caniuse-lite "^1.0.30001751" - electron-to-chromium "^1.5.238" - node-releases "^2.0.26" - update-browserslist-db "^1.1.4" + baseline-browser-mapping "^2.9.0" + caniuse-lite "^1.0.30001759" + electron-to-chromium "^1.5.263" + node-releases "^2.0.27" + update-browserslist-db "^1.2.0" bs-logger@0.x: version "0.2.6" @@ -9046,11 +9046,16 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001579, caniuse-lite@^1.0.30001751: +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001579: version "1.0.30001751" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001751.tgz#dacd5d9f4baeea841641640139d2b2a4df4226ad" integrity sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw== +caniuse-lite@^1.0.30001759: + version "1.0.30001769" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz#1ad91594fad7dc233777c2781879ab5409f7d9c2" + integrity sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg== + capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -10999,10 +11004,10 @@ ejs@^3.1.7: dependencies: jake "^10.8.5" -electron-to-chromium@^1.5.238: - version "1.5.240" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.240.tgz#bfd946570a723aa3754370065d02e23e30824774" - integrity sha512-OBwbZjWgrCOH+g6uJsA2/7Twpas2OlepS9uvByJjR2datRDuKGYeD+nP8lBBks2qnB7bGJNHDUx7c/YLaT3QMQ== +electron-to-chromium@^1.5.263: + version "1.5.286" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz#142be1ab5e1cd5044954db0e5898f60a4960384e" + integrity sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A== elliptic@^6.4.0, elliptic@^6.5.3, elliptic@^6.5.4, elliptic@^6.6.1: version "6.6.1" @@ -11079,13 +11084,13 @@ enhanced-resolve@^4.5.0: memory-fs "^0.5.0" tapable "^1.0.0" -enhanced-resolve@^5.0.0, enhanced-resolve@^5.17.3, enhanced-resolve@^5.7.0: - version "5.18.3" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz#9b5f4c5c076b8787c78fe540392ce76a88855b44" - integrity sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww== +enhanced-resolve@^5.0.0, enhanced-resolve@^5.17.4, enhanced-resolve@^5.7.0: + version "5.19.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz#6687446a15e969eaa63c2fa2694510e17ae6d97c" + integrity sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg== dependencies: graceful-fs "^4.2.4" - tapable "^2.2.0" + tapable "^2.3.0" enquirer@~2.3.6: version "2.3.6" @@ -11262,10 +11267,10 @@ es-iterator-helpers@^1.2.1: iterator.prototype "^1.1.4" safe-array-concat "^1.1.3" -es-module-lexer@^1.2.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz#9159601561880a85f2734560a9099b2c31e5372a" - integrity sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA== +es-module-lexer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-2.0.0.tgz#f657cd7a9448dcdda9c070a3cb75e5dc1e85f5b1" + integrity sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw== es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: version "1.1.1" @@ -15465,7 +15470,7 @@ loader-runner@^2.4.0: resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== -loader-runner@^4.1.0, loader-runner@^4.2.0: +loader-runner@^4.1.0, loader-runner@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.1.tgz#6c76ed29b0ccce9af379208299f07f876de737e3" integrity sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q== @@ -16843,10 +16848,10 @@ node-mock-http@^1.0.2: resolved "https://registry.yarnpkg.com/node-mock-http/-/node-mock-http-1.0.3.tgz#4e55e093267a3b910cded7354389ce2d02c89e77" integrity sha512-jN8dK25fsfnMrVsEhluUTPkBFY+6ybu7jSB1n+ri/vOGjJxU8J9CZhpSGkHXSkFjtUhbmoncG/YG9ta5Ludqog== -node-releases@^2.0.26: - version "2.0.26" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.26.tgz#fdfa272f2718a1309489d18aef4ef5ba7f5dfb52" - integrity sha512-S2M9YimhSjBSvYnlr5/+umAnPHE++ODwt5e2Ij6FoX45HA/s4vHdkDx1eax2pAPeAOqu4s9b7ppahsyEFdVqQA== +node-releases@^2.0.27: + version "2.0.27" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e" + integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== nopt@^6.0.0: version "6.0.0" @@ -20944,7 +20949,7 @@ tapable@^1.0.0, tapable@^1.1.3: resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== -tapable@^2.0.0, tapable@^2.2.0, tapable@^2.2.1, tapable@^2.3.0: +tapable@^2.0.0, tapable@^2.2.1, tapable@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.0.tgz#7e3ea6d5ca31ba8e078b560f0d83ce9a14aa8be6" integrity sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg== @@ -21041,10 +21046,10 @@ terser-webpack-plugin@^4.2.3: terser "^5.3.4" webpack-sources "^1.4.3" -terser-webpack-plugin@^5.0.3, terser-webpack-plugin@^5.3.11: - version "5.3.14" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz#9031d48e57ab27567f02ace85c7d690db66c3e06" - integrity sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw== +terser-webpack-plugin@^5.0.3, terser-webpack-plugin@^5.3.16: + version "5.3.16" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz#741e448cc3f93d8026ebe4f7ef9e4afacfd56330" + integrity sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q== dependencies: "@jridgewell/trace-mapping" "^0.3.25" jest-worker "^27.4.5" @@ -21914,10 +21919,10 @@ upath@^1.1.1: resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== -update-browserslist-db@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz#7802aa2ae91477f255b86e0e46dbc787a206ad4a" - integrity sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A== +update-browserslist-db@^1.2.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz#64d76db58713136acbeb4c49114366cc6cc2e80d" + integrity sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w== dependencies: escalade "^3.2.0" picocolors "^1.1.1" @@ -22460,9 +22465,9 @@ webpack@4: webpack-sources "^1.4.1" "webpack@>=4.43.0 <6.0.0", webpack@^5.75.0, webpack@^5.88.2, webpack@^5.9.0: - version "5.102.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.102.1.tgz#1003a3024741a96ba99c37431938bf61aad3d988" - integrity sha512-7h/weGm9d/ywQ6qzJ+Xy+r9n/3qgp/thalBbpOi5i223dPXKi04IBtqPN9nTd+jBc7QKfvDbaBnFipYp4sJAUQ== + version "5.104.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.104.1.tgz#94bd41eb5dbf06e93be165ba8be41b8260d4fb1a" + integrity sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA== dependencies: "@types/eslint-scope" "^3.7.7" "@types/estree" "^1.0.8" @@ -22472,21 +22477,21 @@ webpack@4: "@webassemblyjs/wasm-parser" "^1.14.1" acorn "^8.15.0" acorn-import-phases "^1.0.3" - browserslist "^4.26.3" + browserslist "^4.28.1" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.17.3" - es-module-lexer "^1.2.1" + enhanced-resolve "^5.17.4" + es-module-lexer "^2.0.0" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" graceful-fs "^4.2.11" json-parse-even-better-errors "^2.3.1" - loader-runner "^4.2.0" + loader-runner "^4.3.1" mime-types "^2.1.27" neo-async "^2.6.2" schema-utils "^4.3.3" tapable "^2.3.0" - terser-webpack-plugin "^5.3.11" + terser-webpack-plugin "^5.3.16" watchpack "^2.4.4" webpack-sources "^3.3.3" From 93834bcf28b0b75980e3ce5273a5ebff45127507 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:49:42 +0000 Subject: [PATCH 23/56] build(deps-dev): bump webpack in /wasm/mix-fetch/internal-dev (#6431) Bumps [webpack](https://github.com/webpack/webpack) from 5.98.0 to 5.105.0. - [Release notes](https://github.com/webpack/webpack/releases) - [Changelog](https://github.com/webpack/webpack/blob/main/CHANGELOG.md) - [Commits](https://github.com/webpack/webpack/compare/v5.98.0...v5.105.0) --- updated-dependencies: - dependency-name: webpack dependency-version: 5.105.0 dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- wasm/mix-fetch/internal-dev/package-lock.json | 225 ++++++++++-------- wasm/mix-fetch/internal-dev/package.json | 2 +- wasm/mix-fetch/internal-dev/yarn.lock | 181 +++++++------- 3 files changed, 218 insertions(+), 190 deletions(-) diff --git a/wasm/mix-fetch/internal-dev/package-lock.json b/wasm/mix-fetch/internal-dev/package-lock.json index 5419a88016..e4a1791162 100644 --- a/wasm/mix-fetch/internal-dev/package-lock.json +++ b/wasm/mix-fetch/internal-dev/package-lock.json @@ -18,7 +18,7 @@ "devDependencies": { "copy-webpack-plugin": "^11.0.0", "hello-wasm-pack": "^0.1.0", - "webpack": "^5.98.0", + "webpack": "^5.105.0", "webpack-cli": "^4.9.2", "webpack-dev-server": "^5.2.1" } @@ -42,18 +42,14 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", - "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { @@ -66,20 +62,10 @@ "node": ">=6.0.0" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", "dev": true, "license": "MIT", "dependencies": { @@ -88,16 +74,16 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", "dependencies": { @@ -276,9 +262,9 @@ } }, "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true, "license": "MIT" }, @@ -326,9 +312,9 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true, "license": "MIT" }, @@ -659,9 +645,9 @@ } }, "node_modules/acorn": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", - "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", "bin": { @@ -671,13 +657,25 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, "node_modules/ajv": { "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -747,6 +745,16 @@ "node": ">= 8" } }, + "node_modules/baseline-browser-mapping": { + "version": "2.9.19", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", + "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, "node_modules/batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", @@ -827,9 +835,9 @@ } }, "node_modules/browserslist": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", - "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "dev": true, "funding": [ { @@ -846,12 +854,12 @@ } ], "license": "MIT", - "peer": true, "dependencies": { - "caniuse-lite": "^1.0.30001688", - "electron-to-chromium": "^1.5.73", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.1" + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" @@ -925,9 +933,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001703", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001703.tgz", - "integrity": "sha512-kRlAGTRWgPsOj7oARC9m1okJEXdL/8fekFVcxA8Hl7GH4r/sN4OJn/i6Flde373T50KS7Y37oFbMwlE8+F42kQ==", + "version": "1.0.30001769", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz", + "integrity": "sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==", "dev": true, "funding": [ { @@ -1288,9 +1296,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.114", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.114.tgz", - "integrity": "sha512-DFptFef3iktoKlFQK/afbo274/XNWD00Am0xa7M8FZUepHlHT8PEuiNBoRfFHbH1okqN58AlhbJ4QTkcnXorjA==", + "version": "1.5.286", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz", + "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==", "dev": true, "license": "ISC" }, @@ -1305,14 +1313,14 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.18.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", - "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "version": "5.19.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz", + "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==", "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "tapable": "^2.3.0" }, "engines": { "node": ">=10.13.0" @@ -1352,9 +1360,9 @@ } }, "node_modules/es-module-lexer": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", - "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", + "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", "dev": true, "license": "MIT" }, @@ -2284,13 +2292,17 @@ } }, "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", "dev": true, "license": "MIT", "engines": { "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/locate-path": { @@ -2489,9 +2501,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", "dev": true, "license": "MIT" }, @@ -3021,9 +3033,9 @@ "license": "MIT" }, "node_modules/schema-utils": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", - "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", "dev": true, "license": "MIT", "dependencies": { @@ -3508,24 +3520,28 @@ } }, "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", "dev": true, "license": "MIT", "engines": { "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/terser": { - "version": "5.39.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz", - "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==", + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", + "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", + "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -3537,9 +3553,9 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.14", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", - "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", + "version": "5.3.16", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", + "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", "dev": true, "license": "MIT", "dependencies": { @@ -3636,8 +3652,7 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, - "license": "0BSD", - "peer": true + "license": "0BSD" }, "node_modules/type-is": { "version": "1.6.18", @@ -3664,9 +3679,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { @@ -3742,9 +3757,9 @@ } }, "node_modules/watchpack": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", - "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", + "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", "dev": true, "license": "MIT", "dependencies": { @@ -3766,36 +3781,37 @@ } }, "node_modules/webpack": { - "version": "5.98.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.98.0.tgz", - "integrity": "sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==", + "version": "5.105.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.0.tgz", + "integrity": "sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", - "@types/estree": "^1.0.6", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.14.0", - "browserslist": "^4.24.0", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.1", - "es-module-lexer": "^1.2.1", + "enhanced-resolve": "^5.19.0", + "es-module-lexer": "^2.0.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", + "loader-runner": "^4.3.1", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^4.3.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.11", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.16", + "watchpack": "^2.5.1", + "webpack-sources": "^3.3.3" }, "bin": { "webpack": "bin/webpack.js" @@ -3819,7 +3835,6 @@ "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/configtest": "^1.2.0", @@ -3975,9 +3990,9 @@ } }, "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", "dev": true, "license": "MIT", "engines": { diff --git a/wasm/mix-fetch/internal-dev/package.json b/wasm/mix-fetch/internal-dev/package.json index cf3cef682a..6eb75e1998 100644 --- a/wasm/mix-fetch/internal-dev/package.json +++ b/wasm/mix-fetch/internal-dev/package.json @@ -30,7 +30,7 @@ "devDependencies": { "copy-webpack-plugin": "^11.0.0", "hello-wasm-pack": "^0.1.0", - "webpack": "^5.98.0", + "webpack": "^5.105.0", "webpack-cli": "^4.9.2", "webpack-dev-server": "^5.2.1" }, diff --git a/wasm/mix-fetch/internal-dev/yarn.lock b/wasm/mix-fetch/internal-dev/yarn.lock index 78d66da81f..7eed240bce 100644 --- a/wasm/mix-fetch/internal-dev/yarn.lock +++ b/wasm/mix-fetch/internal-dev/yarn.lock @@ -147,10 +147,10 @@ "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*", "@types/estree@^1.0.6": - version "1.0.6" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" - integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== +"@types/estree@*", "@types/estree@^1.0.8": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" + integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.21", "@types/express-serve-static-core@^4.17.33": version "4.19.6" @@ -184,10 +184,10 @@ dependencies: "@types/node" "*" -"@types/json-schema@*", "@types/json-schema@^7.0.9": - version "7.0.11" - resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz" - integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== +"@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.9": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== "@types/mime@^1": version "1.3.5" @@ -415,10 +415,15 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: mime-types "~2.1.34" negotiator "0.6.3" -acorn@^8.14.0, acorn@^8.8.2: - version "8.14.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.1.tgz#721d5dc10f7d5b5609a891773d47731796935dfb" - integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg== +acorn-import-phases@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz#16eb850ba99a056cb7cbfe872ffb8972e18c8bd7" + integrity sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ== + +acorn@^8.15.0, acorn@^8.8.2: + version "8.15.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" + integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== ajv-formats@^2.1.1: version "2.1.1" @@ -472,6 +477,11 @@ array-flatten@1.1.1: resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== +baseline-browser-mapping@^2.9.0: + version "2.9.19" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz#3e508c43c46d961eb4d7d2e5b8d1dd0f9ee4f488" + integrity sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg== + batch@0.6.1: version "0.6.1" resolved "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz" @@ -515,15 +525,16 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.1.1" -browserslist@^4.24.0: - version "4.24.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.4.tgz#c6b2865a3f08bcb860a0e827389003b9fe686e4b" - integrity sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A== +browserslist@^4.28.1: + version "4.28.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.1.tgz#7f534594628c53c63101079e27e40de490456a95" + integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA== dependencies: - caniuse-lite "^1.0.30001688" - electron-to-chromium "^1.5.73" - node-releases "^2.0.19" - update-browserslist-db "^1.1.1" + baseline-browser-mapping "^2.9.0" + caniuse-lite "^1.0.30001759" + electron-to-chromium "^1.5.263" + node-releases "^2.0.27" + update-browserslist-db "^1.2.0" buffer-from@^1.0.0: version "1.1.2" @@ -563,10 +574,10 @@ call-bound@^1.0.2: call-bind-apply-helpers "^1.0.2" get-intrinsic "^1.3.0" -caniuse-lite@^1.0.30001688: - version "1.0.30001703" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001703.tgz#977cb4920598c158f491ecf4f4f2cfed9e354718" - integrity sha512-kRlAGTRWgPsOj7oARC9m1okJEXdL/8fekFVcxA8Hl7GH4r/sN4OJn/i6Flde373T50KS7Y37oFbMwlE8+F42kQ== +caniuse-lite@^1.0.30001759: + version "1.0.30001769" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz#1ad91594fad7dc233777c2781879ab5409f7d9c2" + integrity sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg== chokidar@^3.6.0: version "3.6.0" @@ -765,10 +776,10 @@ ee-first@1.1.1: resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -electron-to-chromium@^1.5.73: - version "1.5.114" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.114.tgz#f2bb4fda80a7db4ea273565e75b0ebbe19af0ac3" - integrity sha512-DFptFef3iktoKlFQK/afbo274/XNWD00Am0xa7M8FZUepHlHT8PEuiNBoRfFHbH1okqN58AlhbJ4QTkcnXorjA== +electron-to-chromium@^1.5.263: + version "1.5.286" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz#142be1ab5e1cd5044954db0e5898f60a4960384e" + integrity sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A== encodeurl@~1.0.2: version "1.0.2" @@ -780,13 +791,13 @@ encodeurl@~2.0.0: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== -enhanced-resolve@^5.17.1: - version "5.18.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz#728ab082f8b7b6836de51f1637aab5d3b9568faf" - integrity sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg== +enhanced-resolve@^5.19.0: + version "5.19.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz#6687446a15e969eaa63c2fa2694510e17ae6d97c" + integrity sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg== dependencies: graceful-fs "^4.2.4" - tapable "^2.2.0" + tapable "^2.3.0" envinfo@^7.7.3: version "7.8.1" @@ -803,10 +814,10 @@ es-errors@^1.3.0: resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== -es-module-lexer@^1.2.1: - version "1.6.0" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.6.0.tgz#da49f587fd9e68ee2404fe4e256c0c7d3a81be21" - integrity sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ== +es-module-lexer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-2.0.0.tgz#f657cd7a9448dcdda9c070a3cb75e5dc1e85f5b1" + integrity sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw== es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: version "1.1.1" @@ -1326,10 +1337,10 @@ launch-editor@^2.6.1: picocolors "^1.0.0" shell-quote "^1.8.1" -loader-runner@^4.2.0: - version "4.3.0" - resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz" - integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== +loader-runner@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.1.tgz#6c76ed29b0ccce9af379208299f07f876de737e3" + integrity sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q== locate-path@^5.0.0: version "5.0.0" @@ -1446,10 +1457,10 @@ node-forge@^1: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.3.tgz#0ad80f6333b3a0045e827ac20b7f735f93716751" integrity sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg== -node-releases@^2.0.19: - version "2.0.19" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314" - integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw== +node-releases@^2.0.27: + version "2.0.27" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e" + integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" @@ -1724,10 +1735,10 @@ safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -schema-utils@^4.0.0, schema-utils@^4.2.0, schema-utils@^4.3.0: - version "4.3.2" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.2.tgz#0c10878bf4a73fd2b1dfd14b9462b26788c806ae" - integrity sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ== +schema-utils@^4.0.0, schema-utils@^4.2.0, schema-utils@^4.3.0, schema-utils@^4.3.3: + version "4.3.3" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.3.tgz#5b1850912fa31df90716963d45d9121fdfc09f46" + integrity sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA== dependencies: "@types/json-schema" "^7.0.9" ajv "^8.9.0" @@ -1963,15 +1974,15 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -tapable@^2.1.1, tapable@^2.2.0: - version "2.2.1" - resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz" - integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== +tapable@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.0.tgz#7e3ea6d5ca31ba8e078b560f0d83ce9a14aa8be6" + integrity sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg== -terser-webpack-plugin@^5.3.11: - version "5.3.14" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz#9031d48e57ab27567f02ace85c7d690db66c3e06" - integrity sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw== +terser-webpack-plugin@^5.3.16: + version "5.3.16" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz#741e448cc3f93d8026ebe4f7ef9e4afacfd56330" + integrity sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q== dependencies: "@jridgewell/trace-mapping" "^0.3.25" jest-worker "^27.4.5" @@ -2034,10 +2045,10 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== -update-browserslist-db@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420" - integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw== +update-browserslist-db@^1.2.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz#64d76db58713136acbeb4c49114366cc6cc2e80d" + integrity sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w== dependencies: escalade "^3.2.0" picocolors "^1.1.1" @@ -2069,10 +2080,10 @@ vary@~1.1.2: resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== -watchpack@^2.4.1: - version "2.4.2" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.2.tgz#2feeaed67412e7c33184e5a79ca738fbd38564da" - integrity sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw== +watchpack@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.5.1.tgz#dd38b601f669e0cbf567cb802e75cead82cde102" + integrity sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg== dependencies: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" @@ -2156,39 +2167,41 @@ webpack-merge@^5.7.3: clone-deep "^4.0.1" wildcard "^2.0.0" -webpack-sources@^3.2.3: - version "3.2.3" - resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz" - integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== +webpack-sources@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.3.tgz#d4bf7f9909675d7a070ff14d0ef2a4f3c982c723" + integrity sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg== -webpack@^5.98.0: - version "5.98.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.98.0.tgz#44ae19a8f2ba97537978246072fb89d10d1fbd17" - integrity sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA== +webpack@^5.105.0: + version "5.105.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.105.0.tgz#38b5e6c5db8cbe81debbd16e089335ada05ea23a" + integrity sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw== dependencies: "@types/eslint-scope" "^3.7.7" - "@types/estree" "^1.0.6" + "@types/estree" "^1.0.8" + "@types/json-schema" "^7.0.15" "@webassemblyjs/ast" "^1.14.1" "@webassemblyjs/wasm-edit" "^1.14.1" "@webassemblyjs/wasm-parser" "^1.14.1" - acorn "^8.14.0" - browserslist "^4.24.0" + acorn "^8.15.0" + acorn-import-phases "^1.0.3" + browserslist "^4.28.1" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.17.1" - es-module-lexer "^1.2.1" + enhanced-resolve "^5.19.0" + es-module-lexer "^2.0.0" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" graceful-fs "^4.2.11" json-parse-even-better-errors "^2.3.1" - loader-runner "^4.2.0" + loader-runner "^4.3.1" mime-types "^2.1.27" neo-async "^2.6.2" - schema-utils "^4.3.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.3.11" - watchpack "^2.4.1" - webpack-sources "^3.2.3" + schema-utils "^4.3.3" + tapable "^2.3.0" + terser-webpack-plugin "^5.3.16" + watchpack "^2.5.1" + webpack-sources "^3.3.3" websocket-driver@>=0.5.1, websocket-driver@^0.7.4: version "0.7.4" From 061840c47c090e270116f1cc3ddbc6a030b15b2f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:50:01 +0000 Subject: [PATCH 24/56] build(deps-dev): bump webpack (#6430) Bumps [webpack](https://github.com/webpack/webpack) from 5.94.0 to 5.104.1. - [Release notes](https://github.com/webpack/webpack/releases) - [Changelog](https://github.com/webpack/webpack/blob/main/CHANGELOG.md) - [Commits](https://github.com/webpack/webpack/compare/v5.94.0...v5.104.1) --- updated-dependencies: - dependency-name: webpack dependency-version: 5.104.1 dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../vpn-api-lib-wasm/internal-dev/yarn.lock | 473 +++++++++--------- 1 file changed, 228 insertions(+), 245 deletions(-) diff --git a/nym-credential-proxy/vpn-api-lib-wasm/internal-dev/yarn.lock b/nym-credential-proxy/vpn-api-lib-wasm/internal-dev/yarn.lock index 76ca7b0480..01cda5871e 100644 --- a/nym-credential-proxy/vpn-api-lib-wasm/internal-dev/yarn.lock +++ b/nym-credential-proxy/vpn-api-lib-wasm/internal-dev/yarn.lock @@ -39,7 +39,7 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== -"@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": +"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": version "0.3.25" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== @@ -126,10 +126,26 @@ dependencies: "@types/node" "*" -"@types/estree@^1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" - integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== +"@types/eslint-scope@^3.7.7": + version "3.7.7" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" + integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "9.6.1" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-9.6.1.tgz#d5795ad732ce81715f27f75da913004a56751584" + integrity sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*", "@types/estree@^1.0.8": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" + integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.21", "@types/express-serve-static-core@^4.17.33": version "4.19.6" @@ -163,7 +179,7 @@ dependencies: "@types/node" "*" -"@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.9": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -240,125 +256,125 @@ dependencies: "@types/node" "*" -"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.12.1.tgz#bb16a0e8b1914f979f45864c23819cc3e3f0d4bb" - integrity sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg== +"@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.14.1.tgz#a9f6a07f2b03c95c8d38c4536a1fdfb521ff55b6" + integrity sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ== dependencies: - "@webassemblyjs/helper-numbers" "1.11.6" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/helper-numbers" "1.13.2" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" -"@webassemblyjs/floating-point-hex-parser@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" - integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== +"@webassemblyjs/floating-point-hex-parser@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz#fcca1eeddb1cc4e7b6eed4fc7956d6813b21b9fb" + integrity sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA== -"@webassemblyjs/helper-api-error@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" - integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== +"@webassemblyjs/helper-api-error@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz#e0a16152248bc38daee76dd7e21f15c5ef3ab1e7" + integrity sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ== -"@webassemblyjs/helper-buffer@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz#6df20d272ea5439bf20ab3492b7fb70e9bfcb3f6" - integrity sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw== +"@webassemblyjs/helper-buffer@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz#822a9bc603166531f7d5df84e67b5bf99b72b96b" + integrity sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA== -"@webassemblyjs/helper-numbers@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" - integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== +"@webassemblyjs/helper-numbers@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz#dbd932548e7119f4b8a7877fd5a8d20e63490b2d" + integrity sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA== dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.6" - "@webassemblyjs/helper-api-error" "1.11.6" + "@webassemblyjs/floating-point-hex-parser" "1.13.2" + "@webassemblyjs/helper-api-error" "1.13.2" "@xtuc/long" "4.2.2" -"@webassemblyjs/helper-wasm-bytecode@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" - integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== +"@webassemblyjs/helper-wasm-bytecode@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz#e556108758f448aae84c850e593ce18a0eb31e0b" + integrity sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA== -"@webassemblyjs/helper-wasm-section@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz#3da623233ae1a60409b509a52ade9bc22a37f7bf" - integrity sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g== +"@webassemblyjs/helper-wasm-section@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz#9629dda9c4430eab54b591053d6dc6f3ba050348" + integrity sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw== dependencies: - "@webassemblyjs/ast" "1.12.1" - "@webassemblyjs/helper-buffer" "1.12.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-buffer" "1.14.1" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/wasm-gen" "1.14.1" -"@webassemblyjs/ieee754@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" - integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== +"@webassemblyjs/ieee754@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz#1c5eaace1d606ada2c7fd7045ea9356c59ee0dba" + integrity sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" - integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== +"@webassemblyjs/leb128@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.13.2.tgz#57c5c3deb0105d02ce25fa3fd74f4ebc9fd0bbb0" + integrity sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" - integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== +"@webassemblyjs/utf8@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.13.2.tgz#917a20e93f71ad5602966c2d685ae0c6c21f60f1" + integrity sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ== -"@webassemblyjs/wasm-edit@^1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz#9f9f3ff52a14c980939be0ef9d5df9ebc678ae3b" - integrity sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g== +"@webassemblyjs/wasm-edit@^1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz#ac6689f502219b59198ddec42dcd496b1004d597" + integrity sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ== dependencies: - "@webassemblyjs/ast" "1.12.1" - "@webassemblyjs/helper-buffer" "1.12.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/helper-wasm-section" "1.12.1" - "@webassemblyjs/wasm-gen" "1.12.1" - "@webassemblyjs/wasm-opt" "1.12.1" - "@webassemblyjs/wasm-parser" "1.12.1" - "@webassemblyjs/wast-printer" "1.12.1" + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-buffer" "1.14.1" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/helper-wasm-section" "1.14.1" + "@webassemblyjs/wasm-gen" "1.14.1" + "@webassemblyjs/wasm-opt" "1.14.1" + "@webassemblyjs/wasm-parser" "1.14.1" + "@webassemblyjs/wast-printer" "1.14.1" -"@webassemblyjs/wasm-gen@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz#a6520601da1b5700448273666a71ad0a45d78547" - integrity sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w== +"@webassemblyjs/wasm-gen@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz#991e7f0c090cb0bb62bbac882076e3d219da9570" + integrity sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg== dependencies: - "@webassemblyjs/ast" "1.12.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/ieee754" "1.11.6" - "@webassemblyjs/leb128" "1.11.6" - "@webassemblyjs/utf8" "1.11.6" + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/ieee754" "1.13.2" + "@webassemblyjs/leb128" "1.13.2" + "@webassemblyjs/utf8" "1.13.2" -"@webassemblyjs/wasm-opt@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz#9e6e81475dfcfb62dab574ac2dda38226c232bc5" - integrity sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg== +"@webassemblyjs/wasm-opt@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz#e6f71ed7ccae46781c206017d3c14c50efa8106b" + integrity sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw== dependencies: - "@webassemblyjs/ast" "1.12.1" - "@webassemblyjs/helper-buffer" "1.12.1" - "@webassemblyjs/wasm-gen" "1.12.1" - "@webassemblyjs/wasm-parser" "1.12.1" + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-buffer" "1.14.1" + "@webassemblyjs/wasm-gen" "1.14.1" + "@webassemblyjs/wasm-parser" "1.14.1" -"@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz#c47acb90e6f083391e3fa61d113650eea1e95937" - integrity sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ== +"@webassemblyjs/wasm-parser@1.14.1", "@webassemblyjs/wasm-parser@^1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz#b3e13f1893605ca78b52c68e54cf6a865f90b9fb" + integrity sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ== dependencies: - "@webassemblyjs/ast" "1.12.1" - "@webassemblyjs/helper-api-error" "1.11.6" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/ieee754" "1.11.6" - "@webassemblyjs/leb128" "1.11.6" - "@webassemblyjs/utf8" "1.11.6" + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-api-error" "1.13.2" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/ieee754" "1.13.2" + "@webassemblyjs/leb128" "1.13.2" + "@webassemblyjs/utf8" "1.13.2" -"@webassemblyjs/wast-printer@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz#bcecf661d7d1abdaf989d8341a4833e33e2b31ac" - integrity sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA== +"@webassemblyjs/wast-printer@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz#3bb3e9638a8ae5fdaf9610e7a06b4d9f9aa6fe07" + integrity sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw== dependencies: - "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/ast" "1.14.1" "@xtuc/long" "4.2.2" "@webpack-cli/configtest@^1.2.0": @@ -396,15 +412,15 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: mime-types "~2.1.34" negotiator "0.6.3" -acorn-import-attributes@^1.9.5: - version "1.9.5" - resolved "https://registry.yarnpkg.com/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz#7eb1557b1ba05ef18b5ed0ec67591bfab04688ef" - integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ== +acorn-import-phases@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz#16eb850ba99a056cb7cbfe872ffb8972e18c8bd7" + integrity sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ== -acorn@^8.7.1, acorn@^8.8.2: - version "8.12.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" - integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== +acorn@^8.15.0: + version "8.15.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" + integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== ajv-formats@^2.1.1: version "2.1.1" @@ -413,11 +429,6 @@ ajv-formats@^2.1.1: dependencies: ajv "^8.0.0" -ajv-keywords@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" - integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== - ajv-keywords@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" @@ -425,16 +436,6 @@ ajv-keywords@^5.1.0: dependencies: fast-deep-equal "^3.1.3" -ajv@^6.12.5: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - ajv@^8.0.0, ajv@^8.9.0: version "8.17.1" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" @@ -463,6 +464,11 @@ array-flatten@1.1.1: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== +baseline-browser-mapping@^2.9.0: + version "2.9.19" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz#3e508c43c46d961eb4d7d2e5b8d1dd0f9ee4f488" + integrity sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg== + batch@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" @@ -506,15 +512,16 @@ braces@^3.0.3, braces@~3.0.2: dependencies: fill-range "^7.1.1" -browserslist@^4.21.10: - version "4.23.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.3.tgz#debb029d3c93ebc97ffbc8d9cbb03403e227c800" - integrity sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA== +browserslist@^4.28.1: + version "4.28.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.1.tgz#7f534594628c53c63101079e27e40de490456a95" + integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA== dependencies: - caniuse-lite "^1.0.30001646" - electron-to-chromium "^1.5.4" - node-releases "^2.0.18" - update-browserslist-db "^1.1.0" + baseline-browser-mapping "^2.9.0" + caniuse-lite "^1.0.30001759" + electron-to-chromium "^1.5.263" + node-releases "^2.0.27" + update-browserslist-db "^1.2.0" buffer-from@^1.0.0: version "1.1.2" @@ -554,10 +561,10 @@ call-bound@^1.0.2: call-bind-apply-helpers "^1.0.2" get-intrinsic "^1.3.0" -caniuse-lite@^1.0.30001646: - version "1.0.30001653" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001653.tgz#b8af452f8f33b1c77f122780a4aecebea0caca56" - integrity sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw== +caniuse-lite@^1.0.30001759: + version "1.0.30001769" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz#1ad91594fad7dc233777c2781879ab5409f7d9c2" + integrity sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg== chokidar@^3.6.0: version "3.6.0" @@ -756,10 +763,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -electron-to-chromium@^1.5.4: - version "1.5.13" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz#1abf0410c5344b2b829b7247e031f02810d442e6" - integrity sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q== +electron-to-chromium@^1.5.263: + version "1.5.286" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz#142be1ab5e1cd5044954db0e5898f60a4960384e" + integrity sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A== encodeurl@~1.0.2: version "1.0.2" @@ -771,13 +778,13 @@ encodeurl@~2.0.0: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== -enhanced-resolve@^5.17.1: - version "5.17.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz#67bfbbcc2f81d511be77d686a90267ef7f898a15" - integrity sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg== +enhanced-resolve@^5.17.4: + version "5.19.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz#6687446a15e969eaa63c2fa2694510e17ae6d97c" + integrity sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg== dependencies: graceful-fs "^4.2.4" - tapable "^2.2.0" + tapable "^2.3.0" envinfo@^7.7.3: version "7.13.0" @@ -794,10 +801,10 @@ es-errors@^1.3.0: resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== -es-module-lexer@^1.2.1: - version "1.5.4" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.5.4.tgz#a8efec3a3da991e60efa6b633a7cad6ab8d26b78" - integrity sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw== +es-module-lexer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-2.0.0.tgz#f657cd7a9448dcdda9c070a3cb75e5dc1e85f5b1" + integrity sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw== es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: version "1.1.1" @@ -806,10 +813,10 @@ es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: dependencies: es-errors "^1.3.0" -escalade@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" - integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== +escalade@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== escape-html@~1.0.3: version "1.0.3" @@ -893,7 +900,7 @@ express@^4.21.2: utils-merge "1.0.1" vary "~1.1.2" -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: +fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== @@ -909,11 +916,6 @@ fast-glob@^3.2.11, fast-glob@^3.3.0: merge2 "^1.3.0" micromatch "^4.0.4" -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - fast-uri@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.1.tgz#cddd2eecfc83a71c1be2cc2ef2061331be8a7134" @@ -1294,11 +1296,6 @@ json-parse-even-better-errors@^2.3.1: resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - json-schema-traverse@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" @@ -1317,10 +1314,10 @@ launch-editor@^2.6.1: picocolors "^1.0.0" shell-quote "^1.8.1" -loader-runner@^4.2.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" - integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== +loader-runner@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.1.tgz#6c76ed29b0ccce9af379208299f07f876de737e3" + integrity sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q== locate-path@^5.0.0: version "5.0.0" @@ -1442,10 +1439,10 @@ node-forge@^1: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.2.tgz#d0d2659a26eef778bf84d73e7f55c08144ee7750" integrity sha512-6xKiQ+cph9KImrRh0VsjH2d8/GXA4FIMlgU4B757iI1ApvcyA9VlouP0yZJha01V+huImO+kKMU7ih+2+E14fw== -node-releases@^2.0.18: - version "2.0.18" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" - integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== +node-releases@^2.0.27: + version "2.0.27" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e" + integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" @@ -1542,11 +1539,16 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -picocolors@^1.0.0, picocolors@^1.0.1: +picocolors@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== +picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== + picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" @@ -1572,11 +1574,6 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" -punycode@^2.1.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" - integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== - qs@6.13.0: version "6.13.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" @@ -1715,19 +1712,10 @@ safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -schema-utils@^3.1.1, schema-utils@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" - integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== - dependencies: - "@types/json-schema" "^7.0.8" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - -schema-utils@^4.0.0, schema-utils@^4.2.0: - version "4.3.2" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.2.tgz#0c10878bf4a73fd2b1dfd14b9462b26788c806ae" - integrity sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ== +schema-utils@^4.0.0, schema-utils@^4.2.0, schema-utils@^4.3.0, schema-utils@^4.3.3: + version "4.3.3" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.3.tgz#5b1850912fa31df90716963d45d9121fdfc09f46" + integrity sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA== dependencies: "@types/json-schema" "^7.0.9" ajv "^8.9.0" @@ -1766,7 +1754,7 @@ send@0.19.0: range-parser "~1.2.1" statuses "2.0.1" -serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: +serialize-javascript@^6.0.0, serialize-javascript@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== @@ -1956,29 +1944,29 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -tapable@^2.1.1, tapable@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" - integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== +tapable@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.0.tgz#7e3ea6d5ca31ba8e078b560f0d83ce9a14aa8be6" + integrity sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg== -terser-webpack-plugin@^5.3.10: - version "5.3.10" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" - integrity sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w== +terser-webpack-plugin@^5.3.16: + version "5.3.16" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz#741e448cc3f93d8026ebe4f7ef9e4afacfd56330" + integrity sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q== dependencies: - "@jridgewell/trace-mapping" "^0.3.20" + "@jridgewell/trace-mapping" "^0.3.25" jest-worker "^27.4.5" - schema-utils "^3.1.1" - serialize-javascript "^6.0.1" - terser "^5.26.0" + schema-utils "^4.3.0" + serialize-javascript "^6.0.2" + terser "^5.31.1" -terser@^5.26.0: - version "5.31.6" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.31.6.tgz#c63858a0f0703988d0266a82fcbf2d7ba76422b1" - integrity sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg== +terser@^5.31.1: + version "5.46.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.46.0.tgz#1b81e560d584bbdd74a8ede87b4d9477b0ff9695" + integrity sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg== dependencies: "@jridgewell/source-map" "^0.3.3" - acorn "^8.8.2" + acorn "^8.15.0" commander "^2.20.0" source-map-support "~0.5.20" @@ -2032,20 +2020,13 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== -update-browserslist-db@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e" - integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== +update-browserslist-db@^1.2.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz#64d76db58713136acbeb4c49114366cc6cc2e80d" + integrity sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w== dependencies: - escalade "^3.1.2" - picocolors "^1.0.1" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" + escalade "^3.2.0" + picocolors "^1.1.1" util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" @@ -2067,10 +2048,10 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== -watchpack@^2.4.1: - version "2.4.2" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.2.tgz#2feeaed67412e7c33184e5a79ca738fbd38564da" - integrity sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw== +watchpack@^2.4.4: + version "2.5.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.5.1.tgz#dd38b601f669e0cbf567cb802e75cead82cde102" + integrity sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg== dependencies: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" @@ -2155,39 +2136,41 @@ webpack-merge@^5.7.3: flat "^5.0.2" wildcard "^2.0.0" -webpack-sources@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" - integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== +webpack-sources@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.3.tgz#d4bf7f9909675d7a070ff14d0ef2a4f3c982c723" + integrity sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg== webpack@^5.70.0: - version "5.94.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.94.0.tgz#77a6089c716e7ab90c1c67574a28da518a20970f" - integrity sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg== + version "5.104.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.104.1.tgz#94bd41eb5dbf06e93be165ba8be41b8260d4fb1a" + integrity sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA== dependencies: - "@types/estree" "^1.0.5" - "@webassemblyjs/ast" "^1.12.1" - "@webassemblyjs/wasm-edit" "^1.12.1" - "@webassemblyjs/wasm-parser" "^1.12.1" - acorn "^8.7.1" - acorn-import-attributes "^1.9.5" - browserslist "^4.21.10" + "@types/eslint-scope" "^3.7.7" + "@types/estree" "^1.0.8" + "@types/json-schema" "^7.0.15" + "@webassemblyjs/ast" "^1.14.1" + "@webassemblyjs/wasm-edit" "^1.14.1" + "@webassemblyjs/wasm-parser" "^1.14.1" + acorn "^8.15.0" + acorn-import-phases "^1.0.3" + browserslist "^4.28.1" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.17.1" - es-module-lexer "^1.2.1" + enhanced-resolve "^5.17.4" + es-module-lexer "^2.0.0" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" graceful-fs "^4.2.11" json-parse-even-better-errors "^2.3.1" - loader-runner "^4.2.0" + loader-runner "^4.3.1" mime-types "^2.1.27" neo-async "^2.6.2" - schema-utils "^3.2.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.3.10" - watchpack "^2.4.1" - webpack-sources "^3.2.3" + schema-utils "^4.3.3" + tapable "^2.3.0" + terser-webpack-plugin "^5.3.16" + watchpack "^2.4.4" + webpack-sources "^3.3.3" websocket-driver@>=0.5.1, websocket-driver@^0.7.4: version "0.7.4" From 8e792b7b9353de31d9fcb89bec2d6e8b865a4543 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:50:27 +0000 Subject: [PATCH 25/56] build(deps-dev): bump webpack in /wasm/zknym-lib/internal-dev (#6429) Bumps [webpack](https://github.com/webpack/webpack) from 5.77.0 to 5.104.1. - [Release notes](https://github.com/webpack/webpack/releases) - [Changelog](https://github.com/webpack/webpack/blob/main/CHANGELOG.md) - [Commits](https://github.com/webpack/webpack/compare/v5.77.0...v5.104.1) --- updated-dependencies: - dependency-name: webpack dependency-version: 5.104.1 dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- wasm/zknym-lib/internal-dev/yarn.lock | 551 +++++++++++++------------- 1 file changed, 270 insertions(+), 281 deletions(-) diff --git a/wasm/zknym-lib/internal-dev/yarn.lock b/wasm/zknym-lib/internal-dev/yarn.lock index 14f87b39b1..fec546cbea 100644 --- a/wasm/zknym-lib/internal-dev/yarn.lock +++ b/wasm/zknym-lib/internal-dev/yarn.lock @@ -7,45 +7,39 @@ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== -"@jridgewell/gen-mapping@^0.3.0": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" - integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== +"@jridgewell/gen-mapping@^0.3.5": + version "0.3.13" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f" + integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA== dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" + "@jridgewell/sourcemap-codec" "^1.5.0" + "@jridgewell/trace-mapping" "^0.3.24" -"@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.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== -"@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== +"@jridgewell/source-map@^0.3.3": + version "0.3.11" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.11.tgz#b21835cbd36db656b857c2ad02ebd413cc13a9ba" + integrity sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA== dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" -"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.14" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== +"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" + integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== -"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.17" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" - integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== +"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": + version "0.3.31" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0" + integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== dependencies: - "@jridgewell/resolve-uri" "3.1.0" - "@jridgewell/sourcemap-codec" "1.4.14" + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" "@leichtgewicht/ip-codec@^2.0.1": version "2.0.4" @@ -106,10 +100,10 @@ dependencies: "@types/node" "*" -"@types/eslint-scope@^3.7.3": - version "3.7.4" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" - integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== +"@types/eslint-scope@^3.7.7": + version "3.7.7" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" + integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== dependencies: "@types/eslint" "*" "@types/estree" "*" @@ -122,15 +116,10 @@ "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" - integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== - -"@types/estree@^0.0.51": - version "0.0.51" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" - integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== +"@types/estree@*", "@types/estree@^1.0.8": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" + integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": version "4.17.33" @@ -158,10 +147,10 @@ dependencies: "@types/node" "*" -"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": - version "7.0.11" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" - integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== +"@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.9": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== "@types/mime@*": version "3.0.1" @@ -217,125 +206,125 @@ dependencies: "@types/node" "*" -"@webassemblyjs/ast@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" - integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== +"@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.14.1.tgz#a9f6a07f2b03c95c8d38c4536a1fdfb521ff55b6" + integrity sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ== dependencies: - "@webassemblyjs/helper-numbers" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-numbers" "1.13.2" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" -"@webassemblyjs/floating-point-hex-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" - integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== +"@webassemblyjs/floating-point-hex-parser@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz#fcca1eeddb1cc4e7b6eed4fc7956d6813b21b9fb" + integrity sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA== -"@webassemblyjs/helper-api-error@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" - integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== +"@webassemblyjs/helper-api-error@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz#e0a16152248bc38daee76dd7e21f15c5ef3ab1e7" + integrity sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ== -"@webassemblyjs/helper-buffer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" - integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== +"@webassemblyjs/helper-buffer@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz#822a9bc603166531f7d5df84e67b5bf99b72b96b" + integrity sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA== -"@webassemblyjs/helper-numbers@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" - integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== +"@webassemblyjs/helper-numbers@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz#dbd932548e7119f4b8a7877fd5a8d20e63490b2d" + integrity sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA== dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/floating-point-hex-parser" "1.13.2" + "@webassemblyjs/helper-api-error" "1.13.2" "@xtuc/long" "4.2.2" -"@webassemblyjs/helper-wasm-bytecode@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" - integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== +"@webassemblyjs/helper-wasm-bytecode@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz#e556108758f448aae84c850e593ce18a0eb31e0b" + integrity sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA== -"@webassemblyjs/helper-wasm-section@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" - integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== +"@webassemblyjs/helper-wasm-section@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz#9629dda9c4430eab54b591053d6dc6f3ba050348" + integrity sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-buffer" "1.14.1" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/wasm-gen" "1.14.1" -"@webassemblyjs/ieee754@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" - integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== +"@webassemblyjs/ieee754@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz#1c5eaace1d606ada2c7fd7045ea9356c59ee0dba" + integrity sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" - integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== +"@webassemblyjs/leb128@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.13.2.tgz#57c5c3deb0105d02ce25fa3fd74f4ebc9fd0bbb0" + integrity sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" - integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== +"@webassemblyjs/utf8@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.13.2.tgz#917a20e93f71ad5602966c2d685ae0c6c21f60f1" + integrity sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ== -"@webassemblyjs/wasm-edit@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" - integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== +"@webassemblyjs/wasm-edit@^1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz#ac6689f502219b59198ddec42dcd496b1004d597" + integrity sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/helper-wasm-section" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-opt" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - "@webassemblyjs/wast-printer" "1.11.1" + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-buffer" "1.14.1" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/helper-wasm-section" "1.14.1" + "@webassemblyjs/wasm-gen" "1.14.1" + "@webassemblyjs/wasm-opt" "1.14.1" + "@webassemblyjs/wasm-parser" "1.14.1" + "@webassemblyjs/wast-printer" "1.14.1" -"@webassemblyjs/wasm-gen@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" - integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== +"@webassemblyjs/wasm-gen@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz#991e7f0c090cb0bb62bbac882076e3d219da9570" + integrity sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/ieee754" "1.13.2" + "@webassemblyjs/leb128" "1.13.2" + "@webassemblyjs/utf8" "1.13.2" -"@webassemblyjs/wasm-opt@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" - integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== +"@webassemblyjs/wasm-opt@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz#e6f71ed7ccae46781c206017d3c14c50efa8106b" + integrity sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-buffer" "1.14.1" + "@webassemblyjs/wasm-gen" "1.14.1" + "@webassemblyjs/wasm-parser" "1.14.1" -"@webassemblyjs/wasm-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" - integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== +"@webassemblyjs/wasm-parser@1.14.1", "@webassemblyjs/wasm-parser@^1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz#b3e13f1893605ca78b52c68e54cf6a865f90b9fb" + integrity sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-api-error" "1.13.2" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/ieee754" "1.13.2" + "@webassemblyjs/leb128" "1.13.2" + "@webassemblyjs/utf8" "1.13.2" -"@webassemblyjs/wast-printer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" - integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== +"@webassemblyjs/wast-printer@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz#3bb3e9638a8ae5fdaf9610e7a06b4d9f9aa6fe07" + integrity sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw== dependencies: - "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/ast" "1.14.1" "@xtuc/long" "4.2.2" "@webpack-cli/configtest@^1.2.0": @@ -373,15 +362,15 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: mime-types "~2.1.34" negotiator "0.6.3" -acorn-import-assertions@^1.7.6: - version "1.8.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" - integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== +acorn-import-phases@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz#16eb850ba99a056cb7cbfe872ffb8972e18c8bd7" + integrity sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ== -acorn@^8.5.0, acorn@^8.7.1: - version "8.8.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" - integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== +acorn@^8.15.0: + version "8.15.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" + integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== ajv-formats@^2.1.1: version "2.1.1" @@ -390,29 +379,14 @@ ajv-formats@^2.1.1: dependencies: ajv "^8.0.0" -ajv-keywords@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" - integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== - -ajv-keywords@^5.0.0: +ajv-keywords@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== dependencies: fast-deep-equal "^3.1.3" -ajv@^6.12.5: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ajv@^8.0.0, ajv@^8.8.0: +ajv@^8.0.0: version "8.12.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== @@ -422,6 +396,16 @@ ajv@^8.0.0, ajv@^8.8.0: require-from-string "^2.0.2" uri-js "^4.2.2" +ajv@^8.9.0: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" + integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== + dependencies: + fast-deep-equal "^3.1.3" + fast-uri "^3.0.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + ansi-html-community@^0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" @@ -450,6 +434,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +baseline-browser-mapping@^2.9.0: + version "2.9.19" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz#3e508c43c46d961eb4d7d2e5b8d1dd0f9ee4f488" + integrity sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg== + batch@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" @@ -503,15 +492,16 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.1.1" -browserslist@^4.14.5: - version "4.21.5" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" - integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== +browserslist@^4.28.1: + version "4.28.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.1.tgz#7f534594628c53c63101079e27e40de490456a95" + integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA== dependencies: - caniuse-lite "^1.0.30001449" - electron-to-chromium "^1.4.284" - node-releases "^2.0.8" - update-browserslist-db "^1.0.10" + baseline-browser-mapping "^2.9.0" + caniuse-lite "^1.0.30001759" + electron-to-chromium "^1.5.263" + node-releases "^2.0.27" + update-browserslist-db "^1.2.0" buffer-from@^1.0.0: version "1.1.2" @@ -536,10 +526,10 @@ call-bind@^1.0.0: function-bind "^1.1.1" get-intrinsic "^1.0.2" -caniuse-lite@^1.0.30001449: - version "1.0.30001474" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001474.tgz#13b6fe301a831fe666cce8ca4ef89352334133d5" - integrity sha512-iaIZ8gVrWfemh5DG3T9/YqarVZoYf0r188IjaGwx68j4Pf0SGY6CQkmJUIE+NZHkkecQGohzXmBGEwWDr9aM3Q== +caniuse-lite@^1.0.30001759: + version "1.0.30001769" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz#1ad91594fad7dc233777c2781879ab5409f7d9c2" + integrity sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg== chokidar@^3.5.3: version "3.5.3" @@ -733,38 +723,38 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -electron-to-chromium@^1.4.284: - version "1.4.352" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.352.tgz#be96bd7c2f4b980deebc9338a49a67430a33ed73" - integrity sha512-ikFUEyu5/q+wJpMOxWxTaEVk2M1qKqTGKKyfJmod1CPZxKfYnxVS41/GCBQg21ItBpZybyN8sNpRqCUGm+Zc4Q== +electron-to-chromium@^1.5.263: + version "1.5.286" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz#142be1ab5e1cd5044954db0e5898f60a4960384e" + integrity sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A== encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -enhanced-resolve@^5.10.0: - version "5.12.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz#300e1c90228f5b570c4d35babf263f6da7155634" - integrity sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ== +enhanced-resolve@^5.17.4: + version "5.19.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz#6687446a15e969eaa63c2fa2694510e17ae6d97c" + integrity sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg== dependencies: graceful-fs "^4.2.4" - tapable "^2.2.0" + tapable "^2.3.0" envinfo@^7.7.3: version "7.8.1" resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== -es-module-lexer@^0.9.0: - version "0.9.3" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" - integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== +es-module-lexer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-2.0.0.tgz#f657cd7a9448dcdda9c070a3cb75e5dc1e85f5b1" + integrity sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw== -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +escalade@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== escape-html@~1.0.3: version "1.0.3" @@ -879,10 +869,10 @@ fast-glob@^3.2.11, fast-glob@^3.3.0: merge2 "^1.3.0" micromatch "^4.0.4" -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== +fast-uri@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.0.tgz#66eecff6c764c0df9b762e62ca7edcfb53b4edfa" + integrity sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA== fastest-levenshtein@^1.0.12: version "1.0.16" @@ -1022,7 +1012,7 @@ globby@^13.1.1: merge2 "^1.4.1" slash "^4.0.0" -graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: +graceful-fs@^4.1.2, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -1267,11 +1257,6 @@ json-parse-even-better-errors@^2.3.1: resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - json-schema-traverse@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" @@ -1290,10 +1275,10 @@ launch-editor@^2.6.0: picocolors "^1.0.0" shell-quote "^1.7.3" -loader-runner@^4.2.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" - integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== +loader-runner@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.1.tgz#6c76ed29b0ccce9af379208299f07f876de737e3" + integrity sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q== locate-path@^5.0.0: version "5.0.0" @@ -1414,10 +1399,10 @@ node-forge@^1: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.3.tgz#0ad80f6333b3a0045e827ac20b7f735f93716751" integrity sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg== -node-releases@^2.0.8: - version "2.0.10" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" - integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== +node-releases@^2.0.27: + version "2.0.27" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e" + integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" @@ -1543,6 +1528,11 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== +picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== + picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" @@ -1713,24 +1703,15 @@ safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -schema-utils@^3.1.0, schema-utils@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" - integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== - dependencies: - "@types/json-schema" "^7.0.8" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - -schema-utils@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" - integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== +schema-utils@^4.0.0, schema-utils@^4.3.0, schema-utils@^4.3.3: + version "4.3.3" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.3.tgz#5b1850912fa31df90716963d45d9121fdfc09f46" + integrity sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA== dependencies: "@types/json-schema" "^7.0.9" - ajv "^8.8.0" + ajv "^8.9.0" ajv-formats "^2.1.1" - ajv-keywords "^5.0.0" + ajv-keywords "^5.1.0" select-hose@^2.0.0: version "2.0.0" @@ -1763,13 +1744,20 @@ send@0.18.0: range-parser "~1.2.1" statuses "2.0.1" -serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: +serialize-javascript@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz#b206efb27c3da0b0ab6b52f48d170b7996458e5c" integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== dependencies: randombytes "^2.1.0" +serialize-javascript@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" + integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== + dependencies: + randombytes "^2.1.0" + serve-index@^1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" @@ -1932,29 +1920,29 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -tapable@^2.1.1, tapable@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" - integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== +tapable@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.0.tgz#7e3ea6d5ca31ba8e078b560f0d83ce9a14aa8be6" + integrity sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg== -terser-webpack-plugin@^5.1.3: - version "5.3.7" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.7.tgz#ef760632d24991760f339fe9290deb936ad1ffc7" - integrity sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw== +terser-webpack-plugin@^5.3.16: + version "5.3.16" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz#741e448cc3f93d8026ebe4f7ef9e4afacfd56330" + integrity sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q== dependencies: - "@jridgewell/trace-mapping" "^0.3.17" + "@jridgewell/trace-mapping" "^0.3.25" jest-worker "^27.4.5" - schema-utils "^3.1.1" - serialize-javascript "^6.0.1" - terser "^5.16.5" + schema-utils "^4.3.0" + serialize-javascript "^6.0.2" + terser "^5.31.1" -terser@^5.16.5: - version "5.16.8" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.8.tgz#ccde583dabe71df3f4ed02b65eb6532e0fae15d5" - integrity sha512-QI5g1E/ef7d+PsDifb+a6nnVgC4F22Bg6T0xrBrz6iloVB4PUkkunp6V8nzoOOZJIzjWVdAGqCdlKlhLq/TbIA== +terser@^5.31.1: + version "5.46.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.46.0.tgz#1b81e560d584bbdd74a8ede87b4d9477b0ff9695" + integrity sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg== dependencies: - "@jridgewell/source-map" "^0.3.2" - acorn "^8.5.0" + "@jridgewell/source-map" "^0.3.3" + acorn "^8.15.0" commander "^2.20.0" source-map-support "~0.5.20" @@ -1988,13 +1976,13 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== -update-browserslist-db@^1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" - integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== +update-browserslist-db@^1.2.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz#64d76db58713136acbeb4c49114366cc6cc2e80d" + integrity sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w== dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" + escalade "^3.2.0" + picocolors "^1.1.1" uri-js@^4.2.2: version "4.4.1" @@ -2023,10 +2011,10 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== -watchpack@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" - integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== +watchpack@^2.4.4: + version "2.5.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.5.1.tgz#dd38b601f669e0cbf567cb802e75cead82cde102" + integrity sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg== dependencies: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" @@ -2111,40 +2099,41 @@ webpack-merge@^5.7.3: clone-deep "^4.0.1" wildcard "^2.0.0" -webpack-sources@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" - integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== +webpack-sources@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.3.tgz#d4bf7f9909675d7a070ff14d0ef2a4f3c982c723" + integrity sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg== webpack@^5.70.0: - version "5.77.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.77.0.tgz#dea3ad16d7ea6b84aa55fa42f4eac9f30e7eb9b4" - integrity sha512-sbGNjBr5Ya5ss91yzjeJTLKyfiwo5C628AFjEa6WSXcZa4E+F57om3Cc8xLb1Jh0b243AWuSYRf3dn7HVeFQ9Q== + version "5.104.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.104.1.tgz#94bd41eb5dbf06e93be165ba8be41b8260d4fb1a" + integrity sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA== 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" + "@types/eslint-scope" "^3.7.7" + "@types/estree" "^1.0.8" + "@types/json-schema" "^7.0.15" + "@webassemblyjs/ast" "^1.14.1" + "@webassemblyjs/wasm-edit" "^1.14.1" + "@webassemblyjs/wasm-parser" "^1.14.1" + acorn "^8.15.0" + acorn-import-phases "^1.0.3" + browserslist "^4.28.1" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.10.0" - es-module-lexer "^0.9.0" + enhanced-resolve "^5.17.4" + es-module-lexer "^2.0.0" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" - graceful-fs "^4.2.9" + graceful-fs "^4.2.11" json-parse-even-better-errors "^2.3.1" - loader-runner "^4.2.0" + loader-runner "^4.3.1" 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" + schema-utils "^4.3.3" + tapable "^2.3.0" + terser-webpack-plugin "^5.3.16" + watchpack "^2.4.4" + webpack-sources "^3.3.3" websocket-driver@>=0.5.1, websocket-driver@^0.7.4: version "0.7.4" From b92dd2f264a3b8b687700accb12113776d509460 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:50:47 +0000 Subject: [PATCH 26/56] build(deps-dev): bump webpack (#6428) Bumps [webpack](https://github.com/webpack/webpack) from 5.76.0 to 5.105.0. - [Release notes](https://github.com/webpack/webpack/releases) - [Changelog](https://github.com/webpack/webpack/blob/main/CHANGELOG.md) - [Commits](https://github.com/webpack/webpack/compare/v5.76.0...v5.105.0) --- updated-dependencies: - dependency-name: webpack dependency-version: 5.105.0 dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../js-examples/websocket/package-lock.json | 1234 +++++++---------- .../js-examples/websocket/package.json | 2 +- 2 files changed, 523 insertions(+), 713 deletions(-) diff --git a/clients/native/examples/js-examples/websocket/package-lock.json b/clients/native/examples/js-examples/websocket/package-lock.json index 6752aeb99b..9746d5eb1e 100644 --- a/clients/native/examples/js-examples/websocket/package-lock.json +++ b/clients/native/examples/js-examples/websocket/package-lock.json @@ -13,7 +13,7 @@ }, "devDependencies": { "clean-webpack-plugin": "^4.0.0", - "webpack": "^5.76.0", + "webpack": "^5.105.0", "webpack-cli": "^4.9.2", "webpack-dev-server": "^4.7.4" } @@ -28,16 +28,12 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" } }, "node_modules/@jridgewell/resolve-uri": { @@ -48,35 +44,27 @@ "node": ">=6.0.0" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", - "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@nodelib/fs.scandir": { @@ -153,27 +141,27 @@ } }, "node_modules/@types/eslint": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.1.tgz", - "integrity": "sha512-GE44+DNEyxxh2Kc6ro/VkIj+9ma0pO0bwv9+uHSyBrikYOHr8zYcdPvnBOp1aw8s+CjRvuSx7CyWqRrNFQ59mA==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, "node_modules/@types/eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==", + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "dependencies": { "@types/eslint": "*", "@types/estree": "*" } }, "node_modules/@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==" + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==" }, "node_modules/@types/express": { "version": "4.17.13", @@ -223,9 +211,9 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.10", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.10.tgz", - "integrity": "sha512-BLO9bBq59vW3fxCpD4o0N4U+DXsvwvIcl+jofw0frQo/GrBFC+/jRZj1E7kgp6dvTyNmA4y6JCV5Id/r3mNP5A==" + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" }, "node_modules/@types/mime": { "version": "1.3.2", @@ -300,133 +288,133 @@ } }, "node_modules/@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==" }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==" }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==" + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==" }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==" }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==" }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "dependencies": { - "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" } }, @@ -490,9 +478,9 @@ } }, "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "bin": { "acorn": "bin/acorn" }, @@ -500,12 +488,15 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "engines": { + "node": ">=10.13.0" + }, "peerDependencies": { - "acorn": "^8" + "acorn": "^8.14.0" } }, "node_modules/aggregate-error": { @@ -522,14 +513,14 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -540,7 +531,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, "dependencies": { "ajv": "^8.0.0" }, @@ -553,34 +543,15 @@ } } }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, "peerDependencies": { - "ajv": "^6.9.1" + "ajv": "^8.8.2" } }, "node_modules/ansi-html-community": { @@ -658,6 +629,14 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/baseline-browser-mapping": { + "version": "2.9.19", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", + "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, "node_modules/batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", @@ -757,9 +736,9 @@ } }, "node_modules/browserslist": { - "version": "4.20.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz", - "integrity": "sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "funding": [ { "type": "opencollective", @@ -768,14 +747,18 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "caniuse-lite": "^1.0.30001317", - "electron-to-chromium": "^1.4.84", - "escalade": "^3.1.1", - "node-releases": "^2.0.2", - "picocolors": "^1.0.0" + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" @@ -833,9 +816,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001320", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001320.tgz", - "integrity": "sha512-MWPzG54AGdo3nWx7zHZTefseM5Y1ccM7hlQKHRqJkPozUaw3hNbBTMmLn16GG2FUzjR13Cr3NPfhIieX5PzXDA==", + "version": "1.0.30001769", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz", + "integrity": "sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==", "funding": [ { "type": "opencollective", @@ -844,6 +827,10 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ] }, @@ -1303,9 +1290,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.92", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.92.tgz", - "integrity": "sha512-YAVbvQIcDE/IJ/vzDMjD484/hsRbFPW2qXJPaYTfOhtligmfYEYOep+5QojpaEU9kq6bMvNeC2aG7arYvTHYsA==" + "version": "1.5.286", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz", + "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==" }, "node_modules/encodeurl": { "version": "1.0.2", @@ -1317,12 +1304,12 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", - "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", + "version": "5.19.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz", + "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==", "dependencies": { "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "tapable": "^2.3.0" }, "engines": { "node": ">=10.13.0" @@ -1370,14 +1357,14 @@ } }, "node_modules/es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", + "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==" }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "engines": { "node": ">=6" } @@ -1573,10 +1560,20 @@ "node": ">=8.6" } }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ] }, "node_modules/fastest-levenshtein": { "version": "1.0.12", @@ -1823,9 +1820,9 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, "node_modules/handle-thing": { "version": "2.0.1", @@ -2385,9 +2382,9 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "node_modules/kind-of": { "version": "6.0.3", @@ -2399,11 +2396,15 @@ } }, "node_modules/loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", "engines": { "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/lodash": { @@ -2603,9 +2604,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", - "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==" + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==" }, "node_modules/normalize-path": { "version": "3.0.0", @@ -2881,9 +2882,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" }, "node_modules/picomatch": { "version": "2.3.0", @@ -3154,7 +3155,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -3262,13 +3262,14 @@ "dev": true }, "node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" }, "engines": { "node": ">= 10.13.0" @@ -3345,9 +3346,9 @@ } }, "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dependencies": { "randombytes": "^2.1.0" } @@ -3684,20 +3685,24 @@ } }, "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", "engines": { "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/terser": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.0.tgz", - "integrity": "sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA==", + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", + "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", "dependencies": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -3709,15 +3714,15 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz", - "integrity": "sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==", + "version": "5.3.16", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", + "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.2" + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" }, "engines": { "node": ">= 10.13.0" @@ -3800,20 +3805,33 @@ "node": ">= 0.8" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/uri-js/node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "engines": { - "node": ">=6" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, "node_modules/util-deprecate": { @@ -3856,9 +3874,9 @@ } }, "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", + "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -3877,34 +3895,35 @@ } }, "node_modules/webpack": { - "version": "5.76.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.0.tgz", - "integrity": "sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA==", + "version": "5.105.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.0.tgz", + "integrity": "sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw==", "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", + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.10.0", - "es-module-lexer": "^0.9.0", + "enhanced-resolve": "^5.19.0", + "es-module-lexer": "^2.0.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", + "loader-runner": "^4.3.1", "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" + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.16", + "watchpack": "^2.5.1", + "webpack-sources": "^3.3.3" }, "bin": { "webpack": "bin/webpack.js" @@ -4101,65 +4120,12 @@ "webpack": "^4.0.0 || ^5.0.0" } }, - "node_modules/webpack-dev-middleware/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, "node_modules/webpack-dev-middleware/node_modules/colorette": { "version": "2.0.16", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", "dev": true }, - "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/webpack-dev-middleware/node_modules/schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/webpack-dev-server": { "version": "4.7.4", "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.7.4.tgz", @@ -4212,34 +4178,6 @@ } } }, - "node_modules/webpack-dev-server/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack-dev-server/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, "node_modules/webpack-dev-server/node_modules/ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", @@ -4327,12 +4265,6 @@ "node": ">=8" } }, - "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, "node_modules/webpack-dev-server/node_modules/p-map": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", @@ -4363,25 +4295,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/webpack-dev-server/node_modules/schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/webpack-dev-server/node_modules/strip-ansi": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", @@ -4411,9 +4324,9 @@ } }, "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", "engines": { "node": ">=10.13.0" } @@ -4498,13 +4411,12 @@ "dev": true }, "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" } }, "@jridgewell/resolve-uri": { @@ -4512,32 +4424,27 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" }, - "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" - }, "@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==" }, "@jridgewell/trace-mapping": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", - "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "@nodelib/fs.scandir": { @@ -4605,27 +4512,27 @@ } }, "@types/eslint": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.1.tgz", - "integrity": "sha512-GE44+DNEyxxh2Kc6ro/VkIj+9ma0pO0bwv9+uHSyBrikYOHr8zYcdPvnBOp1aw8s+CjRvuSx7CyWqRrNFQ59mA==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", "requires": { "@types/estree": "*", "@types/json-schema": "*" } }, "@types/eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==", + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "requires": { "@types/eslint": "*", "@types/estree": "*" } }, "@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==" + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==" }, "@types/express": { "version": "4.17.13", @@ -4675,9 +4582,9 @@ } }, "@types/json-schema": { - "version": "7.0.10", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.10.tgz", - "integrity": "sha512-BLO9bBq59vW3fxCpD4o0N4U+DXsvwvIcl+jofw0frQo/GrBFC+/jRZj1E7kgp6dvTyNmA4y6JCV5Id/r3mNP5A==" + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" }, "@types/mime": { "version": "1.3.2", @@ -4752,133 +4659,133 @@ } }, "@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "requires": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==" }, "@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==" }, "@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==" + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==" }, "@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", "@xtuc/long": "4.2.2" } }, "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==" }, "@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" } }, "@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "requires": { "@xtuc/ieee754": "^1.2.0" } }, "@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "requires": { "@xtuc/long": "4.2.2" } }, "@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==" }, "@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" } }, "@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" } }, "@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "requires": { - "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" } }, @@ -4926,14 +4833,14 @@ } }, "acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==" + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==" }, - "acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", "requires": {} }, "aggregate-error": { @@ -4947,50 +4854,31 @@ } }, "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" } }, "ajv-formats": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, "requires": { "ajv": "^8.0.0" - }, - "dependencies": { - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } } }, "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "requires": {} + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "requires": { + "fast-deep-equal": "^3.1.3" + } }, "ansi-html-community": { "version": "0.0.8", @@ -5049,6 +4937,11 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "baseline-browser-mapping": { + "version": "2.9.19", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", + "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==" + }, "batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", @@ -5134,15 +5027,15 @@ } }, "browserslist": { - "version": "4.20.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz", - "integrity": "sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "requires": { - "caniuse-lite": "^1.0.30001317", - "electron-to-chromium": "^1.4.84", - "escalade": "^3.1.1", - "node-releases": "^2.0.2", - "picocolors": "^1.0.0" + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" } }, "buffer-from": { @@ -5185,9 +5078,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001320", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001320.tgz", - "integrity": "sha512-MWPzG54AGdo3nWx7zHZTefseM5Y1ccM7hlQKHRqJkPozUaw3hNbBTMmLn16GG2FUzjR13Cr3NPfhIieX5PzXDA==" + "version": "1.0.30001769", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz", + "integrity": "sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==" }, "chokidar": { "version": "3.5.3", @@ -5536,9 +5429,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.4.92", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.92.tgz", - "integrity": "sha512-YAVbvQIcDE/IJ/vzDMjD484/hsRbFPW2qXJPaYTfOhtligmfYEYOep+5QojpaEU9kq6bMvNeC2aG7arYvTHYsA==" + "version": "1.5.286", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz", + "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==" }, "encodeurl": { "version": "1.0.2", @@ -5547,12 +5440,12 @@ "dev": true }, "enhanced-resolve": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", - "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", + "version": "5.19.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz", + "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==", "requires": { "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "tapable": "^2.3.0" } }, "entities": { @@ -5582,14 +5475,14 @@ "dev": true }, "es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", + "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==" }, "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==" }, "escape-html": { "version": "1.0.3", @@ -5749,10 +5642,10 @@ } } }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + "fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==" }, "fastest-levenshtein": { "version": "1.0.12", @@ -5931,9 +5824,9 @@ } }, "graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, "handle-thing": { "version": "2.0.1", @@ -6330,9 +6223,9 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "kind-of": { "version": "6.0.3", @@ -6341,9 +6234,9 @@ "dev": true }, "loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==" + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==" }, "lodash": { "version": "4.17.21", @@ -6500,9 +6393,9 @@ "dev": true }, "node-releases": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", - "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==" + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==" }, "normalize-path": { "version": "3.0.0", @@ -6708,9 +6601,9 @@ "dev": true }, "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" }, "picomatch": { "version": "2.3.0", @@ -6921,8 +6814,7 @@ "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" }, "requires-port": { "version": "1.0.0", @@ -6983,13 +6875,14 @@ "dev": true }, "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" } }, "select-hose": { @@ -7049,9 +6942,9 @@ } }, "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "requires": { "randombytes": "^2.1.0" } @@ -7318,17 +7211,17 @@ "dev": true }, "tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==" }, "terser": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.0.tgz", - "integrity": "sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA==", + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", + "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", "requires": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -7341,15 +7234,15 @@ } }, "terser-webpack-plugin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz", - "integrity": "sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==", + "version": "5.3.16", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", + "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", "requires": { + "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1", - "terser": "^5.7.2" + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" } }, "thunky": { @@ -7394,19 +7287,13 @@ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "requires": { - "punycode": "^2.1.0" - }, - "dependencies": { - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - } + "escalade": "^3.2.0", + "picocolors": "^1.1.1" } }, "util-deprecate": { @@ -7439,9 +7326,9 @@ "dev": true }, "watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", + "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", "requires": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -7457,34 +7344,35 @@ } }, "webpack": { - "version": "5.76.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.0.tgz", - "integrity": "sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA==", + "version": "5.105.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.0.tgz", + "integrity": "sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw==", "requires": { - "@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", + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.10.0", - "es-module-lexer": "^0.9.0", + "enhanced-resolve": "^5.19.0", + "es-module-lexer": "^2.0.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", + "loader-runner": "^4.3.1", "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" + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.16", + "watchpack": "^2.5.1", + "webpack-sources": "^3.3.3" } }, "webpack-cli": { @@ -7602,50 +7490,11 @@ "schema-utils": "^4.0.0" }, "dependencies": { - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.3" - } - }, "colorette": { "version": "2.0.16", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", "dev": true - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - } } } }, @@ -7687,27 +7536,6 @@ "ws": "^8.4.2" }, "dependencies": { - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.3" - } - }, "ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", @@ -7768,12 +7596,6 @@ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, "p-map": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", @@ -7792,18 +7614,6 @@ "glob": "^7.1.3" } }, - "schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - } - }, "strip-ansi": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", @@ -7826,9 +7636,9 @@ } }, "webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==" + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==" }, "websocket-driver": { "version": "0.7.4", diff --git a/clients/native/examples/js-examples/websocket/package.json b/clients/native/examples/js-examples/websocket/package.json index 4eb9916d49..ee8cab91f1 100644 --- a/clients/native/examples/js-examples/websocket/package.json +++ b/clients/native/examples/js-examples/websocket/package.json @@ -19,7 +19,7 @@ "license": "Apache-2.0", "devDependencies": { "clean-webpack-plugin": "^4.0.0", - "webpack": "^5.76.0", + "webpack": "^5.105.0", "webpack-cli": "^4.9.2", "webpack-dev-server": "^4.7.4" }, From f9827f5dd4d37b83294c252523ae787f328524d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:51:19 +0000 Subject: [PATCH 27/56] build(deps): bump @isaacs/brace-expansion from 5.0.0 to 5.0.1 (#6415) Bumps @isaacs/brace-expansion from 5.0.0 to 5.0.1. --- updated-dependencies: - dependency-name: "@isaacs/brace-expansion" dependency-version: 5.0.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 542f2e8951..3b9917279a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2123,9 +2123,9 @@ integrity sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ== "@isaacs/brace-expansion@^5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz#4b3dabab7d8e75a429414a96bd67bf4c1d13e0f3" - integrity sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA== + version "5.0.1" + resolved "https://registry.yarnpkg.com/@isaacs/brace-expansion/-/brace-expansion-5.0.1.tgz#0ef5a92d91f2fff2a37646ce54da9e5f599f6eff" + integrity sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ== dependencies: "@isaacs/balanced-match" "^4.0.1" From 195c75d293af7b218a46b097afad929f61f24311 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:51:45 +0000 Subject: [PATCH 28/56] build(deps): bump mikefarah/yq from 4.50.1 to 4.52.2 (#6407) Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.50.1 to 4.52.2. - [Release notes](https://github.com/mikefarah/yq/releases) - [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt) - [Commits](https://github.com/mikefarah/yq/compare/v4.50.1...v4.52.2) --- updated-dependencies: - dependency-name: mikefarah/yq dependency-version: 4.52.2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-check-ns-api-version.yml | 2 +- .github/workflows/ci-check-nym-stats-api-version.yml | 2 +- .github/workflows/push-credential-proxy.yaml | 2 +- .github/workflows/push-data-observatory.yaml | 2 +- .github/workflows/push-network-monitor.yaml | 2 +- .github/workflows/push-nym-api.yaml | 2 +- .github/workflows/push-nym-node.yaml | 2 +- .github/workflows/push-nym-statistics-api.yaml | 2 +- .github/workflows/push-nyx-chain-watcher.yaml | 2 +- .github/workflows/push-validator-rewarder.yaml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci-check-ns-api-version.yml b/.github/workflows/ci-check-ns-api-version.yml index e767c26112..19a48d10ff 100644 --- a/.github/workflows/ci-check-ns-api-version.yml +++ b/.github/workflows/ci-check-ns-api-version.yml @@ -16,7 +16,7 @@ jobs: uses: actions/checkout@v6 - name: Get version from cargo.toml - uses: mikefarah/yq@v4.50.1 + uses: mikefarah/yq@v4.52.2 id: get_version with: cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml diff --git a/.github/workflows/ci-check-nym-stats-api-version.yml b/.github/workflows/ci-check-nym-stats-api-version.yml index 1e88be2d4f..0f0eb6f8a9 100644 --- a/.github/workflows/ci-check-nym-stats-api-version.yml +++ b/.github/workflows/ci-check-nym-stats-api-version.yml @@ -16,7 +16,7 @@ jobs: uses: actions/checkout@v6 - name: Get version from cargo.toml - uses: mikefarah/yq@v4.50.1 + uses: mikefarah/yq@v4.52.2 id: get_version with: cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml diff --git a/.github/workflows/push-credential-proxy.yaml b/.github/workflows/push-credential-proxy.yaml index dc0f1ca8f6..89198c6c3a 100644 --- a/.github/workflows/push-credential-proxy.yaml +++ b/.github/workflows/push-credential-proxy.yaml @@ -26,7 +26,7 @@ jobs: git config --global user.name "Lawrence Stalder" - name: Get version from cargo.toml - uses: mikefarah/yq@v4.50.1 + uses: mikefarah/yq@v4.52.2 id: get_version with: cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/nym-credential-proxy/Cargo.toml diff --git a/.github/workflows/push-data-observatory.yaml b/.github/workflows/push-data-observatory.yaml index e708db30ff..34b9c7fcb3 100644 --- a/.github/workflows/push-data-observatory.yaml +++ b/.github/workflows/push-data-observatory.yaml @@ -26,7 +26,7 @@ jobs: git config --global user.name "Lawrence Stalder" - name: Get version from cargo.toml - uses: mikefarah/yq@v4.50.1 + uses: mikefarah/yq@v4.52.2 id: get_version with: cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml diff --git a/.github/workflows/push-network-monitor.yaml b/.github/workflows/push-network-monitor.yaml index 0c69c28816..9295e4769b 100644 --- a/.github/workflows/push-network-monitor.yaml +++ b/.github/workflows/push-network-monitor.yaml @@ -26,7 +26,7 @@ jobs: git config --global user.name "Lawrence Stalder" - name: Get version from cargo.toml - uses: mikefarah/yq@v4.50.1 + uses: mikefarah/yq@v4.52.2 id: get_version with: cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/nym-network-monitor/Cargo.toml diff --git a/.github/workflows/push-nym-api.yaml b/.github/workflows/push-nym-api.yaml index 6f6c1c037a..9bc7074df0 100644 --- a/.github/workflows/push-nym-api.yaml +++ b/.github/workflows/push-nym-api.yaml @@ -26,7 +26,7 @@ jobs: git config --global user.name "Lawrence Stalder" - name: Get version from cargo.toml - uses: mikefarah/yq@v4.50.1 + uses: mikefarah/yq@v4.52.2 id: get_version with: cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/nym-api/Cargo.toml diff --git a/.github/workflows/push-nym-node.yaml b/.github/workflows/push-nym-node.yaml index fdec95302d..94ec7eac4b 100644 --- a/.github/workflows/push-nym-node.yaml +++ b/.github/workflows/push-nym-node.yaml @@ -26,7 +26,7 @@ jobs: git config --global user.name "Lawrence Stalder" - name: Get version from cargo.toml - uses: mikefarah/yq@v4.50.1 + uses: mikefarah/yq@v4.52.2 id: get_version with: cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml diff --git a/.github/workflows/push-nym-statistics-api.yaml b/.github/workflows/push-nym-statistics-api.yaml index c1b23f46a4..68968d1f02 100644 --- a/.github/workflows/push-nym-statistics-api.yaml +++ b/.github/workflows/push-nym-statistics-api.yaml @@ -26,7 +26,7 @@ jobs: git config --global user.name "Lawrence Stalder" - name: Get version from cargo.toml - uses: mikefarah/yq@v4.50.1 + uses: mikefarah/yq@v4.52.2 id: get_version with: cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml diff --git a/.github/workflows/push-nyx-chain-watcher.yaml b/.github/workflows/push-nyx-chain-watcher.yaml index ff1dcf25ba..2a77459392 100644 --- a/.github/workflows/push-nyx-chain-watcher.yaml +++ b/.github/workflows/push-nyx-chain-watcher.yaml @@ -26,7 +26,7 @@ jobs: git config --global user.name "Lawrence Stalder" - name: Get version from cargo.toml - uses: mikefarah/yq@v4.50.1 + uses: mikefarah/yq@v4.52.2 id: get_version with: cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml diff --git a/.github/workflows/push-validator-rewarder.yaml b/.github/workflows/push-validator-rewarder.yaml index e940f9faa3..b7b2ac830b 100644 --- a/.github/workflows/push-validator-rewarder.yaml +++ b/.github/workflows/push-validator-rewarder.yaml @@ -26,7 +26,7 @@ jobs: git config --global user.name "Lawrence Stalder" - name: Get version from cargo.toml - uses: mikefarah/yq@v4.50.1 + uses: mikefarah/yq@v4.52.2 id: get_version with: cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/Cargo.toml From 5f2bc60c2c67ee6a55042c216a0a4c9e03915960 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:53:24 +0000 Subject: [PATCH 29/56] build(deps): bump next in /nym-node-status-api/nym-node-status-ui (#6385) Bumps [next](https://github.com/vercel/next.js) from 15.4.10 to 16.1.5. - [Release notes](https://github.com/vercel/next.js/releases) - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js) - [Commits](https://github.com/vercel/next.js/compare/v15.4.10...v16.1.5) --- updated-dependencies: - dependency-name: next dependency-version: 16.1.5 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../nym-node-status-ui/package.json | 2 +- .../nym-node-status-ui/pnpm-lock.yaml | 113 ++++++++++-------- 2 files changed, 61 insertions(+), 54 deletions(-) diff --git a/nym-node-status-api/nym-node-status-ui/package.json b/nym-node-status-api/nym-node-status-ui/package.json index 1926f207a8..96c735fb15 100644 --- a/nym-node-status-api/nym-node-status-ui/package.json +++ b/nym-node-status-api/nym-node-status-ui/package.json @@ -22,7 +22,7 @@ "d3-array": "^3.2.4", "dayjs": "^1.11.13", "material-react-table": "^3.2.1", - "next": "^15.4.10", + "next": "^16.1.5", "openapi-typescript": "^7.5.2", "react": "^19.0.0", "react-country-flag": "^3.1.0", diff --git a/nym-node-status-api/nym-node-status-ui/pnpm-lock.yaml b/nym-node-status-api/nym-node-status-ui/pnpm-lock.yaml index 50f734bb65..bd6aa4ac2d 100644 --- a/nym-node-status-api/nym-node-status-ui/pnpm-lock.yaml +++ b/nym-node-status-api/nym-node-status-ui/pnpm-lock.yaml @@ -22,7 +22,7 @@ importers: version: 7.2.0(@emotion/react@11.14.0(@types/react@19.0.7)(react@19.0.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.0.7)(react@19.0.0))(@types/react@19.0.7)(react@19.0.0))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@mui/material-nextjs': specifier: ^7.2.0 - version: 7.2.0(@emotion/cache@11.14.0)(@emotion/react@11.14.0(@types/react@19.0.7)(react@19.0.0))(@types/react@19.0.7)(next@15.4.10(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0) + version: 7.2.0(@emotion/cache@11.14.0)(@emotion/react@11.14.0(@types/react@19.0.7)(react@19.0.0))(@types/react@19.0.7)(next@16.1.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0) '@mui/x-charts': specifier: ^8.8.0 version: 8.8.0(@emotion/react@11.14.0(@types/react@19.0.7)(react@19.0.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.0.7)(react@19.0.0))(@types/react@19.0.7)(react@19.0.0))(@mui/material@7.2.0(@emotion/react@11.14.0(@types/react@19.0.7)(react@19.0.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.0.7)(react@19.0.0))(@types/react@19.0.7)(react@19.0.0))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@mui/system@7.2.0(@emotion/react@11.14.0(@types/react@19.0.7)(react@19.0.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.0.7)(react@19.0.0))(@types/react@19.0.7)(react@19.0.0))(@types/react@19.0.7)(react@19.0.0))(@types/react@19.0.7)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) @@ -42,8 +42,8 @@ importers: specifier: ^3.2.1 version: 3.2.1(e4be24f02074e47c0e16001efb50991b) next: - specifier: ^15.4.10 - version: 15.4.10(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + specifier: ^16.1.5 + version: 16.1.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) openapi-typescript: specifier: ^7.5.2 version: 7.5.2(typescript@5.7.3) @@ -179,8 +179,8 @@ packages: cpu: [x64] os: [win32] - '@emnapi/runtime@1.7.1': - resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==} + '@emnapi/runtime@1.8.1': + resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} '@emotion/babel-plugin@11.13.5': resolution: {integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==} @@ -572,53 +572,53 @@ packages: '@mui/system': ^5.15.14 || ^6.0.0 || ^7.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 - '@next/env@15.4.10': - resolution: {integrity: sha512-knhmoJ0Vv7VRf6pZEPSnciUG1S4bIhWx+qTYBW/AjxEtlzsiNORPk8sFDCEvqLfmKuey56UB9FL1UdHEV3uBrg==} + '@next/env@16.1.5': + resolution: {integrity: sha512-CRSCPJiSZoi4Pn69RYBDI9R7YK2g59vLexPQFXY0eyw+ILevIenCywzg+DqmlBik9zszEnw2HLFOUlLAcJbL7g==} - '@next/swc-darwin-arm64@15.4.8': - resolution: {integrity: sha512-Pf6zXp7yyQEn7sqMxur6+kYcywx5up1J849psyET7/8pG2gQTVMjU3NzgIt8SeEP5to3If/SaWmaA6H6ysBr1A==} + '@next/swc-darwin-arm64@16.1.5': + resolution: {integrity: sha512-eK7Wdm3Hjy/SCL7TevlH0C9chrpeOYWx2iR7guJDaz4zEQKWcS1IMVfMb9UKBFMg1XgzcPTYPIp1Vcpukkjg6Q==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@15.4.8': - resolution: {integrity: sha512-xla6AOfz68a6kq3gRQccWEvFC/VRGJmA/QuSLENSO7CZX5WIEkSz7r1FdXUjtGCQ1c2M+ndUAH7opdfLK1PQbw==} + '@next/swc-darwin-x64@16.1.5': + resolution: {integrity: sha512-foQscSHD1dCuxBmGkbIr6ScAUF6pRoDZP6czajyvmXPAOFNnQUJu2Os1SGELODjKp/ULa4fulnBWoHV3XdPLfA==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-linux-arm64-gnu@15.4.8': - resolution: {integrity: sha512-y3fmp+1Px/SJD+5ntve5QLZnGLycsxsVPkTzAc3zUiXYSOlTPqT8ynfmt6tt4fSo1tAhDPmryXpYKEAcoAPDJw==} + '@next/swc-linux-arm64-gnu@16.1.5': + resolution: {integrity: sha512-qNIb42o3C02ccIeSeKjacF3HXotGsxh/FMk/rSRmCzOVMtoWH88odn2uZqF8RLsSUWHcAqTgYmPD3pZ03L9ZAA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-arm64-musl@15.4.8': - resolution: {integrity: sha512-DX/L8VHzrr1CfwaVjBQr3GWCqNNFgyWJbeQ10Lx/phzbQo3JNAxUok1DZ8JHRGcL6PgMRgj6HylnLNndxn4Z6A==} + '@next/swc-linux-arm64-musl@16.1.5': + resolution: {integrity: sha512-U+kBxGUY1xMAzDTXmuVMfhaWUZQAwzRaHJ/I6ihtR5SbTVUEaDRiEU9YMjy1obBWpdOBuk1bcm+tsmifYSygfw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@next/swc-linux-x64-gnu@15.4.8': - resolution: {integrity: sha512-9fLAAXKAL3xEIFdKdzG5rUSvSiZTLLTCc6JKq1z04DR4zY7DbAPcRvNm3K1inVhTiQCs19ZRAgUerHiVKMZZIA==} + '@next/swc-linux-x64-gnu@16.1.5': + resolution: {integrity: sha512-gq2UtoCpN7Ke/7tKaU7i/1L7eFLfhMbXjNghSv0MVGF1dmuoaPeEVDvkDuO/9LVa44h5gqpWeJ4mRRznjDv7LA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-linux-x64-musl@15.4.8': - resolution: {integrity: sha512-s45V7nfb5g7dbS7JK6XZDcapicVrMMvX2uYgOHP16QuKH/JA285oy6HcxlKqwUNaFY/UC6EvQ8QZUOo19cBKSA==} + '@next/swc-linux-x64-musl@16.1.5': + resolution: {integrity: sha512-bQWSE729PbXT6mMklWLf8dotislPle2L70E9q6iwETYEOt092GDn0c+TTNj26AjmeceSsC4ndyGsK5nKqHYXjQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@next/swc-win32-arm64-msvc@15.4.8': - resolution: {integrity: sha512-KjgeQyOAq7t/HzAJcWPGA8X+4WY03uSCZ2Ekk98S9OgCFsb6lfBE3dbUzUuEQAN2THbwYgFfxX2yFTCMm8Kehw==} + '@next/swc-win32-arm64-msvc@16.1.5': + resolution: {integrity: sha512-LZli0anutkIllMtTAWZlDqdfvjWX/ch8AFK5WgkNTvaqwlouiD1oHM+WW8RXMiL0+vAkAJyAGEzPPjO+hnrSNQ==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-x64-msvc@15.4.8': - resolution: {integrity: sha512-Exsmf/+42fWVnLMaZHzshukTBxZrSwuuLKFvqhGHJ+mC1AokqieLY/XzAl3jc/CqhXLqLY3RRjkKJ9YnLPcRWg==} + '@next/swc-win32-x64-msvc@16.1.5': + resolution: {integrity: sha512-7is37HJTNQGhjPpQbkKjKEboHYQnCgpVt/4rBrrln0D9nderNxZ8ZWs8w1fAtzUx7wEyYjQ+/13myFgFj6K2Ng==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -747,6 +747,10 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + baseline-browser-mapping@2.9.19: + resolution: {integrity: sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==} + hasBin: true + bezier-easing@2.1.0: resolution: {integrity: sha512-gbIqZ/eslnUFC1tjEvtz0sgx+xTK20wDnYMIA27VA04R7w6xxXQPZDbibjA9DTWZRA2CXtwHykkVzlCaAJAZig==} @@ -757,8 +761,8 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001760: - resolution: {integrity: sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==} + caniuse-lite@1.0.30001766: + resolution: {integrity: sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==} change-case@5.4.4: resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==} @@ -956,9 +960,9 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - next@15.4.10: - resolution: {integrity: sha512-itVlc79QjpKMFMRhP+kbGKaSG/gZM6RCvwhEbwmCNF06CdDiNaoHcbeg0PqkEa2GOcn8KJ0nnc7+yL7EjoYLHQ==} - engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + next@16.1.5: + resolution: {integrity: sha512-f+wE+NSbiQgh3DSAlTaw2FwY5yGdVViAtp8TotNQj4kk4Q8Bh1sC/aL9aH+Rg1YAVn18OYXsRDT7U/079jgP7w==} + engines: {node: '>=20.9.0'} hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 @@ -1263,7 +1267,7 @@ snapshots: '@biomejs/cli-win32-x64@1.9.4': optional: true - '@emnapi/runtime@1.7.1': + '@emnapi/runtime@1.8.1': dependencies: tslib: 2.8.1 optional: true @@ -1436,7 +1440,7 @@ snapshots: '@img/sharp-wasm32@0.34.5': dependencies: - '@emnapi/runtime': 1.7.1 + '@emnapi/runtime': 1.8.1 optional: true '@img/sharp-win32-arm64@0.34.5': @@ -1475,11 +1479,11 @@ snapshots: optionalDependencies: '@types/react': 19.0.7 - '@mui/material-nextjs@7.2.0(@emotion/cache@11.14.0)(@emotion/react@11.14.0(@types/react@19.0.7)(react@19.0.0))(@types/react@19.0.7)(next@15.4.10(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0)': + '@mui/material-nextjs@7.2.0(@emotion/cache@11.14.0)(@emotion/react@11.14.0(@types/react@19.0.7)(react@19.0.0))(@types/react@19.0.7)(next@16.1.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(react@19.0.0)': dependencies: '@babel/runtime': 7.27.6 '@emotion/react': 11.14.0(@types/react@19.0.7)(react@19.0.0) - next: 15.4.10(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + next: 16.1.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) react: 19.0.0 optionalDependencies: '@emotion/cache': 11.14.0 @@ -1646,30 +1650,30 @@ snapshots: transitivePeerDependencies: - '@types/react' - '@next/env@15.4.10': {} + '@next/env@16.1.5': {} - '@next/swc-darwin-arm64@15.4.8': + '@next/swc-darwin-arm64@16.1.5': optional: true - '@next/swc-darwin-x64@15.4.8': + '@next/swc-darwin-x64@16.1.5': optional: true - '@next/swc-linux-arm64-gnu@15.4.8': + '@next/swc-linux-arm64-gnu@16.1.5': optional: true - '@next/swc-linux-arm64-musl@15.4.8': + '@next/swc-linux-arm64-musl@16.1.5': optional: true - '@next/swc-linux-x64-gnu@15.4.8': + '@next/swc-linux-x64-gnu@16.1.5': optional: true - '@next/swc-linux-x64-musl@15.4.8': + '@next/swc-linux-x64-musl@16.1.5': optional: true - '@next/swc-win32-arm64-msvc@15.4.8': + '@next/swc-win32-arm64-msvc@16.1.5': optional: true - '@next/swc-win32-x64-msvc@15.4.8': + '@next/swc-win32-x64-msvc@16.1.5': optional: true '@popperjs/core@2.11.8': {} @@ -1796,6 +1800,8 @@ snapshots: balanced-match@1.0.2: {} + baseline-browser-mapping@2.9.19: {} + bezier-easing@2.1.0: {} brace-expansion@2.0.1: @@ -1804,7 +1810,7 @@ snapshots: callsites@3.1.0: {} - caniuse-lite@1.0.30001760: {} + caniuse-lite@1.0.30001766: {} change-case@5.4.4: {} @@ -1974,24 +1980,25 @@ snapshots: nanoid@3.3.11: {} - next@15.4.10(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + next@16.1.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0): dependencies: - '@next/env': 15.4.10 + '@next/env': 16.1.5 '@swc/helpers': 0.5.15 - caniuse-lite: 1.0.30001760 + baseline-browser-mapping: 2.9.19 + caniuse-lite: 1.0.30001766 postcss: 8.4.31 react: 19.0.0 react-dom: 19.0.0(react@19.0.0) styled-jsx: 5.1.6(react@19.0.0) optionalDependencies: - '@next/swc-darwin-arm64': 15.4.8 - '@next/swc-darwin-x64': 15.4.8 - '@next/swc-linux-arm64-gnu': 15.4.8 - '@next/swc-linux-arm64-musl': 15.4.8 - '@next/swc-linux-x64-gnu': 15.4.8 - '@next/swc-linux-x64-musl': 15.4.8 - '@next/swc-win32-arm64-msvc': 15.4.8 - '@next/swc-win32-x64-msvc': 15.4.8 + '@next/swc-darwin-arm64': 16.1.5 + '@next/swc-darwin-x64': 16.1.5 + '@next/swc-linux-arm64-gnu': 16.1.5 + '@next/swc-linux-arm64-musl': 16.1.5 + '@next/swc-linux-x64-gnu': 16.1.5 + '@next/swc-linux-x64-musl': 16.1.5 + '@next/swc-win32-arm64-msvc': 16.1.5 + '@next/swc-win32-x64-msvc': 16.1.5 sharp: 0.34.5 transitivePeerDependencies: - '@babel/core' From 5dc6546f1c26c49fd2868272c7c9d793ec46656e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:53:44 +0000 Subject: [PATCH 30/56] build(deps): bump lodash from 4.17.21 to 4.17.23 (#6369) Bumps [lodash](https://github.com/lodash/lodash) from 4.17.21 to 4.17.23. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23) --- updated-dependencies: - dependency-name: lodash dependency-version: 4.17.23 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 3b9917279a..7850a893c0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15583,9 +15583,9 @@ lodash.words@^4.2.0: integrity sha512-mXxqd8Yx9BGPij3lZKFSdOsjOTbL4krbCCp9slEozaN4EMppA2dFmK/f8HeohodprY6W0vOdiQ5WFgPaTI75xQ== lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + version "4.17.23" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.23.tgz#f113b0378386103be4f6893388c73d0bde7f2c5a" + integrity sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w== log-symbols@^4.1.0: version "4.1.0" From a7068ea421878652ee05d6c4df3338145f08c6a5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:54:34 +0000 Subject: [PATCH 31/56] build(deps): bump lodash-es from 4.17.21 to 4.17.23 (#6360) Bumps [lodash-es](https://github.com/lodash/lodash) from 4.17.21 to 4.17.23. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23) --- updated-dependencies: - dependency-name: lodash-es dependency-version: 4.17.23 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 7850a893c0..68cbca7e37 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15538,9 +15538,9 @@ locate-path@^7.1.0: p-locate "^6.0.0" lodash-es@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" - integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== + version "4.17.23" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.23.tgz#58c4360fd1b5d33afc6c0bbd3d1149349b1138e0" + integrity sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg== lodash.debounce@^4.0.8: version "4.0.8" From 1219dcf874080b4b0966c89382d13d0a31282c17 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:54:54 +0000 Subject: [PATCH 32/56] build(deps-dev): bump lodash in /sdk/typescript/codegen/contract-clients (#6359) Bumps [lodash](https://github.com/lodash/lodash) from 4.17.21 to 4.17.23. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23) --- updated-dependencies: - dependency-name: lodash dependency-version: 4.17.23 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../codegen/contract-clients/package-lock.json | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/sdk/typescript/codegen/contract-clients/package-lock.json b/sdk/typescript/codegen/contract-clients/package-lock.json index 37c65830b5..39043a4278 100644 --- a/sdk/typescript/codegen/contract-clients/package-lock.json +++ b/sdk/typescript/codegen/contract-clients/package-lock.json @@ -318,7 +318,6 @@ "integrity": "sha512-c10uXxFz1+51VR0szeB1phn482O03uJiSQ+mZXpeq7IBtU2Hst6Vj1Ttjbx+nlxekhoSGG1jZ0JQ1ewXWYQ6IA==", "dev": true, "license": "SEE LICENSE IN LICENSE", - "peer": true, "dependencies": { "@chain-registry/v2-types": "^0.53.146" } @@ -328,8 +327,7 @@ "resolved": "https://registry.npmjs.org/@chain-registry/v2-types/-/v2-types-0.53.146.tgz", "integrity": "sha512-GnqdNnEJ+ZTAc/0S9fQbwL5GpIvF3LZ/P3o6qh6EyITSiRA1Y55FXs59eSddltpPX5EgyWDwNpJjY+Q5uYlAkA==", "dev": true, - "license": "SEE LICENSE IN LICENSE", - "peer": true + "license": "SEE LICENSE IN LICENSE" }, "node_modules/@cosmwasm/ts-codegen": { "version": "1.13.3", @@ -1229,7 +1227,6 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, - "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -3475,10 +3472,11 @@ } }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "dev": true, + "license": "MIT" }, "node_modules/lru-cache": { "version": "10.4.3", @@ -5165,7 +5163,6 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" From d46e967b5b1aac69ed0369f14f1c71fcea50bfcb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:55:12 +0000 Subject: [PATCH 33/56] build(deps): bump lodash in /sdk/typescript/packages/nodejs-client (#6354) Bumps [lodash](https://github.com/lodash/lodash) from 4.17.21 to 4.17.23. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23) --- updated-dependencies: - dependency-name: lodash dependency-version: 4.17.23 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- sdk/typescript/packages/nodejs-client/yarn.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sdk/typescript/packages/nodejs-client/yarn.lock b/sdk/typescript/packages/nodejs-client/yarn.lock index e2fdd3fe38..18aff2b1e8 100644 --- a/sdk/typescript/packages/nodejs-client/yarn.lock +++ b/sdk/typescript/packages/nodejs-client/yarn.lock @@ -91,10 +91,10 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@nymproject/nym-client-wasm-node@>=1.2.4-rc.2 || ^1": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@nymproject/nym-client-wasm-node/-/nym-client-wasm-node-1.2.3.tgz#e75e234714494fafffb86115cdee6759dcede366" - integrity sha512-fUGld4MJOgnvyqk5/KIpFePIXn8Nsl/7T/jh9a9WdTWntECnnJ/DBqoO+6NzDkyXaLYhByqR7reO8ZApNR0YCw== +"@nymproject/nym-client-wasm-node@>=1.4.1-rc.3 || ^1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@nymproject/nym-client-wasm-node/-/nym-client-wasm-node-1.4.1.tgz#3467e0b389cfec79cde1f4a75cfb8469752585a2" + integrity sha512-+bUIIiZGcv9GPOpKl6Pas2UochIac9EWxT24vmhx+x/Y4B6y4PpFtaVj+TtNwFtCu+/6w2GH0tb7UAJIzpJSQw== "@rollup/plugin-commonjs@^24.0.1": version "24.1.0" @@ -1819,9 +1819,9 @@ lodash.merge@^4.6.2: integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== lodash@^4.7.0: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + version "4.17.23" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.23.tgz#f113b0378386103be4f6893388c73d0bde7f2c5a" + integrity sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w== loose-envify@^1.4.0: version "1.4.0" From ff9365760933c840fbb1eab91830ac39e63d65a0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:55:29 +0000 Subject: [PATCH 34/56] build(deps): bump lodash from 4.17.21 to 4.17.23 in /documentation/docs (#6353) Bumps [lodash](https://github.com/lodash/lodash) from 4.17.21 to 4.17.23. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23) --- updated-dependencies: - dependency-name: lodash dependency-version: 4.17.23 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- documentation/docs/pnpm-lock.yaml | 59 +++++++++++++++++-------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/documentation/docs/pnpm-lock.yaml b/documentation/docs/pnpm-lock.yaml index 24f3297fd2..d2e836eb37 100644 --- a/documentation/docs/pnpm-lock.yaml +++ b/documentation/docs/pnpm-lock.yaml @@ -817,7 +817,7 @@ packages: '@mui/base@5.0.0-beta.40-1': resolution: {integrity: sha512-agKXuNNy0bHUmeU7pNmoZwNFr7Hiyhojkb9+2PVyDG5+6RafYuyMgbrav8CndsB7KUc/U51JAw9vKNDLYBzaUA==} engines: {node: '>=12.0.0'} - deprecated: This package has been replaced by @base-ui-components/react + deprecated: This package has been replaced by @base-ui/react peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -3390,8 +3390,8 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.9.7: - resolution: {integrity: sha512-k9xFKplee6KIio3IDbwj+uaCLpqzOwakOgmqzPezM0sFJlFKcg30vk2wOiAJtkTSfx0SSQDSe8q+mWA/fSH5Zg==} + baseline-browser-mapping@2.9.17: + resolution: {integrity: sha512-agD0MgJFUP/4nvjqzIB29zRPUuCF7Ge6mEv9s8dHrtYD7QWXRcx75rOADE/d5ah1NI+0vkDl0yorDd5U852IQQ==} hasBin: true bech32@1.1.4: @@ -3510,6 +3510,9 @@ packages: caniuse-lite@1.0.30001760: resolution: {integrity: sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==} + caniuse-lite@1.0.30001765: + resolution: {integrity: sha512-LWcNtSyZrakjECqmpP4qdg0MMGdN368D7X8XvvAqOcqMv0RxnlqVKZl2V6/mBR68oYMxOZPLw/gO7DuisMHUvQ==} + cardinal@2.1.1: resolution: {integrity: sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==} hasBin: true @@ -5355,11 +5358,11 @@ packages: modern-ahocorasick@1.1.0: resolution: {integrity: sha512-sEKPVl2rM+MNVkGQt3ChdmD8YsigmXdn5NifZn6jiwn9LRJpWm8F3guhaqrJT/JOat6pwpbXEk6kv+b9DMIjsQ==} - motion-dom@12.23.23: - resolution: {integrity: sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA==} + motion-dom@12.28.1: + resolution: {integrity: sha512-xqgID69syDvXwFJnUd5bW6ajGUAr/qevRoUe/EqpsXUbVIopyWrAOiwQOhpgVQD+B7Ra60zTdj5gVkmwncebMg==} - motion-utils@12.23.6: - resolution: {integrity: sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==} + motion-utils@12.27.2: + resolution: {integrity: sha512-B55gcoL85Mcdt2IEStY5EEAsrMSVE2sI14xQ/uAdPL+mfQxhKKFaEag9JmfxedJOR4vZpBGoPeC/Gm13I/4g5Q==} mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} @@ -6338,8 +6341,8 @@ packages: uglify-js: optional: true - terser@5.44.1: - resolution: {integrity: sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==} + terser@5.46.0: + resolution: {integrity: sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==} engines: {node: '>=10'} hasBin: true @@ -6597,8 +6600,8 @@ packages: uploadthing: optional: true - update-browserslist-db@1.2.2: - resolution: {integrity: sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==} + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -6696,8 +6699,8 @@ packages: vscode-textmate@8.0.0: resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==} - watchpack@2.4.4: - resolution: {integrity: sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==} + watchpack@2.5.1: + resolution: {integrity: sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==} engines: {node: '>=10.13.0'} web-namespaces@2.0.1: @@ -12009,7 +12012,7 @@ snapshots: base64-js@1.5.1: {} - baseline-browser-mapping@2.9.7: {} + baseline-browser-mapping@2.9.17: {} bech32@1.1.4: {} @@ -12079,11 +12082,11 @@ snapshots: browserslist@4.28.1: dependencies: - baseline-browser-mapping: 2.9.7 - caniuse-lite: 1.0.30001760 + baseline-browser-mapping: 2.9.17 + caniuse-lite: 1.0.30001765 electron-to-chromium: 1.5.267 node-releases: 2.0.27 - update-browserslist-db: 1.2.2(browserslist@4.28.1) + update-browserslist-db: 1.2.3(browserslist@4.28.1) bs58@4.0.1: dependencies: @@ -12135,6 +12138,8 @@ snapshots: caniuse-lite@1.0.30001760: {} + caniuse-lite@1.0.30001765: {} + cardinal@2.1.1: dependencies: ansicolors: 0.3.2 @@ -13171,8 +13176,8 @@ snapshots: framer-motion@12.23.12(@emotion/is-prop-valid@1.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - motion-dom: 12.23.23 - motion-utils: 12.23.6 + motion-dom: 12.28.1 + motion-utils: 12.27.2 tslib: 2.8.1 optionalDependencies: '@emotion/is-prop-valid': 1.3.1 @@ -14491,11 +14496,11 @@ snapshots: modern-ahocorasick@1.1.0: {} - motion-dom@12.23.23: + motion-dom@12.28.1: dependencies: - motion-utils: 12.23.6 + motion-utils: 12.27.2 - motion-utils@12.23.6: {} + motion-utils@12.27.2: {} mri@1.2.0: {} @@ -15775,10 +15780,10 @@ snapshots: jest-worker: 27.5.1 schema-utils: 4.3.3 serialize-javascript: 6.0.2 - terser: 5.44.1 + terser: 5.46.0 webpack: 5.101.3 - terser@5.44.1: + terser@5.46.0: dependencies: '@jridgewell/source-map': 0.3.11 acorn: 8.15.0 @@ -16054,7 +16059,7 @@ snapshots: optionalDependencies: idb-keyval: 6.2.2 - update-browserslist-db@1.2.2(browserslist@4.28.1): + update-browserslist-db@1.2.3(browserslist@4.28.1): dependencies: browserslist: 4.28.1 escalade: 3.2.0 @@ -16160,7 +16165,7 @@ snapshots: vscode-textmate@8.0.0: {} - watchpack@2.4.4: + watchpack@2.5.1: dependencies: glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 @@ -16198,7 +16203,7 @@ snapshots: schema-utils: 4.3.3 tapable: 2.3.0 terser-webpack-plugin: 5.3.16(webpack@5.101.3) - watchpack: 2.4.4 + watchpack: 2.5.1 webpack-sources: 3.3.3 transitivePeerDependencies: - '@swc/core' From 8e278866c7ad3433b27bbb1397f6035d2bdced9a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:55:56 +0000 Subject: [PATCH 35/56] build(deps): bump lodash (#6351) Bumps [lodash](https://github.com/lodash/lodash) from 4.17.21 to 4.17.23. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23) --- updated-dependencies: - dependency-name: lodash dependency-version: 4.17.23 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../examples/js-examples/websocket/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/native/examples/js-examples/websocket/package-lock.json b/clients/native/examples/js-examples/websocket/package-lock.json index 9746d5eb1e..83a7418cec 100644 --- a/clients/native/examples/js-examples/websocket/package-lock.json +++ b/clients/native/examples/js-examples/websocket/package-lock.json @@ -2408,9 +2408,9 @@ } }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==" }, "node_modules/lower-case": { "version": "2.0.2", @@ -6239,9 +6239,9 @@ "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==" }, "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==" }, "lower-case": { "version": "2.0.2", From 8bca0698ee3c8713b3dfecb63f42b5fbb084a223 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:56:15 +0000 Subject: [PATCH 36/56] build(deps): bump lodash-es in /documentation/docs (#6350) Bumps [lodash-es](https://github.com/lodash/lodash) from 4.17.21 to 4.17.23. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23) --- updated-dependencies: - dependency-name: lodash-es dependency-version: 4.17.23 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> From 9513eb458b44c60289c87759e8bac2a04f2c7fe9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:58:08 +0000 Subject: [PATCH 37/56] build(deps): bump rsa from 0.9.8 to 0.9.10 (#6311) Bumps [rsa](https://github.com/RustCrypto/RSA) from 0.9.8 to 0.9.10. - [Changelog](https://github.com/RustCrypto/RSA/blob/v0.9.10/CHANGELOG.md) - [Commits](https://github.com/RustCrypto/RSA/compare/v0.9.8...v0.9.10) --- updated-dependencies: - dependency-name: rsa dependency-version: 0.9.10 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> From 492eb22d7414b73a46a9f3962d71c033c507c4e6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:58:33 +0000 Subject: [PATCH 38/56] build(deps): bump qs and express in /wasm/mix-fetch/internal-dev (#6308) Bumps [qs](https://github.com/ljharb/qs) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together. Updates `qs` from 6.13.0 to 6.14.1 - [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md) - [Commits](https://github.com/ljharb/qs/compare/v6.13.0...v6.14.1) Updates `express` from 4.21.2 to 4.22.1 - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/v4.22.1/History.md) - [Commits](https://github.com/expressjs/express/compare/4.21.2...v4.22.1) --- updated-dependencies: - dependency-name: qs dependency-version: 6.14.1 dependency-type: indirect - dependency-name: express dependency-version: 4.22.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- wasm/mix-fetch/internal-dev/package-lock.json | 48 ++-- wasm/mix-fetch/internal-dev/yarn.lock | 211 +++++++++--------- 2 files changed, 135 insertions(+), 124 deletions(-) diff --git a/wasm/mix-fetch/internal-dev/package-lock.json b/wasm/mix-fetch/internal-dev/package-lock.json index e4a1791162..afe79b3098 100644 --- a/wasm/mix-fetch/internal-dev/package-lock.json +++ b/wasm/mix-fetch/internal-dev/package-lock.json @@ -1471,40 +1471,40 @@ } }, "node_modules/express": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", - "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", + "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", "dev": true, "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", + "body-parser": "~1.20.3", + "content-disposition": "~0.5.4", "content-type": "~1.0.4", - "cookie": "0.7.1", - "cookie-signature": "1.0.6", + "cookie": "~0.7.1", + "cookie-signature": "~1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", + "finalhandler": "~1.3.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.0", "merge-descriptors": "1.0.3", "methods": "~1.1.2", - "on-finished": "2.4.1", + "on-finished": "~2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.12", + "path-to-regexp": "~0.1.12", "proxy-addr": "~2.0.7", - "qs": "6.13.0", + "qs": "~6.14.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", + "send": "~0.19.0", + "serve-static": "~1.16.2", "setprototypeof": "1.2.0", - "statuses": "2.0.1", + "statuses": "~2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" @@ -1524,6 +1524,22 @@ "dev": true, "license": "MIT" }, + "node_modules/express/node_modules/qs": { + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", + "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", diff --git a/wasm/mix-fetch/internal-dev/yarn.lock b/wasm/mix-fetch/internal-dev/yarn.lock index 7eed240bce..484b776f5b 100644 --- a/wasm/mix-fetch/internal-dev/yarn.lock +++ b/wasm/mix-fetch/internal-dev/yarn.lock @@ -492,23 +492,23 @@ binary-extensions@^2.0.0: resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -body-parser@1.20.3: - version "1.20.3" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" - integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g== +body-parser@~1.20.3: + version "1.20.4" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.4.tgz#f8e20f4d06ca8a50a71ed329c15dccad1cdc547f" + integrity sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA== dependencies: - bytes "3.1.2" + bytes "~3.1.2" content-type "~1.0.5" 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.13.0" - raw-body "2.5.2" + destroy "~1.2.0" + http-errors "~2.0.1" + iconv-lite "~0.4.24" + on-finished "~2.4.1" + qs "~6.14.0" + raw-body "~2.5.3" type-is "~1.6.18" - unpipe "1.0.0" + unpipe "~1.0.0" bonjour-service@^1.2.1: version "1.3.0" @@ -553,9 +553,9 @@ bytes@3.0.0: resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz" integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== -bytes@3.1.2: +bytes@~3.1.2: version "3.1.2" - resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: @@ -648,9 +648,9 @@ connect-history-api-fallback@^2.0.0: resolved "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz" integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== -content-disposition@0.5.4: +content-disposition@~0.5.4: version "0.5.4" - resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== dependencies: safe-buffer "5.2.1" @@ -660,15 +660,15 @@ content-type@~1.0.4, content-type@~1.0.5: resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" - integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== +cookie-signature@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.7.tgz#ab5dd7ab757c54e60f37ef6550f481c426d10454" + integrity sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA== -cookie@0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.1.tgz#2f73c42142d5d5cf71310a74fc4ae61670e5dbc9" - integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w== +cookie@~0.7.1: + version "0.7.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" + integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== copy-webpack-plugin@^11.0.0: version "11.0.0" @@ -728,7 +728,7 @@ define-lazy-prop@^3.0.0: resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== -depd@2.0.0: +depd@2.0.0, depd@~2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== @@ -738,7 +738,7 @@ depd@~1.1.2: resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== -destroy@1.2.0: +destroy@1.2.0, destroy@~1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== @@ -781,11 +781,6 @@ electron-to-chromium@^1.5.263: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz#142be1ab5e1cd5044954db0e5898f60a4960384e" integrity sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A== -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" - integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== - encodeurl@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" @@ -877,38 +872,38 @@ events@^3.2.0: integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== express@^4.21.2: - version "4.21.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.21.2.tgz#cf250e48362174ead6cea4a566abef0162c1ec32" - integrity sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA== + version "4.22.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.22.1.tgz#1de23a09745a4fffdb39247b344bb5eaff382069" + integrity sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.20.3" - content-disposition "0.5.4" + body-parser "~1.20.3" + content-disposition "~0.5.4" content-type "~1.0.4" - cookie "0.7.1" - cookie-signature "1.0.6" + cookie "~0.7.1" + cookie-signature "~1.0.6" debug "2.6.9" depd "2.0.0" encodeurl "~2.0.0" escape-html "~1.0.3" etag "~1.8.1" - finalhandler "1.3.1" - fresh "0.5.2" - http-errors "2.0.0" + finalhandler "~1.3.1" + fresh "~0.5.2" + http-errors "~2.0.0" merge-descriptors "1.0.3" methods "~1.1.2" - on-finished "2.4.1" + on-finished "~2.4.1" parseurl "~1.3.3" - path-to-regexp "0.1.12" + path-to-regexp "~0.1.12" proxy-addr "~2.0.7" - qs "6.13.0" + qs "~6.14.0" range-parser "~1.2.1" safe-buffer "5.2.1" - send "0.19.0" - serve-static "1.16.2" + send "~0.19.0" + serve-static "~1.16.2" setprototypeof "1.2.0" - statuses "2.0.1" + statuses "~2.0.1" type-is "~1.6.18" utils-merge "1.0.1" vary "~1.1.2" @@ -960,17 +955,17 @@ fill-range@^7.1.1: dependencies: to-regex-range "^5.0.1" -finalhandler@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.1.tgz#0c575f1d1d324ddd1da35ad7ece3df7d19088019" - integrity sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ== +finalhandler@~1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.2.tgz#1ebc2228fc7673aac4a472c310cc05b77d852b88" + integrity sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg== dependencies: debug "2.6.9" encodeurl "~2.0.0" escape-html "~1.0.3" - on-finished "2.4.1" + on-finished "~2.4.1" parseurl "~1.3.3" - statuses "2.0.1" + statuses "~2.0.2" unpipe "~1.0.0" find-up@^4.0.0: @@ -991,9 +986,9 @@ forwarded@0.2.0: resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== -fresh@0.5.2: +fresh@~0.5.2: version "0.5.2" - resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== fsevents@~2.3.2: @@ -1127,17 +1122,6 @@ http-deceiver@^1.2.7: resolved "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz" integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" - 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.npmjs.org/http-errors/-/http-errors-1.6.3.tgz" @@ -1148,6 +1132,17 @@ http-errors@~1.6.2: setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" +http-errors@~2.0.0, http-errors@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.1.tgz#36d2f65bc909c8790018dd36fb4d93da6caae06b" + integrity sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ== + dependencies: + depd "~2.0.0" + inherits "~2.0.4" + setprototypeof "~1.2.0" + statuses "~2.0.2" + toidentifier "~1.0.1" + http-parser-js@>=0.5.1: version "0.5.8" resolved "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz" @@ -1178,9 +1173,9 @@ hyperdyperid@^1.2.0: resolved "https://registry.yarnpkg.com/hyperdyperid/-/hyperdyperid-1.2.0.tgz#59668d323ada92228d2a869d3e474d5a33b69e6b" integrity sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A== -iconv-lite@0.4.24: +iconv-lite@~0.4.24: version "0.4.24" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" @@ -1203,7 +1198,7 @@ inherits@2.0.3: resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== -inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: +inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3, inherits@~2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -1477,7 +1472,7 @@ obuf@^1.0.0, obuf@^1.1.2: resolved "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== -on-finished@2.4.1, on-finished@^2.4.1: +on-finished@^2.4.1, on-finished@~2.4.1: version "2.4.1" resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== @@ -1547,7 +1542,7 @@ path-parse@^1.0.7: resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-to-regexp@0.1.12: +path-to-regexp@~0.1.12: version "0.1.12" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.12.tgz#d5e1a12e478a976d432ef3c58d534b9923164bb7" integrity sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ== @@ -1597,12 +1592,12 @@ punycode@^2.1.0: resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== -qs@6.13.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" - integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== +qs@~6.14.0: + version "6.14.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.1.tgz#a41d85b9d3902f31d27861790506294881871159" + integrity sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ== dependencies: - side-channel "^1.0.6" + side-channel "^1.1.0" queue-microtask@^1.2.2: version "1.2.3" @@ -1621,15 +1616,15 @@ range-parser@^1.2.1, range-parser@~1.2.1: resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.5.2: - version "2.5.2" - resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz" - integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== +raw-body@~2.5.3: + version "2.5.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.3.tgz#11c6650ee770a7de1b494f197927de0c923822e2" + integrity sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA== dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" + bytes "~3.1.2" + http-errors "~2.0.1" + iconv-lite "~0.4.24" + unpipe "~1.0.0" readable-stream@^2.0.1: version "2.3.8" @@ -1758,24 +1753,24 @@ selfsigned@^2.4.1: "@types/node-forge" "^1.3.0" node-forge "^1" -send@0.19.0: - version "0.19.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8" - integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== +send@~0.19.0, send@~0.19.1: + version "0.19.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.19.2.tgz#59bc0da1b4ea7ad42736fd642b1c4294e114ff29" + integrity sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg== dependencies: debug "2.6.9" depd "2.0.0" destroy "1.2.0" - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" etag "~1.8.1" - fresh "0.5.2" - http-errors "2.0.0" + fresh "~0.5.2" + http-errors "~2.0.1" mime "1.6.0" ms "2.1.3" - on-finished "2.4.1" + on-finished "~2.4.1" range-parser "~1.2.1" - statuses "2.0.1" + statuses "~2.0.2" serialize-javascript@^6.0.0: version "6.0.1" @@ -1804,22 +1799,22 @@ serve-index@^1.9.1: mime-types "~2.1.17" parseurl "~1.3.2" -serve-static@1.16.2: - version "1.16.2" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.2.tgz#b6a5343da47f6bdd2673848bf45754941e803296" - integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw== +serve-static@~1.16.2: + version "1.16.3" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.3.tgz#a97b74d955778583f3862a4f0b841eb4d5d78cf9" + integrity sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA== dependencies: encodeurl "~2.0.0" escape-html "~1.0.3" parseurl "~1.3.3" - send "0.19.0" + send "~0.19.1" setprototypeof@1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz" integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== -setprototypeof@1.2.0: +setprototypeof@1.2.0, setprototypeof@~1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== @@ -1877,7 +1872,7 @@ side-channel-weakmap@^1.0.2: object-inspect "^1.13.3" side-channel-map "^1.0.1" -side-channel@^1.0.6: +side-channel@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9" integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== @@ -1938,16 +1933,16 @@ spdy@^4.0.2: select-hose "^2.0.0" spdy-transport "^3.0.0" -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - "statuses@>= 1.4.0 < 2": version "1.5.0" resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== +statuses@~2.0.1, statuses@~2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.2.tgz#8f75eecef765b5e1cfcdc080da59409ed424e382" + integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw== + string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" @@ -2017,9 +2012,9 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -toidentifier@1.0.1: +toidentifier@~1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== tree-dump@^1.0.1: @@ -2040,7 +2035,7 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" -unpipe@1.0.0, unpipe@~1.0.0: +unpipe@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== From 0ca122c56b050834b2623734a0c4224c24030d8a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:58:50 +0000 Subject: [PATCH 39/56] build(deps): bump qs and express (#6307) Bumps [qs](https://github.com/ljharb/qs) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together. Updates `qs` from 6.11.0 to 6.14.1 - [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md) - [Commits](https://github.com/ljharb/qs/compare/v6.11.0...v6.14.1) Updates `express` from 4.19.2 to 4.22.1 - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/v4.22.1/History.md) - [Commits](https://github.com/expressjs/express/compare/4.19.2...v4.22.1) --- updated-dependencies: - dependency-name: qs dependency-version: 6.14.1 dependency-type: indirect - dependency-name: express dependency-version: 4.22.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../js-examples/websocket/package-lock.json | 732 ++++++++++++------ 1 file changed, 476 insertions(+), 256 deletions(-) diff --git a/clients/native/examples/js-examples/websocket/package-lock.json b/clients/native/examples/js-examples/websocket/package-lock.json index 83a7418cec..e30503e936 100644 --- a/clients/native/examples/js-examples/websocket/package-lock.json +++ b/clients/native/examples/js-examples/websocket/package-lock.json @@ -653,23 +653,23 @@ } }, "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", + "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", "dev": true, "dependencies": { - "bytes": "3.1.2", + "bytes": "~3.1.2", "content-type": "~1.0.5", "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.2", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.14.0", + "raw-body": "~2.5.3", "type-is": "~1.6.18", - "unpipe": "1.0.0" + "unpipe": "~1.0.0" }, "engines": { "node": ">= 0.8", @@ -806,6 +806,35 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/camel-case": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", @@ -999,9 +1028,9 @@ } }, "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true, "engines": { "node": ">= 0.6" @@ -1283,6 +1312,20 @@ "tslib": "^2.0.3" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -1295,9 +1338,9 @@ "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==" }, "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "dev": true, "engines": { "node": ">= 0.8" @@ -1336,13 +1379,10 @@ } }, "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4" - }, "engines": { "node": ">= 0.4" } @@ -1361,6 +1401,18 @@ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==" }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -1461,45 +1513,49 @@ } }, "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", + "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", "dev": true, "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.2", - "content-disposition": "0.5.4", + "body-parser": "~1.20.3", + "content-disposition": "~0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", - "cookie-signature": "1.0.6", + "cookie": "~0.7.1", + "cookie-signature": "~1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "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", + "finalhandler": "~1.3.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.0", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", - "on-finished": "2.4.1", + "on-finished": "~2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "~0.1.12", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "~6.14.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "~0.19.0", + "serve-static": "~1.16.2", "setprototypeof": "1.2.0", - "statuses": "2.0.1", + "statuses": "~2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" }, "engines": { "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/express/node_modules/array-flatten": { @@ -1615,17 +1671,17 @@ } }, "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", + "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", "dev": true, "dependencies": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", - "on-finished": "2.4.1", + "on-finished": "~2.4.1", "parseurl": "~1.3.3", - "statuses": "2.0.1", + "statuses": "~2.0.2", "unpipe": "~1.0.0" }, "engines": { @@ -1633,9 +1689,9 @@ } }, "node_modules/finalhandler/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "dev": true, "engines": { "node": ">= 0.8" @@ -1715,16 +1771,21 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -1733,6 +1794,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -1808,12 +1882,12 @@ } }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1862,22 +1936,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, "engines": { "node": ">= 0.4" @@ -1991,19 +2053,23 @@ "dev": true }, "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "dev": true, "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" }, "engines": { "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/http-errors/node_modules/depd": { @@ -2016,9 +2082,9 @@ } }, "node_modules/http-errors/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "dev": true, "engines": { "node": ">= 0.8" @@ -2420,6 +2486,15 @@ "tslib": "^2.0.3" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -2442,10 +2517,13 @@ } }, "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/merge-stream": { "version": "2.0.0", @@ -2650,10 +2728,13 @@ } }, "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "dev": true, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -2867,9 +2948,9 @@ "dev": true }, "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", "dev": true }, "node_modules/path-type": { @@ -2986,12 +3067,12 @@ } }, "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", + "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", "dev": true, "dependencies": { - "side-channel": "^1.0.4" + "side-channel": "^1.1.0" }, "engines": { "node": ">=0.6" @@ -3038,15 +3119,15 @@ } }, "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", "dev": true, "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" }, "engines": { "node": ">= 0.8" @@ -3298,24 +3379,24 @@ } }, "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", + "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", "dev": true, "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", + "fresh": "~0.5.2", + "http-errors": "~2.0.1", "mime": "1.6.0", "ms": "2.1.3", - "on-finished": "2.4.1", + "on-finished": "~2.4.1", "range-parser": "~1.2.1", - "statuses": "2.0.1" + "statuses": "~2.0.2" }, "engines": { "node": ">= 0.8.0" @@ -3337,9 +3418,9 @@ "dev": true }, "node_modules/send/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "dev": true, "engines": { "node": ">= 0.8" @@ -3399,15 +3480,15 @@ "dev": true }, "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", + "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", "dev": true, "dependencies": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "~0.19.1" }, "engines": { "node": ">= 0.8.0" @@ -3470,15 +3551,69 @@ } }, "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -4955,23 +5090,23 @@ "dev": true }, "body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", + "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", "dev": true, "requires": { - "bytes": "3.1.2", + "bytes": "~3.1.2", "content-type": "~1.0.5", "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.2", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.14.0", + "raw-body": "~2.5.3", "type-is": "~1.6.18", - "unpipe": "1.0.0" + "unpipe": "~1.0.0" }, "dependencies": { "bytes": { @@ -5068,6 +5203,26 @@ "set-function-length": "^1.2.1" } }, + "call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + } + }, + "call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "requires": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + } + }, "camel-case": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", @@ -5202,9 +5357,9 @@ "dev": true }, "cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true }, "cookie-signature": { @@ -5422,6 +5577,17 @@ "tslib": "^2.0.3" } }, + "dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "requires": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + } + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -5434,9 +5600,9 @@ "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==" }, "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "dev": true }, "enhanced-resolve": { @@ -5460,13 +5626,10 @@ "dev": true }, "es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.2.4" - } + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true }, "es-errors": { "version": "1.3.0", @@ -5479,6 +5642,15 @@ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==" }, + "es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "requires": { + "es-errors": "^1.3.0" + } + }, "escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -5554,39 +5726,39 @@ } }, "express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", + "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", "dev": true, "requires": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.2", - "content-disposition": "0.5.4", + "body-parser": "~1.20.3", + "content-disposition": "~0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", - "cookie-signature": "1.0.6", + "cookie": "~0.7.1", + "cookie-signature": "~1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "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", + "finalhandler": "~1.3.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.0", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", - "on-finished": "2.4.1", + "on-finished": "~2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "~0.1.12", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "~6.14.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "~0.19.0", + "serve-static": "~1.16.2", "setprototypeof": "1.2.0", - "statuses": "2.0.1", + "statuses": "~2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" @@ -5681,24 +5853,24 @@ } }, "finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", + "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", "dev": true, "requires": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", - "on-finished": "2.4.1", + "on-finished": "~2.4.1", "parseurl": "~1.3.3", - "statuses": "2.0.1", + "statuses": "~2.0.2", "unpipe": "~1.0.0" }, "dependencies": { "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "dev": true } } @@ -5747,16 +5919,31 @@ "dev": true }, "get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, "requires": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + } + }, + "get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "requires": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" } }, "get-stream": { @@ -5815,13 +6002,10 @@ } }, "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.3" - } + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true }, "graceful-fs": { "version": "4.2.11", @@ -5857,16 +6041,10 @@ "es-define-property": "^1.0.0" } }, - "has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true - }, "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true }, "hasown": { @@ -5945,16 +6123,16 @@ "dev": true }, "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "dev": true, "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" }, "dependencies": { "depd": { @@ -5964,9 +6142,9 @@ "dev": true }, "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "dev": true } } @@ -6251,6 +6429,12 @@ "tslib": "^2.0.3" } }, + "math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -6267,9 +6451,9 @@ } }, "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", "dev": true }, "merge-stream": { @@ -6427,9 +6611,9 @@ "dev": true }, "object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "dev": true }, "object-is": { @@ -6589,9 +6773,9 @@ "dev": true }, "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", "dev": true }, "path-type": { @@ -6686,12 +6870,12 @@ } }, "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", + "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", "dev": true, "requires": { - "side-channel": "^1.0.4" + "side-channel": "^1.1.0" } }, "queue-microtask": { @@ -6715,15 +6899,15 @@ "dev": true }, "raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", "dev": true, "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" }, "dependencies": { "bytes": { @@ -6901,24 +7085,24 @@ } }, "send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", + "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", "dev": true, "requires": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", + "fresh": "~0.5.2", + "http-errors": "~2.0.1", "mime": "1.6.0", "ms": "2.1.3", - "on-finished": "2.4.1", + "on-finished": "~2.4.1", "range-parser": "~1.2.1", - "statuses": "2.0.1" + "statuses": "~2.0.2" }, "dependencies": { "depd": { @@ -6934,9 +7118,9 @@ "dev": true }, "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "dev": true } } @@ -6991,15 +7175,15 @@ } }, "serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", + "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", "dev": true, "requires": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "~0.19.1" } }, "set-function-length": { @@ -7047,15 +7231,51 @@ "dev": true }, "side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "dev": true, "requires": { - "call-bind": "^1.0.7", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + } + }, + "side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "requires": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + } + }, + "side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "requires": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + } + }, + "side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "requires": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" } }, "signal-exit": { From 956df22d86eb44df4eb94712ac1758d3fa8e173a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 10 Feb 2026 16:05:45 +0000 Subject: [PATCH 40/56] Chore/revert 6433 (#6445) * Revert "build(deps): bump time from 0.3.41 to 0.3.47 in /nym-wallet (#6433)" This reverts commit fd47ebfad095f02eefccb2c1ddd158852d57fe69. * chore: revert #6433 due to rust version incompatibility --- Cargo.toml | 2 +- nym-wallet/Cargo.lock | 42 +++++++++++++-------------------- nym-wallet/src-tauri/Cargo.toml | 2 +- 3 files changed, 18 insertions(+), 28 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2bf995abc0..3d3a7636d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -353,7 +353,7 @@ tar = "0.4.44" test-with = { version = "0.15.4", default-features = false } tempfile = "3.20" thiserror = "2.0" -time = "0.3.47" +time = "0.3.41" tls_codec = "0.4.1" tokio = "1.47" tokio-postgres = "0.7" diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index f18537b669..f50d5d2658 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -1736,12 +1736,12 @@ dependencies = [ [[package]] name = "deranged" -version = "0.5.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" +checksum = "28cfac68e08048ae1883171632c2aef3ebc555621ae56fbccce1cbf22dd7f058" dependencies = [ "powerfmt", - "serde_core", + "serde", ] [[package]] @@ -4204,9 +4204,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.2.0" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-integer" @@ -6723,11 +6723,10 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.228" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ - "serde_core", "serde_derive", ] @@ -6760,20 +6759,11 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", @@ -7966,9 +7956,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.47" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ "deranged", "itoa 1.0.15", @@ -7976,22 +7966,22 @@ dependencies = [ "num-conv", "num_threads", "powerfmt", - "serde_core", + "serde", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.8" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.27" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" dependencies = [ "num-conv", "time-core", diff --git a/nym-wallet/src-tauri/Cargo.toml b/nym-wallet/src-tauri/Cargo.toml index abac9b8a70..6327991107 100644 --- a/nym-wallet/src-tauri/Cargo.toml +++ b/nym-wallet/src-tauri/Cargo.toml @@ -43,7 +43,7 @@ strum = { version = "0.27.2", features = ["derive"] } tap = "1" tauri = { version = "2", features = [] } #tendermint-rpc = "0.23.0" -time = { version = "0.3.47", features = ["local-offset"] } +time = { version = "0.3.30", features = ["local-offset"] } thiserror = "1.0" tokio = { version = "1.44", features = ["full"] } toml = "0.5.8" From c7a466860ec4d1b8f805404d3c42cf4c9e071245 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 16:06:31 +0000 Subject: [PATCH 41/56] build(deps): bump h3 from 1.15.4 to 1.15.5 (#6339) Bumps [h3](https://github.com/h3js/h3) from 1.15.4 to 1.15.5. - [Release notes](https://github.com/h3js/h3/releases) - [Changelog](https://github.com/h3js/h3/blob/v1.15.5/CHANGELOG.md) - [Commits](https://github.com/h3js/h3/compare/v1.15.4...v1.15.5) --- updated-dependencies: - dependency-name: h3 dependency-version: 1.15.5 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/yarn.lock b/yarn.lock index 68cbca7e37..dbd8fb20d7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12807,18 +12807,18 @@ graphemer@^1.4.0: integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== h3@^1.15.4: - version "1.15.4" - resolved "https://registry.yarnpkg.com/h3/-/h3-1.15.4.tgz#022ab3563bbaf2108c25375c40460f3e54a5fe02" - integrity sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ== + version "1.15.5" + resolved "https://registry.yarnpkg.com/h3/-/h3-1.15.5.tgz#e2f28d4a66a249973bb050eaddb06b9ab55506f8" + integrity sha512-xEyq3rSl+dhGX2Lm0+eFQIAzlDN6Fs0EcC4f7BNUmzaRX/PTzeuM+Tr2lHB8FoXggsQIeXLj8EDVgs5ywxyxmg== dependencies: cookie-es "^1.2.2" crossws "^0.3.5" defu "^6.1.4" destr "^2.0.5" iron-webcrypto "^1.2.1" - node-mock-http "^1.0.2" + node-mock-http "^1.0.4" radix3 "^1.1.2" - ufo "^1.6.1" + ufo "^1.6.3" uncrypto "^0.1.3" handle-thing@^2.0.0: @@ -16843,10 +16843,10 @@ node-machine-id@1.1.12: resolved "https://registry.yarnpkg.com/node-machine-id/-/node-machine-id-1.1.12.tgz#37904eee1e59b320bb9c5d6c0a59f3b469cb6267" integrity sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ== -node-mock-http@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/node-mock-http/-/node-mock-http-1.0.3.tgz#4e55e093267a3b910cded7354389ce2d02c89e77" - integrity sha512-jN8dK25fsfnMrVsEhluUTPkBFY+6ybu7jSB1n+ri/vOGjJxU8J9CZhpSGkHXSkFjtUhbmoncG/YG9ta5Ludqog== +node-mock-http@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/node-mock-http/-/node-mock-http-1.0.4.tgz#21f2ab4ce2fe4fbe8a660d7c5195a1db85e042a4" + integrity sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ== node-releases@^2.0.27: version "2.0.27" @@ -21594,6 +21594,11 @@ ufo@^1.5.4, ufo@^1.6.1: resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.6.1.tgz#ac2db1d54614d1b22c1d603e3aef44a85d8f146b" integrity sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA== +ufo@^1.6.3: + version "1.6.3" + resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.6.3.tgz#799666e4e88c122a9659805e30b9dc071c3aed4f" + integrity sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q== + uglify-js@^3.1.4: version "3.19.3" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.19.3.tgz#82315e9bbc6f2b25888858acd1fff8441035b77f" From c3520b575fa3010d61abb1be469dea750187c30b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 16:06:48 +0000 Subject: [PATCH 42/56] build(deps): bump h3 from 1.15.4 to 1.15.5 in /documentation/docs (#6332) Bumps [h3](https://github.com/h3js/h3) from 1.15.4 to 1.15.5. - [Release notes](https://github.com/h3js/h3/releases) - [Changelog](https://github.com/h3js/h3/blob/v1.15.5/CHANGELOG.md) - [Commits](https://github.com/h3js/h3/compare/v1.15.4...v1.15.5) --- updated-dependencies: - dependency-name: h3 dependency-version: 1.15.5 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- documentation/docs/pnpm-lock.yaml | 54 +++++++++++++++---------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/documentation/docs/pnpm-lock.yaml b/documentation/docs/pnpm-lock.yaml index d2e836eb37..f47efa1d74 100644 --- a/documentation/docs/pnpm-lock.yaml +++ b/documentation/docs/pnpm-lock.yaml @@ -3390,8 +3390,8 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.9.17: - resolution: {integrity: sha512-agD0MgJFUP/4nvjqzIB29zRPUuCF7Ge6mEv9s8dHrtYD7QWXRcx75rOADE/d5ah1NI+0vkDl0yorDd5U852IQQ==} + baseline-browser-mapping@2.9.19: + resolution: {integrity: sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==} hasBin: true bech32@1.1.4: @@ -3510,8 +3510,8 @@ packages: caniuse-lite@1.0.30001760: resolution: {integrity: sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==} - caniuse-lite@1.0.30001765: - resolution: {integrity: sha512-LWcNtSyZrakjECqmpP4qdg0MMGdN368D7X8XvvAqOcqMv0RxnlqVKZl2V6/mBR68oYMxOZPLw/gO7DuisMHUvQ==} + caniuse-lite@1.0.30001769: + resolution: {integrity: sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==} cardinal@2.1.1: resolution: {integrity: sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==} @@ -4025,8 +4025,8 @@ packages: duplexify@4.1.3: resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} - electron-to-chromium@1.5.267: - resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} + electron-to-chromium@1.5.286: + resolution: {integrity: sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==} elkjs@0.9.3: resolution: {integrity: sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==} @@ -4047,8 +4047,8 @@ packages: end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - enhanced-resolve@5.18.4: - resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} + enhanced-resolve@5.19.0: + resolution: {integrity: sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==} engines: {node: '>=10.13.0'} entities@6.0.1: @@ -4467,11 +4467,11 @@ packages: glob@7.1.7: resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me globals@13.24.0: resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} @@ -5358,11 +5358,11 @@ packages: modern-ahocorasick@1.1.0: resolution: {integrity: sha512-sEKPVl2rM+MNVkGQt3ChdmD8YsigmXdn5NifZn6jiwn9LRJpWm8F3guhaqrJT/JOat6pwpbXEk6kv+b9DMIjsQ==} - motion-dom@12.28.1: - resolution: {integrity: sha512-xqgID69syDvXwFJnUd5bW6ajGUAr/qevRoUe/EqpsXUbVIopyWrAOiwQOhpgVQD+B7Ra60zTdj5gVkmwncebMg==} + motion-dom@12.34.0: + resolution: {integrity: sha512-Lql3NuEcScRDxTAO6GgUsRHBZOWI/3fnMlkMcH5NftzcN37zJta+bpbMAV9px4Nj057TuvRooMK7QrzMCgtz6Q==} - motion-utils@12.27.2: - resolution: {integrity: sha512-B55gcoL85Mcdt2IEStY5EEAsrMSVE2sI14xQ/uAdPL+mfQxhKKFaEag9JmfxedJOR4vZpBGoPeC/Gm13I/4g5Q==} + motion-utils@12.29.2: + resolution: {integrity: sha512-G3kc34H2cX2gI63RqU+cZq+zWRRPSsNIOjpdl9TN4AQwC4sgwYPl/Q/Obf/d53nOm569T0fYK+tcoSV50BWx8A==} mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} @@ -12012,7 +12012,7 @@ snapshots: base64-js@1.5.1: {} - baseline-browser-mapping@2.9.17: {} + baseline-browser-mapping@2.9.19: {} bech32@1.1.4: {} @@ -12082,9 +12082,9 @@ snapshots: browserslist@4.28.1: dependencies: - baseline-browser-mapping: 2.9.17 - caniuse-lite: 1.0.30001765 - electron-to-chromium: 1.5.267 + baseline-browser-mapping: 2.9.19 + caniuse-lite: 1.0.30001769 + electron-to-chromium: 1.5.286 node-releases: 2.0.27 update-browserslist-db: 1.2.3(browserslist@4.28.1) @@ -12138,7 +12138,7 @@ snapshots: caniuse-lite@1.0.30001760: {} - caniuse-lite@1.0.30001765: {} + caniuse-lite@1.0.30001769: {} cardinal@2.1.1: dependencies: @@ -12677,7 +12677,7 @@ snapshots: readable-stream: 3.6.2 stream-shift: 1.0.3 - electron-to-chromium@1.5.267: {} + electron-to-chromium@1.5.286: {} elkjs@0.9.3: {} @@ -12701,7 +12701,7 @@ snapshots: dependencies: once: 1.4.0 - enhanced-resolve@5.18.4: + enhanced-resolve@5.19.0: dependencies: graceful-fs: 4.2.11 tapable: 2.3.0 @@ -13176,8 +13176,8 @@ snapshots: framer-motion@12.23.12(@emotion/is-prop-valid@1.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - motion-dom: 12.28.1 - motion-utils: 12.27.2 + motion-dom: 12.34.0 + motion-utils: 12.29.2 tslib: 2.8.1 optionalDependencies: '@emotion/is-prop-valid': 1.3.1 @@ -14496,11 +14496,11 @@ snapshots: modern-ahocorasick@1.1.0: {} - motion-dom@12.28.1: + motion-dom@12.34.0: dependencies: - motion-utils: 12.27.2 + motion-utils: 12.29.2 - motion-utils@12.27.2: {} + motion-utils@12.29.2: {} mri@1.2.0: {} @@ -16190,7 +16190,7 @@ snapshots: acorn-import-phases: 1.0.4(acorn@8.15.0) browserslist: 4.28.1 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.18.4 + enhanced-resolve: 5.19.0 es-module-lexer: 1.7.0 eslint-scope: 5.1.1 events: 3.3.0 From 4e4e0df7219a9f5ea3389ca89801c42d87084dea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 16:07:08 +0000 Subject: [PATCH 43/56] build(deps): bump undici from 6.21.3 to 6.23.0 in /documentation/docs (#6325) Bumps [undici](https://github.com/nodejs/undici) from 6.21.3 to 6.23.0. - [Release notes](https://github.com/nodejs/undici/releases) - [Commits](https://github.com/nodejs/undici/compare/v6.21.3...v6.23.0) --- updated-dependencies: - dependency-name: undici dependency-version: 6.23.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> From b75839461b904719f84b67ded95ebb9dafb16d32 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 16:07:35 +0000 Subject: [PATCH 44/56] build(deps): bump diff from 5.2.0 to 5.2.2 in /documentation/docs (#6345) Bumps [diff](https://github.com/kpdecker/jsdiff) from 5.2.0 to 5.2.2. - [Changelog](https://github.com/kpdecker/jsdiff/blob/master/release-notes.md) - [Commits](https://github.com/kpdecker/jsdiff/compare/v5.2.0...v5.2.2) --- updated-dependencies: - dependency-name: diff dependency-version: 5.2.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> From 505a19e32ff22d7015094e407326d40f3e51d3c0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 16:08:26 +0000 Subject: [PATCH 45/56] build(deps-dev): bump eslint from 8.57.1 to 9.26.0 Bumps [eslint](https://github.com/eslint/eslint) from 8.57.1 to 9.26.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/v9.26.0/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.57.1...v9.26.0) --- updated-dependencies: - dependency-name: eslint dependency-version: 9.26.0 dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- explorer-v2/package.json | 2 +- nym-wallet/package.json | 2 +- .../mix-fetch/internal-dev/package.json | 2 +- .../packages/mui-theme/package.json | 2 +- .../packages/react-components/package.json | 2 +- .../package.json | 2 +- ts-packages/types/package.json | 2 +- ts-packages/webpack/package.json | 2 +- yarn.lock | 572 ++++++++++++++---- 9 files changed, 464 insertions(+), 124 deletions(-) diff --git a/explorer-v2/package.json b/explorer-v2/package.json index 55f5f22b77..912e87ccc5 100644 --- a/explorer-v2/package.json +++ b/explorer-v2/package.json @@ -57,7 +57,7 @@ "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", - "eslint": "^8", + "eslint": "^9", "eslint-config-next": "15.0.3", "lefthook": "^1.8.5", "typescript": "^5" diff --git a/nym-wallet/package.json b/nym-wallet/package.json index 190dadbc1a..134eab22f4 100644 --- a/nym-wallet/package.json +++ b/nym-wallet/package.json @@ -96,7 +96,7 @@ "css-loader": "^6.7.3", "css-minimizer-webpack-plugin": "^3.0.2", "dotenv-webpack": "^7.0.3", - "eslint": "^8.10.0", + "eslint": "^9.26.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^16.1.0", "eslint-config-prettier": "^8.5.0", diff --git a/sdk/typescript/packages/mix-fetch/internal-dev/package.json b/sdk/typescript/packages/mix-fetch/internal-dev/package.json index b8a8d713da..dcee5bf835 100644 --- a/sdk/typescript/packages/mix-fetch/internal-dev/package.json +++ b/sdk/typescript/packages/mix-fetch/internal-dev/package.json @@ -26,7 +26,7 @@ "css-loader": "^6.8.1", "css-minimizer-webpack-plugin": "^5.0.1", "dotenv-webpack": "^8.0.1", - "eslint": "^8.10.0", + "eslint": "^9.26.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^16.1.0", "eslint-config-prettier": "^8.5.0", diff --git a/sdk/typescript/packages/mui-theme/package.json b/sdk/typescript/packages/mui-theme/package.json index 1e74b7cb22..8adf23aa0d 100644 --- a/sdk/typescript/packages/mui-theme/package.json +++ b/sdk/typescript/packages/mui-theme/package.json @@ -14,7 +14,7 @@ "@nymproject/eslint-config-react-typescript": "^1.0.0", "@typescript-eslint/eslint-plugin": "^5.13.0", "@typescript-eslint/parser": "^5.13.0", - "eslint": "^8.10.0", + "eslint": "^9.26.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^16.1.0", "eslint-config-prettier": "^8.5.0", diff --git a/sdk/typescript/packages/react-components/package.json b/sdk/typescript/packages/react-components/package.json index 6d7a21747f..162b41e668 100644 --- a/sdk/typescript/packages/react-components/package.json +++ b/sdk/typescript/packages/react-components/package.json @@ -63,7 +63,7 @@ "@typescript-eslint/parser": "^5.13.0", "babel-loader": "^8.2.3", "babel-plugin-root-import": "^5.1.0", - "eslint": "^8.10.0", + "eslint": "^9.26.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^16.1.0", "eslint-config-prettier": "^8.5.0", diff --git a/ts-packages/eslint-config-react-typescript/package.json b/ts-packages/eslint-config-react-typescript/package.json index 5885f34b93..92929feebb 100644 --- a/ts-packages/eslint-config-react-typescript/package.json +++ b/ts-packages/eslint-config-react-typescript/package.json @@ -23,7 +23,7 @@ "react-dom": "^18.2.0" }, "devDependencies": { - "eslint": "^8.10.0", + "eslint": "^9.26.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-prettier": "^8.5.0", "eslint-import-resolver-root-import": "^1.0.4", diff --git a/ts-packages/types/package.json b/ts-packages/types/package.json index 25157b9753..8a95e038d7 100644 --- a/ts-packages/types/package.json +++ b/ts-packages/types/package.json @@ -13,7 +13,7 @@ "@nymproject/eslint-config-react-typescript": "^1.0.0", "@typescript-eslint/eslint-plugin": "^5.13.0", "@typescript-eslint/parser": "^5.13.0", - "eslint": "^8.10.0", + "eslint": "^9.26.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^16.1.0", "eslint-config-prettier": "^8.5.0", diff --git a/ts-packages/webpack/package.json b/ts-packages/webpack/package.json index 503dcc9459..7b3b6e6106 100644 --- a/ts-packages/webpack/package.json +++ b/ts-packages/webpack/package.json @@ -19,7 +19,7 @@ "clean-webpack-plugin": "^4.0.0", "css-loader": "^6.7.3", "dotenv-webpack": "^7.0.3", - "eslint": "^8.10.0", + "eslint": "^9.26.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-prettier": "^4.0.0", "favicons": "^7.0.2", diff --git a/yarn.lock b/yarn.lock index dbd8fb20d7..1023b90e99 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1728,36 +1728,70 @@ integrity sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg== "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.7.0": - version "4.9.0" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz#7308df158e064f0dd8b8fdb58aa14fa2a7f913b3" - integrity sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g== + version "4.9.1" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz#4e90af67bc51ddee6cdef5284edf572ec376b595" + integrity sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ== dependencies: eslint-visitor-keys "^3.4.3" -"@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.6.1": +"@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.12.1", "@eslint-community/regexpp@^4.4.0": version "4.12.2" resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.2.tgz#bccdf615bcf7b6e8db830ec0b8d21c9a25de597b" integrity sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew== -"@eslint/eslintrc@^2.1.4": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" - integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== +"@eslint/config-array@^0.20.0": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.20.1.tgz#454f89be82b0e5b1ae872c154c7e2f3dd42c3979" + integrity sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw== + dependencies: + "@eslint/object-schema" "^2.1.6" + debug "^4.3.1" + minimatch "^3.1.2" + +"@eslint/config-helpers@^0.2.1": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@eslint/config-helpers/-/config-helpers-0.2.3.tgz#39d6da64ed05d7662659aa7035b54cd55a9f3672" + integrity sha512-u180qk2Um1le4yf0ruXH3PYFeEZeYC3p/4wCTKrr2U1CmGdzGi3KtY0nuPDH48UJxlKCC5RDzbcbh4X0XlqgHg== + +"@eslint/core@^0.13.0": + version "0.13.0" + resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.13.0.tgz#bf02f209846d3bf996f9e8009db62df2739b458c" + integrity sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw== + dependencies: + "@types/json-schema" "^7.0.15" + +"@eslint/eslintrc@^3.3.1": + version "3.3.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.3.3.tgz#26393a0806501b5e2b6a43aa588a4d8df67880ac" + integrity sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.6.0" - globals "^13.19.0" + espree "^10.0.1" + globals "^14.0.0" ignore "^5.2.0" import-fresh "^3.2.1" - js-yaml "^4.1.0" + js-yaml "^4.1.1" minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.57.1": - version "8.57.1" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.1.tgz#de633db3ec2ef6a3c89e2f19038063e8a122e2c2" - integrity sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q== +"@eslint/js@9.26.0": + version "9.26.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.26.0.tgz#1e13126b67a3db15111d2dcc61f69a2acff70bd5" + integrity sha512-I9XlJawFdSMvWjDt6wksMCrgns5ggLNfFwFvnShsleWruvXM514Qxk8V246efTw+eo9JABvVz+u3q2RiAowKxQ== + +"@eslint/object-schema@^2.1.6": + version "2.1.7" + resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.7.tgz#6e2126a1347e86a4dedf8706ec67ff8e107ebbad" + integrity sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA== + +"@eslint/plugin-kit@^0.2.8": + version "0.2.8" + resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz#47488d8f8171b5d4613e833313f3ce708e3525f8" + integrity sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA== + dependencies: + "@eslint/core" "^0.13.0" + levn "^0.4.1" "@ethersproject/address@^5.6.0": version "5.8.0" @@ -1906,29 +1940,38 @@ dependencies: "@hapi/hoek" "^9.0.0" +"@hono/node-server@^1.19.9": + version "1.19.9" + resolved "https://registry.yarnpkg.com/@hono/node-server/-/node-server-1.19.9.tgz#8f37119b1acf283fd3f6035f3d1356fdb97a09ac" + integrity sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw== + "@hookform/resolvers@^2.8.0": version "2.9.11" resolved "https://registry.yarnpkg.com/@hookform/resolvers/-/resolvers-2.9.11.tgz#9ce96e7746625a89239f68ca57c4f654264c17ef" integrity sha512-bA3aZ79UgcHj7tFV7RlgThzwSSHZgvfbt2wprldRkYBcMopdMvHyO17Wwp/twcJasNFischFfS7oz8Katz8DdQ== -"@humanwhocodes/config-array@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz#fb907624df3256d04b9aa2df50d7aa97ec648748" - integrity sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw== +"@humanfs/core@^0.19.1": + version "0.19.1" + resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.1.tgz#17c55ca7d426733fe3c561906b8173c336b40a77" + integrity sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA== + +"@humanfs/node@^0.16.6": + version "0.16.7" + resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.7.tgz#822cb7b3a12c5a240a24f621b5a2413e27a45f26" + integrity sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ== dependencies: - "@humanwhocodes/object-schema" "^2.0.3" - debug "^4.3.1" - minimatch "^3.0.5" + "@humanfs/core" "^0.19.1" + "@humanwhocodes/retry" "^0.4.0" "@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@^2.0.3": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" - integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== +"@humanwhocodes/retry@^0.4.0", "@humanwhocodes/retry@^0.4.2": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.3.tgz#c2b9d2e374ee62c586d3adbea87199b1d7a7a6ba" + integrity sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ== "@hutson/parse-repository-url@^3.0.0": version "3.0.2" @@ -2672,6 +2715,29 @@ resolved "https://registry.yarnpkg.com/@mdx-js/util/-/util-1.6.22.tgz#219dfd89ae5b97a8801f015323ffa4b62f45718b" integrity sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA== +"@modelcontextprotocol/sdk@^1.8.0": + version "1.26.0" + resolved "https://registry.yarnpkg.com/@modelcontextprotocol/sdk/-/sdk-1.26.0.tgz#5b35d73062125f126cc70b0be83cbab53bcdde74" + integrity sha512-Y5RmPncpiDtTXDbLKswIJzTqu2hyBKxTNsgKqKclDbhIgg1wgtf1fRuvxgTnRfcnxtvvgbIEcqUOzZrJ6iSReg== + dependencies: + "@hono/node-server" "^1.19.9" + ajv "^8.17.1" + ajv-formats "^3.0.1" + content-type "^1.0.5" + cors "^2.8.5" + cross-spawn "^7.0.5" + eventsource "^3.0.2" + eventsource-parser "^3.0.0" + express "^5.2.1" + express-rate-limit "^8.2.1" + hono "^4.11.4" + jose "^6.1.3" + json-schema-typed "^8.0.2" + pkce-challenge "^5.0.0" + raw-body "^3.0.0" + zod "^3.25 || ^4.0" + zod-to-json-schema "^3.25.1" + "@mrmlnc/readdir-enhanced@^2.2.1": version "2.2.1" resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" @@ -3145,7 +3211,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.8": +"@nodelib/fs.walk@^1.2.3": version "1.2.8" resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== @@ -6350,7 +6416,7 @@ dependencies: "@types/estree" "*" -"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.8": +"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.6", "@types/estree@^1.0.8": version "1.0.8" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== @@ -7041,7 +7107,7 @@ resolved "https://registry.yarnpkg.com/@uidotdev/usehooks/-/usehooks-2.4.1.tgz#4b733eaeae09a7be143c6c9ca158b56cc1ea75bf" integrity sha512-1I+RwWyS+kdv3Mv0Vmc+p0dPYH0DTRAo04HLyXReYBL9AeseDWUJyi4THuksBJcu9F0Pih69Ak150VDnqbVnXg== -"@ungap/structured-clone@^1.0.0", "@ungap/structured-clone@^1.2.0": +"@ungap/structured-clone@^1.0.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz#d06bbb384ebcf6c505fde1c3d0ed4ddffe0aaff8" integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== @@ -7613,6 +7679,14 @@ abbrev@^1.0.0: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +accepts@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-2.0.0.tgz#bbcf4ba5075467f3f2131eab3cffc73c2f5d7895" + integrity sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng== + dependencies: + mime-types "^3.0.0" + negotiator "^1.0.0" + accepts@~1.3.4, accepts@~1.3.8: version "1.3.8" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" @@ -7654,7 +7728,7 @@ acorn@^7.1.1, acorn@^7.4.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.15.0, acorn@^8.2.4, acorn@^8.9.0: +acorn@^8.15.0, acorn@^8.2.4: version "8.15.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== @@ -7731,6 +7805,13 @@ ajv-formats@^2.1.1: dependencies: ajv "^8.0.0" +ajv-formats@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-3.0.1.tgz#3d5dc762bca17679c3c2ea7e90ad6b7532309578" + integrity sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ== + dependencies: + ajv "^8.0.0" + ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" @@ -7753,7 +7834,7 @@ ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.9.0: +ajv@^8.0.0, ajv@^8.17.1, ajv@^8.9.0: version "8.17.1" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== @@ -8571,6 +8652,21 @@ body-parser@1.20.3: type-is "~1.6.18" unpipe "1.0.0" +body-parser@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-2.2.2.tgz#1a32cdb966beaf68de50a9dfbe5b58f83cb8890c" + integrity sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA== + dependencies: + bytes "^3.1.2" + content-type "^1.0.5" + debug "^4.4.3" + http-errors "^2.0.0" + iconv-lite "^0.7.0" + on-finished "^2.4.1" + qs "^6.14.1" + raw-body "^3.0.1" + type-is "^2.0.1" + bonjour-service@^1.0.11: version "1.3.0" resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.3.0.tgz#80d867430b5a0da64e82a8047fc1e355bdb71722" @@ -8830,7 +8926,7 @@ byte-size@8.1.1: resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-8.1.1.tgz#3424608c62d59de5bfda05d31e0313c6174842ae" integrity sha512-tUkzZWK0M/qdoLEqikxBWe4kumyuwjl3HO6zHTr4yEI23EojPtLYXdG1+AQY7MN0cGyNDvEaJ8wiYQm6P2bPxg== -bytes@3.1.2: +bytes@3.1.2, bytes@^3.1.2, bytes@~3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== @@ -9630,7 +9726,12 @@ content-disposition@0.5.4: dependencies: safe-buffer "5.2.1" -content-type@~1.0.4, content-type@~1.0.5: +content-disposition@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-1.0.1.tgz#a8b7bbeb2904befdfb6787e5c0c086959f605f9b" + integrity sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q== + +content-type@^1.0.5, content-type@~1.0.4, content-type@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== @@ -9728,11 +9829,21 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== +cookie-signature@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.2.2.tgz#57c7fc3cc293acab9fec54d73e15690ebe4a1793" + integrity sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg== + cookie@0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.1.tgz#2f73c42142d5d5cf71310a74fc4ae61670e5dbc9" integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w== +cookie@^0.7.1: + version "0.7.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" + integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== + copy-concurrently@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" @@ -9791,6 +9902,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== +cors@^2.8.5: + version "2.8.6" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.6.tgz#ff5dd69bd95e547503820d29aba4f8faf8dfec96" + integrity sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw== + dependencies: + object-assign "^4" + vary "^1" + cosmiconfig@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" @@ -9902,7 +10021,7 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3, cross-spawn@^7.0.6: +cross-spawn@^7.0.0, cross-spawn@^7.0.3, cross-spawn@^7.0.5, cross-spawn@^7.0.6: version "7.0.6" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== @@ -10451,7 +10570,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3: dependencies: ms "2.0.0" -debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@^4.4.0, debug@^4.4.1: +debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@^4.4.0, debug@^4.4.1, debug@^4.4.3: version "4.4.3" resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== @@ -10657,7 +10776,7 @@ delegates@^1.0.0: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== -depd@2.0.0: +depd@2.0.0, depd@^2.0.0, 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== @@ -11042,16 +11161,16 @@ emojis-list@^3.0.0: resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== +encodeurl@^2.0.0, encodeurl@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" + integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== + encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -encodeurl@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" - integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== - encoding@^0.1.13: version "0.1.13" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" @@ -11554,86 +11673,85 @@ eslint-scope@^4.0.3: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-scope@^7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" - integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== +eslint-scope@^8.3.0: + version "8.4.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.4.0.tgz#88e646a207fad61436ffa39eb505147200655c82" + integrity sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.3: version "3.4.3" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== -eslint-visitor-keys@^4.2.1: +eslint-visitor-keys@^4.2.0, eslint-visitor-keys@^4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz#4cfea60fe7dd0ad8e816e1ed026c1d5251b512c1" integrity sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ== -eslint@^8, eslint@^8.10.0: - version "8.57.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.1.tgz#7df109654aba7e3bbe5c8eae533c5e461d3c6ca9" - integrity sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA== +eslint@^9, eslint@^9.26.0: + version "9.26.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.26.0.tgz#978fe029adc2aceed28ab437bca876e83461c3b4" + integrity sha512-Hx0MOjPh6uK9oq9nVsATZKE/Wlbai7KFjfCuw9UHaguDW3x+HF0O5nIi3ud39TWgrTjTO5nHxmL3R1eANinWHQ== dependencies: "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.6.1" - "@eslint/eslintrc" "^2.1.4" - "@eslint/js" "8.57.1" - "@humanwhocodes/config-array" "^0.13.0" + "@eslint-community/regexpp" "^4.12.1" + "@eslint/config-array" "^0.20.0" + "@eslint/config-helpers" "^0.2.1" + "@eslint/core" "^0.13.0" + "@eslint/eslintrc" "^3.3.1" + "@eslint/js" "9.26.0" + "@eslint/plugin-kit" "^0.2.8" + "@humanfs/node" "^0.16.6" "@humanwhocodes/module-importer" "^1.0.1" - "@nodelib/fs.walk" "^1.2.8" - "@ungap/structured-clone" "^1.2.0" + "@humanwhocodes/retry" "^0.4.2" + "@modelcontextprotocol/sdk" "^1.8.0" + "@types/estree" "^1.0.6" + "@types/json-schema" "^7.0.15" ajv "^6.12.4" chalk "^4.0.0" - cross-spawn "^7.0.2" + cross-spawn "^7.0.6" debug "^4.3.2" - doctrine "^3.0.0" escape-string-regexp "^4.0.0" - eslint-scope "^7.2.2" - eslint-visitor-keys "^3.4.3" - espree "^9.6.1" - esquery "^1.4.2" + eslint-scope "^8.3.0" + eslint-visitor-keys "^4.2.0" + espree "^10.3.0" + esquery "^1.5.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" + file-entry-cache "^8.0.0" find-up "^5.0.0" glob-parent "^6.0.2" - globals "^13.19.0" - graphemer "^1.4.0" ignore "^5.2.0" imurmurhash "^0.1.4" is-glob "^4.0.0" - is-path-inside "^3.0.3" - 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.3" - strip-ansi "^6.0.1" - text-table "^0.2.0" + zod "^3.24.2" -espree@^9.6.0, espree@^9.6.1: - version "9.6.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" - integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== +espree@^10.0.1, espree@^10.3.0: + version "10.4.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-10.4.0.tgz#d54f4949d4629005a1fa168d937c3ff1f7e2a837" + integrity sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ== dependencies: - acorn "^8.9.0" + acorn "^8.15.0" acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" + eslint-visitor-keys "^4.2.1" esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.4.2: - version "1.6.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" - integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== +esquery@^1.5.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.7.0.tgz#08d048f261f0ddedb5bae95f46809463d9c9496d" + integrity sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g== dependencies: estraverse "^5.1.0" @@ -11673,7 +11791,7 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -etag@~1.8.1: +etag@^1.8.1, etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== @@ -11688,6 +11806,18 @@ events@3.3.0, events@^3.0.0, events@^3.2.0, events@^3.3.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== +eventsource-parser@^3.0.0, eventsource-parser@^3.0.1: + version "3.0.6" + resolved "https://registry.yarnpkg.com/eventsource-parser/-/eventsource-parser-3.0.6.tgz#292e165e34cacbc936c3c92719ef326d4aeb4e90" + integrity sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg== + +eventsource@^3.0.2: + version "3.0.7" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-3.0.7.tgz#1157622e2f5377bb6aef2114372728ba0c156989" + integrity sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA== + dependencies: + eventsource-parser "^3.0.1" + evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" @@ -11789,6 +11919,13 @@ exponential-backoff@^3.1.1: resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.3.tgz#51cf92c1c0493c766053f9d3abee4434c244d2f6" integrity sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA== +express-rate-limit@^8.2.1: + version "8.2.1" + resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-8.2.1.tgz#ec75fdfe280ecddd762b8da8784c61bae47d7f7f" + integrity sha512-PCZEIEIxqwhzw4KF0n7QF4QqruVTcF73O5kFKUnGOyjbCCgizBBiFaYpd/fnBLUMPw/BWw9OsiN7GgrNYr7j6g== + dependencies: + ip-address "10.0.1" + express@^4.17.1, express@^4.17.3: version "4.21.2" resolved "https://registry.yarnpkg.com/express/-/express-4.21.2.tgz#cf250e48362174ead6cea4a566abef0162c1ec32" @@ -11826,6 +11963,40 @@ express@^4.17.1, express@^4.17.3: utils-merge "1.0.1" vary "~1.1.2" +express@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/express/-/express-5.2.1.tgz#8f21d15b6d327f92b4794ecf8cb08a72f956ac04" + integrity sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw== + dependencies: + accepts "^2.0.0" + body-parser "^2.2.1" + content-disposition "^1.0.0" + content-type "^1.0.5" + cookie "^0.7.1" + cookie-signature "^1.2.1" + debug "^4.4.0" + depd "^2.0.0" + encodeurl "^2.0.0" + escape-html "^1.0.3" + etag "^1.8.1" + finalhandler "^2.1.0" + fresh "^2.0.0" + http-errors "^2.0.0" + merge-descriptors "^2.0.0" + mime-types "^3.0.0" + on-finished "^2.4.1" + once "^1.4.0" + parseurl "^1.3.3" + proxy-addr "^2.0.7" + qs "^6.14.0" + range-parser "^1.2.1" + router "^2.2.0" + send "^1.1.0" + serve-static "^2.2.0" + statuses "^2.0.1" + type-is "^2.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" @@ -12003,12 +12174,12 @@ figures@3.2.0, figures@^3.0.0: dependencies: escape-string-regexp "^1.0.5" -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== +file-entry-cache@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz#7787bddcf1131bffb92636c69457bbc0edd6d81f" + integrity sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ== dependencies: - flat-cache "^3.0.4" + flat-cache "^4.0.0" file-loader@^6.2.0: version "6.2.0" @@ -12068,6 +12239,18 @@ finalhandler@1.3.1: statuses "2.0.1" unpipe "~1.0.0" +finalhandler@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-2.1.1.tgz#a2c517a6559852bcdb06d1f8bd7f51b68fad8099" + integrity sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA== + dependencies: + debug "^4.4.0" + encodeurl "^2.0.0" + escape-html "^1.0.3" + on-finished "^2.4.1" + parseurl "^1.3.3" + statuses "^2.0.1" + find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" @@ -12154,6 +12337,14 @@ flat-cache@^3.0.4: keyv "^4.5.3" rimraf "^3.0.2" +flat-cache@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-4.0.1.tgz#0ece39fcb14ee012f4b0410bd33dd9c1f011127c" + integrity sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw== + dependencies: + flatted "^3.2.9" + keyv "^4.5.4" + flat@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" @@ -12319,6 +12510,11 @@ fresh@0.5.2, fresh@~0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== +fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-2.0.0.tgz#8dd7df6a1b3a1b3a5cf186c05a5dd267622635a4" + integrity sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A== + from2@^2.1.0: version "2.3.0" resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" @@ -12728,12 +12924,10 @@ global@^4.4.0: min-document "^2.19.0" process "^0.11.10" -globals@^13.19.0: - version "13.24.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" - integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== - dependencies: - type-fest "^0.20.2" +globals@^14.0.0: + version "14.0.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e" + integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ== globalthis@^1.0.0, globalthis@^1.0.1, globalthis@^1.0.4: version "1.0.4" @@ -13087,6 +13281,11 @@ hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react- dependencies: react-is "^16.7.0" +hono@^4.11.4: + version "4.11.9" + resolved "https://registry.yarnpkg.com/hono/-/hono-4.11.9.tgz#4e0dec5309a8f05216c777cbd93131a41cf28eb9" + integrity sha512-Eaw2YTGM6WOxA6CXbckaEvslr2Ne4NFsKrvc0v97JD5awbmeBLO5w9Ho9L9kmKonrwF9RJlW6BxT1PVv/agBHQ== + 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" @@ -13252,6 +13451,17 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" +http-errors@^2.0.0, http-errors@^2.0.1, http-errors@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.1.tgz#36d2f65bc909c8790018dd36fb4d93da6caae06b" + integrity sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ== + dependencies: + depd "~2.0.0" + inherits "~2.0.4" + setprototypeof "~1.2.0" + statuses "~2.0.2" + 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" @@ -13386,6 +13596,13 @@ iconv-lite@^0.7.0: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" +iconv-lite@~0.7.0: + version "0.7.2" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.7.2.tgz#d0bdeac3f12b4835b7359c2ad89c422a4d1cc72e" + integrity sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + icss-utils@^4.0.0, icss-utils@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" @@ -13506,7 +13723,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -13604,7 +13821,7 @@ intl-messageformat@^10.1.0: "@formatjs/icu-messageformat-parser" "2.11.4" tslib "^2.8.0" -ip-address@^10.0.1: +ip-address@10.0.1, ip-address@^10.0.1: version "10.0.1" resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-10.0.1.tgz#a8180b783ce7788777d796286d61bce4276818ed" integrity sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA== @@ -13993,11 +14210,6 @@ is-path-inside@^2.1.0: dependencies: path-is-inside "^1.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== - is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" @@ -14035,6 +14247,11 @@ 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-promise@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-4.0.0.tgz#42ff9f84206c1991d26debf520dd5c01042dd2f3" + integrity sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ== + is-regex@^1.1.2, is-regex@^1.1.4, is-regex@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.2.1.tgz#76d70a3ed10ef9be48eb577887d74205bf0cad22" @@ -14891,6 +15108,11 @@ joi@^17.11.0: "@sideway/formula" "^3.0.1" "@sideway/pinpoint" "^2.0.0" +jose@^6.1.3: + version "6.1.3" + resolved "https://registry.yarnpkg.com/jose/-/jose-6.1.3.tgz#8453d7be88af7bb7d64a0481d6a35a0145ba3ea5" + integrity sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ== + js-sha3@0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" @@ -14921,6 +15143,13 @@ js-yaml@^3.10.0, js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.1.tgz#854c292467705b699476e1a2decc0c8a3458806b" + integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== + dependencies: + argparse "^2.0.1" + jsdom@^16.6.0: version "16.7.0" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" @@ -15015,6 +15244,11 @@ 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-typed@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/json-schema-typed/-/json-schema-typed-8.0.2.tgz#e98ee7b1899ff4a184534d1f167c288c66bbeff4" + integrity sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA== + json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" @@ -15141,7 +15375,7 @@ junk@^3.1.0: resolved "https://registry.yarnpkg.com/junk/-/junk-3.1.0.tgz#31499098d902b7e98c5d9b9c80f43457a88abfa1" integrity sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ== -keyv@^4.5.3: +keyv@^4.5.3, keyv@^4.5.4: version "4.5.4" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== @@ -15986,6 +16220,11 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== +media-typer@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-1.1.0.tgz#6ab74b8f2d3320f2064b2a87a38e7931ff3a5561" + integrity sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw== + mem@^8.1.1: version "8.1.1" resolved "https://registry.yarnpkg.com/mem/-/mem-8.1.1.tgz#cf118b357c65ab7b7e0817bdf00c8062297c0122" @@ -16067,6 +16306,11 @@ merge-descriptors@1.0.3: resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5" integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ== +merge-descriptors@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-2.0.0.tgz#ea922f660635a2249ee565e0449f951e6b603808" + integrity sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g== + merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -16321,7 +16565,7 @@ mime-db@1.52.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -"mime-db@>= 1.43.0 < 2": +"mime-db@>= 1.43.0 < 2", mime-db@^1.54.0: version "1.54.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.54.0.tgz#cddb3ee4f9c64530dff640236661d42cb6a314f5" integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== @@ -16333,6 +16577,13 @@ mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.30, mime-types@^2.1.31, dependencies: mime-db "1.52.0" +mime-types@^3.0.0, mime-types@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-3.0.2.tgz#39002d4182575d5af036ffa118100f2524b2e2ab" + integrity sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A== + dependencies: + mime-db "^1.54.0" + mime@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" @@ -16397,7 +16648,7 @@ minimatch@^10.0.3: dependencies: "@isaacs/brace-expansion" "^5.0.0" -minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: +minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.1.1, 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== @@ -16686,6 +16937,11 @@ negotiator@^0.6.3, negotiator@~0.6.4: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.4.tgz#777948e2452651c570b712dd01c23e262713fff7" integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== +negotiator@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-1.0.0.tgz#b6c91bb47172d69f93cfd7c357bbb529019b5f6a" + integrity sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg== + neo-async@^2.5.0, neo-async@^2.6.1, neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" @@ -17129,7 +17385,7 @@ nx@16.10.0, "nx@>=16.5.1 < 17": "@nx/nx-win32-arm64-msvc" "16.10.0" "@nx/nx-win32-x64-msvc" "16.10.0" -object-assign@^4.0.1, object-assign@^4.1.1: +object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== @@ -17263,7 +17519,7 @@ on-exit-leak-free@^0.2.0: resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz#b39c9e3bf7690d890f4861558b0d7b90a442d209" integrity sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg== -on-finished@2.4.1: +on-finished@2.4.1, 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== @@ -17689,7 +17945,7 @@ parse5@^8.0.0: dependencies: entities "^6.0.0" -parseurl@~1.3.2, parseurl@~1.3.3: +parseurl@^1.3.3, parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== @@ -17790,6 +18046,11 @@ path-to-regexp@0.1.12: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.12.tgz#d5e1a12e478a976d432ef3c58d534b9923164bb7" integrity sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ== +path-to-regexp@^8.0.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-8.3.0.tgz#aa818a6981f99321003a08987d3cec9c3474cd1f" + integrity sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA== + path-type@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" @@ -17915,6 +18176,11 @@ pirates@^4.0.1, pirates@^4.0.4, pirates@^4.0.6: resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.7.tgz#643b4a18c4257c8a65104b73f3049ce9a0a15e22" integrity sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA== +pkce-challenge@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/pkce-challenge/-/pkce-challenge-5.0.1.tgz#3b4446865b17b1745e9ace2016a31f48ddf6230d" + integrity sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ== + pkg-dir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" @@ -18682,7 +18948,7 @@ protocols@^2.0.0, protocols@^2.0.1: resolved "https://registry.yarnpkg.com/protocols/-/protocols-2.0.2.tgz#822e8fcdcb3df5356538b3e91bfd890b067fd0a4" integrity sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ== -proxy-addr@~2.0.7: +proxy-addr@^2.0.7, proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== @@ -18787,6 +19053,13 @@ qs@^6.10.0, qs@^6.12.3, qs@^6.14.0: dependencies: side-channel "^1.1.0" +qs@^6.14.1: + version "6.14.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.1.tgz#a41d85b9d3902f31d27861790506294881871159" + integrity sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ== + dependencies: + side-channel "^1.1.0" + querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" @@ -18862,6 +19135,16 @@ raw-body@2.5.2: iconv-lite "0.4.24" unpipe "1.0.0" +raw-body@^3.0.0, raw-body@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-3.0.2.tgz#3e3ada5ae5568f9095d84376fd3a49b8fb000a51" + integrity sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA== + dependencies: + bytes "~3.1.2" + http-errors "~2.0.1" + iconv-lite "~0.7.0" + 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" @@ -19678,6 +19961,17 @@ robust-predicates@^3.0.2: resolved "https://registry.yarnpkg.com/robust-predicates/-/robust-predicates-3.0.2.tgz#d5b28528c4824d20fc48df1928d41d9efa1ad771" integrity sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg== +router@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/router/-/router-2.2.0.tgz#019be620b711c87641167cc79b99090f00b146ef" + integrity sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ== + dependencies: + debug "^4.4.0" + depd "^2.0.0" + is-promise "^4.0.0" + parseurl "^1.3.3" + path-to-regexp "^8.0.0" + rrweb-cssom@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz#3021d1b4352fbf3b614aaeed0bc0d5739abe0bc2" @@ -19910,6 +20204,23 @@ send@0.19.0: range-parser "~1.2.1" statuses "2.0.1" +send@^1.1.0, send@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/send/-/send-1.2.1.tgz#9eab743b874f3550f40a26867bf286ad60d3f3ed" + integrity sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ== + dependencies: + debug "^4.4.3" + encodeurl "^2.0.0" + escape-html "^1.0.3" + etag "^1.8.1" + fresh "^2.0.0" + http-errors "^2.0.1" + mime-types "^3.0.2" + ms "^2.1.3" + on-finished "^2.4.1" + range-parser "^1.2.1" + statuses "^2.0.2" + serialize-javascript@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" @@ -19965,6 +20276,16 @@ serve-static@1.16.2: parseurl "~1.3.3" send "0.19.0" +serve-static@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-2.2.1.tgz#7f186a4a4e5f5b663ad7a4294ff1bf37cf0e98a9" + integrity sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw== + dependencies: + encodeurl "^2.0.0" + escape-html "^1.0.3" + parseurl "^1.3.3" + send "^1.2.0" + set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -20021,7 +20342,7 @@ setprototypeof@1.1.0: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== -setprototypeof@1.2.0: +setprototypeof@1.2.0, setprototypeof@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== @@ -20480,6 +20801,11 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== +statuses@^2.0.1, statuses@^2.0.2, statuses@~2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.2.tgz#8f75eecef765b5e1cfcdc080da59409ed424e382" + integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw== + stop-iteration-iterator@^1.0.0, stop-iteration-iterator@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz#f481ff70a548f6124d0312c3aa14cbfa7aa542ad" @@ -21090,11 +21416,6 @@ text-extensions@^1.0.0: resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ== -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - thread-loader@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/thread-loader/-/thread-loader-3.0.4.tgz#c392e4c0241fbc80430eb680e4886819b504a31b" @@ -21260,7 +21581,7 @@ toggle-selection@^1.0.6: resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ== -toidentifier@1.0.1: +toidentifier@1.0.1, toidentifier@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== @@ -21509,6 +21830,15 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +type-is@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-2.0.1.tgz#64f6cf03f92fce4015c2b224793f6bdd4b068c97" + integrity sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw== + dependencies: + content-type "^1.0.5" + media-typer "^1.1.0" + mime-types "^3.0.0" + type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -22103,7 +22433,7 @@ validate-npm-package-name@^5.0.0: resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz#a316573e9b49f3ccd90dbb6eb52b3f06c6d604e8" integrity sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ== -vary@~1.1.2: +vary@^1, vary@^1.1.2, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== @@ -22928,11 +23258,21 @@ yup@^0.32.9: property-expr "^2.0.4" toposort "^2.0.2" -zod@^3.24.1: +zod-to-json-schema@^3.25.1: + version "3.25.1" + resolved "https://registry.yarnpkg.com/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz#7f24962101a439ddade2bf1aeab3c3bfec7d84ba" + integrity sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA== + +zod@^3.24.1, zod@^3.24.2: version "3.25.76" resolved "https://registry.yarnpkg.com/zod/-/zod-3.25.76.tgz#26841c3f6fd22a6a2760e7ccb719179768471e34" integrity sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ== +"zod@^3.25 || ^4.0": + version "4.3.6" + resolved "https://registry.yarnpkg.com/zod/-/zod-4.3.6.tgz#89c56e0aa7d2b05107d894412227087885ab112a" + integrity sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg== + zustand@^4.5.5: version "4.5.7" resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.5.7.tgz#7d6bb2026a142415dd8be8891d7870e6dbe65f55" From 220c64100dfc32d8703305fced00b367819435ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 16:08:44 +0000 Subject: [PATCH 46/56] build(deps): bump next from 15.5.9 to 16.1.5 in /documentation/docs Bumps [next](https://github.com/vercel/next.js) from 15.5.9 to 16.1.5. - [Release notes](https://github.com/vercel/next.js/releases) - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js) - [Commits](https://github.com/vercel/next.js/compare/v15.5.9...v16.1.5) --- updated-dependencies: - dependency-name: next dependency-version: 16.1.5 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- documentation/docs/package.json | 2 +- documentation/docs/pnpm-lock.yaml | 333 +++++++++++++++--------------- 2 files changed, 165 insertions(+), 170 deletions(-) diff --git a/documentation/docs/package.json b/documentation/docs/package.json index de66c0ee5a..63e3132a88 100644 --- a/documentation/docs/package.json +++ b/documentation/docs/package.json @@ -45,7 +45,7 @@ "chain-registry": "^1.19.0", "cosmjs-types": "^0.9.0", "lucide-react": "^0.438.0", - "next": "15.5.9", + "next": "15.5.10", "nextra": "2", "nextra-theme-docs": "2", "react": "^18.2.0", diff --git a/documentation/docs/pnpm-lock.yaml b/documentation/docs/pnpm-lock.yaml index f47efa1d74..b04428b429 100644 --- a/documentation/docs/pnpm-lock.yaml +++ b/documentation/docs/pnpm-lock.yaml @@ -99,14 +99,14 @@ importers: specifier: ^0.438.0 version: 0.438.0(react@18.3.1) next: - specifier: 15.5.9 - version: 15.5.9(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 15.5.10 + version: 15.5.10(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) nextra: specifier: '2' - version: 2.13.4(next@15.5.9(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 2.13.4(next@15.5.10(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) nextra-theme-docs: specifier: '2' - version: 2.13.4(next@15.5.9(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(nextra@2.13.4(next@15.5.9(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 2.13.4(next@15.5.10(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(nextra@2.13.4(next@15.5.10(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: ^18.2.0 version: 18.3.1 @@ -364,8 +364,8 @@ packages: '@emnapi/core@1.4.5': resolution: {integrity: sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==} - '@emnapi/runtime@1.7.1': - resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==} + '@emnapi/runtime@1.8.1': + resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} '@emnapi/wasi-threads@1.0.4': resolution: {integrity: sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==} @@ -1029,8 +1029,8 @@ packages: '@napi-rs/wasm-runtime@0.2.12': resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} - '@next/env@15.5.9': - resolution: {integrity: sha512-4GlTZ+EJM7WaW2HEZcyU317tIQDjkQIyENDLxYJfSWlfqguN+dHkZgyQTV/7ykvobU7yEH5gKvreNrH4B6QgIg==} + '@next/env@15.5.10': + resolution: {integrity: sha512-plg+9A/KoZcTS26fe15LHg+QxReTazrIOoKKUC3Uz4leGGeNPgLHdevVraAAOX0snnUs3WkRx3eUQpj9mreG6A==} '@next/eslint-plugin-next@13.4.13': resolution: {integrity: sha512-RpZeXlPxQ9FLeYN84XHDqRN20XxmVNclYCraLYdifRsmibtcWUWdwE/ANp2C8kgesFRsvwfsw6eOkYNl9sLJ3A==} @@ -2775,8 +2775,8 @@ packages: '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} - '@swc/helpers@0.5.17': - resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} + '@swc/helpers@0.5.18': + resolution: {integrity: sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==} '@tanstack/react-virtual@3.11.2': resolution: {integrity: sha512-OuFzMXPF4+xZgx8UzJha0AieuMihhhaWG0tCqpp6tDzlFwOmNBPYMuLOtMJ1Tr4pXLHmgjcWhG6RlknY2oNTdQ==} @@ -3507,9 +3507,6 @@ packages: camelize@1.0.1: resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} - caniuse-lite@1.0.30001760: - resolution: {integrity: sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==} - caniuse-lite@1.0.30001769: resolution: {integrity: sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==} @@ -5414,8 +5411,8 @@ packages: react: '*' react-dom: '*' - next@15.5.9: - resolution: {integrity: sha512-agNLK89seZEtC5zUHwtut0+tNrc0Xw4FT/Dg+B/VLEo9pAcS9rtTKpek3V6kVcVwsB2YlqMaHdfZL4eLEVYuCg==} + next@15.5.10: + resolution: {integrity: sha512-r0X65PNwyDDyOrWNKpQoZvOatw7BcsTPRKdwEqtc9cj3wv7mbBIk9tKed4klRaFXJdX0rugpuMTHslDrAU1bBg==} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} hasBin: true peerDependencies: @@ -6015,8 +6012,8 @@ packages: engines: {node: '>=10'} hasBin: true - semver@7.7.3: - resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} engines: {node: '>=10'} hasBin: true @@ -7456,7 +7453,7 @@ snapshots: tslib: 2.8.1 optional: true - '@emnapi/runtime@1.7.1': + '@emnapi/runtime@1.8.1': dependencies: tslib: 2.8.1 optional: true @@ -7773,7 +7770,7 @@ snapshots: '@img/sharp-wasm32@0.34.5': dependencies: - '@emnapi/runtime': 1.7.1 + '@emnapi/runtime': 1.8.1 optional: true '@img/sharp-win32-arm64@0.34.5': @@ -7821,24 +7818,24 @@ snapshots: '@internationalized/date@3.6.0': dependencies: - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 '@internationalized/date@3.8.2': dependencies: - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 '@internationalized/message@3.1.8': dependencies: - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 intl-messageformat: 10.7.16 '@internationalized/number@3.6.4': dependencies: - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 '@internationalized/string@3.2.7': dependencies: - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 '@jest/schemas@29.6.3': dependencies: @@ -7968,7 +7965,7 @@ snapshots: '@ledgerhq/errors': 6.24.0 '@ledgerhq/logs': 6.13.0 rxjs: 7.8.2 - semver: 7.7.3 + semver: 7.7.4 '@ledgerhq/errors@6.24.0': {} @@ -8212,11 +8209,11 @@ snapshots: '@napi-rs/wasm-runtime@0.2.12': dependencies: '@emnapi/core': 1.4.5 - '@emnapi/runtime': 1.7.1 + '@emnapi/runtime': 1.8.1 '@tybys/wasm-util': 0.10.0 optional: true - '@next/env@15.5.9': {} + '@next/env@15.5.10': {} '@next/eslint-plugin-next@13.4.13': dependencies: @@ -9435,7 +9432,7 @@ snapshots: '@react-aria/utils': 3.26.0(react@18.3.1) '@react-types/breadcrumbs': 3.7.9(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 transitivePeerDependencies: - react-dom @@ -9447,7 +9444,7 @@ snapshots: '@react-aria/utils': 3.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-types/breadcrumbs': 3.7.15(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9460,7 +9457,7 @@ snapshots: '@react-stately/toggle': 3.9.0(react@18.3.1) '@react-types/button': 3.13.0(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 transitivePeerDependencies: - react-dom @@ -9473,7 +9470,7 @@ snapshots: '@react-stately/toggle': 3.9.0(react@18.3.1) '@react-types/button': 3.13.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9488,7 +9485,7 @@ snapshots: '@react-types/button': 3.10.1(react@18.3.1) '@react-types/calendar': 3.5.0(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9503,7 +9500,7 @@ snapshots: '@react-types/button': 3.13.0(react@18.3.1) '@react-types/calendar': 3.7.3(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9519,7 +9516,7 @@ snapshots: '@react-stately/toggle': 3.8.0(react@18.3.1) '@react-types/checkbox': 3.9.0(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 transitivePeerDependencies: - react-dom @@ -9536,7 +9533,7 @@ snapshots: '@react-stately/toggle': 3.9.0(react@18.3.1) '@react-types/checkbox': 3.10.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9554,7 +9551,7 @@ snapshots: '@react-stately/form': 3.2.0(react@18.3.1) '@react-types/color': 3.1.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9574,7 +9571,7 @@ snapshots: '@react-types/button': 3.13.0(react@18.3.1) '@react-types/combobox': 3.13.1(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9595,7 +9592,7 @@ snapshots: '@react-types/button': 3.13.0(react@18.3.1) '@react-types/combobox': 3.13.7(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9618,7 +9615,7 @@ snapshots: '@react-types/datepicker': 3.9.0(react@18.3.1) '@react-types/dialog': 3.5.20(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9641,7 +9638,7 @@ snapshots: '@react-types/datepicker': 3.13.0(react@18.3.1) '@react-types/dialog': 3.5.20(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9652,7 +9649,7 @@ snapshots: '@react-aria/utils': 3.26.0(react@18.3.1) '@react-types/dialog': 3.5.20(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9663,7 +9660,7 @@ snapshots: '@react-aria/utils': 3.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-types/dialog': 3.5.20(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9673,7 +9670,7 @@ snapshots: '@react-aria/utils': 3.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-stately/disclosure': 3.0.6(react@18.3.1) '@react-types/button': 3.13.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9689,7 +9686,7 @@ snapshots: '@react-stately/dnd': 3.6.1(react@18.3.1) '@react-types/button': 3.13.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9698,7 +9695,7 @@ snapshots: '@react-aria/interactions': 3.22.5(react@18.3.1) '@react-aria/utils': 3.26.0(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 clsx: 2.1.1 react: 18.3.1 @@ -9707,7 +9704,7 @@ snapshots: '@react-aria/interactions': 3.25.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-aria/utils': 3.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 clsx: 2.1.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9718,7 +9715,7 @@ snapshots: '@react-aria/utils': 3.26.0(react@18.3.1) '@react-stately/form': 3.2.0(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-aria/form@3.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': @@ -9727,7 +9724,7 @@ snapshots: '@react-aria/utils': 3.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-stately/form': 3.2.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9745,7 +9742,7 @@ snapshots: '@react-types/checkbox': 3.10.0(react@18.3.1) '@react-types/grid': 3.3.4(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9760,7 +9757,7 @@ snapshots: '@react-stately/list': 3.12.4(react@18.3.1) '@react-stately/tree': 3.9.1(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9773,7 +9770,7 @@ snapshots: '@react-aria/ssr': 3.9.10(react@18.3.1) '@react-aria/utils': 3.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9786,7 +9783,7 @@ snapshots: '@react-aria/ssr': 3.9.10(react@18.3.1) '@react-aria/utils': 3.26.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-aria/interactions@3.22.5(react@18.3.1)': @@ -9794,7 +9791,7 @@ snapshots: '@react-aria/ssr': 3.9.10(react@18.3.1) '@react-aria/utils': 3.26.0(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-aria/interactions@3.25.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': @@ -9803,7 +9800,7 @@ snapshots: '@react-aria/utils': 3.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-stately/flags': 3.1.2 '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9811,14 +9808,14 @@ snapshots: dependencies: '@react-aria/utils': 3.26.0(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-aria/label@3.7.20(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@react-aria/utils': 3.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9826,7 +9823,7 @@ snapshots: dependencies: '@react-aria/utils': 3.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) use-sync-external-store: 1.5.0(react@18.3.1) @@ -9838,7 +9835,7 @@ snapshots: '@react-aria/utils': 3.26.0(react@18.3.1) '@react-types/link': 3.5.9(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 transitivePeerDependencies: - react-dom @@ -9849,7 +9846,7 @@ snapshots: '@react-aria/utils': 3.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-types/link': 3.6.3(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9863,7 +9860,7 @@ snapshots: '@react-stately/list': 3.11.1(react@18.3.1) '@react-types/listbox': 3.7.2(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9877,13 +9874,13 @@ snapshots: '@react-stately/list': 3.12.4(react@18.3.1) '@react-types/listbox': 3.7.2(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) '@react-aria/live-announcer@3.4.4': dependencies: - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 '@react-aria/menu@3.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: @@ -9900,7 +9897,7 @@ snapshots: '@react-types/button': 3.13.0(react@18.3.1) '@react-types/menu': 3.9.13(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9919,7 +9916,7 @@ snapshots: '@react-types/button': 3.13.0(react@18.3.1) '@react-types/menu': 3.10.3(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9928,7 +9925,7 @@ snapshots: '@react-aria/progress': 3.4.25(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-types/meter': 3.4.11(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9944,7 +9941,7 @@ snapshots: '@react-types/button': 3.13.0(react@18.3.1) '@react-types/numberfield': 3.8.13(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9960,7 +9957,7 @@ snapshots: '@react-types/button': 3.13.0(react@18.3.1) '@react-types/overlays': 3.8.11(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9976,7 +9973,7 @@ snapshots: '@react-types/button': 3.13.0(react@18.3.1) '@react-types/overlays': 3.9.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9987,7 +9984,7 @@ snapshots: '@react-aria/utils': 3.26.0(react@18.3.1) '@react-types/progress': 3.5.8(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 transitivePeerDependencies: - react-dom @@ -9999,7 +9996,7 @@ snapshots: '@react-aria/utils': 3.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-types/progress': 3.5.14(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10014,7 +10011,7 @@ snapshots: '@react-stately/radio': 3.10.9(react@18.3.1) '@react-types/radio': 3.8.5(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 transitivePeerDependencies: - react-dom @@ -10030,7 +10027,7 @@ snapshots: '@react-stately/radio': 3.11.0(react@18.3.1) '@react-types/radio': 3.9.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10043,7 +10040,7 @@ snapshots: '@react-types/button': 3.13.0(react@18.3.1) '@react-types/searchfield': 3.6.4(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10062,7 +10059,7 @@ snapshots: '@react-types/button': 3.13.0(react@18.3.1) '@react-types/select': 3.10.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10074,7 +10071,7 @@ snapshots: '@react-aria/utils': 3.26.0(react@18.3.1) '@react-stately/selection': 3.20.4(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10086,7 +10083,7 @@ snapshots: '@react-aria/utils': 3.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-stately/selection': 3.20.4(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10094,7 +10091,7 @@ snapshots: dependencies: '@react-aria/utils': 3.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10108,7 +10105,7 @@ snapshots: '@react-stately/slider': 3.6.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) '@react-types/slider': 3.8.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 transitivePeerDependencies: - react-dom @@ -10122,7 +10119,7 @@ snapshots: '@react-stately/slider': 3.7.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) '@react-types/slider': 3.8.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10133,18 +10130,18 @@ snapshots: '@react-aria/utils': 3.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-types/button': 3.13.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) '@react-aria/ssr@3.9.10(react@18.3.1)': dependencies: - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-aria/ssr@3.9.7(react@18.3.1)': dependencies: - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-aria/switch@3.6.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': @@ -10153,7 +10150,7 @@ snapshots: '@react-stately/toggle': 3.8.0(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) '@react-types/switch': 3.5.13(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 transitivePeerDependencies: - react-dom @@ -10164,7 +10161,7 @@ snapshots: '@react-stately/toggle': 3.9.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) '@react-types/switch': 3.5.13(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10184,7 +10181,7 @@ snapshots: '@react-types/grid': 3.2.10(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) '@react-types/table': 3.10.3(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10204,7 +10201,7 @@ snapshots: '@react-types/grid': 3.3.4(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) '@react-types/table': 3.13.2(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10217,7 +10214,7 @@ snapshots: '@react-stately/tabs': 3.8.4(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) '@react-types/tabs': 3.3.17(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10230,7 +10227,7 @@ snapshots: '@react-stately/tabs': 3.7.0(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) '@react-types/tabs': 3.3.11(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10245,7 +10242,7 @@ snapshots: '@react-stately/list': 3.12.4(react@18.3.1) '@react-types/button': 3.13.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10259,7 +10256,7 @@ snapshots: '@react-stately/utils': 3.10.5(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) '@react-types/textfield': 3.10.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 transitivePeerDependencies: - react-dom @@ -10274,7 +10271,7 @@ snapshots: '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) '@react-types/textfield': 3.12.4(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10287,7 +10284,7 @@ snapshots: '@react-stately/toast': 3.1.2(react@18.3.1) '@react-types/button': 3.13.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10298,7 +10295,7 @@ snapshots: '@react-stately/toggle': 3.9.0(react@18.3.1) '@react-types/checkbox': 3.10.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10308,7 +10305,7 @@ snapshots: '@react-aria/i18n': 3.12.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-aria/utils': 3.26.0(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 transitivePeerDependencies: - react-dom @@ -10319,7 +10316,7 @@ snapshots: '@react-aria/i18n': 3.12.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-aria/utils': 3.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10331,7 +10328,7 @@ snapshots: '@react-stately/tooltip': 3.5.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) '@react-types/tooltip': 3.4.13(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 transitivePeerDependencies: - react-dom @@ -10343,7 +10340,7 @@ snapshots: '@react-stately/tooltip': 3.5.6(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) '@react-types/tooltip': 3.4.19(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10356,7 +10353,7 @@ snapshots: '@react-stately/tree': 3.9.1(react@18.3.1) '@react-types/button': 3.13.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10365,7 +10362,7 @@ snapshots: '@react-aria/ssr': 3.9.10(react@18.3.1) '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 clsx: 2.1.1 react: 18.3.1 @@ -10375,7 +10372,7 @@ snapshots: '@react-stately/flags': 3.1.2 '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 clsx: 2.1.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10385,7 +10382,7 @@ snapshots: '@react-aria/interactions': 3.25.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-aria/utils': 3.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 transitivePeerDependencies: - react-dom @@ -10395,7 +10392,7 @@ snapshots: '@react-aria/interactions': 3.25.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-aria/utils': 3.30.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -10409,7 +10406,7 @@ snapshots: '@react-stately/utils': 3.10.5(react@18.3.1) '@react-types/calendar': 3.5.0(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/calendar@3.8.3(react@18.3.1)': @@ -10418,7 +10415,7 @@ snapshots: '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/calendar': 3.7.3(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/checkbox@3.6.10(react@18.3.1)': @@ -10427,7 +10424,7 @@ snapshots: '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/checkbox': 3.9.0(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/checkbox@3.7.0(react@18.3.1)': @@ -10436,19 +10433,19 @@ snapshots: '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/checkbox': 3.10.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/collections@3.12.0(react@18.3.1)': dependencies: '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/collections@3.12.6(react@18.3.1)': dependencies: '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/color@3.9.0(react@18.3.1)': @@ -10461,7 +10458,7 @@ snapshots: '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/color': 3.1.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/combobox@3.10.1(react@18.3.1)': @@ -10474,7 +10471,7 @@ snapshots: '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/combobox': 3.13.1(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/combobox@3.11.0(react@18.3.1)': @@ -10487,13 +10484,13 @@ snapshots: '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/combobox': 3.13.7(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/data@3.13.2(react@18.3.1)': dependencies: '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/datepicker@3.11.0(react@18.3.1)': @@ -10505,7 +10502,7 @@ snapshots: '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/datepicker': 3.9.0(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/datepicker@3.15.0(react@18.3.1)': @@ -10517,37 +10514,37 @@ snapshots: '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/datepicker': 3.13.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/disclosure@3.0.6(react@18.3.1)': dependencies: '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/dnd@3.6.1(react@18.3.1)': dependencies: '@react-stately/selection': 3.20.4(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/flags@3.1.2': dependencies: - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 '@react-stately/form@3.1.0(react@18.3.1)': dependencies: '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/form@3.2.0(react@18.3.1)': dependencies: '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/grid@3.11.4(react@18.3.1)': @@ -10556,7 +10553,7 @@ snapshots: '@react-stately/selection': 3.20.4(react@18.3.1) '@react-types/grid': 3.3.4(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/list@3.11.1(react@18.3.1)': @@ -10565,7 +10562,7 @@ snapshots: '@react-stately/selection': 3.20.4(react@18.3.1) '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/list@3.12.4(react@18.3.1)': @@ -10574,7 +10571,7 @@ snapshots: '@react-stately/selection': 3.20.4(react@18.3.1) '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/menu@3.9.0(react@18.3.1)': @@ -10582,7 +10579,7 @@ snapshots: '@react-stately/overlays': 3.6.18(react@18.3.1) '@react-types/menu': 3.9.13(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/menu@3.9.6(react@18.3.1)': @@ -10590,7 +10587,7 @@ snapshots: '@react-stately/overlays': 3.6.18(react@18.3.1) '@react-types/menu': 3.10.3(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/numberfield@3.10.0(react@18.3.1)': @@ -10599,21 +10596,21 @@ snapshots: '@react-stately/form': 3.2.0(react@18.3.1) '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/numberfield': 3.8.13(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/overlays@3.6.12(react@18.3.1)': dependencies: '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/overlays': 3.8.11(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/overlays@3.6.18(react@18.3.1)': dependencies: '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/overlays': 3.9.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/radio@3.10.9(react@18.3.1)': @@ -10622,7 +10619,7 @@ snapshots: '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/radio': 3.8.5(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/radio@3.11.0(react@18.3.1)': @@ -10631,14 +10628,14 @@ snapshots: '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/radio': 3.9.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/searchfield@3.5.14(react@18.3.1)': dependencies: '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/searchfield': 3.6.4(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/select@3.7.0(react@18.3.1)': @@ -10648,7 +10645,7 @@ snapshots: '@react-stately/overlays': 3.6.18(react@18.3.1) '@react-types/select': 3.10.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/selection@3.20.4(react@18.3.1)': @@ -10656,7 +10653,7 @@ snapshots: '@react-stately/collections': 3.12.6(react@18.3.1) '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/slider@3.6.0(react@18.3.1)': @@ -10664,7 +10661,7 @@ snapshots: '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) '@react-types/slider': 3.8.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/slider@3.7.0(react@18.3.1)': @@ -10672,7 +10669,7 @@ snapshots: '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) '@react-types/slider': 3.8.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/table@3.13.0(react@18.3.1)': @@ -10685,7 +10682,7 @@ snapshots: '@react-types/grid': 3.2.10(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) '@react-types/table': 3.10.3(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/table@3.14.4(react@18.3.1)': @@ -10698,7 +10695,7 @@ snapshots: '@react-types/grid': 3.3.4(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) '@react-types/table': 3.13.2(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/tabs@3.7.0(react@18.3.1)': @@ -10706,7 +10703,7 @@ snapshots: '@react-stately/list': 3.12.4(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) '@react-types/tabs': 3.3.11(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/tabs@3.8.4(react@18.3.1)': @@ -10714,12 +10711,12 @@ snapshots: '@react-stately/list': 3.12.4(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) '@react-types/tabs': 3.3.17(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/toast@3.1.2(react@18.3.1)': dependencies: - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 use-sync-external-store: 1.5.0(react@18.3.1) @@ -10728,7 +10725,7 @@ snapshots: '@react-stately/utils': 3.10.5(react@18.3.1) '@react-types/checkbox': 3.10.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/toggle@3.9.0(react@18.3.1)': @@ -10736,21 +10733,21 @@ snapshots: '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/checkbox': 3.10.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/tooltip@3.5.0(react@18.3.1)': dependencies: '@react-stately/overlays': 3.6.18(react@18.3.1) '@react-types/tooltip': 3.4.13(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/tooltip@3.5.6(react@18.3.1)': dependencies: '@react-stately/overlays': 3.6.18(react@18.3.1) '@react-types/tooltip': 3.4.19(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/tree@3.8.6(react@18.3.1)': @@ -10759,7 +10756,7 @@ snapshots: '@react-stately/selection': 3.20.4(react@18.3.1) '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/shared': 3.26.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/tree@3.9.1(react@18.3.1)': @@ -10768,24 +10765,24 @@ snapshots: '@react-stately/selection': 3.20.4(react@18.3.1) '@react-stately/utils': 3.10.8(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/utils@3.10.5(react@18.3.1)': dependencies: - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/utils@3.10.8(react@18.3.1)': dependencies: - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-stately/virtualizer@4.2.0(react@18.3.1)': dependencies: '@react-aria/utils': 3.26.0(react@18.3.1) '@react-types/shared': 3.31.0(react@18.3.1) - '@swc/helpers': 0.5.17 + '@swc/helpers': 0.5.18 react: 18.3.1 '@react-types/accordion@3.0.0-alpha.25(react@18.3.1)': @@ -11160,7 +11157,7 @@ snapshots: dependencies: tslib: 2.8.1 - '@swc/helpers@0.5.17': + '@swc/helpers@0.5.18': dependencies: tslib: 2.8.1 @@ -11324,7 +11321,7 @@ snapshots: globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 - semver: 7.7.3 + semver: 7.7.4 ts-api-utils: 1.4.3(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 @@ -12136,8 +12133,6 @@ snapshots: camelize@1.0.1: {} - caniuse-lite@1.0.30001760: {} - caniuse-lite@1.0.30001769: {} cardinal@2.1.1: @@ -13609,7 +13604,7 @@ snapshots: is-bun-module@2.0.0: dependencies: - semver: 7.7.3 + semver: 7.7.4 is-callable@1.2.7: {} @@ -14529,23 +14524,23 @@ snapshots: transitivePeerDependencies: - supports-color - next-seo@6.8.0(next@15.5.9(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next-seo@6.8.0(next@15.5.10(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - next: 15.5.9(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 15.5.10(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - next-themes@0.2.1(next@15.5.9(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next-themes@0.2.1(next@15.5.10(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - next: 15.5.9(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 15.5.10(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - next@15.5.9(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next@15.5.10(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@next/env': 15.5.9 + '@next/env': 15.5.10 '@swc/helpers': 0.5.15 - caniuse-lite: 1.0.30001760 + caniuse-lite: 1.0.30001769 postcss: 8.4.31 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -14565,7 +14560,7 @@ snapshots: - '@babel/core' - babel-plugin-macros - nextra-theme-docs@2.13.4(next@15.5.9(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(nextra@2.13.4(next@15.5.9(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + nextra-theme-docs@2.13.4(next@15.5.10(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(nextra@2.13.4(next@15.5.10(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@headlessui/react': 1.7.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@popperjs/core': 2.11.8 @@ -14576,16 +14571,16 @@ snapshots: git-url-parse: 13.1.1 intersection-observer: 0.12.2 match-sorter: 6.3.4 - next: 15.5.9(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - next-seo: 6.8.0(next@15.5.9(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - next-themes: 0.2.1(next@15.5.9(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - nextra: 2.13.4(next@15.5.9(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 15.5.10(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next-seo: 6.8.0(next@15.5.10(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next-themes: 0.2.1(next@15.5.10(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + nextra: 2.13.4(next@15.5.10(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) scroll-into-view-if-needed: 3.1.0 zod: 3.25.76 - nextra@2.13.4(next@15.5.9(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + nextra@2.13.4(next@15.5.10(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@headlessui/react': 1.7.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mdx-js/mdx': 2.3.0 @@ -14599,7 +14594,7 @@ snapshots: gray-matter: 4.0.3 katex: 0.16.22 lodash.get: 4.4.2 - next: 15.5.9(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 15.5.10(@opentelemetry/api@1.9.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) next-mdx-remote: 4.4.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) p-limit: 3.1.0 react: 18.3.1 @@ -15386,7 +15381,7 @@ snapshots: semver@7.7.2: {} - semver@7.7.3: {} + semver@7.7.4: {} serialize-javascript@6.0.2: dependencies: @@ -15428,7 +15423,7 @@ snapshots: dependencies: '@img/colour': 1.0.0 detect-libc: 2.1.2 - semver: 7.7.3 + semver: 7.7.4 optionalDependencies: '@img/sharp-darwin-arm64': 0.34.5 '@img/sharp-darwin-x64': 0.34.5 From ca5ad9442029a103d7232462f5a530219b381bd3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 16:28:35 +0000 Subject: [PATCH 47/56] build(deps): bump bytes from 1.11.0 to 1.11.1 (#6414) Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.11.0 to 1.11.1. - [Release notes](https://github.com/tokio-rs/bytes/releases) - [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/bytes/compare/v1.11.0...v1.11.1) --- updated-dependencies: - dependency-name: bytes dependency-version: 1.11.1 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 22 +++++++++++----------- Cargo.toml | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e7b63d261c..136e11bd65 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1008,9 +1008,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" dependencies = [ "serde", ] @@ -5331,9 +5331,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" [[package]] name = "num-integer" @@ -11671,9 +11671,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.44" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "itoa", @@ -11682,22 +11682,22 @@ dependencies = [ "num-conv", "num_threads", "powerfmt", - "serde", + "serde_core", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "time-macros" -version = "0.2.24" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" dependencies = [ "num-conv", "time-core", diff --git a/Cargo.toml b/Cargo.toml index 3d3a7636d7..2541455d35 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -232,7 +232,7 @@ blake3 = "1.7.0" bloomfilter = "3.0.1" bs58 = "0.5.1" bytecodec = "0.4.15" -bytes = "1.10.1" +bytes = "1.11.1" cargo_metadata = "0.19.2" celes = "2.6.0" cfg-if = "1.0.0" From 0c3efe67fb02b37b978d15bf68780a3456812e31 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 16:28:48 +0000 Subject: [PATCH 48/56] build(deps): bump bytes from 1.10.1 to 1.11.1 in /nym-wallet (#6413) Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.10.1 to 1.11.1. - [Release notes](https://github.com/tokio-rs/bytes/releases) - [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/bytes/compare/v1.10.1...v1.11.1) --- updated-dependencies: - dependency-name: bytes dependency-version: 1.11.1 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- nym-wallet/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index f50d5d2658..423c497a0c 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -902,9 +902,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "bytes" -version = "1.10.1" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" dependencies = [ "serde", ] From 9cb2655e7de97555e8bad86b42fb3e8fcebd27be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 16:29:24 +0000 Subject: [PATCH 49/56] build(deps): bump bytes from 1.6.0 to 1.11.1 in /contracts (#6416) Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.6.0 to 1.11.1. - [Release notes](https://github.com/tokio-rs/bytes/releases) - [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/bytes/compare/v1.6.0...v1.11.1) --- updated-dependencies: - dependency-name: bytes dependency-version: 1.11.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- contracts/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/Cargo.lock b/contracts/Cargo.lock index f7f8f0ccfe..5468e50112 100644 --- a/contracts/Cargo.lock +++ b/contracts/Cargo.lock @@ -265,9 +265,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "camino" From bb694855d553d2f989fbe5779d520318df81076c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 10 Feb 2026 17:20:54 +0000 Subject: [PATCH 50/56] Lp/stateless handshake (#6437) * perform KKT/PSQ handshake outside of LPStateMachine * initiator * responder * concurrent test * remove KTT/PSQ from the LpStateMachine * adjusted gateway's Handler to accomodate new changes * filling in placehlders * fixed imports in nym-kkt crate * naming * clippy and moved more placeholder tests * split up the initiator side of the PSQ * split up the responder side of the PSQ * additional helpers * addressing review comments * additional tests and explicit Error message --- Cargo.lock | 5 +- Cargo.toml | 7 +- common/bin-common/src/logging/mod.rs | 2 +- common/crypto/Cargo.toml | 4 +- common/nym-kkt/Cargo.toml | 3 +- common/nym-kkt/benches/benches.rs | 44 +- common/nym-kkt/src/encryption.rs | 7 +- common/nym-kkt/src/key_utils.rs | 3 +- common/nym-kkt/src/kkt.rs | 29 +- common/nym-kkt/src/lib.rs | 52 +- common/nym-kkt/src/session.rs | 6 +- common/nym-lp-transport/src/traits.rs | 130 +- common/nym-lp/Cargo.toml | 14 +- common/nym-lp/benches/replay_protection.rs | 6 +- common/nym-lp/src/codec.rs | 41 +- common/nym-lp/src/error.rs | 23 + common/nym-lp/src/lib.rs | 197 +- common/nym-lp/src/message.rs | 143 +- common/nym-lp/src/noise_protocol.rs | 87 +- common/nym-lp/src/packet.rs | 6 +- common/nym-lp/src/peer.rs | 39 +- common/nym-lp/src/psq/helpers.rs | 52 + common/nym-lp/src/psq/initiator.rs | 391 ++++ common/nym-lp/src/psq/mod.rs | 340 +++ common/nym-lp/src/psq/responder.rs | 461 ++++ common/nym-lp/src/session.rs | 1955 ++--------------- common/nym-lp/src/session_integration/mod.rs | 699 +----- common/nym-lp/src/session_manager.rs | 241 +- common/nym-lp/src/state_machine.rs | 1042 ++------- common/test-utils/Cargo.toml | 2 +- gateway/Cargo.toml | 1 + gateway/src/node/lp_listener/data_handler.rs | 9 +- gateway/src/node/lp_listener/handler.rs | 858 ++------ gateway/src/node/lp_listener/mod.rs | 43 +- gateway/src/node/mod.rs | 1 - integration-tests/src/lp_registration.rs | 3 - .../src/lp_client/client.rs | 434 +--- .../lp_client/nested_session/connection.rs | 135 ++ .../mod.rs} | 205 +- .../src/lp_client/state_machine_helpers.rs | 24 +- nym-wallet/Cargo.lock | 197 +- 41 files changed, 2815 insertions(+), 5126 deletions(-) create mode 100644 common/nym-lp/src/psq/helpers.rs create mode 100644 common/nym-lp/src/psq/initiator.rs create mode 100644 common/nym-lp/src/psq/mod.rs create mode 100644 common/nym-lp/src/psq/responder.rs create mode 100644 nym-registration-client/src/lp_client/nested_session/connection.rs rename nym-registration-client/src/lp_client/{nested_session.rs => nested_session/mod.rs} (71%) diff --git a/Cargo.lock b/Cargo.lock index 136e11bd65..83b806eb3f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6925,6 +6925,7 @@ dependencies = [ name = "nym-lp" version = "0.1.0" dependencies = [ + "anyhow", "bs58", "bytes", "chacha20poly1305", @@ -6933,20 +6934,22 @@ dependencies = [ "libcrux-kem", "libcrux-psq", "libcrux-traits", + "mock_instant", "num_enum", "nym-crypto", "nym-kkt", "nym-lp-common", + "nym-lp-transport", "nym-test-utils", "parking_lot", "rand 0.8.5", "rand 0.9.2", - "rand_chacha 0.3.1", "serde", "sha2 0.10.9", "snow", "thiserror 2.0.17", "tls_codec", + "tokio", "tracing", "zeroize", ] diff --git a/Cargo.toml b/Cargo.toml index 2541455d35..5d4ba68b35 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -320,6 +320,7 @@ publicsuffix = "2.3.0" proc_pidinfo = "0.1.3" quote = "1" rand = "0.8.5" +rand09 = { package = "rand", version = "=0.9.2" } rand_chacha = "0.3" rand_core = "0.6.3" rand_distr = "0.4" @@ -483,9 +484,9 @@ nym-vesting-contract-common = { version = "1.20.4", path = "common/cosmwasm-smar nym-verloc = { version = "1.20.4", path = "common/verloc" } nym-wireguard = { version = "1.20.4", path = "common/wireguard" } nym-wireguard-types = { version = "1.20.4", path = "common/wireguard-types" } -nym-wireguard-private-metadata-shared = { version = "1.20.4", path = "common/wireguard-private-metadata/shared" } -nym-wireguard-private-metadata-client = { version = "1.20.4", path = "common/wireguard-private-metadata/client" } -nym-wireguard-private-metadata-server = { version = "1.20.4", path = "common/wireguard-private-metadata/server" } +nym-wireguard-private-metadata-shared = { version = "1.20.4", path = "common/wireguard-private-metadata/shared" } +nym-wireguard-private-metadata-client = { version = "1.20.4", path = "common/wireguard-private-metadata/client" } +nym-wireguard-private-metadata-server = { version = "1.20.4", path = "common/wireguard-private-metadata/server" } nym-sqlx-pool-guard = { version = "1.2.0", path = "nym-sqlx-pool-guard" } nym-wasm-client-core = { version = "1.20.4", path = "common/wasm/client-core" } nym-wasm-storage = { version = "1.20.4", path = "common/wasm/storage" } diff --git a/common/bin-common/src/logging/mod.rs b/common/bin-common/src/logging/mod.rs index b5a9c68e40..20d2e9e274 100644 --- a/common/bin-common/src/logging/mod.rs +++ b/common/bin-common/src/logging/mod.rs @@ -10,7 +10,7 @@ pub use opentelemetry; pub use opentelemetry_jaeger; #[cfg(feature = "tracing")] pub use tracing_opentelemetry; -#[cfg(feature = "tracing")] +#[cfg(feature = "basic_tracing")] pub use tracing_subscriber; #[cfg(feature = "tracing")] pub use tracing_tree; diff --git a/common/crypto/Cargo.toml b/common/crypto/Cargo.toml index 8b08749512..1b5d62f85e 100644 --- a/common/crypto/Cargo.toml +++ b/common/crypto/Cargo.toml @@ -33,7 +33,7 @@ thiserror = { workspace = true } zeroize = { workspace = true, optional = true, features = ["zeroize_derive"] } # internal -nym-sphinx-types = { workspace = true } +nym-sphinx-types = { workspace = true, optional = true } nym-pemstore = { workspace = true } [dev-dependencies] @@ -51,7 +51,7 @@ serde = ["dep:serde", "serde_bytes", "ed25519-dalek/serde", "x25519-dalek/serde" asymmetric = ["x25519-dalek", "ed25519-dalek", "curve25519-dalek", "sha2", "zeroize"] hashing = ["blake3", "digest", "hkdf", "hmac", "generic-array", "sha2", "zeroize"] stream_cipher = ["aes", "ctr", "cipher", "generic-array"] -sphinx = ["nym-sphinx-types/sphinx"] +sphinx = ["nym-sphinx-types", "nym-sphinx-types/sphinx"] [lints] workspace = true diff --git a/common/nym-kkt/Cargo.toml b/common/nym-kkt/Cargo.toml index fcc535016d..705395f712 100644 --- a/common/nym-kkt/Cargo.toml +++ b/common/nym-kkt/Cargo.toml @@ -21,7 +21,8 @@ libcrux-kem = { git = "https://github.com/cryspen/libcrux" } libcrux-ecdh = { git = "https://github.com/cryspen/libcrux", features = ["codec"] } libcrux-chacha20poly1305 = { git = "https://github.com/cryspen/libcrux" } -rand = "0.9.2" +# rand 0.9 for libcrux integration (libcrux uses rand 0.9) +rand09 = { workspace = true } zeroize = { workspace = true, features = ["zeroize_derive"] } classic-mceliece-rust = { git = "https://github.com/georgio/classic-mceliece-rust", features = ["mceliece460896f", "zeroize"] } diff --git a/common/nym-kkt/benches/benches.rs b/common/nym-kkt/benches/benches.rs index 2acb7ab7b5..4d4f0f7e13 100644 --- a/common/nym-kkt/benches/benches.rs +++ b/common/nym-kkt/benches/benches.rs @@ -18,13 +18,13 @@ use nym_kkt::{ responder_ingest_message, responder_process, }, }; -use rand::prelude::*; +use rand09::prelude::*; pub fn gen_ed25519_keypair(c: &mut Criterion) { c.bench_function("Generate Ed25519 Keypair", |b| { b.iter(|| { let mut s: [u8; 32] = [0u8; 32]; - rand::rng().fill_bytes(&mut s); + rand09::rng().fill_bytes(&mut s); ed25519::KeyPair::from_secret(s, 0) }); }); @@ -33,13 +33,13 @@ pub fn gen_ed25519_keypair(c: &mut Criterion) { pub fn gen_mlkem768_keypair(c: &mut Criterion) { c.bench_function("Generate MlKem768 Keypair", |b| { b.iter(|| { - libcrux_kem::key_gen(libcrux_kem::Algorithm::MlKem768, &mut rand::rng()).unwrap() + libcrux_kem::key_gen(libcrux_kem::Algorithm::MlKem768, &mut rand09::rng()).unwrap() }); }); } pub fn kkt_benchmark(c: &mut Criterion) { - let mut rng = rand::rng(); + let mut rng = rand09::rng(); // generate ed25519 keys let mut secret_initiator: [u8; 32] = [0u8; 32]; @@ -111,7 +111,7 @@ pub fn kkt_benchmark(c: &mut Criterion) { }, ); - let (mut i_context, i_frame) = + let (i_context, i_frame) = anonymous_initiator_process(&mut rng, ciphersuite).unwrap(); c.bench_function( @@ -143,7 +143,7 @@ pub fn kkt_benchmark(c: &mut Criterion) { }, ); - let (mut r_context, _) = + let (r_context, _) = responder_ingest_message(&r_context, None, None, &i_frame_r).unwrap(); c.bench_function( @@ -153,7 +153,7 @@ pub fn kkt_benchmark(c: &mut Criterion) { |b| { b.iter(|| { responder_process( - &mut r_context, + &r_context, i_frame_r.session_id(), responder_ed25519_keypair.private_key(), &responder_kem_public_key, @@ -163,7 +163,7 @@ pub fn kkt_benchmark(c: &mut Criterion) { }, ); let r_frame = responder_process( - &mut r_context, + &r_context, i_frame_r.session_id(), responder_ed25519_keypair.private_key(), &responder_kem_public_key, @@ -184,7 +184,7 @@ pub fn kkt_benchmark(c: &mut Criterion) { |b| { b.iter(|| { initiator_ingest_response( - &mut i_context, + &i_context, &r_frame, &r_frame.context().unwrap(), responder_ed25519_keypair.public_key(), @@ -196,7 +196,7 @@ pub fn kkt_benchmark(c: &mut Criterion) { ); let obtained_key = initiator_ingest_response( - &mut i_context, + &i_context, &r_frame, &r_frame.context().unwrap(), responder_ed25519_keypair.public_key(), @@ -208,7 +208,7 @@ pub fn kkt_benchmark(c: &mut Criterion) { } // Initiator, OneWay { - let (mut i_context, i_frame) = initiator_process( + let (i_context, i_frame) = initiator_process( &mut rng, KKTMode::OneWay, ciphersuite, @@ -262,7 +262,7 @@ pub fn kkt_benchmark(c: &mut Criterion) { }, ); - let (mut r_context, r_obtained_key) = responder_ingest_message( + let (r_context, r_obtained_key) = responder_ingest_message( &r_context, Some(initiator_ed25519_keypair.public_key()), None, @@ -279,7 +279,7 @@ pub fn kkt_benchmark(c: &mut Criterion) { |b| { b.iter(|| { responder_process( - &mut r_context, + &r_context, i_frame_r.session_id(), responder_ed25519_keypair.private_key(), &responder_kem_public_key, @@ -290,7 +290,7 @@ pub fn kkt_benchmark(c: &mut Criterion) { ); let r_frame = responder_process( - &mut r_context, + &r_context, i_frame_r.session_id(), responder_ed25519_keypair.private_key(), &responder_kem_public_key, @@ -311,7 +311,7 @@ pub fn kkt_benchmark(c: &mut Criterion) { |b| { b.iter(|| { initiator_ingest_response( - &mut i_context, + &i_context, &r_frame, &r_frame.context().unwrap(), responder_ed25519_keypair.public_key(), @@ -323,7 +323,7 @@ pub fn kkt_benchmark(c: &mut Criterion) { ); let i_obtained_key = initiator_ingest_response( - &mut i_context, + &i_context, &r_frame, &r_frame.context().unwrap(), responder_ed25519_keypair.public_key(), @@ -352,7 +352,7 @@ pub fn kkt_benchmark(c: &mut Criterion) { }, ); - let (mut i_context, i_frame) = initiator_process( + let (i_context, i_frame) = initiator_process( &mut rng, KKTMode::Mutual, ciphersuite, @@ -394,7 +394,7 @@ pub fn kkt_benchmark(c: &mut Criterion) { }, ); - let (mut r_context, r_obtained_key) = responder_ingest_message( + let (r_context, r_obtained_key) = responder_ingest_message( &r_context, Some(initiator_ed25519_keypair.public_key()), Some(&i_dir_hash), @@ -411,7 +411,7 @@ pub fn kkt_benchmark(c: &mut Criterion) { |b| { b.iter(|| { responder_process( - &mut r_context, + &r_context, i_frame_r.session_id(), responder_ed25519_keypair.private_key(), &responder_kem_public_key, @@ -422,7 +422,7 @@ pub fn kkt_benchmark(c: &mut Criterion) { ); let r_frame = responder_process( - &mut r_context, + &r_context, i_frame_r.session_id(), responder_ed25519_keypair.private_key(), &responder_kem_public_key, @@ -445,7 +445,7 @@ pub fn kkt_benchmark(c: &mut Criterion) { |b| { b.iter(|| { initiator_ingest_response( - &mut i_context, + &i_context, &r_frame, &r_frame.context().unwrap(), responder_ed25519_keypair.public_key(), @@ -457,7 +457,7 @@ pub fn kkt_benchmark(c: &mut Criterion) { ); let obtained_key = initiator_ingest_response( - &mut i_context, + &i_context, &r_frame, &r_frame.context().unwrap(), responder_ed25519_keypair.public_key(), diff --git a/common/nym-kkt/src/encryption.rs b/common/nym-kkt/src/encryption.rs index 75257fc79c..c4189f9552 100644 --- a/common/nym-kkt/src/encryption.rs +++ b/common/nym-kkt/src/encryption.rs @@ -5,7 +5,7 @@ use crate::{KKT_INITIAL_FRAME_AAD, context::KKTContext, error::KKTError, frame:: use blake3::Hasher; use libcrux_chacha20poly1305::{NONCE_LEN, TAG_LEN}; use nym_crypto::asymmetric::x25519; -use rand::{CryptoRng, RngCore}; +use rand09::{CryptoRng, RngCore}; use zeroize::Zeroize; #[derive(Clone, Copy, Zeroize)] @@ -182,8 +182,7 @@ mod test { encryption::{KKTSessionSecret, decrypt, encrypt}, key_utils::generate_keypair_x25519, }; - use rand::{RngCore, SeedableRng, rng}; - use rand_chacha::ChaCha20Rng; + use rand09::{RngCore, SeedableRng, rng}; #[test] fn test_keygen() { @@ -227,7 +226,7 @@ mod test { #[test] fn kkt_frame_encryption() -> anyhow::Result<()> { - let mut rng = ChaCha20Rng::seed_from_u64(42); + let mut rng = rand_chacha::ChaCha20Rng::seed_from_u64(42); let session_key = KKTSessionSecret::from_bytes([42u8; 32]); let aad = b"my-amazing-aad"; diff --git a/common/nym-kkt/src/key_utils.rs b/common/nym-kkt/src/key_utils.rs index 535ba8b000..2ea88d231b 100644 --- a/common/nym-kkt/src/key_utils.rs +++ b/common/nym-kkt/src/key_utils.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use classic_mceliece_rust::keypair_boxed; use nym_kkt_ciphersuite::{DEFAULT_HASH_LEN, KeyDigests}; -use rand::{CryptoRng, RngCore}; +use rand09::{CryptoRng, RngCore}; pub fn generate_keypair_ed25519( rng: &mut R, @@ -61,7 +61,6 @@ pub fn generate_keypair_mceliece<'a, R>( classic_mceliece_rust::PublicKey<'a>, ) where - // this is annoying because mceliece lib uses rand 0.8.5... R: RngCore + CryptoRng, { let (encapsulation_key, decapsulation_key) = keypair_boxed(rng); diff --git a/common/nym-kkt/src/kkt.rs b/common/nym-kkt/src/kkt.rs index 05b55d575d..c1d21982f3 100644 --- a/common/nym-kkt/src/kkt.rs +++ b/common/nym-kkt/src/kkt.rs @@ -9,7 +9,7 @@ //! The underlying KKT protocol is implemented in the `session` module. use nym_crypto::asymmetric::{ed25519, x25519}; -use rand::{CryptoRng, RngCore}; +use rand09::{CryptoRng, RngCore}; use crate::{ ciphersuite::{Ciphersuite, EncapsulationKey}, @@ -33,7 +33,7 @@ use crate::frame::KKTFrame; /// The request will be signed with the provided signing key. /// /// # Arguments -/// * `rng` - Random number generator +/// * `rng` - random number generator /// * `ciphersuite` - Negotiated ciphersuite (KEM, hash, signature algorithms) /// * `signing_key` - Client's Ed25519 signing key for authentication /// * `responder_dh_public_key` - Responder's long-term x25519 Diffie-Hellman public key @@ -90,7 +90,7 @@ pub fn request_kem_key( /// # Example /// ```ignore /// let gateway_kem_key = validate_kem_response( -/// &mut context, +/// &context, /// &session_secret, /// &gateway_verification_key, /// &expected_hash_from_directory, @@ -199,14 +199,14 @@ mod tests { fn random_x25519_key() -> x25519::PrivateKey { let mut bytes = [0u8; 32]; - let mut rng = rand::rng(); + let mut rng = rand09::rng(); rng.fill_bytes(&mut bytes); x25519::PrivateKey::from_secret(bytes) } #[test] fn test_kkt_wrappers_oneway_authenticated() { - let mut rng = rand::rng(); + let mut rng = rand09::rng(); // Generate Ed25519 keypairs for both parties let mut initiator_secret = [0u8; 32]; @@ -241,7 +241,7 @@ mod tests { ); // Client: Request KEM key - let (session_key, mut context, request_frame_ciphertext) = request_kem_key( + let (session_key, context, request_frame_ciphertext) = request_kem_key( &mut rng, ciphersuite, ed25519_init.private_key(), @@ -262,7 +262,7 @@ mod tests { // Client: Validate response let obtained_key = validate_kem_response( - &mut context, + &context, &session_key, ed25519_resp.public_key(), &key_hash, @@ -276,7 +276,7 @@ mod tests { #[test] fn test_kkt_wrappers_anonymous() { - let mut rng = rand::rng(); + let mut rng = rand09::rng(); // Only responder has keys let mut responder_secret = [0u8; 32]; @@ -304,8 +304,7 @@ mod tests { ); // Anonymous initiator - let (mut context, request_frame) = - anonymous_initiator_process(&mut rng, ciphersuite).unwrap(); + let (context, request_frame) = anonymous_initiator_process(&mut rng, ciphersuite).unwrap(); // Generate the session's shared secret and encrypt the Initiator's request let (session_secret, encrypted_request_bytes) = @@ -324,7 +323,7 @@ mod tests { // Initiator: Validate response let obtained_key = validate_kem_response( - &mut context, + &context, &session_secret, responder_keypair.public_key(), &key_hash, @@ -337,7 +336,7 @@ mod tests { #[test] fn test_invalid_signature_rejected() { - let mut rng = rand::rng(); + let mut rng = rand09::rng(); let mut initiator_secret = [0u8; 32]; rng.fill_bytes(&mut initiator_secret); @@ -390,7 +389,7 @@ mod tests { #[test] fn test_hash_mismatch_rejected() { - let mut rng = rand::rng(); + let mut rng = rand09::rng(); let mut initiator_secret = [0u8; 32]; rng.fill_bytes(&mut initiator_secret); @@ -417,7 +416,7 @@ mod tests { // Use WRONG hash let wrong_hash = [0u8; 32]; - let (session_key, mut context, request_frame) = request_kem_key( + let (session_key, context, request_frame) = request_kem_key( &mut rng, ciphersuite, initiator_keypair.private_key(), @@ -437,7 +436,7 @@ mod tests { // Client validates with WRONG hash let result = validate_kem_response( - &mut context, + &context, &session_key, responder_keypair.public_key(), &wrong_hash, // Wrong! diff --git a/common/nym-kkt/src/lib.rs b/common/nym-kkt/src/lib.rs index e6a91a83ec..d879cf2286 100644 --- a/common/nym-kkt/src/lib.rs +++ b/common/nym-kkt/src/lib.rs @@ -38,7 +38,7 @@ mod test { #[test] fn test_kkt_psq_e2e_clear() { - let mut rng = rand::rng(); + let mut rng = rand09::rng(); // generate ed25519 keys let initiator_ed25519_keypair = generate_keypair_ed25519(&mut rng, Some(0)); @@ -106,18 +106,18 @@ mod test { // Anonymous Initiator, OneWay { - let (mut i_context, i_frame) = + let (i_context, i_frame) = anonymous_initiator_process(&mut rng, ciphersuite).unwrap(); let i_frame_bytes = i_frame.to_bytes(); let (i_frame_r, r_context) = KKTFrame::from_bytes(&i_frame_bytes).unwrap(); - let (mut r_context, _) = + let (r_context, _) = responder_ingest_message(&r_context, None, None, &i_frame_r).unwrap(); let r_frame = responder_process( - &mut r_context, + &r_context, i_frame_r.session_id(), responder_ed25519_keypair.private_key(), &responder_kem_public_key, @@ -129,7 +129,7 @@ mod test { let (i_frame_r, i_context_r) = KKTFrame::from_bytes(&r_bytes).unwrap(); let i_obtained_key = initiator_ingest_response( - &mut i_context, + &i_context, &i_frame_r, &i_context_r, responder_ed25519_keypair.public_key(), @@ -141,7 +141,7 @@ mod test { } // Initiator, OneWay { - let (mut i_context, i_frame) = initiator_process( + let (i_context, i_frame) = initiator_process( &mut rng, crate::context::KKTMode::OneWay, ciphersuite, @@ -154,7 +154,7 @@ mod test { let (i_frame_r, r_context) = KKTFrame::from_bytes(&i_frame_bytes).unwrap(); - let (mut r_context, r_obtained_key) = responder_ingest_message( + let (r_context, r_obtained_key) = responder_ingest_message( &r_context, Some(initiator_ed25519_keypair.public_key()), None, @@ -165,7 +165,7 @@ mod test { assert!(r_obtained_key.is_none()); let r_frame = responder_process( - &mut r_context, + &r_context, i_frame_r.session_id(), responder_ed25519_keypair.private_key(), &responder_kem_public_key, @@ -177,7 +177,7 @@ mod test { let (i_frame_r, i_context_r) = KKTFrame::from_bytes(&r_bytes).unwrap(); let i_obtained_key = initiator_ingest_response( - &mut i_context, + &i_context, &i_frame_r, &i_context_r, responder_ed25519_keypair.public_key(), @@ -190,7 +190,7 @@ mod test { // Initiator, Mutual { - let (mut i_context, i_frame) = initiator_process( + let (i_context, i_frame) = initiator_process( &mut rng, crate::context::KKTMode::Mutual, ciphersuite, @@ -203,7 +203,7 @@ mod test { let (i_frame_r, r_context) = KKTFrame::from_bytes(&i_frame_bytes).unwrap(); - let (mut r_context, r_obtained_key) = responder_ingest_message( + let (r_context, r_obtained_key) = responder_ingest_message( &r_context, Some(initiator_ed25519_keypair.public_key()), Some(&i_dir_hash), @@ -214,7 +214,7 @@ mod test { assert_eq!(r_obtained_key.unwrap().encode(), i_kem_key_bytes); let r_frame = responder_process( - &mut r_context, + &r_context, i_frame_r.session_id(), responder_ed25519_keypair.private_key(), &responder_kem_public_key, @@ -226,7 +226,7 @@ mod test { let (i_frame_r, i_context_r) = KKTFrame::from_bytes(&r_bytes).unwrap(); let i_obtained_key = initiator_ingest_response( - &mut i_context, + &i_context, &i_frame_r, &i_context_r, responder_ed25519_keypair.public_key(), @@ -241,7 +241,7 @@ mod test { } #[test] fn test_kkt_psq_e2e_encrypted() { - let mut rng = rand::rng(); + let mut rng = rand09::rng(); // generate ed25519 keys let initiator_ed25519_keypair = generate_keypair_ed25519(&mut rng, Some(0)); @@ -312,7 +312,7 @@ mod test { // Anonymous Initiator, OneWay { - let (mut i_context, i_frame) = + let (i_context, i_frame) = anonymous_initiator_process(&mut rng, ciphersuite).unwrap(); // encryption - initiator frame @@ -330,11 +330,11 @@ mod test { decrypt_initial_kkt_frame(responder_x25519_keypair.private_key(), &i_bytes) .unwrap(); - let (mut r_context, _) = + let (r_context, _) = responder_ingest_message(&i_context_r, None, None, &i_frame_r).unwrap(); let r_frame = responder_process( - &mut r_context, + &r_context, i_frame_r.session_id(), responder_ed25519_keypair.private_key(), &responder_kem_public_key, @@ -352,7 +352,7 @@ mod test { decrypt_kkt_frame(&i_session_secret, &r_bytes, KKT_RESPONSE_AAD).unwrap(); let i_obtained_key = initiator_ingest_response( - &mut i_context, + &i_context, &i_frame_r, &i_context_r, responder_ed25519_keypair.public_key(), @@ -364,7 +364,7 @@ mod test { } // Initiator, OneWay { - let (mut i_context, i_frame) = initiator_process( + let (i_context, i_frame) = initiator_process( &mut rng, crate::context::KKTMode::OneWay, ciphersuite, @@ -388,7 +388,7 @@ mod test { decrypt_initial_kkt_frame(responder_x25519_keypair.private_key(), &i_bytes) .unwrap(); - let (mut r_context, r_obtained_key) = responder_ingest_message( + let (r_context, r_obtained_key) = responder_ingest_message( &r_context, Some(initiator_ed25519_keypair.public_key()), None, @@ -399,7 +399,7 @@ mod test { assert!(r_obtained_key.is_none()); let r_frame = responder_process( - &mut r_context, + &r_context, i_frame_r.session_id(), responder_ed25519_keypair.private_key(), &responder_kem_public_key, @@ -417,7 +417,7 @@ mod test { decrypt_kkt_frame(&i_session_secret, &r_bytes, KKT_RESPONSE_AAD).unwrap(); let i_obtained_key = initiator_ingest_response( - &mut i_context, + &i_context, &i_frame_r, &i_context_r, responder_ed25519_keypair.public_key(), @@ -430,7 +430,7 @@ mod test { // Initiator, Mutual { - let (mut i_context, i_frame) = initiator_process( + let (i_context, i_frame) = initiator_process( &mut rng, crate::context::KKTMode::Mutual, ciphersuite, @@ -454,7 +454,7 @@ mod test { decrypt_initial_kkt_frame(responder_x25519_keypair.private_key(), &i_bytes) .unwrap(); - let (mut r_context, r_obtained_key) = responder_ingest_message( + let (r_context, r_obtained_key) = responder_ingest_message( &i_context_r, Some(initiator_ed25519_keypair.public_key()), Some(&i_dir_hash), @@ -465,7 +465,7 @@ mod test { assert_eq!(r_obtained_key.unwrap().encode(), i_kem_key_bytes); let r_frame = responder_process( - &mut r_context, + &r_context, i_frame_r.session_id(), responder_ed25519_keypair.private_key(), &responder_kem_public_key, @@ -483,7 +483,7 @@ mod test { decrypt_kkt_frame(&i_session_secret, &r_bytes, KKT_RESPONSE_AAD).unwrap(); let i_obtained_key = initiator_ingest_response( - &mut i_context, + &i_context, &i_frame_r, &i_context_r, responder_ed25519_keypair.public_key(), diff --git a/common/nym-kkt/src/session.rs b/common/nym-kkt/src/session.rs index 88a59500eb..40db3d275d 100644 --- a/common/nym-kkt/src/session.rs +++ b/common/nym-kkt/src/session.rs @@ -1,5 +1,5 @@ use nym_crypto::asymmetric::ed25519::{self, Signature}; -use rand::{CryptoRng, RngCore}; +use rand09::{CryptoRng, RngCore}; use crate::frame::KKTSessionId; use crate::{ @@ -73,7 +73,7 @@ where } pub fn initiator_ingest_response<'a>( - own_context: &mut KKTContext, + own_context: &KKTContext, remote_frame: &KKTFrame, remote_context: &KKTContext, remote_verification_key: &ed25519::PublicKey, @@ -201,7 +201,7 @@ pub fn responder_ingest_message<'a>( } pub fn responder_process<'a>( - own_context: &mut KKTContext, + own_context: &KKTContext, session_id: KKTSessionId, signing_key: &ed25519::PrivateKey, encapsulation_key: &EncapsulationKey<'a>, diff --git a/common/nym-lp-transport/src/traits.rs b/common/nym-lp-transport/src/traits.rs index 888c800f64..045bf29498 100644 --- a/common/nym-lp-transport/src/traits.rs +++ b/common/nym-lp-transport/src/traits.rs @@ -10,7 +10,7 @@ use tracing::debug; // only used in internal code (and tests) #[allow(async_fn_in_trait)] -pub trait LpTransport: AsyncRead + AsyncWrite + Sized { +pub trait LpTransport: Sized { async fn connect(endpoint: SocketAddr) -> std::io::Result; fn set_no_delay(&mut self, nodelay: bool) -> std::io::Result<()>; @@ -24,32 +24,7 @@ pub trait LpTransport: AsyncRead + AsyncWrite + Sized { /// /// # Errors /// Returns an error on network transmission fails. - async fn send_serialised_packet(&mut self, packet_data: &[u8]) -> std::io::Result<()> - where - Self: Unpin, - { - // Send 4-byte length prefix (u32 big-endian) - let len = packet_data.len() as u32; - self.write_all(&len.to_be_bytes()) - .await - .inspect_err(|e| debug!("Failed to send packet length: {e}"))?; - - // Send the actual packet data - self.write_all(packet_data) - .await - .inspect_err(|e| debug!("Failed to send packet data: {e}"))?; - - // Flush to ensure data is sent immediately - self.flush() - .await - .inspect_err(|e| debug!("Failed to flush stream: {e}"))?; - - tracing::trace!( - "Sent LP packet ({} bytes + 4 byte header)", - packet_data.len() - ); - Ok(()) - } + async fn send_serialised_packet(&mut self, packet_data: &[u8]) -> std::io::Result<()>; /// Receives an LP packet from a TCP stream with length-prefixed framing. /// @@ -57,35 +32,72 @@ pub trait LpTransport: AsyncRead + AsyncWrite + Sized { /// /// # Errors /// Returns an error on network transmission fails. - async fn receive_raw_packet(&mut self) -> std::io::Result> - where - Self: Unpin, - { - // Read 4-byte length prefix (u32 big-endian) - let mut len_buf = [0u8; 4]; - self.read_exact(&mut len_buf) - .await - .inspect_err(|e| debug!("Failed to read packet length: {e}"))?; + async fn receive_raw_packet(&mut self) -> std::io::Result>; +} - let packet_len = u32::from_be_bytes(len_buf) as usize; +async fn send_serialised_packet_async_write( + writer: &mut W, + packet_data: &[u8], +) -> std::io::Result<()> +where + W: AsyncWrite + Unpin, +{ + // Send 4-byte length prefix (u32 big-endian) + let len = packet_data.len() as u32; + writer + .write_all(&len.to_be_bytes()) + .await + .inspect_err(|e| debug!("Failed to send packet length: {e}"))?; - // Sanity check to prevent huge allocations - const MAX_PACKET_SIZE: usize = 65536; // 64KB max - if packet_len > MAX_PACKET_SIZE { - return Err(std::io::Error::other(format!( - "Packet size {packet_len} exceeds maximum {MAX_PACKET_SIZE}", - ))); - } + // Send the actual packet data + writer + .write_all(packet_data) + .await + .inspect_err(|e| debug!("Failed to send packet data: {e}"))?; - // Read the actual packet data - let mut packet_buf = vec![0u8; packet_len]; - self.read_exact(&mut packet_buf) - .await - .inspect_err(|e| debug!("Failed to read packet data: {e}"))?; + // Flush to ensure data is sent immediately + writer + .flush() + .await + .inspect_err(|e| debug!("Failed to flush stream: {e}"))?; - tracing::trace!("Received LP packet ({packet_len} bytes + 4 byte header)"); - Ok(packet_buf) + tracing::trace!( + "Sent LP packet ({} bytes + 4 byte header)", + packet_data.len() + ); + Ok(()) +} + +async fn receive_raw_packet_async_read(reader: &mut R) -> std::io::Result> +where + R: AsyncRead + Unpin, +{ + // Read 4-byte length prefix (u32 big-endian) + let mut len_buf = [0u8; 4]; + reader + .read_exact(&mut len_buf) + .await + .inspect_err(|e| debug!("Failed to read packet length: {e}"))?; + + let packet_len = u32::from_be_bytes(len_buf) as usize; + + // Sanity check to prevent huge allocations + const MAX_PACKET_SIZE: usize = 65536; // 64KB max + if packet_len > MAX_PACKET_SIZE { + return Err(std::io::Error::other(format!( + "Packet size {packet_len} exceeds maximum {MAX_PACKET_SIZE}", + ))); } + + // Read the actual packet data + let mut packet_buf = vec![0u8; packet_len]; + reader + .read_exact(&mut packet_buf) + .await + .inspect_err(|e| debug!("Failed to read packet data: {e}"))?; + + tracing::trace!("Received LP packet ({packet_len} bytes + 4 byte header)"); + Ok(packet_buf) } impl LpTransport for TcpStream { @@ -97,6 +109,14 @@ impl LpTransport for TcpStream { // Set TCP_NODELAY for low latency self.set_nodelay(nodelay) } + + async fn send_serialised_packet(&mut self, packet_data: &[u8]) -> std::io::Result<()> { + send_serialised_packet_async_write(self, packet_data).await + } + + async fn receive_raw_packet(&mut self) -> std::io::Result> { + receive_raw_packet_async_read(self).await + } } #[cfg(feature = "io-mocks")] @@ -108,4 +128,12 @@ impl LpTransport for MockIOStream { fn set_no_delay(&mut self, _nodelay: bool) -> std::io::Result<()> { Ok(()) } + + async fn send_serialised_packet(&mut self, packet_data: &[u8]) -> std::io::Result<()> { + send_serialised_packet_async_write(self, packet_data).await + } + + async fn receive_raw_packet(&mut self) -> std::io::Result> { + receive_raw_packet_async_read(self).await + } } diff --git a/common/nym-lp/Cargo.toml b/common/nym-lp/Cargo.toml index 58f376b1e5..22f11c279b 100644 --- a/common/nym-lp/Cargo.toml +++ b/common/nym-lp/Cargo.toml @@ -17,11 +17,12 @@ sha2 = { workspace = true } tracing = { workspace = true } rand = { workspace = true } # rand 0.9 for KKT integration (nym-kkt uses rand 0.9) -rand09 = { package = "rand", version = "0.9.2" } +rand09 = { workspace = true } nym-crypto = { path = "../crypto", features = ["hashing", "asymmetric"] } nym-kkt = { path = "../nym-kkt" } nym-lp-common = { path = "../nym-lp-common" } +nym-lp-transport = { path = "../nym-lp-transport" } # libcrux dependencies for PSQ (Post-Quantum PSK derivation) libcrux-psq = { git = "https://github.com/cryspen/libcrux", features = [ @@ -34,12 +35,21 @@ num_enum = { workspace = true } chacha20poly1305 = { workspace = true } zeroize = { workspace = true, features = ["zeroize_derive"] } +# needed for the 'mock 'feature +nym-test-utils = { workspace = true, optional = true } + [dev-dependencies] criterion = { version = "0.5", features = ["html_reports"] } -rand_chacha = "0.3" +#rand_chacha = "0.3" +mock_instant = { workspace = true } nym-crypto = { path = "../crypto", features = ["rand"] } nym-test-utils = { workspace = true } +anyhow = { workspace = true } +tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } +nym-lp-transport = { path = "../nym-lp-transport", features = ["io-mocks"] } +[features] +mock = ["nym-test-utils", "nym-crypto/rand"] [[bench]] name = "replay_protection" diff --git a/common/nym-lp/benches/replay_protection.rs b/common/nym-lp/benches/replay_protection.rs index 562982e527..a21a1092f0 100644 --- a/common/nym-lp/benches/replay_protection.rs +++ b/common/nym-lp/benches/replay_protection.rs @@ -1,8 +1,8 @@ use criterion::{BenchmarkId, Criterion, Throughput, black_box, criterion_group, criterion_main}; use nym_lp::replay::ReceivingKeyCounterValidator; +use nym_test_utils::helpers::u64_seeded_rng; use parking_lot::Mutex; -use rand::{Rng, SeedableRng}; -use rand_chacha::ChaCha8Rng; +use rand::Rng; use std::sync::Arc; fn bench_sequential_counters(c: &mut Criterion) { @@ -47,7 +47,7 @@ fn bench_out_of_order_counters(c: &mut Criterion) { let validator = ReceivingKeyCounterValidator::default(); // Create random counters within a valid window - let mut rng = ChaCha8Rng::seed_from_u64(42); + let mut rng = u64_seeded_rng(42); let counters: Vec = (0..size).map(|_| rng.gen_range(0..1024)).collect(); b.iter(|| { diff --git a/common/nym-lp/src/codec.rs b/common/nym-lp/src/codec.rs index d8eee41844..94eedc1199 100644 --- a/common/nym-lp/src/codec.rs +++ b/common/nym-lp/src/codec.rs @@ -555,7 +555,7 @@ mod tests { buf.extend_from_slice(&[1, 0, 0, 0]); // Version + reserved buf.extend_from_slice(&42u32.to_le_bytes()); // Sender index buf.extend_from_slice(&123u64.to_le_bytes()); // Counter - buf.extend_from_slice(&255u16.to_le_bytes()); // Invalid message type + buf.extend_from_slice(&231u16.to_le_bytes()); // Invalid message type // Need payload and trailer to meet min_size requirement let payload_size = 10; // Arbitrary buf.extend_from_slice(&vec![0u8; payload_size]); // Some data @@ -565,7 +565,7 @@ mod tests { let result = parse_lp_packet(&buf, None); assert!(result.is_err()); match result { - Err(LpError::InvalidMessageType(255)) => {} // Expected error + Err(LpError::InvalidMessageType(231)) => {} // Expected error Err(e) => panic!("Expected InvalidMessageType error, got {:?}", e), Ok(_) => panic!("Expected error, but got Ok"), } @@ -628,7 +628,7 @@ mod tests { receiver_idx: 42, counter: 123, }, - message: LpMessage::ClientHello(hello_data.clone()), + message: LpMessage::ClientHello(hello_data), trailer: [0; TRAILER_LEN], }; @@ -681,7 +681,7 @@ mod tests { receiver_idx: 100, counter: 200, }, - message: LpMessage::ClientHello(hello_data.clone()), + message: LpMessage::ClientHello(hello_data), trailer: [55; TRAILER_LEN], }; @@ -1289,4 +1289,37 @@ mod tests { _ => panic!("Expected SubsessionKK1 message"), } } + + #[test] + fn test_serialize_parse_error() { + use crate::message::ErrorPacketData; + + let mut dst = BytesMut::new(); + + let error_data = ErrorPacketData { + message: "this is an error".to_string(), + }; + + let packet = LpPacket { + header: LpHeader { + protocol_version: 1, + reserved: [0u8; 3], + receiver_idx: 42, + counter: 200, + }, + message: LpMessage::Error(error_data.clone()), + trailer: [0; TRAILER_LEN], + }; + + serialize_lp_packet(&packet, &mut dst, None).unwrap(); + let decoded = parse_lp_packet(&dst, None).unwrap(); + + assert_eq!(decoded.header.receiver_idx, 42); + match decoded.message { + LpMessage::Error(data) => { + assert_eq!(data.message, "this is an error"); + } + _ => panic!("Expected Error message"), + } + } } diff --git a/common/nym-lp/src/error.rs b/common/nym-lp/src/error.rs index caedcc84e4..cf3b5e5085 100644 --- a/common/nym-lp/src/error.rs +++ b/common/nym-lp/src/error.rs @@ -1,9 +1,11 @@ // Copyright 2025 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::message::MessageType; use crate::{noise_protocol::NoiseError, replay::ReplayError}; use nym_crypto::asymmetric::ed25519::Ed25519RecoveryError; use nym_kkt::ciphersuite::{HashFunction, KEM}; +use nym_kkt::error::KKTError; use thiserror::Error; #[derive(Error, Debug)] @@ -102,4 +104,25 @@ pub enum LpError { kem: KEM, hash_function: HashFunction, }, + + #[error("failed to complete KKT/PSQ handshake: {0}")] + KKTPSQHandshake(String), + + #[error("failed to complete the KKT exchange: {source}")] + KKTFailure { + #[from] + source: KKTError, + }, +} + +impl LpError { + pub fn kkt_psq_handshake(msg: impl Into) -> Self { + Self::KKTPSQHandshake(msg.into()) + } + + pub fn unexpected_handshake_response(got: MessageType, expected: MessageType) -> LpError { + Self::KKTPSQHandshake(format!( + "received unexpected response, got: {got:?}, expected: {expected:?}" + )) + } } diff --git a/common/nym-lp/src/lib.rs b/common/nym-lp/src/lib.rs index e1198e7fdc..be5bb991af 100644 --- a/common/nym-lp/src/lib.rs +++ b/common/nym-lp/src/lib.rs @@ -10,6 +10,7 @@ pub mod noise_protocol; pub mod packet; pub mod peer; pub mod psk; +mod psq; pub mod replay; pub mod session; mod session_integration; @@ -21,62 +22,156 @@ pub use error::LpError; pub use message::{ClientHelloData, LpMessage}; pub use packet::{BOOTSTRAP_RECEIVER_IDX, LpPacket, OuterHeader}; pub use replay::{ReceivingKeyCounterValidator, ReplayError}; -pub use session::{LpSession, generate_fresh_salt}; +pub use session::LpSession; pub use session_manager::SessionManager; pub use state_machine::LpStateMachine; pub const NOISE_PATTERN: &str = "Noise_XKpsk3_25519_ChaChaPoly_SHA256"; pub const NOISE_PSK_INDEX: u8 = 3; -#[cfg(test)] +#[cfg(any(feature = "mock", test))] +pub struct SessionsMock { + pub initiator: LpSession, + pub responder: LpSession, +} + +#[cfg(any(feature = "mock", test))] +impl SessionsMock { + pub fn mock_post_handshake(session_id: u32) -> SessionsMock { + use crate::peer::mock_peers; + use nym_kkt::ciphersuite::{DecapsulationKey, EncapsulationKey}; + + let (init, resp) = mock_peers(); + let resp_remote = resp.as_remote(); + let init_remote = init.as_remote(); + let salt = [42u8; 32]; + let session_id_bytes = session_id.to_le_bytes(); + + // skip KKT by just deriving the kem key locally + let kem_keys = resp.kem_psq.as_ref().unwrap(); + + let libcrux_private_key = libcrux_kem::PrivateKey::decode( + libcrux_kem::Algorithm::X25519, + kem_keys.private_key().as_bytes(), + ) + .unwrap(); + let decapsulation_key = DecapsulationKey::X25519(libcrux_private_key); + + let libcrux_public_key = libcrux_kem::PublicKey::decode( + libcrux_kem::Algorithm::X25519, + kem_keys.public_key().as_bytes(), + ) + .unwrap(); + let encapsulation_key = EncapsulationKey::X25519(libcrux_public_key); + + // INIT -> RESP: PSQ MSG1 + let psq_initiator = crate::psk::psq_initiator_create_message( + init.x25519.private_key(), + &resp_remote.x25519_public, + &encapsulation_key, + init.ed25519.private_key(), + init.ed25519.public_key(), + &salt, + &session_id_bytes, + ) + .unwrap(); + + let psk = psq_initiator.psk; + let psq_payload = psq_initiator.payload; + let outer_aead_key = crate::codec::OuterAeadKey::from_psk(&psk); + + let noise_state_init = snow::Builder::new(crate::noise_protocol::NoiseProtocol::params()) + .local_private_key(init.x25519().private_key().as_bytes()) + .remote_public_key(resp_remote.x25519_public.as_bytes()) + .psk(crate::NOISE_PSK_INDEX, &psk) + .build_initiator() + .unwrap(); + let mut noise_protocol_init = crate::noise_protocol::NoiseProtocol::new(noise_state_init); + let noise_msg1 = noise_protocol_init.get_bytes_to_send().unwrap().unwrap(); + + let psq_responder = crate::psk::psq_responder_process_message( + resp.x25519.private_key(), + &init_remote.x25519_public, + (&decapsulation_key, &encapsulation_key), + &init_remote.ed25519_public, + &psq_payload, + &salt, + &session_id_bytes, + ) + .unwrap(); + + let noise_state_resp = snow::Builder::new(crate::noise_protocol::NoiseProtocol::params()) + .local_private_key(resp.x25519().private_key().as_bytes()) + .remote_public_key(init_remote.x25519_public.as_bytes()) + .psk(crate::NOISE_PSK_INDEX, &psk) + .build_responder() + .unwrap(); + let mut noise_protocol_resp = crate::noise_protocol::NoiseProtocol::new(noise_state_resp); + noise_protocol_resp.read_message(&noise_msg1).unwrap(); + + let noise_msg2 = noise_protocol_resp.get_bytes_to_send().unwrap().unwrap(); + noise_protocol_init.read_message(&noise_msg2).unwrap(); + let noise_msg3 = noise_protocol_init.get_bytes_to_send().unwrap().unwrap(); + + assert!(noise_protocol_init.is_handshake_finished()); + + noise_protocol_resp.read_message(&noise_msg3).unwrap(); + assert!(noise_protocol_resp.is_handshake_finished()); + + SessionsMock { + initiator: LpSession::new( + session_id, + 1, + outer_aead_key.clone(), + init, + resp_remote, + crate::session::PqSharedSecret::new(psq_initiator.pq_shared_secret), + noise_protocol_init, + ), + responder: LpSession::new( + session_id, + 1, + outer_aead_key, + resp, + init_remote, + crate::session::PqSharedSecret::new(psq_responder.pq_shared_secret), + noise_protocol_resp, + ), + } + } + + // we just need a dummy 'valid' session for simpler tests + pub fn mock_initiator() -> LpSession { + Self::mock_post_handshake(1234).initiator + } +} + +#[cfg(any(feature = "mock", test))] pub fn sessions_for_tests() -> (LpSession, LpSession) { - let (init, resp) = crate::peer::mock_peers(); + let sessions = SessionsMock::mock_post_handshake(69); + (sessions.initiator, sessions.responder) +} - // Use a fixed receiver_index for deterministic tests - let receiver_index: u32 = 12345; - - // Use consistent salt for deterministic tests - let salt = [1u8; 32]; - - let initiator_session = LpSession::new( - receiver_index, - true, - init.clone(), - resp.as_remote(), - &salt, - packet::version::CURRENT, - ) - .expect("Test session creation failed"); - - let responder_session = LpSession::new( - receiver_index, - false, - resp, - init.as_remote(), - &salt, - packet::version::CURRENT, - ) - .expect("Test session creation failed"); - - (initiator_session, responder_session) +#[cfg(any(feature = "mock", test))] +pub fn mock_session_for_test() -> LpSession { + SessionsMock::mock_initiator() } #[cfg(test)] mod tests { use crate::message::LpMessage; - use crate::packet::{LpHeader, LpPacket, TRAILER_LEN, version}; + use crate::packet::{LpHeader, LpPacket, TRAILER_LEN}; use crate::session_manager::SessionManager; - use crate::{LpError, sessions_for_tests}; + use crate::{LpError, SessionsMock, mock_session_for_test}; use bytes::BytesMut; // Import the new standalone functions use crate::codec::{parse_lp_packet, serialize_lp_packet}; - use crate::peer::mock_peers; #[test] fn test_replay_protection_integration() { // Create session - let session = sessions_for_tests().0; + let mut session = mock_session_for_test(); // === Packet 1 (Counter 0 - Should succeed) === let packet1 = LpPacket { @@ -175,40 +270,20 @@ mod tests { #[test] fn test_session_manager_integration() { // Create session manager - let local_manager = SessionManager::new(); - let remote_manager = SessionManager::new(); - - // Generate Ed25519 keypairs for PSQ authentication - let (init, resp) = mock_peers(); + let mut local_manager = SessionManager::new(); + let mut remote_manager = SessionManager::new(); // Use fixed receiver_index for deterministic test let receiver_index: u32 = 54321; - // Test salt - let salt = [46u8; 32]; + let sessions = SessionsMock::mock_post_handshake(receiver_index); + let local_session = sessions.initiator; + let remote_session = sessions.responder; // Create a session via manager - let _ = local_manager - .create_session_state_machine( - receiver_index, - true, - init.clone(), - resp.as_remote(), - &salt, - version::CURRENT, - ) - .unwrap(); + let _ = local_manager.create_session_state_machine(local_session); + let _ = remote_manager.create_session_state_machine(remote_session); - let _ = remote_manager - .create_session_state_machine( - receiver_index, - false, - resp, - init.as_remote(), - &salt, - version::CURRENT, - ) - .unwrap(); // === Packet 1 (Counter 0 - Should succeed) === let packet1 = LpPacket { header: LpHeader { diff --git a/common/nym-lp/src/message.rs b/common/nym-lp/src/message.rs index 0796d0ffcc..fbd692175b 100644 --- a/common/nym-lp/src/message.rs +++ b/common/nym-lp/src/message.rs @@ -1,8 +1,9 @@ // Copyright 2025 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::packet::LpHeader; use crate::peer::LpRemotePeer; -use crate::{BOOTSTRAP_RECEIVER_IDX, LpError}; +use crate::{BOOTSTRAP_RECEIVER_IDX, LpError, LpPacket}; use bytes::{BufMut, BytesMut}; use num_enum::{IntoPrimitive, TryFromPrimitive}; use nym_crypto::asymmetric::{ed25519, x25519}; @@ -12,7 +13,7 @@ use std::fmt::{self, Display}; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; /// Data structure for the ClientHello message -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)] pub struct ClientHelloData { /// Client-proposed receiver index for session identification (4 bytes) /// Auto-generated randomly by the client @@ -29,6 +30,17 @@ impl ClientHelloData { // 4 bytes for receiver index + 32 bytes for client lp key, 32 bytes for client ed25519 key + 32 bytes for salt pub const LEN: usize = 100; + pub fn into_lp_packet(self, protocol_version: u8) -> LpPacket { + LpPacket::new( + LpHeader::new( + BOOTSTRAP_RECEIVER_IDX, // session_id not yet established + 0, // counter starts at 0 + protocol_version, + ), + LpMessage::ClientHello(self), + ) + } + fn len(&self) -> usize { Self::LEN } @@ -142,6 +154,8 @@ pub enum MessageType { SubsessionReady = 0x000C, /// Subsession abort - race winner tells loser to become responder SubsessionAbort = 0x000D, + /// General error + Error = 0x00FF, } impl MessageType { @@ -158,6 +172,9 @@ impl MessageType { pub struct HandshakeData(pub Vec); impl HandshakeData { + pub(crate) fn new(bytes: Vec) -> Self { + Self(bytes) + } fn len(&self) -> usize { self.0.len() } @@ -175,6 +192,11 @@ impl HandshakeData { pub struct EncryptedDataPayload(pub Vec); impl EncryptedDataPayload { + #[allow(dead_code)] + pub(crate) fn new(bytes: Vec) -> Self { + Self(bytes) + } + fn len(&self) -> usize { self.0.len() } @@ -193,6 +215,10 @@ impl EncryptedDataPayload { pub struct KKTRequestData(pub Vec); impl KKTRequestData { + pub(crate) fn new(bytes: Vec) -> Self { + Self(bytes) + } + fn len(&self) -> usize { self.0.len() } @@ -211,6 +237,10 @@ impl KKTRequestData { pub struct KKTResponseData(pub Vec); impl KKTResponseData { + pub(crate) fn new(bytes: Vec) -> Self { + Self(bytes) + } + fn len(&self) -> usize { self.0.len() } @@ -224,6 +254,52 @@ impl KKTResponseData { } } +/// General human-readable error message +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ErrorPacketData { + pub message: String, +} + +impl ErrorPacketData { + pub(crate) fn new(message: impl Into) -> Self { + ErrorPacketData { + message: message.into(), + } + } + + fn len(&self) -> usize { + // length-encoding + message + 4 + self.message.len() + } + + fn encode(&self, dst: &mut BytesMut) { + dst.put_u32_le(self.message.len() as u32); + dst.put_slice(self.message.as_bytes()); + } + + fn decode(bytes: &[u8]) -> Result { + if bytes.len() < 4 { + return Err(LpError::DeserializationError(format!( + "Too few bytes to deserialise ErrorPacketData. got {}", + bytes.len() + ))); + } + + let message_len = u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]) as usize; + if bytes[4..].len() != message_len { + return Err(LpError::DeserializationError(format!( + "Wrong number of bytes to deserialise ErrorPacketData. got {}. Expected {}", + bytes.len(), + 4 + message_len + ))); + } + + let message = String::from_utf8_lossy(&bytes[4..]).to_string(); + + Ok(ErrorPacketData { message }) + } +} + /// Packet forwarding request with embedded inner LP packet #[derive(Debug, Clone)] pub struct ForwardPacketData { @@ -449,6 +525,62 @@ pub enum LpMessage { SubsessionReady(SubsessionReadyData), /// Subsession abort - race winner tells loser to become responder (empty, signal only) SubsessionAbort, + /// An error has occurred + Error(ErrorPacketData), +} + +impl From for LpMessage { + fn from(value: HandshakeData) -> Self { + LpMessage::Handshake(value) + } +} + +impl From for LpMessage { + fn from(value: EncryptedDataPayload) -> Self { + LpMessage::EncryptedData(value) + } +} + +impl From for LpMessage { + fn from(value: ClientHelloData) -> Self { + LpMessage::ClientHello(value) + } +} + +impl From for LpMessage { + fn from(value: KKTRequestData) -> Self { + LpMessage::KKTRequest(value) + } +} + +impl From for LpMessage { + fn from(value: KKTResponseData) -> Self { + LpMessage::KKTResponse(value) + } +} + +impl From for LpMessage { + fn from(value: ForwardPacketData) -> Self { + LpMessage::ForwardPacket(value) + } +} + +impl From for LpMessage { + fn from(value: SubsessionKK1Data) -> Self { + LpMessage::SubsessionKK1(value) + } +} + +impl From for LpMessage { + fn from(value: SubsessionKK2Data) -> Self { + LpMessage::SubsessionKK2(value) + } +} + +impl From for LpMessage { + fn from(value: SubsessionReadyData) -> Self { + LpMessage::SubsessionReady(value) + } } impl Display for LpMessage { @@ -468,6 +600,7 @@ impl Display for LpMessage { LpMessage::SubsessionKK2(_) => write!(f, "SubsessionKK2"), LpMessage::SubsessionReady(_) => write!(f, "SubsessionReady"), LpMessage::SubsessionAbort => write!(f, "SubsessionAbort"), + LpMessage::Error(_) => write!(f, "Error"), } } } @@ -489,6 +622,7 @@ impl LpMessage { LpMessage::SubsessionKK2(_) => &[], // Structured data, serialized in encode_content LpMessage::SubsessionReady(_) => &[], // Structured data, serialized in encode_content LpMessage::SubsessionAbort => &[], + LpMessage::Error(_) => &[], // Structured data, serialized in encode_content (?) } } @@ -508,6 +642,7 @@ impl LpMessage { LpMessage::SubsessionKK2(_) => false, // Always has payload LpMessage::SubsessionReady(_) => false, // Always has receiver_index LpMessage::SubsessionAbort => true, // Empty signal + LpMessage::Error(_) => false, } } @@ -527,6 +662,7 @@ impl LpMessage { LpMessage::SubsessionKK2(payload) => payload.len(), LpMessage::SubsessionReady(payload) => payload.len(), LpMessage::SubsessionAbort => 0, + LpMessage::Error(payload) => payload.len(), } } @@ -546,6 +682,7 @@ impl LpMessage { LpMessage::SubsessionKK2(_) => MessageType::SubsessionKK2, LpMessage::SubsessionReady(_) => MessageType::SubsessionReady, LpMessage::SubsessionAbort => MessageType::SubsessionAbort, + LpMessage::Error(_) => MessageType::Error, } } @@ -565,6 +702,7 @@ impl LpMessage { LpMessage::SubsessionKK2(data) => data.encode(dst), LpMessage::SubsessionReady(data) => data.encode(dst), LpMessage::SubsessionAbort => { /* No content - signal only */ } + LpMessage::Error(data) => data.encode(dst), } } @@ -617,6 +755,7 @@ impl LpMessage { content.ensure_empty()?; Ok(LpMessage::SubsessionAbort) } + MessageType::Error => Ok(LpMessage::Error(ErrorPacketData::decode(content)?)), } } } diff --git a/common/nym-lp/src/noise_protocol.rs b/common/nym-lp/src/noise_protocol.rs index 293bd9ccd4..c56f7cd9b9 100644 --- a/common/nym-lp/src/noise_protocol.rs +++ b/common/nym-lp/src/noise_protocol.rs @@ -82,6 +82,13 @@ pub enum ReadResult { // --- Implementation --- impl NoiseProtocol { + pub fn params() -> NoiseParams { + // SAFETY: the hardcoded pattern must be valid + // and if for some reason it was not, we MUST fail non-gracefully for there is no possible recovery + #[allow(clippy::unwrap_used)] + crate::NOISE_PATTERN.parse().unwrap() + } + /// Creates a new `NoiseProtocol` instance in the Handshaking state. /// /// Takes an initialized `snow::HandshakeState` (e.g., from `snow::Builder`). @@ -91,6 +98,46 @@ impl NoiseProtocol { } } + fn prepare_handshake_state<'a>( + local_private_key: &'a [u8], + remote_public_key: &'a [u8], + psk: &'a [u8], + ) -> snow::Builder<'a> { + let psk_index = crate::NOISE_PSK_INDEX; + let noise_params = NoiseProtocol::params(); + + snow::Builder::new(noise_params) + .local_private_key(local_private_key) + .remote_public_key(remote_public_key) + .psk(psk_index, psk) + } + + /// Builds a new `NoiseProtocol` initiator instance with the provided local private key, + /// remote public key and psk + pub fn build_new_initiator( + local_private_key: &[u8], + remote_public_key: &[u8], + psk: &[u8], + ) -> Result { + let handshake_state = + Self::prepare_handshake_state(local_private_key, remote_public_key, psk) + .build_initiator()?; + Ok(Self::new(handshake_state)) + } + + /// Builds a new `NoiseProtocol` responder instance with the provided local private key, + /// remote public key and psk + pub fn build_new_responder( + local_private_key: &[u8], + remote_public_key: &[u8], + psk: &[u8], + ) -> Result { + let handshake_state = + Self::prepare_handshake_state(local_private_key, remote_public_key, psk) + .build_responder()?; + Ok(Self::new(handshake_state)) + } + /// Processes a single, complete incoming Noise message frame. /// /// Assumes the caller handles buffering and framing to provide one full message. @@ -288,43 +335,3 @@ impl NoiseProtocol { } } } - -pub fn create_noise_state( - local_private_key: &[u8], - remote_public_key: &[u8], - psk: &[u8], -) -> Result { - let pattern_name = crate::NOISE_PATTERN; - let psk_index = crate::NOISE_PSK_INDEX; - let noise_params: NoiseParams = pattern_name.parse().unwrap(); - - let builder = snow::Builder::new(noise_params.clone()); - // Using dummy remote key as it's not needed for state creation itself - // In a real scenario, the key would depend on initiator/responder role - let handshake_state = builder - .local_private_key(local_private_key) - .remote_public_key(remote_public_key) // Use own public as dummy remote - .psk(psk_index, psk) - .build_initiator()?; - Ok(NoiseProtocol::new(handshake_state)) -} - -pub fn create_noise_state_responder( - local_private_key: &[u8], - remote_public_key: &[u8], - psk: &[u8], -) -> Result { - let pattern_name = crate::NOISE_PATTERN; - let psk_index = crate::NOISE_PSK_INDEX; - let noise_params: NoiseParams = pattern_name.parse().unwrap(); - - let builder = snow::Builder::new(noise_params.clone()); - // Using dummy remote key as it's not needed for state creation itself - // In a real scenario, the key would depend on initiator/responder role - let handshake_state = builder - .local_private_key(local_private_key) - .remote_public_key(remote_public_key) // Use own public as dummy remote - .psk(psk_index, psk) - .build_responder()?; - Ok(NoiseProtocol::new(handshake_state)) -} diff --git a/common/nym-lp/src/packet.rs b/common/nym-lp/src/packet.rs index e93edfaad4..db2644b5fa 100644 --- a/common/nym-lp/src/packet.rs +++ b/common/nym-lp/src/packet.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::LpError; -use crate::message::LpMessage; +use crate::message::{LpMessage, MessageType}; use crate::replay::ReceivingKeyCounterValidator; use bytes::{BufMut, BytesMut}; use nym_lp_common::format_debug_bytes; @@ -53,6 +53,10 @@ impl LpPacket { } } + pub fn typ(&self) -> MessageType { + self.message.typ() + } + /// Compute a hash of the message payload /// /// This can be used for message integrity verification or deduplication diff --git a/common/nym-lp/src/peer.rs b/common/nym-lp/src/peer.rs index fd6e5ab7f3..085ea8be5b 100644 --- a/common/nym-lp/src/peer.rs +++ b/common/nym-lp/src/peer.rs @@ -1,9 +1,9 @@ // Copyright 2026 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::ClientHelloData; +use crate::{ClientHelloData, LpError}; use nym_crypto::asymmetric::{ed25519, x25519}; -use nym_kkt::ciphersuite::{KEM, KEMKeyDigests, SignatureScheme, SigningKeyDigests}; +use nym_kkt::ciphersuite::{Ciphersuite, KEM, KEMKeyDigests, SignatureScheme, SigningKeyDigests}; use std::collections::HashMap; use std::sync::Arc; @@ -52,6 +52,14 @@ impl LpLocalPeer { &self.x25519 } + /// Returns the reference to the KEM Public key of the peer (if available). + pub fn get_kem_key_handle(&self) -> Result<&x25519::PublicKey, LpError> { + self.kem_psq + .as_ref() + .map(|kp| kp.public_key()) + .ok_or(LpError::ResponderWithMissingKEMKey) + } + /// Convert this `LpLocalPeer` into a valid `LpRemotePeer` that can be used within tests #[doc(hidden)] pub fn as_remote(&self) -> LpRemotePeer { @@ -137,16 +145,37 @@ impl LpRemotePeer { self.expected_signing_key_digests = expected_signing_key_digests; self } + + /// Attempt to retrieve expected KEM key hash of the remote + /// for [`nym_kkt::ciphersuite::KEM`] key type and [`nym_kkt::ciphersuite::HashFunction`] + /// specified by own [`nym_kkt::ciphersuite::Ciphersuite`] + pub(crate) fn expected_kem_key_hash( + &self, + ciphersuite: Ciphersuite, + ) -> Result, LpError> { + let kem = ciphersuite.kem(); + let hash_function = ciphersuite.hash_function(); + + let digests = self + .expected_kem_key_digests + .get(&kem) + .ok_or(LpError::NoKnownKEMKeyDigests { kem, hash_function })?; + + digests + .get(&hash_function) + .ok_or(LpError::NoKnownKEMKeyDigests { kem, hash_function }) + .cloned() + } } -#[cfg(test)] +#[cfg(any(feature = "mock", test))] pub fn mock_peer() -> LpLocalPeer { // use deterministic rng let mut rng = nym_test_utils::helpers::deterministic_rng(); random_peer(&mut rng) } -#[cfg(test)] +#[cfg(any(feature = "mock", test))] pub fn random_peer(rng: &mut R) -> LpLocalPeer { let ed25519 = Arc::new(ed25519::KeyPair::new(rng)); let x25519 = Arc::new(ed25519.to_x25519()); @@ -159,7 +188,7 @@ pub fn random_peer(rng: &mut R) -> LpLocalPe } } -#[cfg(test)] +#[cfg(any(feature = "mock", test))] pub fn mock_peers() -> (LpLocalPeer, LpLocalPeer) { // use deterministic rng let mut rng = nym_test_utils::helpers::deterministic_rng(); diff --git a/common/nym-lp/src/psq/helpers.rs b/common/nym-lp/src/psq/helpers.rs new file mode 100644 index 0000000000..7c488187a6 --- /dev/null +++ b/common/nym-lp/src/psq/helpers.rs @@ -0,0 +1,52 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::codec::{OuterAeadKey, parse_lp_packet, serialize_lp_packet}; +use crate::{LpError, LpPacket}; +use bytes::BytesMut; +use nym_lp_transport::traits::LpTransport; + +#[cfg(test)] +use mock_instant::thread_local::{SystemTime, UNIX_EPOCH}; +#[cfg(not(test))] +use std::time::{SystemTime, UNIX_EPOCH}; + +pub(crate) fn current_timestamp() -> Result { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .map_err(|_| LpError::Internal("System time before UNIX epoch".into())) + .map(|d| d.as_secs()) +} + +// only used in internal code (and tests) +#[allow(async_fn_in_trait)] +pub trait LpTransportHandshakeExt: LpTransport { + // the outer key is temporary until the algorithm is changed with psqv2 + async fn receive_packet( + &mut self, + outer_key: Option<&OuterAeadKey>, + ) -> Result + where + Self: Unpin, + { + let raw = self.receive_raw_packet().await?; + parse_lp_packet(&raw, outer_key) + } + + async fn send_packet( + &mut self, + packet: LpPacket, + outer_key: Option<&OuterAeadKey>, + ) -> Result<(), LpError> + where + Self: Unpin, + { + let mut packet_buf = BytesMut::new(); + + serialize_lp_packet(&packet, &mut packet_buf, outer_key)?; + self.send_serialised_packet(&packet_buf).await?; + Ok(()) + } +} + +impl LpTransportHandshakeExt for T where T: LpTransport {} diff --git a/common/nym-lp/src/psq/initiator.rs b/common/nym-lp/src/psq/initiator.rs new file mode 100644 index 0000000000..61804124a9 --- /dev/null +++ b/common/nym-lp/src/psq/initiator.rs @@ -0,0 +1,391 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::codec::OuterAeadKey; +use crate::message::{HandshakeData, KKTRequestData, MessageType}; +use crate::noise_protocol::NoiseProtocol; +use crate::peer::LpRemotePeer; +use crate::psk::psq_initiator_create_message; +use crate::psq::helpers::{LpTransportHandshakeExt, current_timestamp}; +use crate::psq::{IntermediateHandshakeFailure, PSQHandshakeState}; +use crate::session::PqSharedSecret; +use crate::{ClientHelloData, LpError, LpMessage, LpSession}; +use nym_kkt::KKT_RESPONSE_AAD; +use nym_kkt::ciphersuite::EncapsulationKey; +use nym_kkt::context::KKTContext; +use nym_kkt::encryption::{KKTSessionSecret, decrypt_kkt_frame, encrypt_initial_kkt_frame}; +use nym_kkt::session::{anonymous_initiator_process, initiator_ingest_response}; +use nym_lp_transport::traits::LpTransport; +use rand09::rng; +use tracing::debug; + +impl<'a, S> PSQHandshakeState<'a, S> +where + S: LpTransport + Unpin, +{ + /// Generate and send client hello to the responder + pub(crate) async fn send_client_hello(&mut self) -> Result { + let protocol = self.protocol_version()?; + + // 1. Generate and send ClientHelloData with fresh salt and both public keys + let timestamp = current_timestamp()?; + + let client_hello_data = self.local_peer.build_client_hello_data(timestamp); + self.connection + .send_packet(client_hello_data.into_lp_packet(protocol), None) + .await?; + Ok(client_hello_data) + } + + /// Attempt to receive an ack to sent client hello. returns a boolean indicating + /// whether the request has been successful or whether there has been a collision in receiver + /// index requiring a retry + pub(crate) async fn receive_client_hello_ack(&mut self) -> Result { + match self.receive_non_error(None).await?.message { + LpMessage::Ack => Ok(true), + LpMessage::Collision => Ok(false), + other => { + // TODO: retry on collision + Err(LpError::unexpected_handshake_response( + other.typ(), + MessageType::Ack, + )) + } + } + } + + /// Attempt to send KKT request to begin the handshake + pub(crate) async fn send_kkt_request( + &mut self, + session_id: u32, + remote_peer: &LpRemotePeer, + ) -> Result<(KKTContext, KKTSessionSecret), LpError> { + let protocol = self.protocol_version()?; + + let (kkt_context, kkt_frame) = anonymous_initiator_process(&mut rng(), self.ciphersuite)?; + let (session_secret, encrypted_frame) = + encrypt_initial_kkt_frame(&mut rng(), &remote_peer.x25519_public, &kkt_frame)?; + let lp_message = KKTRequestData::new(encrypted_frame).into(); + let lp_packet = self.next_packet(session_id, protocol, lp_message); + self.connection.send_packet(lp_packet, None).await?; + Ok((kkt_context, session_secret)) + } + + /// Attempt to receive a KKT response to the previously sent request and extract (and validate) + /// the received encapsulation key + pub(crate) async fn receive_kkt_response( + &mut self, + (kkt_context, session_secret): (KKTContext, KKTSessionSecret), + remote_peer: &LpRemotePeer, + ) -> Result, LpError> { + let kkt_response = match self.receive_non_error(None).await?.message { + LpMessage::KKTResponse(response) => response, + other => { + return Err(LpError::unexpected_handshake_response( + other.typ(), + MessageType::KKTResponse, + )); + } + }; + debug!("received KKT response"); + let expected_kem_key_digest = remote_peer.expected_kem_key_hash(self.ciphersuite)?; + + let (response_frame, remote_context) = + decrypt_kkt_frame(&session_secret, &kkt_response.0, KKT_RESPONSE_AAD)?; + let encapsulation_key = initiator_ingest_response( + &kkt_context, + &response_frame, + &remote_context, + &remote_peer.ed25519_public, + &expected_kem_key_digest, + )?; + Ok(encapsulation_key) + } + + /// Attempt to prepare and send initial PSQ msg1 + pub(crate) async fn send_psq_initiator_message( + &mut self, + remote_peer: &LpRemotePeer, + encapsulation_key: &EncapsulationKey<'_>, + salt: &[u8; 32], + session_id_bytes: &[u8; 4], + ) -> Result<(OuterAeadKey, NoiseProtocol, PqSharedSecret), LpError> { + let protocol = self.protocol_version()?; + let session_id = u32::from_le_bytes(*session_id_bytes); + + let psq_initiator = psq_initiator_create_message( + self.local_peer.x25519.private_key(), + &remote_peer.x25519_public, + encapsulation_key, + self.local_peer.ed25519.private_key(), + self.local_peer.ed25519.public_key(), + salt, + session_id_bytes, + )?; + let psk = psq_initiator.psk; + let psq_payload = psq_initiator.payload; + + // TEMP \/ + let outer_aead_key = OuterAeadKey::from_psk(&psk); + // TEMP /\ + + // prepare noise state and msg1 + let mut noise_protocol = NoiseProtocol::build_new_initiator( + self.local_peer.x25519().private_key().as_bytes(), + remote_peer.x25519_public.as_bytes(), + &psk, + )?; + + // prepare noise msg1 + let noise_msg1 = noise_protocol + .get_bytes_to_send() + .ok_or_else(|| LpError::kkt_psq_handshake("failed to generate noise msg1"))??; + let psq_len = psq_payload.len() as u16; + let mut combined = Vec::with_capacity(2 + psq_payload.len() + noise_msg1.len()); + combined.extend_from_slice(&psq_len.to_le_bytes()); + combined.extend_from_slice(&psq_payload); + combined.extend_from_slice(&noise_msg1); + + let lp_message = HandshakeData::new(combined).into(); + let lp_packet = self.next_packet(session_id, protocol, lp_message); + + self.connection.send_packet(lp_packet, None).await?; + Ok(( + outer_aead_key, + noise_protocol, + PqSharedSecret::new(psq_initiator.pq_shared_secret), + )) + } + + /// Attempt to receive and validate received PSQ msg2 + pub(crate) async fn receive_psq_responder_message( + &mut self, + outer_aead_key: &OuterAeadKey, + noise_protocol: &mut NoiseProtocol, + ) -> Result<(), LpError> { + let psq_msg2 = match self + .connection + .receive_packet(Some(outer_aead_key)) + .await? + .message + { + LpMessage::Handshake(response) => response.0, + other => { + return Err(LpError::unexpected_handshake_response( + other.typ(), + MessageType::Handshake, + )); + } + }; + + // Extract PSK handle: [u16 handle_len][handle_bytes][noise_msg] + if psq_msg2.len() < 2 { + return Err(LpError::kkt_psq_handshake("too short msg2 received")); + } + let handle_len = u16::from_le_bytes([psq_msg2[0], psq_msg2[1]]) as usize; + if psq_msg2.len() < 2 + handle_len { + return Err(LpError::kkt_psq_handshake("too short msg2 received")); + } + // Extract and "store" the PSK handle + let _psq_handle_bytes = &psq_msg2[2..2 + handle_len]; + let noise_payload = &psq_msg2[2 + handle_len..]; + + // *sigh* ignore the message + let _noise_msg2 = noise_protocol.read_message(noise_payload)?; + Ok(()) + } + + /// Attempt to prepare and send final PSQ msg3 + pub(crate) async fn send_final_psq_message( + &mut self, + session_id: u32, + outer_aead_key: &OuterAeadKey, + noise_protocol: &mut NoiseProtocol, + ) -> Result<(), LpError> { + let protocol = self.protocol_version()?; + + let noise_msg3 = noise_protocol + .get_bytes_to_send() + .ok_or_else(|| LpError::kkt_psq_handshake("failed to generate noise msg3"))??; + + let lp_message = HandshakeData::new(noise_msg3).into(); + let lp_packet = self.next_packet(session_id, protocol, lp_message); + self.connection + .send_packet(lp_packet, Some(outer_aead_key)) + .await?; + + if !noise_protocol.is_handshake_finished() { + return Err(LpError::kkt_psq_handshake( + "noise handshake not finished after msg3", + )); + } + + Ok(()) + } + + /// Receive final ACK that indicates finalisation of the handshake + pub(crate) async fn receive_final_ack( + &mut self, + outer_aead_key: &OuterAeadKey, + ) -> Result<(), LpError> { + match self + .connection + .receive_packet(Some(outer_aead_key)) + .await? + .message + { + LpMessage::Ack => Ok(()), + other => Err(LpError::unexpected_handshake_response( + other.typ(), + MessageType::Ack, + )), + } + } + + async fn complete_as_initiator_inner( + &mut self, + ) -> Result + where + S: LpTransport + Unpin, + { + // 0. retrieve the expected kem key hash. if we don't know it, + // there's no point in even trying to start the handshake + let Some(remote_peer) = self.remote_peer.take() else { + return Err(IntermediateHandshakeFailure::plain( + LpError::kkt_psq_handshake("initiator can't proceed without remote information"), + )); + }; + + // 1. Generate and send ClientHelloData with fresh salt and both public keys + // and keep retrying until we manage to establish a receiver index without collisions + let mut attempt = 0; + let client_hello_data = loop { + attempt += 1; + + debug!("sending client hello"); + let client_hello = self + .send_client_hello() + .await + .map_err(IntermediateHandshakeFailure::plain)?; + if self + .receive_client_hello_ack() + .await + .map_err(IntermediateHandshakeFailure::plain)? + { + debug!("received client hello ACK"); + break client_hello; + } + debug!("received client hello collision"); + + // TODO: make it configurable + if attempt > 3 { + return Err(IntermediateHandshakeFailure::plain( + LpError::kkt_psq_handshake( + "failed to establish receiver index without collision", + ), + )); + } + }; + let session_id = client_hello_data.receiver_index; + let session_id_bytes = session_id.to_le_bytes(); + let salt = client_hello_data.salt; + + // 3. prepare and send KKT request + debug!("sending KKT request"); + let kkt_data = self + .send_kkt_request(session_id, &remote_peer) + .await + .map_err(|source| IntermediateHandshakeFailure { + session_id: Some(session_id), + protocol_version: self.protocol_version, + outer_aead_key: None, + source, + })?; + + // 4. receive and process KKT response + let encapsulation_key = self + .receive_kkt_response(kkt_data, &remote_peer) + .await + .map_err(|source| IntermediateHandshakeFailure { + session_id: Some(session_id), + protocol_version: self.protocol_version, + outer_aead_key: None, + source, + })?; + debug!("received KKT response"); + + // 5. prepare and send PSQ msg1 + debug!("sending PSQ msg1"); + let (outer_aead_key, mut noise_protocol, pq_shared_secret) = self + .send_psq_initiator_message(&remote_peer, &encapsulation_key, &salt, &session_id_bytes) + .await + .map_err(|source| IntermediateHandshakeFailure { + session_id: Some(session_id), + protocol_version: self.protocol_version, + outer_aead_key: None, + source, + })?; + + // 6. receive and process PSQ msg2 + debug!("received PSQ msg2"); + if let Err(source) = self + .receive_psq_responder_message(&outer_aead_key, &mut noise_protocol) + .await + { + return Err(IntermediateHandshakeFailure { + session_id: Some(session_id), + protocol_version: self.protocol_version, + outer_aead_key: Some(outer_aead_key), + source, + }); + } + + // 7. prepare and send PSQ msg3 + debug!("sending PSQ msg3"); + if let Err(source) = self + .send_final_psq_message(session_id, &outer_aead_key, &mut noise_protocol) + .await + { + return Err(IntermediateHandshakeFailure { + session_id: Some(session_id), + protocol_version: self.protocol_version, + outer_aead_key: Some(outer_aead_key), + source, + }); + } + + // 8. receive final ACK and finalise + debug!("received final ACK"); + if let Err(source) = self.receive_final_ack(&outer_aead_key).await { + return Err(IntermediateHandshakeFailure { + session_id: Some(session_id), + protocol_version: self.protocol_version, + outer_aead_key: Some(outer_aead_key), + source, + }); + } + + #[allow(clippy::expect_used)] + Ok(LpSession::new( + session_id, + self.protocol_version() + .expect("protocol version is known at this point"), + outer_aead_key, + self.local_peer.clone(), + remote_peer, + pq_shared_secret, + noise_protocol, + )) + } + + // TODO: missing: receive counter check + pub async fn complete_as_initiator(mut self) -> Result + where + S: LpTransport + Unpin, + { + match self.complete_as_initiator_inner().await { + Ok(res) => Ok(res), + Err(err) => Err(self.try_send_error_packet(err).await), + } + } +} diff --git a/common/nym-lp/src/psq/mod.rs b/common/nym-lp/src/psq/mod.rs new file mode 100644 index 0000000000..06be6f26ec --- /dev/null +++ b/common/nym-lp/src/psq/mod.rs @@ -0,0 +1,340 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::codec::OuterAeadKey; +use crate::message::ErrorPacketData; +use crate::packet::LpHeader; +use crate::peer::{LpLocalPeer, LpRemotePeer}; +use crate::psq::helpers::LpTransportHandshakeExt; +use crate::{LpError, LpMessage, LpPacket}; +use nym_kkt::ciphersuite::Ciphersuite; +use nym_lp_transport::traits::LpTransport; +use tracing::debug; + +mod helpers; +mod initiator; +mod responder; + +pub(crate) struct IntermediateHandshakeFailure { + /// Session id established during exchange if we managed to derive it + session_id: Option, + + /// Protocol version established during the exchange + protocol_version: Option, + + /// Outer aead key established during exchange if we managed to derive it + outer_aead_key: Option, + + /// The error source + source: LpError, +} + +impl IntermediateHandshakeFailure { + fn plain(source: LpError) -> IntermediateHandshakeFailure { + IntermediateHandshakeFailure { + session_id: None, + protocol_version: None, + outer_aead_key: None, + source, + } + } +} + +pub struct PSQHandshakeState<'a, S> { + /// The underlying connection established for the handshake + connection: &'a mut S, + + /// Protocol version used for the exchange. + /// either known implicitly through the directory (initiator) + /// or established through client hello (responder) + protocol_version: Option, + + /// Ciphersuite selected for the KKT/PSQ exchange + ciphersuite: Ciphersuite, + + /// Representation of a local Lewes Protocol peer + /// encapsulating all the known information and keys. + local_peer: LpLocalPeer, + + /// Representation of a remote Lewes Protocol peer + /// encapsulating all the known information and keys. + remote_peer: Option, + + /// Counter for outgoing packets + sending_counter: u64, +} + +impl<'a, S> PSQHandshakeState<'a, S> +where + S: LpTransport + Unpin, +{ + pub fn new(connection: &'a mut S, ciphersuite: Ciphersuite, local_peer: LpLocalPeer) -> Self { + PSQHandshakeState { + connection, + protocol_version: None, + ciphersuite, + local_peer, + remote_peer: None, + sending_counter: 0, + } + } + + #[must_use] + pub fn with_protocol_version(mut self, protocol_version: u8) -> Self { + self.protocol_version = Some(protocol_version); + self + } + + #[must_use] + pub fn with_remote_peer(mut self, remote_peer: LpRemotePeer) -> Self { + self.remote_peer = Some(remote_peer); + self + } + + fn protocol_version(&self) -> Result { + self.protocol_version + .ok_or_else(|| LpError::kkt_psq_handshake("unknown protocol version")) + } + + /// Generates the next counter value for outgoing packets. + pub fn next_counter(&mut self) -> u64 { + let counter = self.sending_counter; + self.sending_counter += 1; + counter + } + + pub fn next_packet( + &mut self, + session_id: u32, + protocol_version: u8, + message: LpMessage, + ) -> LpPacket { + let counter = self.next_counter(); + let header = LpHeader::new(session_id, counter, protocol_version); + LpPacket::new(header, message) + } + + pub(crate) async fn try_send_error_packet( + &mut self, + err: IntermediateHandshakeFailure, + ) -> LpError { + // if session_id is not known, we can't send the packet back (with the current design) + let (Some(session_id), Some(protocol)) = (err.session_id, err.protocol_version) else { + return err.source; + }; + if let Err(err) = self + .send_error_packet( + session_id, + protocol, + err.source.to_string(), + err.outer_aead_key.as_ref(), + ) + .await + { + debug!("failed to send back error response: {err}") + } + err.source + } + + /// Attempt to send an error packet + pub(crate) async fn send_error_packet( + &mut self, + session_id: u32, + protocol_version: u8, + msg: impl Into, + outer_aead_key: Option<&OuterAeadKey>, + ) -> Result<(), LpError> { + let packet = self.next_packet( + session_id, + protocol_version, + LpMessage::Error(ErrorPacketData::new(msg)), + ); + self.connection.send_packet(packet, outer_aead_key).await?; + Ok(()) + } + + /// Attempt to receive a packet from connection, explicitly checking for an error response + /// and returning corresponding message if received + pub(crate) async fn receive_non_error( + &mut self, + outer_aead_key: Option<&OuterAeadKey>, + ) -> Result { + let packet = self.connection.receive_packet(outer_aead_key).await?; + + match &packet.message { + LpMessage::Error(error_packet) => Err(LpError::kkt_psq_handshake(format!( + "remote error: {}", + error_packet.message + ))), + _ => Ok(packet), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::peer::mock_peers; + use crate::psq::helpers::LpTransportHandshakeExt; + use crate::psq::responder::DEFAULT_TIMESTAMP_TOLERANCE; + use mock_instant::thread_local::MockClock; + use nym_kkt::ciphersuite::{HashFunction, HashLength, KEM, SignatureScheme}; + use nym_test_utils::mocks::async_read_write::MockIOStream; + use nym_test_utils::traits::{Leak, TimeboxedSpawnable}; + use std::time::Duration; + use tokio::join; + + #[allow(dead_code)] + async fn extract_error(conn: &mut MockIOStream) -> String { + let packet = conn.receive_packet(None).await.unwrap(); + match packet.message { + LpMessage::Error(error) => error.message, + _ => panic!("non error packet"), + } + } + + #[tokio::test] + async fn e2e_psq_handshake() -> anyhow::Result<()> { + let conn_init = MockIOStream::default(); + let conn_resp = conn_init.try_get_remote_handle(); + + // leak the connections (JUST FOR THE PURPOSE OF THIS TEST!) + // so they'd get 'static lifetime + let conn_init = conn_init.leak(); + let conn_resp = conn_resp.leak(); + + let ciphersuite = Ciphersuite::new( + KEM::X25519, + HashFunction::Blake3, + SignatureScheme::Ed25519, + HashLength::Default, + ); + + let (init, resp) = mock_peers(); + let resp_remote = resp.as_remote(); + + let handshake_init = PSQHandshakeState::new(conn_init, ciphersuite, init) + .with_protocol_version(1) + .with_remote_peer(resp_remote); + let handshake_resp = PSQHandshakeState::new(conn_resp, ciphersuite, resp); + + let resp_fut = handshake_resp.complete_as_responder().spawn_timeboxed(); + let init_fut = handshake_init.complete_as_initiator().spawn_timeboxed(); + + let (session_init, session_resp) = join!(init_fut, resp_fut); + + let session_init = session_init???; + let session_resp = session_resp???; + + assert_eq!(session_init.id(), session_resp.id()); + assert_eq!( + session_init.outer_aead_key().as_bytes(), + session_resp.outer_aead_key().as_bytes() + ); + assert_eq!( + session_init.pq_shared_secret().as_bytes(), + session_resp.pq_shared_secret().as_bytes() + ); + + Ok(()) + } + + #[tokio::test] + async fn preparing_client_hello_initiator() -> anyhow::Result<()> { + let mut conn_init = MockIOStream::default(); + let mut conn_resp = conn_init.try_get_remote_handle(); + + let ciphersuite = Ciphersuite::new( + KEM::X25519, + HashFunction::Blake3, + SignatureScheme::Ed25519, + HashLength::Default, + ); + let (init, resp) = mock_peers(); + let resp_remote = resp.as_remote(); + + // as initiator + let mut handshake_init = PSQHandshakeState::new(&mut conn_init, ciphersuite, init) + .with_protocol_version(1) + .with_remote_peer(resp_remote); + + // you can generate and send (valid) client hello as initiator + let client_hello = handshake_init.send_client_hello().await?; + let LpMessage::ClientHello(received_client_hello) = + conn_resp.receive_packet(None).await?.message + else { + panic!("wrong message type"); + }; + assert_eq!(client_hello, received_client_hello); + Ok(()) + } + + // essentially make sure you can't accidentally trigger the handshake as the responder + #[tokio::test] + async fn preparing_client_hello_responder() -> anyhow::Result<()> { + let conn_init = MockIOStream::default(); + let mut conn_resp = conn_init.try_get_remote_handle(); + + let ciphersuite = Ciphersuite::new( + KEM::X25519, + HashFunction::Blake3, + SignatureScheme::Ed25519, + HashLength::Default, + ); + let (_, resp) = mock_peers(); + + // as initiator + let mut handshake_resp = PSQHandshakeState::new(&mut conn_resp, ciphersuite, resp); + + // you can generate and send (valid) client hello as initiator + let sending_res = handshake_resp.send_client_hello().await; + assert!(sending_res.is_err()); + Ok(()) + } + + #[tokio::test] + async fn test_receive_client_hello_timestamp_too_skewed() -> anyhow::Result<()> { + let current_time = Duration::from_secs(10000); + MockClock::set_system_time(current_time); + + let too_old = current_time - DEFAULT_TIMESTAMP_TOLERANCE - Duration::from_secs(1); + let too_recent = current_time + DEFAULT_TIMESTAMP_TOLERANCE + Duration::from_secs(1); + + let ciphersuite = Ciphersuite::new( + KEM::X25519, + HashFunction::Blake3, + SignatureScheme::Ed25519, + HashLength::Default, + ); + + // TOO OLD + let mut conn_init = MockIOStream::default(); + let mut conn_resp = conn_init.try_get_remote_handle(); + let (init, resp) = mock_peers(); + + let mut handshake_resp = PSQHandshakeState::new(&mut conn_resp, ciphersuite, resp); + let client_hello_too_old = init.build_client_hello_data(too_old.as_secs()); + + conn_init + .send_packet(client_hello_too_old.into_lp_packet(1), None) + .await?; + let err = handshake_resp.receive_client_hello().await.unwrap_err(); + assert!(err.to_string().contains("too old")); + + // TOO RECENT + let mut conn_init = MockIOStream::default(); + let mut conn_resp = conn_init.try_get_remote_handle(); + let (init, resp) = mock_peers(); + + let mut handshake_resp = PSQHandshakeState::new(&mut conn_resp, ciphersuite, resp); + let client_hello_too_recent = init.build_client_hello_data(too_recent.as_secs()); + + conn_init + .send_packet(client_hello_too_recent.into_lp_packet(1), None) + .await?; + let err = handshake_resp.receive_client_hello().await.unwrap_err(); + + assert!(err.to_string().contains("too future")); + Ok(()) + } +} diff --git a/common/nym-lp/src/psq/responder.rs b/common/nym-lp/src/psq/responder.rs new file mode 100644 index 0000000000..8882e1269f --- /dev/null +++ b/common/nym-lp/src/psq/responder.rs @@ -0,0 +1,461 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::codec::OuterAeadKey; +use crate::message::{HandshakeData, KKTResponseData, MessageType}; +use crate::noise_protocol::NoiseProtocol; +use crate::peer::LpRemotePeer; +use crate::psk::psq_responder_process_message; +use crate::psq::helpers::{LpTransportHandshakeExt, current_timestamp}; +use crate::psq::{IntermediateHandshakeFailure, PSQHandshakeState}; +use crate::session::PqSharedSecret; +use crate::{ClientHelloData, LpError, LpMessage, LpSession}; +use nym_kkt::KKT_RESPONSE_AAD; +use nym_kkt::ciphersuite::{DecapsulationKey, EncapsulationKey}; +use nym_kkt::context::KKTContext; +use nym_kkt::encryption::{KKTSessionSecret, decrypt_initial_kkt_frame, encrypt_kkt_frame}; +use nym_kkt::frame::KKTSessionId; +use nym_kkt::session::{responder_ingest_message, responder_process}; +use nym_lp_transport::traits::LpTransport; +use rand09::rng; +use std::time::Duration; +use tracing::debug; + +pub const DEFAULT_TIMESTAMP_TOLERANCE: Duration = Duration::from_secs(30); + +// this will be removed anyway, so no point in doing anything more than a hardcoded placeholder +fn validate_client_hello_timestamp( + client_timestamp: u64, + tolerance: Duration, +) -> Result<(), LpError> { + let now = current_timestamp()?; + + let age = now.abs_diff(client_timestamp); + if age > tolerance.as_secs() { + let direction = if now >= client_timestamp { + "old" + } else { + "future" + }; + + return Err(LpError::kkt_psq_handshake(format!( + "ClientHello timestamp is too {direction} (age: {age}s, tolerance: {}s)", + tolerance.as_secs() + ))); + } + + Ok(()) +} + +impl<'a, S> PSQHandshakeState<'a, S> +where + S: LpTransport + Unpin, +{ + pub(crate) fn encapsulated_kem_keys( + &self, + ) -> Result<(DecapsulationKey<'static>, EncapsulationKey<'static>), LpError> { + let kem_keys = self + .local_peer + .kem_psq + .as_ref() + .ok_or(LpError::ResponderWithMissingKEMKey)?; + + let libcrux_private_key = libcrux_kem::PrivateKey::decode( + libcrux_kem::Algorithm::X25519, + kem_keys.private_key().as_bytes(), + ) + .map_err(|e| { + LpError::KKTError(format!( + "Failed to convert X25519 private key to libcrux PrivateKey: {e:?}", + )) + })?; + let dec_key = DecapsulationKey::X25519(libcrux_private_key); + + let libcrux_public_key = libcrux_kem::PublicKey::decode( + libcrux_kem::Algorithm::X25519, + kem_keys.public_key().as_bytes(), + ) + .map_err(|e| { + LpError::KKTError(format!( + "Failed to convert X25519 public key to libcrux PublicKey: {e:?}", + )) + })?; + let enc_key = EncapsulationKey::X25519(libcrux_public_key); + Ok((dec_key, enc_key)) + } + + /// Attempt to receive and validate ClientHello + pub(crate) async fn receive_client_hello( + &mut self, + ) -> Result<(ClientHelloData, LpRemotePeer), LpError> { + let client_hello_packet = self.receive_non_error(None).await?; + let client_hello = match client_hello_packet.message { + LpMessage::ClientHello(client_hello) => client_hello, + other => { + return Err(LpError::unexpected_handshake_response( + other.typ(), + MessageType::ClientHello, + )); + } + }; + + validate_client_hello_timestamp( + client_hello.extract_timestamp(), + DEFAULT_TIMESTAMP_TOLERANCE, + )?; + + // TODO: somehow check for collision + + // set version and remote peer information + self.protocol_version = Some(client_hello_packet.header.protocol_version); + let remote_peer = LpRemotePeer::new( + client_hello.client_ed25519_public_key, + client_hello.client_lp_public_key, + ); + + Ok((client_hello, remote_peer)) + } + + /// Send client hello ACK + pub(crate) async fn send_client_hello_ack(&mut self, session_id: u32) -> Result<(), LpError> { + let protocol = self.protocol_version()?; + + let ack = self.next_packet(session_id, protocol, LpMessage::Ack); + self.connection.send_packet(ack, None).await?; + Ok(()) + } + + /// Attempt to receive and process a KKT request + pub(crate) async fn receive_kkt_request( + &mut self, + ) -> Result<(KKTContext, KKTSessionSecret, KKTSessionId), LpError> { + let kkt_request = match self.receive_non_error(None).await?.message { + LpMessage::KKTRequest(request) => request.0, + other => { + return Err(LpError::unexpected_handshake_response( + other.typ(), + MessageType::KKTRequest, + )); + } + }; + + let (session_secret, request_frame, remote_context) = + decrypt_initial_kkt_frame(self.local_peer.x25519.private_key(), &kkt_request)?; + let (context, _) = responder_ingest_message(&remote_context, None, None, &request_frame)?; + + Ok((context, session_secret, request_frame.session_id())) + } + + /// Attempt to send KKT response to the previously received request + pub(crate) async fn send_kkt_response( + &mut self, + session_id: u32, + (kkt_context, session_secret, kkt_session_id): (KKTContext, KKTSessionSecret, KKTSessionId), + encapsulation_key: &EncapsulationKey<'_>, + ) -> Result<(), LpError> { + let protocol = self.protocol_version()?; + + let response_frame = responder_process( + &kkt_context, + kkt_session_id, + self.local_peer.ed25519().private_key(), + encapsulation_key, + )?; + let encrypted_frame = encrypt_kkt_frame( + &mut rng(), + &session_secret, + &response_frame, + KKT_RESPONSE_AAD, + )?; + let lp_message = KKTResponseData::new(encrypted_frame).into(); + let lp_packet = self.next_packet(session_id, protocol, lp_message); + + self.connection.send_packet(lp_packet, None).await?; + Ok(()) + } + + /// Attempt to receive and process a PSQ msg1 request + pub(crate) async fn receive_psq_initiator_message( + &mut self, + remote_peer: &LpRemotePeer, + local_kem_keypair: (&DecapsulationKey<'_>, &EncapsulationKey<'_>), + salt: &[u8; 32], + session_id_bytes: &[u8; 4], + ) -> Result<(OuterAeadKey, NoiseProtocol, PqSharedSecret, Vec), LpError> { + let psq_msg1 = match self.receive_non_error(None).await?.message { + LpMessage::Handshake(response) => response.0, + other => { + return Err(LpError::unexpected_handshake_response( + other.typ(), + MessageType::Handshake, + )); + } + }; + + // Extract PSQ payload: [u16 psq_len][psq_payload][noise_msg] + if psq_msg1.len() < 2 { + return Err(LpError::kkt_psq_handshake("too short msg1 received")); + } + let handle_len = u16::from_le_bytes([psq_msg1[0], psq_msg1[1]]) as usize; + if psq_msg1.len() < 2 + handle_len { + return Err(LpError::kkt_psq_handshake("too short msg1 received")); + } + let psq_payload = &psq_msg1[2..2 + handle_len]; + let noise_payload = &psq_msg1[2 + handle_len..]; + + // Decapsulate PSK from PSQ payload using X25519 as DHKEM + let psq_responder = psq_responder_process_message( + self.local_peer.x25519.private_key(), + &remote_peer.x25519_public, + local_kem_keypair, + &remote_peer.ed25519_public, + psq_payload, + salt, + session_id_bytes, + )?; + + let psk = psq_responder.psk; + let psk_handle = psq_responder.psk_handle; + + // TEMP \/ + let outer_aead_key = OuterAeadKey::from_psk(&psk); + // TEMP /\ + + let mut noise_protocol = NoiseProtocol::build_new_responder( + self.local_peer.x25519().private_key().as_bytes(), + remote_peer.x25519_public.as_bytes(), + &psk, + )?; + noise_protocol.read_message(noise_payload)?; + + Ok(( + outer_aead_key, + noise_protocol, + PqSharedSecret::new(psq_responder.pq_shared_secret), + psk_handle, + )) + } + + /// Attempt to prepare and generate a responder PSQ msg2 + pub(crate) async fn send_psq_responder_message( + &mut self, + session_id: u32, + psk_handle: &[u8], + outer_aead_key: &OuterAeadKey, + noise_protocol: &mut NoiseProtocol, + ) -> Result<(), LpError> { + let protocol = self.protocol_version()?; + + let msg2 = noise_protocol + .get_bytes_to_send() + .ok_or_else(|| LpError::kkt_psq_handshake("failed to generate noise msg2"))??; + // Embed PSK handle in message: [u16 handle_len][handle_bytes][noise_msg] + let handle_len = psk_handle.len() as u16; + let mut combined = Vec::with_capacity(2 + psk_handle.len() + msg2.len()); + combined.extend_from_slice(&handle_len.to_le_bytes()); + combined.extend_from_slice(psk_handle); + combined.extend_from_slice(&msg2); + + let lp_message = HandshakeData::new(combined).into(); + let lp_packet = self.next_packet(session_id, protocol, lp_message); + self.connection + .send_packet(lp_packet, Some(outer_aead_key)) + .await?; + Ok(()) + } + + /// Attempt to receive and process final PSQ msg3 + pub(crate) async fn receive_final_psq_message( + &mut self, + outer_aead_key: &OuterAeadKey, + noise_protocol: &mut NoiseProtocol, + ) -> Result<(), LpError> { + let psq_msg3 = match self + .connection + .receive_packet(Some(outer_aead_key)) + .await? + .message + { + LpMessage::Handshake(response) => response.0, + other => { + return Err(LpError::unexpected_handshake_response( + other.typ(), + MessageType::Handshake, + )); + } + }; + + noise_protocol.read_message(&psq_msg3)?; + if !noise_protocol.is_handshake_finished() { + return Err(LpError::kkt_psq_handshake( + "noise handshake not finished after msg3", + )); + } + Ok(()) + } + + /// Send final ACK to indicate finalisation of the handshake + pub(crate) async fn send_final_ack( + &mut self, + session_id: u32, + outer_aead_key: &OuterAeadKey, + ) -> Result<(), LpError> { + let protocol = self.protocol_version()?; + + let ack = self.next_packet(session_id, protocol, LpMessage::Ack); + self.connection + .send_packet(ack, Some(outer_aead_key)) + .await?; + Ok(()) + } + + async fn complete_as_responder_inner( + &mut self, + ) -> Result + where + S: LpTransport + Unpin, + { + // 1. receive and validate ClientHello + let (client_hello_data, remote_peer) = + self.receive_client_hello() + .await + .map_err(|source| IntermediateHandshakeFailure { + session_id: None, + protocol_version: self.protocol_version, + outer_aead_key: None, + source, + })?; + debug!("received client hello"); + + let session_id = client_hello_data.receiver_index; + let session_id_bytes = session_id.to_le_bytes(); + let salt = client_hello_data.salt; + + // 2. send ack + debug!("sending client hello ACK"); + self.send_client_hello_ack(session_id) + .await + .map_err(|source| IntermediateHandshakeFailure { + session_id: Some(session_id), + protocol_version: self.protocol_version, + outer_aead_key: None, + source, + })?; + + // 3. receive and process KKT request + let kkt_data = + self.receive_kkt_request() + .await + .map_err(|source| IntermediateHandshakeFailure { + session_id: Some(session_id), + protocol_version: self.protocol_version, + outer_aead_key: None, + source, + })?; + debug!("received KKT request"); + + // TEMP: 'derive' KEM keys + let (dec_key, enc_key) = + self.encapsulated_kem_keys() + .map_err(|source| IntermediateHandshakeFailure { + session_id: Some(session_id), + protocol_version: self.protocol_version, + outer_aead_key: None, + source, + })?; + + // 4. prepare and send KKT response + debug!("sending KKT response"); + self.send_kkt_response(session_id, kkt_data, &enc_key) + .await + .map_err(|source| IntermediateHandshakeFailure { + session_id: Some(session_id), + protocol_version: self.protocol_version, + outer_aead_key: None, + source, + })?; + + // 5. receive and process PSQ msg1 + debug!("received PSQ msg1"); + let (outer_aead_key, mut noise_protocol, pq_shared_secret, psk_handle) = self + .receive_psq_initiator_message( + &remote_peer, + (&dec_key, &enc_key), + &salt, + &session_id_bytes, + ) + .await + .map_err(|source| IntermediateHandshakeFailure { + session_id: Some(session_id), + protocol_version: self.protocol_version, + outer_aead_key: None, + source, + })?; + + // 6. prepare and send PSQ msg2 + debug!("sending PSQ msg2"); + if let Err(source) = self + .send_psq_responder_message( + session_id, + &psk_handle, + &outer_aead_key, + &mut noise_protocol, + ) + .await + { + return Err(IntermediateHandshakeFailure { + session_id: Some(session_id), + protocol_version: self.protocol_version, + outer_aead_key: Some(outer_aead_key), + source, + }); + } + + // 7. receive and process PSQ msg3 + debug!("received PSQ msg3"); + if let Err(source) = self + .receive_final_psq_message(&outer_aead_key, &mut noise_protocol) + .await + { + return Err(IntermediateHandshakeFailure { + session_id: Some(session_id), + protocol_version: self.protocol_version, + outer_aead_key: Some(outer_aead_key), + source, + }); + } + + // 8. [optionally] send ACK to finalise + debug!("sending final ACK"); + if let Err(source) = self.send_final_ack(session_id, &outer_aead_key).await { + return Err(IntermediateHandshakeFailure { + session_id: Some(session_id), + protocol_version: self.protocol_version, + outer_aead_key: Some(outer_aead_key), + source, + }); + } + + #[allow(clippy::expect_used)] + Ok(LpSession::new( + session_id, + self.protocol_version() + .expect("protocol version is known at this point"), + outer_aead_key, + self.local_peer.clone(), + remote_peer, + pq_shared_secret, + noise_protocol, + )) + } + + pub async fn complete_as_responder(mut self) -> Result + where + S: LpTransport + Unpin, + { + match self.complete_as_responder_inner().await { + Ok(res) => Ok(res), + Err(err) => Err(self.try_send_error_packet(err).await), + } + } +} diff --git a/common/nym-lp/src/session.rs b/common/nym-lp/src/session.rs index 0b8cee57a3..52a336cfca 100644 --- a/common/nym-lp/src/session.rs +++ b/common/nym-lp/src/session.rs @@ -7,33 +7,20 @@ //! and Noise protocol state handling. use crate::codec::OuterAeadKey; -use crate::message::{EncryptedDataPayload, HandshakeData}; +use crate::message::EncryptedDataPayload; // noiserm use crate::noise_protocol::{NoiseError, NoiseProtocol, ReadResult}; use crate::packet::LpHeader; use crate::peer::{LpLocalPeer, LpRemotePeer}; -use crate::psk::{ - derive_subsession_psk, psq_initiator_create_message, psq_responder_process_message, -}; +use crate::psk::derive_subsession_psk; +use crate::psq::PSQHandshakeState; use crate::replay::ReceivingKeyCounterValidator; use crate::{LpError, LpMessage, LpPacket}; use nym_crypto::asymmetric::{ed25519, x25519}; -use nym_kkt::KKT_RESPONSE_AAD; -use nym_kkt::ciphersuite::{DecapsulationKey, EncapsulationKey}; -use nym_kkt::context::KKTContext; -use nym_kkt::encryption::{ - KKTSessionSecret, decrypt_initial_kkt_frame, decrypt_kkt_frame, encrypt_initial_kkt_frame, - encrypt_kkt_frame, -}; -use nym_kkt::session::{ - anonymous_initiator_process, initiator_ingest_response, responder_ingest_message, - responder_process, -}; +use nym_kkt::ciphersuite::{Ciphersuite, HashFunction, HashLength, KEM, SignatureScheme}; +use nym_lp_transport::traits::LpTransport; use parking_lot::Mutex; -use rand::RngCore; use snow::Builder; -use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; -use std::time::{SystemTime, UNIX_EPOCH}; use zeroize::{Zeroize, ZeroizeOnDrop}; /// PQ shared secret wrapper with automatic memory zeroization. @@ -59,140 +46,22 @@ impl std::fmt::Debug for PqSharedSecret { } } -/// KKT (KEM Key Transfer) exchange state. -/// -/// Tracks the KKT protocol for obtaining the responder's KEM public key -/// before PSQ can begin. This allows post-quantum KEM algorithms to be -/// used even when keys are not pre-published. -/// -/// # State Transitions -/// -/// **Initiator path:** -/// ```text -/// NotStarted → InitiatorWaiting → Completed -/// ``` -/// -/// **Responder path:** -/// ```text -/// NotStarted → ResponderProcessed -/// ``` -pub enum KKTState { - /// KKT exchange not started. - NotStarted, - - /// Initiator sent KKT request and is waiting for responder's KEM key. - InitiatorWaiting { - /// KKT context for verifying the response - context: nym_kkt::context::KKTContext, - session_secret: KKTSessionSecret, - }, - - /// KKT exchange completed (initiator received and validated KEM key). - Completed { - /// Responder's KEM public key for PSQ encapsulation - kem_pk: Box>, - }, - - /// Responder processed a KKT request and sent response. - /// Responder uses their own KEM keypair, not the one from KKT. - ResponderProcessed, -} - -impl std::fmt::Debug for KKTState { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::NotStarted => write!(f, "KKTState::NotStarted"), - Self::InitiatorWaiting { context, .. } => f - .debug_struct("KKTState::InitiatorWaiting") - .field("context", context) - .finish(), - Self::Completed { .. } => write!(f, "KKTState::Completed {{ kem_pk: }}"), - Self::ResponderProcessed => write!(f, "KKTState::ResponderProcessed"), - } - } -} - -/// PSQ (Post-Quantum Secure PSK) handshake state. -/// -/// Tracks the PSQ protocol state machine through the session lifecycle. -/// -/// # State Transitions -/// -/// **Initiator path:** -/// ```text -/// NotStarted → InitiatorWaiting → Completed -/// ``` -/// -/// **Responder path:** -/// ```text -/// NotStarted → ResponderWaiting → Completed -/// ``` -#[derive(Debug)] -pub enum PSQState { - /// PSQ handshake not yet started. - NotStarted, - - /// Initiator has sent PSQ ciphertext and is waiting for confirmation. - /// PSK is already derived, but we don't encrypt outgoing packets yet - /// because the responder may not have processed our message yet. - InitiatorWaiting { - /// The derived PSK, stored until we transition to Completed - psk: [u8; 32], - }, - - /// Responder is ready to receive and decapsulate PSQ ciphertext. - ResponderWaiting, - - /// PSQ handshake completed successfully. - /// The PSK has been derived and registered with the Noise protocol. - Completed { - /// The derived post-quantum PSK - psk: [u8; 32], - }, -} - /// A session in the Lewes Protocol, handling connection state with Noise. /// -/// Sessions manage connection state, including LP replay protection and Noise cryptography. +/// Sessions manage connection state, including LP replay protection. /// Each session has a unique receiving index and sending index for connection identification. -/// -/// ## PSK Injection Lifecycle -/// -/// 1. Session created with dummy PSK `[0u8; 32]` in Noise HandshakeState -/// 2. During handshake, PSQ runs and derives real post-quantum PSK -/// 3. Real PSK injected via `set_psk()` - `psk_injected` flag set to `true` -/// 4. Handshake completes, transport mode available -/// 5. Transport operations (`encrypt_data`/`decrypt_data`) check `psk_injected` flag for safety #[derive(Debug)] pub struct LpSession { - id: u32, + /// Id of the established session + session_id: u32, - /// Flag indicating if this session acts as the Noise protocol initiator. - is_initiator: bool, + /// Negotiated protocol version from handshake. + /// Set during handshake completion from the ClientHello/ServerHello packet header. + /// Used for future version negotiation and compatibility checks. + version: u8, - // noiserm - /// Noise protocol state machine - noise_state: Mutex, - - /// KKT (KEM Key Transfer) exchange state - kkt_state: Mutex, - - /// PSQ (Post-Quantum Secure PSK) handshake state - psq_state: Mutex, - - /// PSK handle from responder (ctxt_B) for future re-registration - psk_handle: Mutex>>, - - /// Counter for outgoing packets - sending_counter: AtomicU64, - - /// Validator for incoming packet counters to prevent replay attacks - receiving_counter: Mutex, - - // noiserm - /// Safety flag: `true` if real PSK was injected via PSQ, `false` if still using dummy PSK. - /// This prevents transport mode operations from running with the insecure dummy `[0u8; 32]` PSK. - psk_injected: AtomicBool, + /// Outer AEAD key for packet encryption (derived from PSK after PSQ handshake). + outer_aead_key: OuterAeadKey, /// Representation of a local Lewes Protocol peer /// encapsulating all the known information and keys. @@ -202,83 +71,120 @@ pub struct LpSession { /// encapsulating all the known information and keys. remote_peer: LpRemotePeer, - /// Salt for PSK derivation - salt: [u8; 32], - - /// Outer AEAD key for packet encryption (derived from PSK after PSQ handshake). - /// None before PSK is available, Some after PSK injection. - outer_aead_key: Mutex>, - + // TODO: ALL BELOW maybe not needed after all? /// Raw PQ shared secret (K_pq) from PSQ KEM encapsulation/decapsulation. /// Stored after PSQ handshake completes for subsession PSK derivation. - /// This preserves PQ protection when creating subsessions via KKpsk0. - /// Wrapped in PqSharedSecret for automatic memory zeroization on drop. - pq_shared_secret: Mutex>, + pq_shared_secret: PqSharedSecret, + + /// Noise protocol state machine + noise_state: NoiseProtocol, + + /// Counter for outgoing packets + sending_counter: u64, + + /// Validator for incoming packet counters to prevent replay attacks + receiving_counter: ReceivingKeyCounterValidator, /// Monotonically increasing counter for subsession indices. /// Each subsession gets a unique index to ensure unique PSK derivation. /// Uses u64 to make overflow practically impossible (~585k years at 1M/sec). - subsession_counter: AtomicU64, + subsession_counter: u64, /// True if this session has been demoted to read-only mode. /// Demoted sessions can still receive/decrypt but cannot send/encrypt. - read_only: AtomicBool, + read_only: bool, /// ID of the successor session that replaced this one. /// Set when demote() is called. - successor_session_id: Mutex>, - - /// Negotiated protocol version from handshake. - /// Set during handshake completion from the ClientHello/ServerHello packet header. - /// Used for future version negotiation and compatibility checks. - negotiated_version: u8, -} - -// noiserm -/// Generates a fresh salt for PSK derivation. -/// -/// Salt format: 8 bytes timestamp (u64 LE) + 24 bytes random nonce -/// -/// This ensures each session derives a unique PSK, even with the same key pairs. -/// The timestamp provides temporal uniqueness while the random nonce prevents collisions. -/// -/// # Returns -/// A 32-byte array containing fresh salt material -pub fn generate_fresh_salt() -> [u8; 32] { - let mut salt = [0u8; 32]; - - // First 8 bytes: current timestamp as u64 little-endian - let timestamp = SystemTime::now() - .duration_since(UNIX_EPOCH) - .expect("System time before UNIX epoch") - .as_secs(); - salt[..8].copy_from_slice(×tamp.to_le_bytes()); - - // Last 24 bytes: random nonce - rand::thread_rng().fill_bytes(&mut salt[8..]); - - salt + successor_session_id: Option, } impl LpSession { + /// Creates a new session after completed KTT/PSQ exchange + /// + /// # Arguments + /// + /// * `session_id` - Session identifier + /// * `version` - Protocol version to attach in all `LpPacket`s + /// * `outer_aead_key` - Outer AEAD key for packet encryption + /// * `local_peer` - This side's LP peer's keys + /// * `remote_peer` - The remote's LP peer's keys + /// * `pq_shared_secret` - Raw PQ shared secret (K_pq) from PSQ KEM encapsulation/decapsulation. + /// * `noise_state` - Noise protocol state machine + pub fn new( + session_id: u32, + version: u8, + outer_aead_key: OuterAeadKey, + local_peer: LpLocalPeer, + remote_peer: LpRemotePeer, + pq_shared_secret: PqSharedSecret, + noise_state: NoiseProtocol, + ) -> Self { + LpSession { + session_id, + version, + outer_aead_key, + local_peer, + remote_peer, + pq_shared_secret, + noise_state, + sending_counter: 0, + receiving_counter: Default::default(), + subsession_counter: 0, + read_only: false, + successor_session_id: None, + } + } + + /// Create an instance of `Ciphersuite` using hardcoded defaults. + /// This is a temporary workaround until values can be properly inferred + /// from reported version + pub fn default_ciphersuite() -> Ciphersuite { + Ciphersuite::new( + KEM::X25519, + HashFunction::Blake3, + SignatureScheme::Ed25519, + HashLength::Default, + ) + } + + /// Helper function to create `PSQHandshakeState` for the handshake initiator + pub fn complete_as_initiator( + connection: &'_ mut S, + ciphersuite: Ciphersuite, + local_peer: LpLocalPeer, + remote_peer: LpRemotePeer, + remote_protocol_version: u8, + ) -> PSQHandshakeState<'_, S> + where + S: LpTransport + Unpin, + { + PSQHandshakeState::new(connection, ciphersuite, local_peer) + .with_protocol_version(remote_protocol_version) + .with_remote_peer(remote_peer) + } + + /// Helper function to create `PSQHandshakeState` for the handshake responder + pub fn psq_handshake_responder( + connection: &'_ mut S, + ciphersuite: Ciphersuite, + local_peer: LpLocalPeer, + ) -> PSQHandshakeState<'_, S> + where + S: LpTransport + Unpin, + { + PSQHandshakeState::new(connection, ciphersuite, local_peer) + } + pub fn id(&self) -> u32 { - self.id - } - - pub fn noise_state(&self) -> &Mutex { - &self.noise_state - } - - /// Returns true if this session was created as the initiator. - pub fn is_initiator(&self) -> bool { - self.is_initiator + self.session_id } /// Returns the negotiated protocol version from the handshake. /// /// Set during `LpSession` creation after sending / receiving `ClientHelloData` pub fn negotiated_version(&self) -> u8 { - self.negotiated_version + self.version } /// Returns the local X25519 public key. @@ -303,154 +209,22 @@ impl LpSession { } /// Returns the outer AEAD key for packet encryption/decryption. - /// - /// Returns `None` before PSK is derived (during initial handshake), - /// `Some(&OuterAeadKey)` after PSK injection via PSQ. - /// - /// Callers should use `None` for packet encryption/decryption during - /// the handshake phase, and use the returned key for transport phase. - /// - /// Note: For sending packets during handshake, use `outer_aead_key_for_sending()` - /// which checks PSQ state to avoid encrypting before the responder can decrypt. - pub fn outer_aead_key(&self) -> Option { - self.outer_aead_key.lock().clone() + pub fn outer_aead_key(&self) -> &OuterAeadKey { + &self.outer_aead_key } - /// Returns the outer AEAD key only if it's safe to use for sending. - /// - /// This method gates the key based on PSQ handshake state: - /// - Returns `None` if PSQ is NotStarted, InitiatorWaiting, or ResponderWaiting - /// - Returns `Some(key)` only if PSQ is Completed - /// - /// # Why This Matters - /// - /// The first Noise handshake message (containing PSQ payload from initiator) - /// must be sent in cleartext because the responder hasn't derived the PSK yet. - /// Only after the responder processes the PSQ and both sides have the PSK - /// can outer encryption be used for sending. - /// - /// For receiving, use `outer_aead_key()` which returns the key as soon as - /// it's derived (needed because the peer may start encrypting before we've - /// finished our send). - // This fixes a bug where the initiator encrypted the first Noise - // message with outer AEAD, but the responder couldn't decrypt because it - // hadn't processed the PSQ yet to derive the same PSK. - pub fn outer_aead_key_for_sending(&self) -> Option { - let psq_state = self.psq_state.lock(); - match &*psq_state { - PSQState::Completed { .. } => self.outer_aead_key.lock().clone(), - _ => None, - } - } - - /// Creates a new session and initializes the Noise protocol state. - /// - /// PSQ always runs during the handshake to derive the real PSK from X25519 DHKEM. - /// The Noise protocol is initialized with a dummy PSK that gets replaced during handshake. - /// - /// # Arguments - /// - /// * `id` - Session identifier - /// * `is_initiator` - True if this side initiates the Noise handshake. - /// * `local_peer` - This side's LP peer's keys - /// * `remote_peer` - The remote's LP peer's keys - /// * `salt` - Salt for PSK derivation - /// * `protocol_version` - Protocol version to attach in all `LpPacket`s - pub fn new( - id: u32, - is_initiator: bool, - local_peer: LpLocalPeer, - remote_peer: LpRemotePeer, - salt: &[u8; 32], - protocol_version: u8, - ) -> Result { - // noiserm - // if we're LP responder, we **must** set our kem key - // georgio: if the initiator is a client, this is ok. but if it's a node then this will block mutual kkt. - if !is_initiator && local_peer.kem_psq.is_none() { - return Err(LpError::ResponderWithMissingKEMKey); - } - - // XKpsk3 pattern requires remote static key known upfront (XK) - // and PSK mixed at position 3. This provides forward secrecy with PSK authentication. - let pattern_name = crate::NOISE_PATTERN; - let psk_index = crate::NOISE_PSK_INDEX; - - // noiserm - let params = pattern_name.parse()?; - let builder = Builder::new(params); - - let local_key_bytes = local_peer.x25519.private_key().as_bytes(); - // noiserm - let builder = builder.local_private_key(local_key_bytes); - - let remote_key_bytes = remote_peer.x25519_public.to_bytes(); - // noiserm - let builder = builder.remote_public_key(&remote_key_bytes); - - // noiserm - // Initialize with dummy PSK - real PSK will be injected via set_psk() during handshake - // when PSQ runs using X25519 as DHKEM - let dummy_psk = [0u8; 32]; - let builder = builder.psk(psk_index, &dummy_psk); - - // noiserm - let initial_state = if is_initiator { - builder.build_initiator().map_err(LpError::SnowKeyError)? - } else { - builder.build_responder().map_err(LpError::SnowKeyError)? - }; - - // noiserm - let noise_protocol = NoiseProtocol::new(initial_state); - - // Initialize KKT state - both roles start at NotStarted - let kkt_state = KKTState::NotStarted; - - // Initialize PSQ state based on role - // georgio: why PSQState::ResponderWaiting if responder? - // georgio: maybe because we can start straight with PSQ? - // georgio: either way, doesn't matter so much because a bad PSQ request will be rejected - let psq_state = if is_initiator { - PSQState::NotStarted - } else { - PSQState::ResponderWaiting - }; - - Ok(Self { - id, - is_initiator, - // noiserm - noise_state: Mutex::new(noise_protocol), - kkt_state: Mutex::new(kkt_state), - psq_state: Mutex::new(psq_state), - psk_handle: Mutex::new(None), - sending_counter: AtomicU64::new(0), - receiving_counter: Mutex::new(ReceivingKeyCounterValidator::default()), - // noiserm - psk_injected: AtomicBool::new(false), - local_peer, - remote_peer, - salt: *salt, - outer_aead_key: Mutex::new(None), - pq_shared_secret: Mutex::new(None), - subsession_counter: AtomicU64::new(0), - read_only: AtomicBool::new(false), - successor_session_id: Mutex::new(None), - negotiated_version: protocol_version, - }) - } - - pub fn next_packet(&self, message: LpMessage) -> Result { + pub fn next_packet(&mut self, message: LpMessage) -> Result { let counter = self.next_counter(); - let header = LpHeader::new(self.id(), counter, self.negotiated_version); + let header = LpHeader::new(self.id(), counter, self.version); let packet = LpPacket::new(header, message); Ok(packet) } /// Generates the next counter value for outgoing packets. - pub fn next_counter(&self) -> u64 { - self.sending_counter.fetch_add(1, Ordering::Relaxed) + pub fn next_counter(&mut self) -> u64 { + let counter = self.sending_counter; + self.sending_counter += 1; + counter } /// Performs a quick validation check for an incoming packet counter. @@ -469,8 +243,7 @@ impl LpSession { pub fn receiving_counter_quick_check(&self, counter: u64) -> Result<(), LpError> { // Branchless implementation uses SIMD when available for constant-time // operations, preventing timing attacks. Check before crypto to save CPU cycles. - let counter_validator = self.receiving_counter.lock(); - counter_validator + self.receiving_counter .will_accept_branchless(counter) .map_err(LpError::Replay) } @@ -488,9 +261,8 @@ impl LpSession { /// /// * `Ok(())` if the counter was successfully marked /// * `Err(LpError::Replay)` if the counter cannot be marked (duplicate, too old, etc.) - pub fn receiving_counter_mark(&self, counter: u64) -> Result<(), LpError> { - let mut counter_validator = self.receiving_counter.lock(); - counter_validator + pub fn receiving_counter_mark(&mut self, counter: u64) -> Result<(), LpError> { + self.receiving_counter .mark_did_receive_branchless(counter) .map_err(LpError::Replay) } @@ -503,601 +275,25 @@ impl LpSession { /// * The next expected counter value for incoming packets /// * The total number of received packets pub fn current_packet_cnt(&self) -> (u64, u64) { - let counter_validator = self.receiving_counter.lock(); - counter_validator.current_packet_cnt() + self.receiving_counter.current_packet_cnt() } - /// Returns the stored PSK handle (ctxt_B) if available. - /// - /// The PSK handle is received from the responder during handshake and can be - /// used for future PSK re-registration without running KEM encapsulation again. - /// - /// # Returns - /// - /// * `Some(Vec)` - The encrypted PSK handle from the responder - /// * `None` - PSK handle not yet received or session is initiator before handshake completion - pub fn get_psk_handle(&self) -> Option> { - self.psk_handle.lock().clone() - } - - /// Returns the reference to the KEM Public key of the peer (if available). - pub fn get_kem_key_handle(&self) -> Result<&x25519::PublicKey, LpError> { - self.local_peer - .kem_psq - .as_ref() - .map(|kp| kp.public_key()) - .ok_or(LpError::ResponderWithMissingKEMKey) - } - - // TODO: missing Zeroize - /// Convert local KEM PSQ keys to typed EncapsulationKey / EncapsulationKey - pub fn encapsulated_kem_keys( - &self, - ) -> Result<(DecapsulationKey<'_>, EncapsulationKey<'_>), LpError> { - let kem_keys = self - .local_peer - .kem_psq - .as_ref() - .ok_or(LpError::ResponderWithMissingKEMKey)?; - - let libcrux_private_key = libcrux_kem::PrivateKey::decode( - libcrux_kem::Algorithm::X25519, - kem_keys.private_key().as_bytes(), - ) - .map_err(|e| { - LpError::KKTError(format!( - "Failed to convert X25519 private key to libcrux PrivateKey: {e:?}", - )) - })?; - let dec_key = DecapsulationKey::X25519(libcrux_private_key); - - let libcrux_public_key = libcrux_kem::PublicKey::decode( - libcrux_kem::Algorithm::X25519, - kem_keys.public_key().as_bytes(), - ) - .map_err(|e| { - LpError::KKTError(format!( - "Failed to convert X25519 public key to libcrux PublicKey: {e:?}", - )) - })?; - let enc_key = EncapsulationKey::X25519(libcrux_public_key); - Ok((dec_key, enc_key)) - } - - /// Prepares a KKT (KEM Key Transfer) request message. - /// Config: Encryption Enabled, One-Way, Anonymous - /// - /// This should be called by the initiator before starting PSQ - /// to obtain the responder's KEM public key. - /// - /// **Protocol Flow:** - /// 1. Initiator creates an Encrypted, Anonymous, One-Way, KKT request - /// 2. Responder responds with encrypted KEM public key + signature - /// 3. Initiator validates response and stores KEM key for PSQ use - /// - /// # Returns - /// - /// * `Some(Ok(LpMessage::KKTRequest))` - KKT request ready to send - /// * `Some(Err(LpError))` - Error creating KKT request - /// * `None` - KKT not applicable (responder, or already completed) - pub fn prepare_kkt_request(&self) -> Option> { - use nym_kkt::ciphersuite::{Ciphersuite, HashFunction, KEM, SignatureScheme}; - - let mut kkt_state = self.kkt_state.lock(); - - // Only initiator creates KKT requests, and only when not started - if !self.is_initiator || !matches!(*kkt_state, KKTState::NotStarted) { - return None; - } - - // georgio this needs to be moved one level up (maybe chosen in LPSession) - let ciphersuite = match Ciphersuite::resolve_ciphersuite( - KEM::X25519, - HashFunction::Blake3, - SignatureScheme::Ed25519, - None, - ) { - Ok(cs) => cs, - Err(e) => { - return Some(Err(LpError::Internal(format!( - "KKT ciphersuite error: {:?}", - e - )))); - } - }; - - let mut rng = rand09::rng(); - match anonymous_initiator_process(&mut rng, ciphersuite) { - Ok((context, kkt_frame)) => { - match encrypt_initial_kkt_frame( - &mut rng, - &self.remote_peer.x25519_public, - &kkt_frame, - ) { - Ok((session_secret, encrypted_request_bytes)) => { - // Store context for response validation - *kkt_state = KKTState::InitiatorWaiting { - context, - session_secret, - }; - - // Serialize KKT frame to bytes - Some(Ok(LpMessage::KKTRequest(crate::message::KKTRequestData( - encrypted_request_bytes, - )))) - } - Err(e) => Some(Err(LpError::Internal(format!( - "KKT request encryption failed: {:?}", - e - )))), - } - } - Err(e) => Some(Err(LpError::Internal(format!( - "KKT request creation failed: {:?}", - e - )))), - } - } - - /// Attempt to retrieve expected KEM key hash of the remote - /// for [KEM] key type and [HashFunction] specified by own [KKTContext] - fn expected_kem_key_hash(&self, context: KKTContext) -> Result<&Vec, LpError> { - let kem = context.ciphersuite().kem(); - let hash_function = context.ciphersuite().hash_function(); - - let digests = self - .remote_peer - .expected_kem_key_digests - .get(&kem) - .ok_or(LpError::NoKnownKEMKeyDigests { kem, hash_function })?; - - digests - .get(&hash_function) - .ok_or(LpError::NoKnownKEMKeyDigests { kem, hash_function }) - } - - /// Processes a KKT response from the responder. - /// - /// Decrypts and validates the response and stores the authenticated KEM public key - /// for use in PSQ encapsulation. - /// - /// # Arguments - /// - /// * `response_bytes` - Raw KKT response message from responder - /// * `expected_key_hash` - Expected hash of responder's KEM key (obtained from directory). - /// - /// # Returns - /// - /// * `Ok(())` - KKT exchange completed, KEM key stored - /// * `Err(LpError)` - Signature verification failed, hash mismatch, or invalid state - /// - pub fn process_kkt_response(&self, encrypted_response_bytes: &[u8]) -> Result<(), LpError> { - let mut kkt_state = self.kkt_state.lock(); - - // Extract context from waiting state - let (mut context, session_secret) = match &*kkt_state { - KKTState::InitiatorWaiting { - context, - session_secret, - } => (*context, *session_secret), - _ => { - return Err(LpError::Internal( - "KKT response received in invalid state".to_string(), - )); - } - }; - - let remote_encapsulation_key = - match decrypt_kkt_frame(&session_secret, encrypted_response_bytes, KKT_RESPONSE_AAD) { - Ok((response_frame, remote_context)) => { - let expected_kem_key_digest = self.expected_kem_key_hash(context)?; - match initiator_ingest_response( - &mut context, - &response_frame, - &remote_context, - &self.remote_peer.ed25519_public, - expected_kem_key_digest, - ) { - Ok(remote_encapsulation_key) => remote_encapsulation_key, - Err(e) => { - return Err(LpError::Internal(format!( - "KKT response handling failure: {:?}", - e - ))); - } - } - } - Err(e) => { - return Err(LpError::Internal(format!( - "KKT response decryption failure: {:?}", - e - ))); - } - }; - - // Store the authenticated KEM key - *kkt_state = KKTState::Completed { - kem_pk: Box::new(remote_encapsulation_key), - }; - Ok(()) - } - - /// Processes a KKT request from the initiator and prepares a signed response. - /// - /// Validates the initiator's signature and creates a response containing this - /// responder's KEM public key, signed with Ed25519. - /// - /// # Arguments - /// - /// * `request_bytes` - Raw KKT request message from initiator - /// * `responder_kem_pk` - This responder's KEM public key to send - /// - /// # Returns - /// - /// * `Ok(LpMessage::KKTResponse)` - Signed KKT response ready to send - /// * `Err(LpError)` - Signature verification failed or invalid request - pub fn process_kkt_request( - &self, - request_bytes: &[u8], - responder_kem_pk: &EncapsulationKey, - ) -> Result { - let mut rng = rand09::rng(); - - let mut kkt_state = self.kkt_state.lock(); - - let response_bytes = match decrypt_initial_kkt_frame( - self.local_peer.x25519().private_key(), - request_bytes, - ) { - Ok((session_secret, request_frame, remote_context)) => { - match responder_ingest_message(&remote_context, None, None, &request_frame) { - Ok((mut context, _)) => match responder_process( - &mut context, - request_frame.session_id(), - self.local_peer.ed25519().private_key(), - responder_kem_pk, - ) { - Ok(response_frame) => match encrypt_kkt_frame( - &mut rng, - &session_secret, - &response_frame, - KKT_RESPONSE_AAD, - ) { - Ok(response_bytes) => response_bytes, - Err(e) => { - return Err(LpError::Internal(format!( - "KKT response encryption failure : {:?}", - e - ))); - } - }, - Err(e) => { - return Err(LpError::Internal(format!( - "KKT response generation failure : {:?}", - e - ))); - } - }, - Err(e) => { - return Err(LpError::Internal(format!( - "KKT request handling failure: {:?}", - e - ))); - } - } - } - Err(e) => { - return Err(LpError::Internal(format!( - "KKT request decryption failure: {:?}", - e - ))); - } - }; - - // Mark KKT as processed - // Responder doesn't store the kem_pk since they already have their own KEM keypair - *kkt_state = KKTState::ResponderProcessed; - - Ok(LpMessage::KKTResponse(crate::message::KKTResponseData( - response_bytes, - ))) - } - - /// Prepares the next handshake message to be sent, if any. - /// - /// This should be called by the driver/IO layer to check if the Noise protocol - /// state machine requires a message to be sent to the peer. - /// - /// For initiators, PSQ always runs on the first message: - /// 1. Converts X25519 keys to DHKEM format - /// 2. Generates PSQ payload and derives PSK - /// 3. Injects PSK into Noise HandshakeState - /// 4. Embeds PSQ payload in first handshake message as: [u16 len][psq_payload][noise_msg] - /// - /// # Returns - /// - /// * `None` if no message needs to be sent currently (e.g., waiting for peer, or handshake complete). - /// * `Some(LpError)` if there's an error within the Noise protocol or PSQ. - pub fn prepare_handshake_message(&self) -> Option> { - let mut noise_state = self.noise_state.lock(); - - // PSQ always runs for initiator on first message - let mut psq_state = self.psq_state.lock(); - - if self.is_initiator && matches!(*psq_state, PSQState::NotStarted) { - // Extract KEM public key from completed KKT exchange - // PSQ requires the authenticated KEM key obtained via KKT protocol - let kkt_state = self.kkt_state.lock(); - let remote_kem = match &*kkt_state { - KKTState::Completed { kem_pk } => kem_pk, - _ => { - return Some(Err(LpError::KKTError( - "PSQ handshake requires completed KKT exchange".to_string(), - ))); - } - }; - - // Generate PSQ payload and PSK using KKT-authenticated KEM key - let session_context = self.id.to_le_bytes(); - - let psq_result = match psq_initiator_create_message( - self.local_peer.x25519.private_key(), - &self.remote_peer.x25519_public, - remote_kem, - self.local_peer.ed25519.private_key(), - self.local_peer.ed25519.public_key(), - &self.salt, - &session_context, - ) { - Ok(result) => result, - Err(e) => { - tracing::error!("PSQ handshake preparation failed, aborting: {:?}", e); - return Some(Err(e)); - } - }; - let psk = psq_result.psk; - let psq_payload = psq_result.payload; - - // Store PQ shared secret for subsession PSK derivation - *self.pq_shared_secret.lock() = Some(PqSharedSecret::new(psq_result.pq_shared_secret)); - - // georgio start psq v2 here - - // Inject PSK into Noise HandshakeState - if let Err(e) = noise_state.set_psk(3, &psk) { - return Some(Err(LpError::NoiseError(e))); - } - // noiserm - // Mark PSK as injected for safety checks in transport mode - self.psk_injected.store(true, Ordering::Release); - - // Derive and store outer AEAD key from PSK - { - let mut outer_key = self.outer_aead_key.lock(); - *outer_key = Some(OuterAeadKey::from_psk(&psk)); - } - - // Get the Noise handshake message - let noise_msg = match noise_state.get_bytes_to_send() { - Some(Ok(msg)) => msg, - Some(Err(e)) => return Some(Err(LpError::NoiseError(e))), - None => return None, // Should not happen if is_my_turn, but handle gracefully - }; - - // Combine: [u16 psq_len][psq_payload][noise_msg] - let psq_len = psq_payload.len() as u16; - let mut combined = Vec::with_capacity(2 + psq_payload.len() + noise_msg.len()); - combined.extend_from_slice(&psq_len.to_le_bytes()); - combined.extend_from_slice(&psq_payload); - combined.extend_from_slice(&noise_msg); - - // PSK is derived but we stay in InitiatorWaiting until we receive msg 2. - // This ensures we send msg 1 in cleartext (responder can't decrypt yet). - *psq_state = PSQState::InitiatorWaiting { psk }; - - return Some(Ok(LpMessage::Handshake(HandshakeData(combined)))); - } - - // Normal flow (no PSQ, or PSQ already completed) - drop(psq_state); // Release lock - - if let Some(message) = noise_state.get_bytes_to_send() { - match message { - Ok(noise_msg) => { - // Check if we have a PSK handle (ctxt_B) to embed (responder message 2 only) - // Only the responder should embed the handle, never the initiator - if !self.is_initiator { - let mut psk_handle_guard = self.psk_handle.lock(); - if let Some(handle_bytes) = psk_handle_guard.take() { - // Embed PSK handle in message: [u16 handle_len][handle_bytes][noise_msg] - let handle_len = handle_bytes.len() as u16; - let mut combined = - Vec::with_capacity(2 + handle_bytes.len() + noise_msg.len()); - combined.extend_from_slice(&handle_len.to_le_bytes()); - combined.extend_from_slice(&handle_bytes); - combined.extend_from_slice(&noise_msg); - - tracing::debug!( - "Embedding PSK handle ({} bytes) in handshake message 2", - handle_bytes.len() - ); - - return Some(Ok(LpMessage::Handshake(HandshakeData(combined)))); - } - } - // No PSK handle to embed, send noise message as-is - Some(Ok(LpMessage::Handshake(HandshakeData(noise_msg)))) - } - Err(e) => Some(Err(LpError::NoiseError(e))), - } - } else { - None - } - } - - /// Processes a received handshake message from the peer. - /// - /// This should be called by the driver/IO layer after receiving a potential - /// handshake message payload from an LP packet. - /// - /// For responders, PSQ always runs on the first message: - /// 1. Extracts PSQ payload from the first handshake message: [u16 len][psq_payload][noise_msg] - /// 2. Converts X25519 keys to DHKEM format - /// 3. Decapsulates PSK from PSQ payload - /// 4. Injects PSK into Noise HandshakeState - /// 5. Processes the remaining Noise handshake message - /// - /// # Arguments - /// - /// * `message` - The LP message received from the peer, expected to be a Handshake message. - /// - /// # Returns - /// - /// * `Ok(ReadResult)` detailing the outcome (e.g., handshake complete, no-op). - /// * `Err(LpError)` if the message is invalid or causes a Noise/PSQ protocol error. - pub fn process_handshake_message(&self, message: &LpMessage) -> Result { - let mut noise_state = self.noise_state.lock(); - let mut psq_state = self.psq_state.lock(); - - match message { - LpMessage::Handshake(HandshakeData(payload)) => { - // PSQ always runs for responder on first message - if !self.is_initiator && matches!(*psq_state, PSQState::ResponderWaiting) { - // Extract PSQ payload: [u16 psq_len][psq_payload][noise_msg] - if payload.len() < 2 { - return Err(LpError::NoiseError(NoiseError::Other( - "Payload too short for PSQ extraction".to_string(), - ))); - } - - let psq_len = u16::from_le_bytes([payload[0], payload[1]]) as usize; - - if payload.len() < 2 + psq_len { - return Err(LpError::NoiseError(NoiseError::Other( - "Payload length mismatch for PSQ extraction".to_string(), - ))); - } - - let psq_payload = &payload[2..2 + psq_len]; - let noise_payload = &payload[2 + psq_len..]; - - let (dec_key, enc_key) = self.encapsulated_kem_keys()?; - - // Decapsulate PSK from PSQ payload using X25519 as DHKEM - let session_context = self.id.to_le_bytes(); - - let psq_result = match psq_responder_process_message( - self.local_peer.x25519.private_key(), - &self.remote_peer.x25519_public, - (&dec_key, &enc_key), - &self.remote_peer.ed25519_public, - psq_payload, - &self.salt, - &session_context, - ) { - Ok(result) => result, - Err(e) => { - tracing::error!("PSQ handshake processing failed, aborting: {:?}", e); - return Err(e); - } - }; - let psk = psq_result.psk; - - // Store PQ shared secret for subsession PSK derivation - *self.pq_shared_secret.lock() = - Some(PqSharedSecret::new(psq_result.pq_shared_secret)); - - // Store the PSK handle (ctxt_B) for transmission in next message - { - let mut psk_handle = self.psk_handle.lock(); - *psk_handle = Some(psq_result.psk_handle); - } - - // Inject PSK into Noise HandshakeState - noise_state.set_psk(3, &psk)?; - // Mark PSK as injected for safety checks in transport mode - self.psk_injected.store(true, Ordering::Release); - - // Derive and store outer AEAD key from PSK - { - let mut outer_key = self.outer_aead_key.lock(); - *outer_key = Some(OuterAeadKey::from_psk(&psk)); - } - - // Update PSQ state to Completed - *psq_state = PSQState::Completed { psk }; - - // Process the Noise handshake message (without PSQ prefix) - drop(psq_state); // Release lock before processing - return noise_state - .read_message(noise_payload) - .map_err(LpError::NoiseError); - } - - // Check if initiator should extract PSK handle from message 2 - if let PSQState::InitiatorWaiting { psk } = *psq_state - && self.is_initiator - { - // Extract PSK handle: [u16 handle_len][handle_bytes][noise_msg] - if payload.len() >= 2 { - let handle_len = u16::from_le_bytes([payload[0], payload[1]]) as usize; - - if handle_len > 0 && payload.len() >= 2 + handle_len { - // Extract and store the PSK handle - let handle_bytes = &payload[2..2 + handle_len]; - let noise_payload = &payload[2 + handle_len..]; - - tracing::debug!( - "Extracted PSK handle ({} bytes) from message 2", - handle_len - ); - - { - let mut psk_handle = self.psk_handle.lock(); - *psk_handle = Some(handle_bytes.to_vec()); - } - - // Transition to Completed - we've received confirmation from responder - *psq_state = PSQState::Completed { psk }; - drop(psq_state); - - // Process only the Noise message part - return noise_state - .read_message(noise_payload) - .map_err(LpError::NoiseError); - } - } - // If no valid handle found, fall through to normal processing - } - - // The sans-io NoiseProtocol::read_message expects only the payload. - noise_state - .read_message(payload) - .map_err(LpError::NoiseError) - } - _ => Err(LpError::NoiseError(NoiseError::IncorrectStateError)), - } - } - - /// Checks if the Noise handshake phase is complete. - pub fn is_handshake_complete(&self) -> bool { - self.noise_state.lock().is_handshake_finished() - } - - /// Returns the PQ shared secret (K_pq) if available. + /// Returns the PQ shared secret (K_pq). /// /// This is the raw KEM output from PSQ before Blake3 KDF combination. /// Used for deriving subsession PSKs to maintain PQ protection. - pub fn pq_shared_secret(&self) -> Option<[u8; 32]> { - self.pq_shared_secret.lock().as_ref().map(|s| *s.as_bytes()) + pub fn pq_shared_secret(&self) -> &PqSharedSecret { + &self.pq_shared_secret } /// Gets the next subsession index and increments the counter. /// /// Each subsession requires a unique index to ensure unique PSK derivation. /// The index is monotonically increasing per session. - pub fn next_subsession_index(&self) -> u64 { - self.subsession_counter.fetch_add(1, Ordering::Relaxed) + pub fn next_subsession_index(&mut self) -> u64 { + let next = self.subsession_counter; + self.subsession_counter += 1; + next } /// Returns true if this session is in read-only mode. @@ -1105,7 +301,7 @@ impl LpSession { /// Read-only sessions have been demoted after a subsession was promoted. /// They can still decrypt incoming messages but cannot encrypt outgoing ones. pub fn is_read_only(&self) -> bool { - self.read_only.load(Ordering::Acquire) + self.read_only } /// Demotes this session to read-only mode after a subsession replaces it. @@ -1117,20 +313,18 @@ impl LpSession { /// /// # Arguments /// * `successor_idx` - The receiver index of the session that replaced this one - pub fn demote(&self, successor_idx: u32) { - *self.successor_session_id.lock() = Some(successor_idx); - self.read_only.store(true, Ordering::Release); + pub fn demote(&mut self, successor_idx: u32) { + self.successor_session_id = Some(successor_idx); + self.read_only = true; } /// Returns the successor session ID if this session was demoted. pub fn successor_session_id(&self) -> Option { - *self.successor_session_id.lock() + self.successor_session_id } /// Encrypts application data payload using the established Noise transport session. /// - /// This should only be called after the handshake is complete (`is_handshake_complete` returns true). - /// /// # Arguments /// /// * `payload` - The application data to encrypt. @@ -1139,30 +333,18 @@ impl LpSession { /// /// * `Ok(Vec)` containing the encrypted Noise message ciphertext. /// * `Err(NoiseError)` if the session is not in transport mode or encryption fails. - pub fn encrypt_data(&self, payload: &[u8]) -> Result { + pub fn encrypt_data(&mut self, payload: &[u8]) -> Result { // Check if session is read-only (demoted) - if self.read_only.load(Ordering::Acquire) { + if self.read_only { return Err(NoiseError::SessionReadOnly); } - let mut noise_state = self.noise_state.lock(); - // Safety: Prevent transport mode with dummy PSK - if !self.psk_injected.load(Ordering::Acquire) { - return Err(NoiseError::PskNotInjected); - } - // Explicitly check if handshake is finished before trying to write - if !noise_state.is_handshake_finished() { - return Err(NoiseError::IncorrectStateError); - } - let payload = noise_state.write_message(payload)?; + let payload = self.noise_state.write_message(payload)?; Ok(LpMessage::EncryptedData(EncryptedDataPayload(payload))) } /// Decrypts an incoming Noise message containing application data. /// - /// This should only be called after the handshake is complete (`is_handshake_complete` returns true) - /// and when an `LPMessage::EncryptedData` is received. - /// /// # Arguments /// /// * `noise_ciphertext` - The encrypted Noise message received from the peer. @@ -1171,42 +353,15 @@ impl LpSession { /// /// * `Ok(Vec)` containing the decrypted application data payload. /// * `Err(NoiseError)` if the session is not in transport mode, decryption fails, or the message is not data. - pub fn decrypt_data(&self, noise_ciphertext: &LpMessage) -> Result, NoiseError> { - let mut noise_state = self.noise_state.lock(); - // Safety: Prevent transport mode with dummy PSK - if !self.psk_injected.load(Ordering::Acquire) { - return Err(NoiseError::PskNotInjected); - } - // Explicitly check if handshake is finished before trying to read - if !noise_state.is_handshake_finished() { - return Err(NoiseError::IncorrectStateError); - } - + pub fn decrypt_data(&mut self, noise_ciphertext: &LpMessage) -> Result, NoiseError> { let payload = noise_ciphertext.payload(); - match noise_state.read_message(payload)? { + match self.noise_state.read_message(payload)? { ReadResult::DecryptedData(data) => Ok(data), _ => Err(NoiseError::IncorrectStateError), } } - /// Test-only method to set KKT state to Completed with a mock KEM key. - /// This allows tests to bypass KKT exchange and directly test PSQ handshake. - #[cfg(test)] - pub(crate) fn set_kkt_completed_for_test(&self, remote_x25519_pub: &x25519::PublicKey) { - // Convert remote X25519 public key to EncapsulationKey for testing - let remote_kem_bytes = remote_x25519_pub.as_bytes(); - let libcrux_public_key = - libcrux_kem::PublicKey::decode(libcrux_kem::Algorithm::X25519, remote_kem_bytes) - .expect("Test KEM key conversion failed"); - let kem_pk = EncapsulationKey::X25519(libcrux_public_key); - - let mut kkt_state = self.kkt_state.lock(); - *kkt_state = KKTState::Completed { - kem_pk: Box::new(kem_pk), - }; - } - /// Creates a new subsession using Noise KKpsk0 pattern. /// /// KKpsk0 reuses parent's static X25519 keys (both parties know each other from parent session). @@ -1227,18 +382,11 @@ impl LpSession { subsession_index: u64, is_initiator: bool, ) -> Result { - // Verify parent handshake is complete - if !self.is_handshake_complete() { - return Err(LpError::Internal("Parent handshake not complete".into())); - } - // Get PQ shared secret - let pq_secret = self - .pq_shared_secret() - .ok_or_else(|| LpError::Internal("PQ shared secret not available".into()))?; + let pq_secret = self.pq_shared_secret(); // Derive subsession PSK from parent's PQ shared secret - let subsession_psk = derive_subsession_psk(&pq_secret, subsession_index); + let subsession_psk = derive_subsession_psk(pq_secret.as_bytes(), subsession_index); // Build KKpsk0 handshake // Pattern: Noise_KKpsk0_25519_ChaChaPoly_SHA256 @@ -1266,9 +414,9 @@ impl LpSession { is_initiator, local_peer: self.local_peer.clone(), remote_peer: self.remote_peer.clone(), - pq_shared_secret: PqSharedSecret::new(pq_secret), + pq_shared_secret: self.pq_shared_secret.clone(), subsession_psk, - negotiated_version: self.negotiated_version, + negotiated_version: self.version, }) } } @@ -1382,38 +530,23 @@ impl SubsessionHandshake { // Extract the noise state (now in transport mode) let noise_state = self.noise_state.into_inner(); - // Generate fresh salt for the new session - let salt = generate_fresh_salt(); - // Derive outer AEAD key from the subsession PSK let outer_key = OuterAeadKey::from_psk(&self.subsession_psk); Ok(LpSession { - id: receiver_index, - is_initiator: self.is_initiator, // noiserm - noise_state: Mutex::new(noise_state), - // KKT: subsession inherits from parent, mark as processed - kkt_state: Mutex::new(KKTState::ResponderProcessed), - // PSQ: subsession uses PSK derived from parent's PQ secret - psq_state: Mutex::new(PSQState::Completed { - psk: self.subsession_psk, - }), - psk_handle: Mutex::new(None), // Subsession doesn't have its own handle - sending_counter: AtomicU64::new(0), - receiving_counter: Mutex::new(ReceivingKeyCounterValidator::new(0)), - // noiserm - psk_injected: AtomicBool::new(true), // PSK was in KKpsk0 + session_id: receiver_index, + noise_state, + sending_counter: 0, + receiving_counter: ReceivingKeyCounterValidator::new(0), local_peer: self.local_peer, remote_peer: self.remote_peer, - salt, - outer_aead_key: Mutex::new(Some(outer_key)), - pq_shared_secret: Mutex::new(Some(self.pq_shared_secret)), - subsession_counter: AtomicU64::new(0), - read_only: AtomicBool::new(false), - successor_session_id: Mutex::new(None), - // Inherit parent's protocol version - negotiated_version: self.negotiated_version, + outer_aead_key: outer_key, + pq_shared_secret: self.pq_shared_secret, + subsession_counter: 0, + read_only: false, + successor_session_id: None, + version: self.negotiated_version, }) } } @@ -1421,10 +554,7 @@ impl SubsessionHandshake { #[cfg(test)] mod tests { use super::*; - use crate::packet::version; - use crate::peer::mock_peers; - use crate::{replay::ReplayError, sessions_for_tests}; - use nym_crypto::asymmetric::ed25519; + use crate::{SessionsMock, replay::ReplayError, sessions_for_tests}; use rand::thread_rng; // Helper function to generate keypairs for tests @@ -1432,41 +562,9 @@ mod tests { x25519::KeyPair::new(&mut thread_rng()) } - // Helper function to create a session with real keys for handshake tests - fn create_handshake_test_session(receiver_index: u32, is_initiator: bool) -> LpSession { - let (keys_1, keys_2) = mock_peers(); - - // Create Ed25519 keypairs that correspond to initiator/responder roles - // Initiator uses [1u8], Responder uses [2u8] - let (local, remote) = if is_initiator { - (keys_1, keys_2.as_remote()) - } else { - (keys_2, keys_1.as_remote()) - }; - - let salt = [0u8; 32]; // Test salt - - // PSQ will derive the PSK during handshake using X25519 as DHKEM - let session = LpSession::new( - receiver_index, - is_initiator, - local, - remote.clone(), - &salt, - version::CURRENT, - ) - .expect("Test session creation failed"); - - // Initialize KKT state to Completed for tests (bypasses KKT exchange) - // This simulates having already received the remote party's KEM key via KKT - session.set_kkt_completed_for_test(&remote.x25519_public); - - session - } - #[test] fn test_session_creation() { - let session = sessions_for_tests().0; + let mut session = sessions_for_tests().0; // Initial counter should be zero let counter = session.next_counter(); @@ -1494,7 +592,7 @@ mod tests { #[test] fn test_replay_protection_sequential() { - let session = sessions_for_tests().1; + let mut session = sessions_for_tests().1; // Sequential counters should be accepted assert!(session.receiving_counter_quick_check(0).is_ok()); @@ -1516,7 +614,7 @@ mod tests { #[test] fn test_replay_protection_out_of_order() { - let session = sessions_for_tests().1; + let mut session = sessions_for_tests().1; // Receive packets in order assert!(session.receiving_counter_mark(0).is_ok()); @@ -1537,7 +635,7 @@ mod tests { #[test] fn test_packet_stats() { - let session = sessions_for_tests().1; + let mut session = sessions_for_tests().1; // Initial stats let (next, received) = session.current_packet_cnt(); @@ -1553,235 +651,11 @@ mod tests { assert_eq!(received, 2); } - #[test] - fn test_prepare_handshake_message_initial_state() { - let receiver_index = 12345u32; - - let initiator_session = create_handshake_test_session(receiver_index, true); - let responder_session = create_handshake_test_session( - receiver_index, - false, - // Responder also needs initiator's key for XK - ); - - // Initiator should have a message to send immediately (-> e) - let initiator_msg_result = initiator_session.prepare_handshake_message(); - assert!(initiator_msg_result.is_some()); - let initiator_msg = initiator_msg_result - .unwrap() - .expect("Initiator msg prep failed"); - assert!(!initiator_msg.is_empty()); - - // Responder should have nothing to send initially (waits for <- e) - let responder_msg_result = responder_session.prepare_handshake_message(); - assert!(responder_msg_result.is_none()); - } - - #[test] - fn test_process_handshake_message_first_step() { - let receiver_index = 12345u32; - - let initiator_session = create_handshake_test_session(receiver_index, true); - let responder_session = create_handshake_test_session(receiver_index, false); - - // 1. Initiator prepares the first message (-> e) - let initiator_msg_result = initiator_session.prepare_handshake_message(); - let initiator_msg = initiator_msg_result - .unwrap() - .expect("Initiator msg prep failed"); - - // 2. Responder processes the message (<- e) - let process_result = responder_session.process_handshake_message(&initiator_msg); - - // Check the result of processing - match process_result { - Ok(ReadResult::NoOp) => { - // Expected for XK first message, responder doesn't decrypt data yet - } - Ok(other) => panic!("Unexpected process result: {:?}", other), - Err(e) => panic!("Responder processing failed: {:?}", e), - } - - // 3. After processing, responder should now have a message to send (-> e, es) - let responder_response_result = responder_session.prepare_handshake_message(); - assert!(responder_response_result.is_some()); - let responder_response = responder_response_result - .unwrap() - .expect("Responder response prep failed"); - assert!(!responder_response.is_empty()); - } - - #[test] - fn test_handshake_driver_simulation() { - let initiator_session = create_handshake_test_session(12345u32, true); - let responder_session = create_handshake_test_session(12345u32, false); - - let mut responder_to_initiator_msg = None; - let mut rounds = 0; - const MAX_ROUNDS: usize = 10; // Safety break for the loop - - // Start by priming the initiator message - let mut initiator_to_responder_msg = - initiator_session.prepare_handshake_message().unwrap().ok(); - assert!( - initiator_to_responder_msg.is_some(), - "Initiator did not produce initial message" - ); - - while rounds < MAX_ROUNDS { - rounds += 1; - - // === Initiator -> Responder === - if let Some(msg) = initiator_to_responder_msg.take() { - // Process message - match responder_session.process_handshake_message(&msg) { - Ok(_) => {} - Err(e) => panic!("Responder processing failed: {:?}", e), - } - - // Check if responder needs to send a reply - responder_to_initiator_msg = responder_session - .prepare_handshake_message() - .transpose() - .unwrap(); - } - - // Check completion after potentially processing responder's message below - if initiator_session.is_handshake_complete() - && responder_session.is_handshake_complete() - { - break; - } - - // === Responder -> Initiator === - if let Some(msg) = responder_to_initiator_msg.take() { - // Process message - match initiator_session.process_handshake_message(&msg) { - Ok(_) => {} - Err(e) => panic!("Initiator processing failed: {:?}", e), - } - - // Check if initiator needs to send a reply (should be last message in XK) - initiator_to_responder_msg = initiator_session - .prepare_handshake_message() - .transpose() - .unwrap(); - } - - // Check completion again after potentially processing initiator's message above - if initiator_session.is_handshake_complete() - && responder_session.is_handshake_complete() - { - break; - } - } - - assert!( - rounds < MAX_ROUNDS, - "Handshake did not complete within max rounds" - ); - assert!( - initiator_session.is_handshake_complete(), - "Initiator handshake did not complete" - ); - assert!( - responder_session.is_handshake_complete(), - "Responder handshake did not complete" - ); - - println!("Handshake completed in {} rounds.", rounds); - } - - #[test] - fn test_encrypt_decrypt_after_handshake() { - // --- Setup Handshake --- - - let initiator_session = create_handshake_test_session(12345u32, true); - let responder_session = create_handshake_test_session(12345u32, false); - - // Drive handshake to completion (simplified loop from previous test) - let mut i_msg = initiator_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - responder_session.process_handshake_message(&i_msg).unwrap(); - let r_msg = responder_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - initiator_session.process_handshake_message(&r_msg).unwrap(); - i_msg = initiator_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - responder_session.process_handshake_message(&i_msg).unwrap(); - - assert!(initiator_session.is_handshake_complete()); - assert!(responder_session.is_handshake_complete()); - - // --- Test Encryption/Decryption --- - let plaintext = b"Hello, Lewes Protocol!"; - - // Initiator encrypts - let ciphertext = initiator_session - .encrypt_data(plaintext) - .expect("Initiator encryption failed"); - assert_ne!(ciphertext.payload(), plaintext); // Ensure it's actually encrypted - - // Responder decrypts - let decrypted = responder_session - .decrypt_data(&ciphertext) - .expect("Responder decryption failed"); - assert_eq!(decrypted, plaintext); - - // --- Test other direction --- - let plaintext2 = b"Response from responder."; - - // Responder encrypts - let ciphertext2 = responder_session - .encrypt_data(plaintext2) - .expect("Responder encryption failed"); - assert_ne!(ciphertext2.payload(), plaintext2); - - // Initiator decrypts - let decrypted2 = initiator_session - .decrypt_data(&ciphertext2) - .expect("Initiator decryption failed"); - assert_eq!(decrypted2, plaintext2); - } - - #[test] - fn test_encrypt_decrypt_before_handshake() { - let initiator_session = create_handshake_test_session(12345u32, true); - - assert!(!initiator_session.is_handshake_complete()); - - // Attempt to encrypt before handshake - let plaintext = b"This should fail"; - let result = initiator_session.encrypt_data(plaintext); - assert!(result.is_err()); - match result.unwrap_err() { - NoiseError::PskNotInjected => {} // Expected - PSK check comes before handshake check - e => panic!("Expected PskNotInjected, got {:?}", e), - } - - // Attempt to decrypt before handshake (using dummy ciphertext) - let dummy_ciphertext = vec![0u8; 32]; - let result_decrypt = initiator_session.decrypt_data(&LpMessage::EncryptedData( - EncryptedDataPayload(dummy_ciphertext), - )); - assert!(result_decrypt.is_err()); - match result_decrypt.unwrap_err() { - NoiseError::PskNotInjected => {} // Expected - PSK check comes before handshake check - e => panic!("Expected PskNotInjected, got {:?}", e), - } - } - /* // These tests remain commented as they rely on the old mock crypto functions #[test] fn test_mock_crypto() { - let session = create_test_session(true); + let mut session = create_test_session(true); let data = [1, 2, 3, 4, 5]; let mut encrypted = [0; 5]; let mut decrypted = [0; 5]; @@ -1799,7 +673,7 @@ mod tests { #[test] fn test_mock_crypto_buffer_too_small() { - let session = create_test_session(true); + let mut session = create_test_session(true); let data = [1, 2, 3, 4, 5]; let mut too_small = [0; 3]; @@ -1813,72 +687,6 @@ mod tests { } */ - // ==================================================================== - // PSQ Handshake Integration Tests - // ==================================================================== - - /// Test that PSQ runs during handshake and derives a PSK - #[test] - fn test_psq_handshake_runs_with_psk_injection() { - let initiator_session = create_handshake_test_session(12345u32, true); - let responder_session = create_handshake_test_session(12345u32, false); - - // Drive the handshake - let mut i_msg = initiator_session - .prepare_handshake_message() - .expect("Initiator should have message") - .expect("Message prep should succeed"); - - // The first message should contain PSQ payload embedded - // Verify message is not empty and has reasonable size - assert!(!i_msg.is_empty(), "Initiator message should not be empty"); - assert!( - i_msg.len() > 100, - "Message should contain PSQ payload (actual: {})", - i_msg.len() - ); - - // Responder processes message (which includes PSQ decapsulation) - responder_session - .process_handshake_message(&i_msg) - .expect("Responder should process first message"); - - // Continue handshake - let r_msg = responder_session - .prepare_handshake_message() - .expect("Responder should have message") - .expect("Responder message prep should succeed"); - - initiator_session - .process_handshake_message(&r_msg) - .expect("Initiator should process responder message"); - - i_msg = initiator_session - .prepare_handshake_message() - .expect("Initiator should have final message") - .expect("Final message prep should succeed"); - - responder_session - .process_handshake_message(&i_msg) - .expect("Responder should process final message"); - - // Verify handshake completed - assert!(initiator_session.is_handshake_complete()); - assert!(responder_session.is_handshake_complete()); - - // Verify encryption works (implicitly tests PSK was correctly injected) - let plaintext = b"PSQ test message"; - let encrypted = initiator_session - .encrypt_data(plaintext) - .expect("Encryption should work after handshake"); - - let decrypted = responder_session - .decrypt_data(&encrypted) - .expect("Decryption should work with PSQ-derived PSK"); - - assert_eq!(decrypted, plaintext); - } - /// Test that X25519 keys are correctly converted to KEM format #[test] fn test_x25519_to_kem_conversion() { @@ -1905,404 +713,10 @@ mod tests { // (libcrux_kem::PrivateKey is an enum with no len() method, conversion success is enough) } - /// Test that PSQ actually derives a different PSK (not using dummy) - #[test] - fn test_psq_derived_psk_differs_from_dummy() { - // Create sessions - they start with dummy PSK [0u8; 32] - let initiator_session = create_handshake_test_session(12345u32, true); - let responder_session = create_handshake_test_session(12345u32, false); - - // Prepare first message (initiator runs PSQ and injects PSK) - let i_msg = initiator_session - .prepare_handshake_message() - .expect("Initiator should have message") - .expect("Message prep should succeed"); - - // Verify message is not empty (PSQ runs successfully) - assert!( - !i_msg.is_empty(), - "First message should contain PSQ payload" - ); - - // Complete handshake - responder_session - .process_handshake_message(&i_msg) - .expect("Responder should process message"); - - let r_msg = responder_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - - initiator_session.process_handshake_message(&r_msg).unwrap(); - - let final_msg = initiator_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - - responder_session - .process_handshake_message(&final_msg) - .unwrap(); - - // Test that encryption produces non-trivial ciphertext - // (would fail if using dummy PSK incorrectly) - let plaintext = b"test"; - let encrypted = initiator_session.encrypt_data(plaintext).unwrap(); - - // Decrypt should work - let decrypted = responder_session.decrypt_data(&encrypted).unwrap(); - assert_eq!(decrypted, plaintext); - - // Verify ciphertext is not just plaintext (basic encryption sanity) - if let LpMessage::EncryptedData(payload) = encrypted { - assert_ne!( - &payload.0[..plaintext.len()], - plaintext, - "Ciphertext should differ from plaintext" - ); - } else { - panic!("Expected EncryptedData message"); - } - } - - /// Test full end-to-end handshake with PSQ integration - #[test] - fn test_handshake_with_psq_end_to_end() { - let initiator_session = create_handshake_test_session(12345u32, true); - let responder_session = create_handshake_test_session(12345u32, false); - - // Verify initial state - assert!(!initiator_session.is_handshake_complete()); - assert!(!responder_session.is_handshake_complete()); - assert!(initiator_session.is_initiator()); - assert!(!responder_session.is_initiator()); - - // Round 1: Initiator -> Responder (contains PSQ encapsulation) - let msg1 = initiator_session - .prepare_handshake_message() - .expect("Initiator should prepare message") - .expect("Message should succeed"); - - assert!(!msg1.is_empty()); - assert!(!initiator_session.is_handshake_complete()); - - responder_session - .process_handshake_message(&msg1) - .expect("Responder should process PSQ message"); - - assert!(!responder_session.is_handshake_complete()); - - // Round 2: Responder -> Initiator - let msg2 = responder_session - .prepare_handshake_message() - .expect("Responder should prepare message") - .expect("Message should succeed"); - - initiator_session - .process_handshake_message(&msg2) - .expect("Initiator should process message"); - - // Round 3: Initiator -> Responder (final) - let msg3 = initiator_session - .prepare_handshake_message() - .expect("Initiator should prepare final message") - .expect("Message should succeed"); - - responder_session - .process_handshake_message(&msg3) - .expect("Responder should process final message"); - - // Verify both sides completed - assert!(initiator_session.is_handshake_complete()); - assert!(responder_session.is_handshake_complete()); - - // Test bidirectional encrypted communication - let msg_i_to_r = b"Hello from initiator"; - let encrypted_i = initiator_session - .encrypt_data(msg_i_to_r) - .expect("Initiator encryption"); - let decrypted_i = responder_session - .decrypt_data(&encrypted_i) - .expect("Responder decryption"); - assert_eq!(decrypted_i, msg_i_to_r); - - let msg_r_to_i = b"Hello from responder"; - let encrypted_r = responder_session - .encrypt_data(msg_r_to_i) - .expect("Responder encryption"); - let decrypted_r = initiator_session - .decrypt_data(&encrypted_r) - .expect("Initiator decryption"); - assert_eq!(decrypted_r, msg_r_to_i); - - // Successfully completed end-to-end test with PSQ - } - - /// Test that Ed25519 keys are used in PSQ authentication - #[test] - fn test_psq_handshake_uses_ed25519_authentication() { - // Create sessions with explicit Ed25519 keys - let initiator_session = create_handshake_test_session(12345u32, true); - let responder_session = create_handshake_test_session(12345u32, false); - - // Verify sessions store Ed25519 keys - // (Internal verification - keys are used in PSQ calls) - assert_eq!(initiator_session.id(), responder_session.id()); - - // Complete handshake - let msg1 = initiator_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - responder_session.process_handshake_message(&msg1).unwrap(); - - let msg2 = responder_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - initiator_session.process_handshake_message(&msg2).unwrap(); - - let msg3 = initiator_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - responder_session.process_handshake_message(&msg3).unwrap(); - - // If Ed25519 authentication failed, handshake would not complete - assert!(initiator_session.is_handshake_complete()); - assert!(responder_session.is_handshake_complete()); - - // Verify encrypted communication works (proof of successful PSQ with auth) - let test_data = b"Authentication test"; - let encrypted = initiator_session.encrypt_data(test_data).unwrap(); - let decrypted = responder_session.decrypt_data(&encrypted).unwrap(); - assert_eq!(decrypted, test_data); - } - - #[test] - fn test_psq_deserialization_failure() { - // Test that corrupted PSQ payload causes clean abort - - let responder_session = create_handshake_test_session(12345u32, false); - - // Create a handshake message with corrupted PSQ payload - let corrupted_psq_data = vec![0xFF; 128]; // Random garbage - let bad_message = LpMessage::Handshake(HandshakeData(corrupted_psq_data)); - - // Attempt to process corrupted message - should fail - let result = responder_session.process_handshake_message(&bad_message); - - // Should return error (PSQ deserialization will fail) - assert!(result.is_err(), "Expected error for corrupted PSQ payload"); - - // Verify session state is unchanged - // PSQ state should still be ResponderWaiting (not modified) - // Noise PSK should still be dummy [0u8; 32] - assert!(!responder_session.is_handshake_complete()); - } - - #[test] - fn test_handshake_abort_on_psq_failure() { - let (init, resp) = mock_peers(); - - let mut bad_resp = resp.as_remote(); - let wrong_ed25519 = ed25519::KeyPair::from_secret([99u8; 32], 99); // Different key! - bad_resp.ed25519_public = *wrong_ed25519.public_key(); - - let mut bad_init = init.as_remote(); - bad_init.ed25519_public = *wrong_ed25519.public_key(); - - // Create sessions with MISMATCHED Ed25519 keys - // This simulates authentication failure - let receiver_index: u32 = 55555; - let salt = [0u8; 32]; - - let initiator_session = LpSession::new( - receiver_index, - true, - init.clone(), - bad_resp, - &salt, - version::CURRENT, - ) - .unwrap(); - - // Initialize KKT state for test - initiator_session.set_kkt_completed_for_test(resp.x25519.public_key()); - - let responder_session = LpSession::new( - receiver_index, - false, - resp, - bad_init, - &salt, - version::CURRENT, - ) - .unwrap(); - // Initialize KKT state for test - responder_session.set_kkt_completed_for_test(init.x25519.public_key()); - - // Initiator prepares message (should succeed - signing works) - let msg1 = initiator_session - .prepare_handshake_message() - .expect("Initiator should prepare message") - .expect("Initiator should have message"); - - // Responder processes message - should FAIL (signature verification fails) - let result = responder_session.process_handshake_message(&msg1); - - // Should return CredError due to Ed25519 signature mismatch - assert!( - result.is_err(), - "Expected error for Ed25519 authentication failure" - ); - - // Verify handshake aborted cleanly - assert!(!initiator_session.is_handshake_complete()); - assert!(!responder_session.is_handshake_complete()); - } - - #[test] - fn test_psq_invalid_signature() { - let (init, resp) = mock_peers(); - - let mut bad_init = init.as_remote(); - let wrong_ed25519 = ed25519::KeyPair::from_secret([99u8; 32], 99); // Different key! - bad_init.ed25519_public = *wrong_ed25519.public_key(); - - let receiver_index: u32 = 66666; - let salt = [0u8; 32]; - - let initiator_session = LpSession::new( - receiver_index, - true, - init.clone(), - resp.as_remote(), - &salt, - version::CURRENT, - ) - .unwrap(); - // Initialize KKT state for test - initiator_session.set_kkt_completed_for_test(resp.x25519.public_key()); - - let responder_session = LpSession::new( - receiver_index, - false, - resp, - bad_init, - &salt, - version::CURRENT, - ) - .unwrap(); - // Initialize KKT state for test - responder_session.set_kkt_completed_for_test(init.x25519.public_key()); - - // Initiator creates message with valid signature (signed with [1u8]) - let msg = initiator_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - - // Responder tries to verify with wrong public key [99u8] - // This should fail Ed25519 signature verification - let result = responder_session.process_handshake_message(&msg); - - assert!(result.is_err(), "Expected signature verification to fail"); - - // Verify error is related to PSQ/authentication - match result.unwrap_err() { - LpError::Internal(msg) if msg.contains("PSQ") => { - // Expected - PSQ v1 responder send failed due to CredError - } - e => panic!("Unexpected error type: {:?}", e), - } - } - - #[test] - fn test_psq_state_unchanged_on_error() { - // Verify that PSQ errors leave session in clean state - let responder_session = create_handshake_test_session(12345u32, false); - - // Capture initial PSQ state (should be ResponderWaiting) - // (We can't directly access psq_state, but we can verify behavior) - - // Send corrupted data - let corrupted_message = LpMessage::Handshake(HandshakeData(vec![0xFF; 100])); - - // Process should fail - let result = responder_session.process_handshake_message(&corrupted_message); - assert!(result.is_err()); - - // After error, session should still be in handshake mode (not complete) - assert!(!responder_session.is_handshake_complete()); - - // Session should still be functional - can process valid messages - // Create a proper initiator to send valid message - let initiator_session = create_handshake_test_session(12345u32, true); - - let valid_msg = initiator_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - - // After the error, responder should still be able to process valid messages - let result2 = responder_session.process_handshake_message(&valid_msg); - - // Should succeed (session state was not corrupted by previous error) - assert!( - result2.is_ok(), - "Session should still be functional after PSQ error" - ); - } - - #[test] - fn test_transport_fails_without_psk_injection() { - // This test verifies the safety mechanism that prevents transport mode operations - // from running with the dummy PSK if PSQ injection fails or is skipped. - - // Create session but don't complete handshake (no PSK injection will occur) - let session = create_handshake_test_session(12345u32, true); - - // Verify session was created successfully - assert!(!session.is_handshake_complete()); - - // Attempt to encrypt data - should fail with PskNotInjected - let plaintext = b"test data"; - let encrypt_result = session.encrypt_data(plaintext); - - assert!( - encrypt_result.is_err(), - "encrypt_data should fail without PSK injection" - ); - match encrypt_result.unwrap_err() { - NoiseError::PskNotInjected => { - // Expected - this is the safety mechanism working - } - e => panic!("Expected PskNotInjected error, got: {:?}", e), - } - - // Create a dummy encrypted message to test decrypt - let dummy_ciphertext = LpMessage::EncryptedData(EncryptedDataPayload(vec![0u8; 48])); - - // Attempt to decrypt data - should also fail with PskNotInjected - let decrypt_result = session.decrypt_data(&dummy_ciphertext); - - assert!( - decrypt_result.is_err(), - "decrypt_data should fail without PSK injection" - ); - match decrypt_result.unwrap_err() { - NoiseError::PskNotInjected => { - // Expected - this is the safety mechanism working - } - e => panic!("Expected PskNotInjected error, got: {:?}", e), - } - } - #[test] fn test_demote_sets_read_only() { - let session = create_handshake_test_session(12345u32, true); + let sessions = SessionsMock::mock_post_handshake(12345); + let mut session = sessions.initiator; // Initially not read-only assert!(!session.is_read_only()); @@ -2318,29 +732,9 @@ mod tests { #[test] fn test_encrypt_fails_after_demotion() { - // --- Setup Handshake --- - - let initiator_session = create_handshake_test_session(12345u32, true); - let responder_session = create_handshake_test_session(12345u32, false); - - // Drive handshake to completion - let i_msg = initiator_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - responder_session.process_handshake_message(&i_msg).unwrap(); - let r_msg = responder_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - initiator_session.process_handshake_message(&r_msg).unwrap(); - let i_msg = initiator_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - responder_session.process_handshake_message(&i_msg).unwrap(); - - assert!(initiator_session.is_handshake_complete()); + let receiver_index = 12345; + let sessions = SessionsMock::mock_post_handshake(receiver_index); + let mut initiator_session = sessions.initiator; // Encryption works before demotion let plaintext = b"Hello before demotion"; @@ -2363,29 +757,10 @@ mod tests { #[test] fn test_decrypt_works_after_demotion() { // --- Setup Handshake --- - - let initiator_session = create_handshake_test_session(12345u32, true); - let responder_session = create_handshake_test_session(12345u32, false); - - // Drive handshake to completion - let i_msg = initiator_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - responder_session.process_handshake_message(&i_msg).unwrap(); - let r_msg = responder_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - initiator_session.process_handshake_message(&r_msg).unwrap(); - let i_msg = initiator_session - .prepare_handshake_message() - .unwrap() - .unwrap(); - responder_session.process_handshake_message(&i_msg).unwrap(); - - assert!(initiator_session.is_handshake_complete()); - assert!(responder_session.is_handshake_complete()); + let receiver_index = 12345; + let sessions = SessionsMock::mock_post_handshake(receiver_index); + let mut initiator_session = sessions.initiator; + let mut responder_session = sessions.responder; // Responder encrypts a message let plaintext = b"Message to demoted initiator"; diff --git a/common/nym-lp/src/session_integration/mod.rs b/common/nym-lp/src/session_integration/mod.rs index 7e52d88b9c..e72242a507 100644 --- a/common/nym-lp/src/session_integration/mod.rs +++ b/common/nym-lp/src/session_integration/mod.rs @@ -2,7 +2,7 @@ mod tests { use crate::codec::{parse_lp_packet, serialize_lp_packet}; use crate::{ - LpError, + LpError, SessionsMock, message::LpMessage, packet::{LpHeader, LpPacket, TRAILER_LEN}, session_manager::SessionManager, @@ -44,214 +44,21 @@ mod tests { #[test] fn test_full_session_flow() { // 1. Initialize session manager - let session_manager_1 = SessionManager::new(); - let session_manager_2 = SessionManager::new(); + let mut session_manager_1 = SessionManager::new(); + let mut session_manager_2 = SessionManager::new(); - // 2. Generate Ed25519 keypairs for PSQ authentication - let (a, b) = mock_peers(); + let receiver_index = 12345; + let sessions = SessionsMock::mock_post_handshake(receiver_index); - // Use fixed receiver_index for deterministic test - let receiver_index: u32 = 100001; - - // Test salt - let salt = [42u8; 32]; - - // 4. Create sessions using the pre-built Noise states - let peer_a_sm = session_manager_1 - .create_session_state_machine( - receiver_index, - true, - a.clone(), - b.as_remote(), - &salt, - version::CURRENT, - ) - .expect("Failed to create session A"); - - let peer_b_sm = session_manager_2 - .create_session_state_machine( - receiver_index, - false, - b.clone(), - a.as_remote(), - &salt, - version::CURRENT, - ) - .expect("Failed to create session B"); + // 2. Create sessions using the pre-built Noise states + let peer_a_sm = session_manager_1.create_session_state_machine(sessions.initiator); + let peer_b_sm = session_manager_2.create_session_state_machine(sessions.responder); // Verify session count assert_eq!(session_manager_1.session_count(), 1); assert_eq!(session_manager_2.session_count(), 1); - // Initialize KKT state for both sessions (test bypass) - session_manager_1 - .init_kkt_for_test(peer_a_sm, b.x25519.public_key()) - .expect("Failed to init KKT for peer A"); - session_manager_2 - .init_kkt_for_test(peer_b_sm, a.x25519.public_key()) - .expect("Failed to init KKT for peer B"); - - // 5. Simulate Noise Handshake (Sans-IO) - println!("Starting handshake simulation..."); - let mut i_msg_payload; - let mut r_msg_payload = None; - let mut rounds = 0; - const MAX_ROUNDS: usize = 10; - - // Prime initiator's first message - i_msg_payload = session_manager_1 - .prepare_handshake_message(peer_a_sm) - .transpose() - .unwrap(); - - assert!( - i_msg_payload.is_some(), - "Initiator did not produce initial message" - ); - - while rounds < MAX_ROUNDS { - rounds += 1; - let mut did_exchange = false; - - // === Initiator -> Responder === - if let Some(payload) = i_msg_payload.take() { - did_exchange = true; - println!( - " Round {}: Initiator -> Responder ({} bytes)", - rounds, - payload.len() - ); - - // A prepares packet - let counter = session_manager_1.next_counter(receiver_index).unwrap(); - let message_a_to_b = create_test_packet(1, receiver_index, counter, payload); - let mut encoded_msg = BytesMut::new(); - serialize_lp_packet(&message_a_to_b, &mut encoded_msg, None) - .expect("A serialize failed"); - - // B parses packet and checks replay - let decoded_packet = parse_lp_packet(&encoded_msg, None).expect("B parse failed"); - assert_eq!(decoded_packet.header.counter, counter); - - // Check replay before processing handshake - session_manager_2 - .receiving_counter_quick_check(peer_b_sm, decoded_packet.header.counter) - .expect("B replay check failed (A->B)"); - - match session_manager_2 - .process_handshake_message(peer_b_sm, &decoded_packet.message) - { - Ok(_) => { - // Mark counter only after successful processing - session_manager_2 - .receiving_counter_mark(peer_b_sm, decoded_packet.header.counter) - .expect("B mark counter failed"); - } - Err(e) => panic!("Responder processing failed: {:?}", e), - } - // Check if responder needs to send a reply - r_msg_payload = session_manager_2 - .prepare_handshake_message(peer_b_sm) - .transpose() - .unwrap(); - println!("{:?}", r_msg_payload); - } - - // Check completion - if session_manager_1.is_handshake_complete(peer_a_sm).unwrap() - && session_manager_2.is_handshake_complete(peer_b_sm).unwrap() - { - println!("Handshake completed after Initiator->Responder message."); - break; - } - - // === Responder -> Initiator === - if let Some(payload) = r_msg_payload.take() { - did_exchange = true; - println!( - " Round {}: Responder -> Initiator ({} bytes)", - rounds, - payload.len() - ); - - // B prepares packet - let counter = session_manager_2.next_counter(peer_b_sm).unwrap(); - let message_b_to_a = create_test_packet(1, receiver_index, counter, payload); - let mut encoded_msg = BytesMut::new(); - serialize_lp_packet(&message_b_to_a, &mut encoded_msg, None) - .expect("B serialize failed"); - - // A parses packet and checks replay - let decoded_packet = parse_lp_packet(&encoded_msg, None).expect("A parse failed"); - assert_eq!(decoded_packet.header.counter, counter); - - // Check replay before processing handshake - session_manager_1 - .receiving_counter_quick_check(peer_a_sm, decoded_packet.header.counter) - .expect("A replay check failed (B->A)"); - - match session_manager_1 - .process_handshake_message(peer_a_sm, &decoded_packet.message) - { - Ok(_) => { - // Mark counter only after successful processing - session_manager_1 - .receiving_counter_mark(peer_a_sm, decoded_packet.header.counter) - .expect("A mark counter failed"); - } - Err(e) => panic!("Initiator processing failed: {:?}", e), - } - - // Check if initiator needs to send a reply - i_msg_payload = session_manager_1 - .prepare_handshake_message(peer_a_sm) - .transpose() - .unwrap(); - } - - // println!("Initiator state: {}", session_manager_1.get_state(peer_a_sm).unwrap()); - // println!("Responder state: {}", session_manager_2.get_state(peer_b_sm).unwrap()); - - println!( - "Initiator state: {}", - session_manager_1.is_handshake_complete(peer_a_sm).unwrap() - ); - println!( - "Responder state: {}", - session_manager_2.is_handshake_complete(peer_b_sm).unwrap() - ); - - // Check completion again - if session_manager_1.is_handshake_complete(peer_a_sm).unwrap() - && session_manager_2.is_handshake_complete(peer_b_sm).unwrap() - { - println!("Handshake completed after Responder->Initiator message."); - - // Safety break if no messages were exchanged in a round - if !did_exchange { - println!("No messages exchanged in round {}, breaking.", rounds); - break; - } - } - - assert!(rounds < MAX_ROUNDS, "Handshake loop exceeded max rounds"); - } - assert!( - session_manager_1.is_handshake_complete(peer_a_sm).unwrap(), - "Initiator handshake did not complete" - ); - assert!( - session_manager_2.is_handshake_complete(peer_b_sm).unwrap(), - "Responder handshake did not complete" - ); - println!( - "Handshake simulation completed successfully in {} rounds.", - rounds - ); - - // --- Handshake Complete --- - - // 7. Simulate Data Transfer (Post-Handshake) + // 3. Simulate Data Transfer (Post-Handshake) println!("Starting data transfer simulation..."); let plaintext_a_to_b = b"Hello from A!"; @@ -328,7 +135,7 @@ mod tests { println!("Data transfer simulation completed."); - // 8. Replay Protection Test (Data Packet) + // 4. Replay Protection Test (Data Packet) println!("Testing data packet replay protection..."); // Try to replay the last message from B to A // Need to re-encode because decode consumes the buffer @@ -359,7 +166,7 @@ mod tests { ); println!("Data packet replay protection test passed."); - // 9. Test out-of-order packet reception (send counter N+1 before counter N) + // 5. Test out-of-order packet reception (send counter N+1 before counter N) println!("Testing out-of-order data packet reception..."); let counter_a_next = session_manager_1.next_counter(peer_a_sm).unwrap(); // Should be counter_a + 1 let counter_a_skip = session_manager_1.next_counter(peer_a_sm).unwrap(); // Should be counter_a + 2 @@ -405,7 +212,7 @@ mod tests { String::from_utf8_lossy(&decrypted_payload) ); - // 10. Now send the skipped counter N message (should still work) + // 6. Now send the skipped counter N message (should still work) println!("Testing delayed data packet reception..."); // Prepare data for counter_a_next (N) let plaintext_delayed = b"Delayed message"; @@ -453,7 +260,7 @@ mod tests { println!("Delayed data packet reception test passed."); - // 11. Try to replay message with counter N (should fail) + // 7. Try to replay message with counter N (should fail) println!("Testing replay of delayed packet..."); let parsed_delayed_replay = parse_lp_packet(&encoded_delayed_copy, None).expect("Parse delayed replay failed"); @@ -465,7 +272,7 @@ mod tests { "Should be a replay protection error" ); - // 12. Session removal + // 8. Session removal assert!(session_manager_1.remove_state_machine(receiver_index)); assert_eq!(session_manager_1.session_count(), 0); @@ -482,94 +289,21 @@ mod tests { #[test] fn test_bidirectional_communication() { // 1. Initialize session manager - let session_manager_1 = SessionManager::new(); - let session_manager_2 = SessionManager::new(); + let mut session_manager_1 = SessionManager::new(); + let mut session_manager_2 = SessionManager::new(); - // 2. Generate Ed25519 keypairs for PSQ authentication - let (a, b) = mock_peers(); + let receiver_index = 12345; + let sessions = SessionsMock::mock_post_handshake(receiver_index); - // Use fixed receiver_index for test - let receiver_index: u32 = 100002; + // 2. Create sessions using the pre-built Noise states + let peer_a_sm = session_manager_1.create_session_state_machine(sessions.initiator); + let peer_b_sm = session_manager_2.create_session_state_machine(sessions.responder); - // Test salt - let salt = [43u8; 32]; + // Counters after handshake + let mut counter_a = 0; // Next counter for A to send + let mut counter_b = 0; // Next counter for B to send - let peer_a_sm = session_manager_1 - .create_session_state_machine( - receiver_index, - true, - a.clone(), - b.as_remote(), - &salt, - version::CURRENT, - ) - .expect("Failed to create session A"); - - let peer_b_sm = session_manager_2 - .create_session_state_machine( - receiver_index, - false, - b.clone(), - a.as_remote(), - &salt, - version::CURRENT, - ) - .expect("Failed to create session B"); - - // Initialize KKT state for both sessions (test bypass) - session_manager_1 - .init_kkt_for_test(peer_a_sm, b.x25519.public_key()) - .expect("Failed to init KKT for peer A"); - session_manager_2 - .init_kkt_for_test(peer_b_sm, a.x25519.public_key()) - .expect("Failed to init KKT for peer B"); - - // Drive handshake to completion (simplified) - let mut i_msg = session_manager_1 - .prepare_handshake_message(peer_a_sm) - .transpose() - .unwrap() - .unwrap(); - - session_manager_2 - .process_handshake_message(peer_b_sm, &i_msg) - .unwrap(); - session_manager_2 - .receiving_counter_mark(peer_b_sm, 0) - .unwrap(); // Assume counter 0 for first msg - let r_msg = session_manager_2 - .prepare_handshake_message(peer_b_sm) - .transpose() - .unwrap() - .unwrap(); - session_manager_1 - .process_handshake_message(peer_a_sm, &r_msg) - .unwrap(); - session_manager_1 - .receiving_counter_mark(peer_a_sm, 0) - .unwrap(); // Assume counter 0 for first msg - i_msg = session_manager_1 - .prepare_handshake_message(peer_a_sm) - .transpose() - .unwrap() - .unwrap(); - - session_manager_2 - .process_handshake_message(peer_b_sm, &i_msg) - .unwrap(); - session_manager_2 - .receiving_counter_mark(peer_b_sm, 1) - .unwrap(); // Assume counter 1 for second msg from A - - assert!(session_manager_1.is_handshake_complete(peer_a_sm).unwrap()); - assert!(session_manager_2.is_handshake_complete(peer_b_sm).unwrap()); - println!("Bidirectional test: Handshake complete."); - - // Counters after handshake (A sent 2, B sent 1) - let mut counter_a = 2; // Next counter for A to send - let mut counter_b = 1; // Next counter for B to send - - // 4. Send multiple encrypted messages both ways + // 3. Send multiple encrypted messages both ways const NUM_MESSAGES: u64 = 5; for i in 0..NUM_MESSAGES { println!("Bidirectional test: Round {}", i); @@ -634,36 +368,30 @@ mod tests { // Peer A sent handshake(0), handshake(1) + 5 data packets = 7 total. Next send counter = 7. // Peer A received handshake(0) + 5 data packets = 6 total. Next expected recv counter = 6. assert_eq!( - counter_a, - 2 + NUM_MESSAGES, + counter_a, NUM_MESSAGES, "Peer A final send counter mismatch" ); assert_eq!( - total_recv_a, - 1 + NUM_MESSAGES, + total_recv_a, NUM_MESSAGES, "Peer A total received count mismatch" - ); // Received 1 handshake + 5 data + ); // Received 5 data assert_eq!( - next_recv_a, - 1 + NUM_MESSAGES, + next_recv_a, NUM_MESSAGES, "Peer A next expected receive counter mismatch" ); // Expected counter for msg from B // Peer B sent handshake(0) + 5 data packets = 6 total. Next send counter = 6. // Peer B received handshake(0), handshake(1) + 5 data packets = 7 total. Next expected recv counter = 7. assert_eq!( - counter_b, - 1 + NUM_MESSAGES, + counter_b, NUM_MESSAGES, "Peer B final send counter mismatch" ); assert_eq!( - total_recv_b, - 2 + NUM_MESSAGES, + total_recv_b, NUM_MESSAGES, "Peer B total received count mismatch" - ); // Received 2 handshake + 5 data + ); // Received 5 data assert_eq!( - next_recv_b, - 2 + NUM_MESSAGES, + next_recv_b, NUM_MESSAGES, "Peer B next expected receive counter mismatch" ); // Expected counter for msg from A @@ -674,28 +402,14 @@ mod tests { #[test] fn test_session_error_handling() { // 1. Initialize session manager - let session_manager = SessionManager::new(); + let mut session_manager = SessionManager::new(); - // Generate Ed25519 keypair for PSQ authentication - let (a, b) = mock_peers(); - - // Use fixed receiver_index for test - let receiver_index: u32 = 100003; - - // Test salt - let salt = [44u8; 32]; + let receiver_index = 123; + let session1 = SessionsMock::mock_post_handshake(receiver_index).initiator; + let session2 = SessionsMock::mock_post_handshake(124).initiator; // 2. Create a session (using real noise state) - let _session = session_manager - .create_session_state_machine( - receiver_index, - true, - a.clone(), - b.as_remote(), - &salt, - version::CURRENT, - ) - .expect("Failed to create session"); + let _session = session_manager.create_session_state_machine(session1); // 3. Try to get a non-existent session let result = session_manager.state_machine_exists(999); @@ -709,20 +423,10 @@ mod tests { ); // 5. Create and immediately remove a session - let receiver_index_temp: u32 = 100004; - let _temp_session = session_manager - .create_session_state_machine( - receiver_index_temp, - true, - a.clone(), - b.as_remote(), - &salt, - version::CURRENT, - ) - .expect("Failed to create temp session"); + let _temp_session = session_manager.create_session_state_machine(session2); assert!( - session_manager.remove_state_machine(receiver_index_temp), + session_manager.remove_state_machine(124), "Should remove the session" ); @@ -769,15 +473,8 @@ mod tests { } // Remove unused imports if SessionManager methods are no longer direct dependencies // use crate::noise_protocol::{create_noise_state, create_noise_state_responder}; - use crate::packet::version; - use crate::peer::mock_peers; use crate::state_machine::LpData; - use crate::{ - // Bring in state machine types - state_machine::{LpAction, LpInput, LpStateBare}, - // message::LpMessage, // LpMessage likely still needed for LpInput/LpAction - // packet::{LpHeader, LpPacket, TRAILER_LEN}, // LpPacket needed for LpAction/LpInput - }; + use crate::state_machine::{LpAction, LpInput, LpStateBare}; // Use Bytes for SendData input // Keep helper function for creating test packets if needed, @@ -794,309 +491,22 @@ mod tests { #[test] fn test_full_session_flow_with_process_input() { // 1. Initialize session managers - let session_manager_1 = SessionManager::new(); - let session_manager_2 = SessionManager::new(); + let mut session_manager_1 = SessionManager::new(); + let mut session_manager_2 = SessionManager::new(); - // 2. Generate Ed25519 keypairs for PSQ authentication - let (a, b) = mock_peers(); + let receiver_index = 12345; + let sessions = SessionsMock::mock_post_handshake(receiver_index); - // Use fixed receiver_index for test - let receiver_index: u32 = 100005; - - // Test salt - let salt = [45u8; 32]; - - // 3. Create sessions state machines - assert!( - session_manager_1 - .create_session_state_machine( - receiver_index, - true, - a.clone(), - b.as_remote(), - &salt, - version::CURRENT - ) // Initiator - .is_ok() - ); - assert!( - session_manager_2 - .create_session_state_machine( - receiver_index, - false, - b, - a.as_remote(), - &salt, - version::CURRENT - ) // Responder - .is_ok() - ); + // 2. Create sessions state machines + session_manager_1.create_session_state_machine(sessions.initiator); + session_manager_2.create_session_state_machine(sessions.responder); assert_eq!(session_manager_1.session_count(), 1); assert_eq!(session_manager_2.session_count(), 1); assert!(session_manager_1.state_machine_exists(receiver_index)); assert!(session_manager_2.state_machine_exists(receiver_index)); - // Verify initial states are ReadyToHandshake - assert_eq!( - session_manager_1.get_state(receiver_index).unwrap(), - LpStateBare::ReadyToHandshake - ); - assert_eq!( - session_manager_2.get_state(receiver_index).unwrap(), - LpStateBare::ReadyToHandshake - ); - - // --- 4. Simulate Noise Handshake via process_input --- - println!("Starting handshake simulation via process_input..."); - - let mut packet_a_to_b: Option; - let mut packet_b_to_a: Option; - let mut rounds = 0; - const MAX_ROUNDS: usize = 10; // KKT (2 messages) + XK handshake (3 messages) + PSQ = 6 rounds total - - // --- Round 1: Initiator Starts --- - println!(" Round {}: Initiator starts handshake", rounds); - let action_a1 = session_manager_1 - .process_input(receiver_index, LpInput::StartHandshake) - .expect("Initiator StartHandshake should produce an action") - .expect("Initiator StartHandshake failed"); - - if let LpAction::SendPacket(packet) = action_a1 { - println!(" Initiator produced SendPacket (KKT request)"); - packet_a_to_b = Some(packet); - } else { - panic!("Initiator StartHandshake did not produce SendPacket"); - } - // After StartHandshake, initiator should be in KKTExchange state (not Handshaking yet) - assert_eq!( - session_manager_1.get_state(receiver_index).unwrap(), - LpStateBare::KKTExchange, - "Initiator state wrong after StartHandshake (should be KKTExchange)" - ); - - // *** ADD THIS BLOCK for Responder StartHandshake *** - println!( - " Round {}: Responder explicitly enters KKTExchange state", - rounds - ); - let action_b_start = - session_manager_2.process_input(receiver_index, LpInput::StartHandshake); - // Responder's StartHandshake should not produce an action to send - assert!( - action_b_start.as_ref().unwrap().is_none(), - "Responder StartHandshake should produce None action, got {:?}", - action_b_start - ); - // Verify responder transitions to KKTExchange state (not Handshaking yet) - assert_eq!( - session_manager_2.get_state(receiver_index).unwrap(), - LpStateBare::KKTExchange, // Responder also enters KKTExchange state - "Responder state should be KKTExchange after its StartHandshake" - ); - // *** END OF ADDED BLOCK *** - - // --- Round 2: Responder Receives KKT Request, Sends KKT Response --- - rounds += 1; - println!( - " Round {}: Responder receives KKT request, sends KKT response", - rounds - ); - let packet_to_process = packet_a_to_b - .take() - .expect("KKT request from A was missing"); - - // Simulate network: serialize -> parse (optional but good practice) - let mut buf_a = BytesMut::new(); - serialize_lp_packet(&packet_to_process, &mut buf_a, None).unwrap(); - let parsed_packet_a = parse_lp_packet(&buf_a, None).unwrap(); - - // Responder processes KKT request - let action_b1 = session_manager_2 - .process_input(receiver_index, LpInput::ReceivePacket(parsed_packet_a)) - .expect("Responder ReceivePacket should produce an action") - .expect("Responder ReceivePacket failed"); - - if let LpAction::SendPacket(packet) = action_b1 { - println!(" Responder received KKT request, produced KKT response"); - packet_b_to_a = Some(packet); - } else { - panic!("Responder ReceivePacket did not produce SendPacket for KKT response"); - } - // Responder transitions to Handshaking after KKT completes - assert_eq!( - session_manager_2.get_state(receiver_index).unwrap(), - LpStateBare::Handshaking, - "Responder state should be Handshaking after KKT exchange" - ); - - // --- Round 3: Initiator Receives KKT Response, Sends First Noise Message (with PSQ) --- - rounds += 1; - println!( - " Round {}: Initiator receives KKT response, sends first Noise message (with PSQ)", - rounds - ); - let packet_to_process = packet_b_to_a - .take() - .expect("KKT response from B was missing"); - - // Simulate network - let mut buf_b = BytesMut::new(); - serialize_lp_packet(&packet_to_process, &mut buf_b, None).unwrap(); - let parsed_packet_b = parse_lp_packet(&buf_b, None).unwrap(); - - // Initiator processes KKT response - let action_a2 = session_manager_1 - .process_input(receiver_index, LpInput::ReceivePacket(parsed_packet_b)) - .expect("Initiator ReceivePacket should produce an action") - .expect("Initiator ReceivePacket failed"); - - match action_a2 { - LpAction::SendPacket(packet) => { - println!( - " Initiator received KKT response, produced first Noise message (-> e)" - ); - packet_a_to_b = Some(packet); - // Initiator transitions to Handshaking after KKT completes - assert_eq!( - session_manager_1.get_state(receiver_index).unwrap(), - LpStateBare::Handshaking, - "Initiator state should be Handshaking after receiving KKT response" - ); - } - LpAction::KKTComplete => { - println!( - " Initiator received KKT response, produced KKTComplete (will send Noise in next step)" - ); - // KKT completed, now need to explicitly trigger handshake message - // This might be the case if KKT completion doesn't automatically send the first Noise message - // Let's try to prepare the handshake message - if let Some(msg_result) = - session_manager_1.prepare_handshake_message(receiver_index) - { - let msg = msg_result.expect("Failed to prepare handshake message after KKT"); - // Create a packet from the message - let packet = create_test_packet(1, receiver_index, 0, msg); - packet_a_to_b = Some(packet); - println!(" Prepared first Noise message after KKTComplete"); - } else { - panic!("No handshake message available after KKT complete"); - } - } - other => { - panic!( - "Initiator ReceivePacket produced unexpected action after KKT response: {:?}", - other - ); - } - } - - // --- Round 4: Responder Receives First Noise Message, Sends Second --- - rounds += 1; - println!( - " Round {}: Responder receives first Noise message, sends second", - rounds - ); - let packet_to_process = packet_a_to_b - .take() - .expect("First Noise packet from A was missing"); - - // Simulate network - let mut buf_a2 = BytesMut::new(); - serialize_lp_packet(&packet_to_process, &mut buf_a2, None).unwrap(); - let parsed_packet_a2 = parse_lp_packet(&buf_a2, None).unwrap(); - - // Responder processes first Noise message and sends second Noise message - let action_b2 = session_manager_2 - .process_input(receiver_index, LpInput::ReceivePacket(parsed_packet_a2)) - .expect("Responder ReceivePacket should produce an action") - .expect("Responder ReceivePacket failed"); - - if let LpAction::SendPacket(packet) = action_b2 { - println!( - " Responder received first Noise message, produced second Noise message (<- e, ee, s, es)" - ); - packet_b_to_a = Some(packet); - } else { - panic!("Responder did not produce SendPacket for second Noise message"); - } - // Responder still in Handshaking, waiting for final message - assert_eq!( - session_manager_2.get_state(receiver_index).unwrap(), - LpStateBare::Handshaking, - "Responder state should still be Handshaking after sending second message" - ); - - // --- Round 5: Initiator Receives Second Noise Message, Sends Third, Completes --- - rounds += 1; - println!( - " Round {}: Initiator receives second Noise message, sends third, completes", - rounds - ); - let packet_to_process = packet_b_to_a - .take() - .expect("Second Noise packet from B was missing"); - - let mut buf_b2 = BytesMut::new(); - serialize_lp_packet(&packet_to_process, &mut buf_b2, None).unwrap(); - let parsed_packet_b2 = parse_lp_packet(&buf_b2, None).unwrap(); - - let action_a3 = session_manager_1 - .process_input(receiver_index, LpInput::ReceivePacket(parsed_packet_b2)) - .expect("Initiator ReceivePacket should produce an action") - .expect("Initiator ReceivePacket failed"); - - if let LpAction::SendPacket(packet) = action_a3 { - println!( - " Initiator received second Noise message, produced third Noise message (-> s, se)" - ); - packet_a_to_b = Some(packet); - } else { - panic!("Initiator did not produce SendPacket for third Noise message"); - } - // Initiator transitions to Transport after sending third message - assert_eq!( - session_manager_1.get_state(receiver_index).unwrap(), - LpStateBare::Transport, - "Initiator state should be Transport after sending third message" - ); - - // --- Round 6: Responder Receives Third Noise Message, Completes --- - rounds += 1; - println!( - " Round {}: Responder receives third Noise message, completes", - rounds - ); - let packet_to_process = packet_a_to_b - .take() - .expect("Third Noise packet from A was missing"); - - let mut buf_a3 = BytesMut::new(); - serialize_lp_packet(&packet_to_process, &mut buf_a3, None).unwrap(); - let parsed_packet_a3 = parse_lp_packet(&buf_a3, None).unwrap(); - - let action_b3 = session_manager_2 - .process_input(receiver_index, LpInput::ReceivePacket(parsed_packet_a3)) - .expect("Responder final ReceivePacket should produce an action") - .expect("Responder final ReceivePacket failed"); - - // Responder completes handshake - if let LpAction::HandshakeComplete = action_b3 { - println!(" Responder received third Noise message, produced HandshakeComplete"); - } else { - println!( - " Responder received third Noise message (Action: {:?})", - action_b3 - ); - } - assert_eq!( - session_manager_2.get_state(receiver_index).unwrap(), - LpStateBare::Transport, - "Responder state should be Transport after processing third message" - ); - - // --- Verification --- - assert!(rounds < MAX_ROUNDS, "Handshake took too many rounds"); + // Verify initial states are Transport assert_eq!( session_manager_1.get_state(receiver_index).unwrap(), LpStateBare::Transport @@ -1105,9 +515,8 @@ mod tests { session_manager_2.get_state(receiver_index).unwrap(), LpStateBare::Transport ); - println!("Handshake simulation completed successfully via process_input."); - // --- 5. Simulate Data Transfer via process_input --- + // --- 3. Simulate Data Transfer via process_input --- println!("Starting data transfer simulation via process_input..."); let plaintext_a_to_b = LpData::new_opaque(b"Hello from A via process_input!".to_vec()); let plaintext_b_to_a = LpData::new_opaque(b"Hello from B via process_input!".to_vec()); @@ -1185,7 +594,7 @@ mod tests { } println!("Data transfer simulation completed."); - // --- 6. Replay Protection Test --- + // --- 4. Replay Protection Test --- println!("Testing data packet replay protection via process_input..."); let replay_result = session_manager_1 .process_input(receiver_index, LpInput::ReceivePacket(data_packet_b_replay)); // Use cloned packet @@ -1199,7 +608,7 @@ mod tests { ); println!("Data packet replay protection test passed."); - // --- 7. Out-of-Order Test --- + // --- 5. Out-of-Order Test --- println!("Testing out-of-order reception via process_input..."); // A prepares N+1 then N @@ -1258,7 +667,7 @@ mod tests { ); println!("Out-of-order test passed."); - // --- 8. Close Test --- + // --- 6. Close Test --- println!("Testing close via process_input..."); // A closes @@ -1306,7 +715,7 @@ mod tests { )); println!("Close test passed."); - // --- 9. Session Removal --- + // --- 7. Session Removal --- assert!(session_manager_1.remove_state_machine(receiver_index)); assert_eq!(session_manager_1.session_count(), 0); assert!(!session_manager_1.state_machine_exists(receiver_index)); diff --git a/common/nym-lp/src/session_manager.rs b/common/nym-lp/src/session_manager.rs index 9988167164..9ddcb91d3f 100644 --- a/common/nym-lp/src/session_manager.rs +++ b/common/nym-lp/src/session_manager.rs @@ -6,11 +6,9 @@ //! This module implements session lifecycle management functionality, handling //! creation, retrieval, and storage of sessions. -use crate::noise_protocol::ReadResult; -use crate::peer::{LpLocalPeer, LpRemotePeer}; -use crate::state_machine::{LpAction, LpInput, LpState, LpStateBare}; +use crate::state_machine::{LpAction, LpInput, LpStateBare}; use crate::{LpError, LpMessage, LpSession, LpStateMachine}; -use dashmap::DashMap; +use std::collections::HashMap; /// Manages the lifecycle of Lewes Protocol sessions. /// @@ -18,7 +16,7 @@ use dashmap::DashMap; /// ensuring proper thread-safety for concurrent access. pub struct SessionManager { /// Manages state machines directly, keyed by lp_id - state_machines: DashMap, + state_machines: HashMap, } impl Default for SessionManager { @@ -31,36 +29,18 @@ impl SessionManager { /// Creates a new session manager with empty session storage. pub fn new() -> Self { Self { - state_machines: DashMap::new(), + state_machines: HashMap::new(), } } - pub fn process_input(&self, lp_id: u32, input: LpInput) -> Result, LpError> { + pub fn process_input( + &mut self, + lp_id: u32, + input: LpInput, + ) -> Result, LpError> { self.with_state_machine_mut(lp_id, |sm| sm.process_input(input).transpose())? } - pub fn add(&self, session: LpSession) -> Result<(), LpError> { - let sm = LpStateMachine { - state: LpState::ReadyToHandshake { - session: Box::new(session), - }, - }; - self.state_machines.insert(sm.id()?, sm); - Ok(()) - } - - pub fn handshaking(&self, lp_id: u32) -> Result { - Ok(self.get_state(lp_id)? == LpStateBare::Handshaking) - } - - pub fn should_initiate_handshake(&self, lp_id: u32) -> Result { - Ok(self.ready_to_handshake(lp_id)? || self.closed(lp_id)?) - } - - pub fn ready_to_handshake(&self, lp_id: u32) -> Result { - Ok(self.get_state(lp_id)? == LpStateBare::ReadyToHandshake) - } - pub fn closed(&self, lp_id: u32) -> Result { Ok(self.get_state(lp_id)? == LpStateBare::Closed) } @@ -84,38 +64,27 @@ impl SessionManager { })? } - pub fn receiving_counter_mark(&self, lp_id: u32, counter: u64) -> Result<(), LpError> { - self.with_state_machine(lp_id, |sm| sm.session()?.receiving_counter_mark(counter))? + pub fn receiving_counter_mark(&mut self, lp_id: u32, counter: u64) -> Result<(), LpError> { + self.with_state_machine_mut(lp_id, |sm| { + sm.session_mut()?.receiving_counter_mark(counter) + })? } - pub fn start_handshake(&self, lp_id: u32) -> Option> { - self.prepare_handshake_message(lp_id) + pub fn next_counter(&mut self, lp_id: u32) -> Result { + self.with_state_machine_mut(lp_id, |sm| Ok(sm.session_mut()?.next_counter()))? } - pub fn prepare_handshake_message(&self, lp_id: u32) -> Option> { - self.with_state_machine(lp_id, |sm| sm.session().ok()?.prepare_handshake_message()) - .ok()? - } - - pub fn is_handshake_complete(&self, lp_id: u32) -> Result { - self.with_state_machine(lp_id, |sm| Ok(sm.session()?.is_handshake_complete()))? - } - - pub fn next_counter(&self, lp_id: u32) -> Result { - self.with_state_machine(lp_id, |sm| Ok(sm.session()?.next_counter()))? - } - - pub fn decrypt_data(&self, lp_id: u32, message: &LpMessage) -> Result, LpError> { - self.with_state_machine(lp_id, |sm| { - sm.session()? + pub fn decrypt_data(&mut self, lp_id: u32, message: &LpMessage) -> Result, LpError> { + self.with_state_machine_mut(lp_id, |sm| { + sm.session_mut()? .decrypt_data(message) .map_err(LpError::NoiseError) })? } - pub fn encrypt_data(&self, lp_id: u32, message: &[u8]) -> Result { - self.with_state_machine(lp_id, |sm| { - sm.session()? + pub fn encrypt_data(&mut self, lp_id: u32, message: &[u8]) -> Result { + self.with_state_machine_mut(lp_id, |sm| { + sm.session_mut()? .encrypt_data(message) .map_err(LpError::NoiseError) })? @@ -125,14 +94,6 @@ impl SessionManager { self.with_state_machine(lp_id, |sm| Ok(sm.session()?.current_packet_cnt()))? } - pub fn process_handshake_message( - &self, - lp_id: u32, - message: &LpMessage, - ) -> Result { - self.with_state_machine(lp_id, |sm| sm.session()?.process_handshake_message(message))? - } - pub fn session_count(&self) -> usize { self.state_machines.len() } @@ -146,7 +107,7 @@ impl SessionManager { F: FnOnce(&LpStateMachine) -> R, { if let Some(sm) = self.state_machines.get(&lp_id) { - Ok(f(&sm)) + Ok(f(sm)) } else { Err(LpError::StateMachineNotFound { lp_id }) } @@ -154,90 +115,48 @@ impl SessionManager { } // For mutable access (like running process_input) - pub fn with_state_machine_mut(&self, lp_id: u32, f: F) -> Result + pub fn with_state_machine_mut(&mut self, lp_id: u32, f: F) -> Result where F: FnOnce(&mut LpStateMachine) -> R, // Closure takes mutable ref { - if let Some(mut sm) = self.state_machines.get_mut(&lp_id) { - Ok(f(&mut sm)) + if let Some(sm) = self.state_machines.get_mut(&lp_id) { + Ok(f(sm)) } else { Err(LpError::StateMachineNotFound { lp_id }) } } - pub fn create_session_state_machine( - &self, - receiver_index: u32, - is_initiator: bool, - local_peer: LpLocalPeer, - remote_peer: LpRemotePeer, - salt: &[u8; 32], - protocol_version: u8, - ) -> Result { - let sm = LpStateMachine::new( - receiver_index, - is_initiator, - local_peer, - remote_peer, - salt, - protocol_version, - )?; - + pub fn create_session_state_machine(&mut self, lp_session: LpSession) -> u32 { + let receiver_index = lp_session.id(); + let sm = LpStateMachine::new(lp_session); self.state_machines.insert(receiver_index, sm); - Ok(receiver_index) + receiver_index } /// Method to remove a state machine - pub fn remove_state_machine(&self, lp_id: u32) -> bool { + pub fn remove_state_machine(&mut self, lp_id: u32) -> bool { let removed = self.state_machines.remove(&lp_id); removed.is_some() } - - /// Test-only method to initialize KKT state to Completed for a session. - /// This allows integration tests to bypass KKT exchange and directly test PSQ/handshake. - #[cfg(test)] - pub fn init_kkt_for_test( - &self, - lp_id: u32, - remote_x25519_pub: &nym_crypto::asymmetric::x25519::PublicKey, - ) -> Result<(), LpError> { - self.with_state_machine(lp_id, |sm| { - sm.session()?.set_kkt_completed_for_test(remote_x25519_pub); - Ok(()) - })? - } } #[cfg(test)] mod tests { use super::*; - use crate::packet::version; - use crate::peer::{mock_peers, random_peer}; - use nym_test_utils::helpers::deterministic_rng; + use crate::{SessionsMock, mock_session_for_test}; #[test] fn test_session_manager_get() { - let manager = SessionManager::new(); - let mut rng = deterministic_rng(); - let local = random_peer(&mut rng); - let peer1 = random_peer(&mut rng); + let mut manager = SessionManager::new(); - let salt = [47u8; 32]; - let receiver_index: u32 = 1001; + let local_session = mock_session_for_test(); + let id = local_session.id(); - let sm_1_id = manager - .create_session_state_machine( - receiver_index, - true, - local, - peer1.as_remote(), - &salt, - version::CURRENT, - ) - .unwrap(); + let sm_1_id = manager.create_session_state_machine(local_session); + assert_eq!(sm_1_id, id); - let retrieved = manager.state_machine_exists(sm_1_id); + let retrieved = manager.state_machine_exists(id); assert!(retrieved); let not_found = manager.state_machine_exists(99); @@ -246,24 +165,10 @@ mod tests { #[test] fn test_session_manager_remove() { - let manager = SessionManager::new(); - let mut rng = deterministic_rng(); - let local = random_peer(&mut rng); - let peer1 = random_peer(&mut rng); + let mut manager = SessionManager::new(); + let local_session = mock_session_for_test(); - let salt = [48u8; 32]; - let receiver_index: u32 = 2002; - - let sm_1_id = manager - .create_session_state_machine( - receiver_index, - true, - local, - peer1.as_remote(), - &salt, - version::CURRENT, - ) - .unwrap(); + let sm_1_id = manager.create_session_state_machine(local_session); let removed = manager.remove_state_machine(sm_1_id); assert!(removed); @@ -275,47 +180,14 @@ mod tests { #[test] fn test_multiple_sessions() { - let manager = SessionManager::new(); - let mut rng = deterministic_rng(); - let local = random_peer(&mut rng); - let peer1 = random_peer(&mut rng); - let peer2 = random_peer(&mut rng); - let peer3 = random_peer(&mut rng); + let mut manager = SessionManager::new(); + let session1 = SessionsMock::mock_post_handshake(123).initiator; + let session2 = SessionsMock::mock_post_handshake(124).initiator; + let session3 = SessionsMock::mock_post_handshake(125).initiator; - let salt = [49u8; 32]; - - let sm_1 = manager - .create_session_state_machine( - 3001, - true, - local.clone(), - peer1.as_remote(), - &salt, - version::CURRENT, - ) - .unwrap(); - - let sm_2 = manager - .create_session_state_machine( - 3002, - true, - local.clone(), - peer2.as_remote(), - &salt, - version::CURRENT, - ) - .unwrap(); - - let sm_3 = manager - .create_session_state_machine( - 3003, - true, - local.clone(), - peer3.as_remote(), - &salt, - version::CURRENT, - ) - .unwrap(); + let sm_1 = manager.create_session_state_machine(session1); + let sm_2 = manager.create_session_state_machine(session2); + let sm_3 = manager.create_session_state_machine(session3); assert_eq!(manager.session_count(), 3); @@ -330,24 +202,11 @@ mod tests { #[test] fn test_session_manager_create_session() { - let manager = SessionManager::new(); - let (init, resp) = mock_peers(); + let mut manager = SessionManager::new(); - let salt = [50u8; 32]; - let receiver_index: u32 = 4004; - - let sm = manager.create_session_state_machine( - receiver_index, - true, - init, - resp.as_remote(), - &salt, - version::CURRENT, - ); - - assert!(sm.is_ok()); - let sm = sm.unwrap(); + let sesion = mock_session_for_test(); + let sm = manager.create_session_state_machine(sesion); assert_eq!(manager.session_count(), 1); let retrieved = manager.get_state_machine_id(sm); diff --git a/common/nym-lp/src/state_machine.rs b/common/nym-lp/src/state_machine.rs index 91fa48cbe7..7892fbf017 100644 --- a/common/nym-lp/src/state_machine.rs +++ b/common/nym-lp/src/state_machine.rs @@ -13,7 +13,6 @@ //! State machine ensures protocol steps execute in correct order. Invalid transitions //! return LpError, preventing protocol violations. -use crate::peer::{LpLocalPeer, LpRemotePeer}; use crate::{ LpError, message::{LpMessage, SubsessionKK1Data, SubsessionKK2Data, SubsessionReadyData}, @@ -23,25 +22,12 @@ use crate::{ }; use bytes::{Buf, Bytes}; use num_enum::{IntoPrimitive, TryFromPrimitive}; -use nym_kkt::ciphersuite::EncapsulationKey; use std::mem; use tracing::debug; /// Represents the possible states of the Lewes Protocol connection. #[derive(Debug, Default)] pub enum LpState { - /// Initial state: Ready to start the handshake. - /// State machine is created with keys, lp_id is derived, session is ready. - ReadyToHandshake { session: Box }, - - /// Performing KKT (KEM Key Transfer) exchange before Noise handshake. - /// Initiator requests responder's KEM public key, responder provides signed key. - KKTExchange { session: Box }, - - /// Actively performing the Noise handshake. - /// (We might be able to merge this with ReadyToHandshake if the first step always happens) - Handshaking { session: Box }, // Kept for now, logic might merge later - /// Handshake complete, ready for data transport. Transport { session: Box }, @@ -65,9 +51,6 @@ pub enum LpState { #[derive(Debug, Clone, PartialEq, Eq)] pub enum LpStateBare { - ReadyToHandshake, - KKTExchange, - Handshaking, Transport, SubsessionHandshaking, ReadOnlyTransport, @@ -78,9 +61,6 @@ pub enum LpStateBare { impl From<&LpState> for LpStateBare { fn from(state: &LpState) -> Self { match state { - LpState::ReadyToHandshake { .. } => LpStateBare::ReadyToHandshake, - LpState::KKTExchange { .. } => LpStateBare::KKTExchange, - LpState::Handshaking { .. } => LpStateBare::Handshaking, LpState::Transport { .. } => LpStateBare::Transport, LpState::SubsessionHandshaking { .. } => LpStateBare::SubsessionHandshaking, LpState::ReadOnlyTransport { .. } => LpStateBare::ReadOnlyTransport, @@ -94,8 +74,6 @@ impl From<&LpState> for LpStateBare { #[allow(clippy::large_enum_variant)] #[derive(Debug)] pub enum LpInput { - /// Explicitly trigger the start of the handshake (optional, could be implicit on creation) - StartHandshake, /// Received an LP Packet from the network. ReceivePacket(LpPacket), /// Application wants to send data (only valid in Transport state). @@ -114,10 +92,6 @@ pub enum LpAction { SendPacket(LpPacket), /// Deliver decrypted application data received from the peer. DeliverData(LpData), - /// Inform the environment that KKT exchange completed successfully. - KKTComplete, - /// Inform the environment that the handshake is complete. - HandshakeComplete, /// Inform the environment that the connection is closed. ConnectionClosed, /// Subsession KK handshake initiated by this side. @@ -215,12 +189,19 @@ impl LpStateMachine { LpStateBare::from(&self.state) } + pub fn session_mut(&mut self) -> Result<&mut LpSession, LpError> { + match &mut self.state { + LpState::Transport { session } + | LpState::SubsessionHandshaking { session, .. } + | LpState::ReadOnlyTransport { session } => Ok(session), + LpState::Closed { .. } => Err(LpError::LpSessionClosed), + LpState::Processing => Err(LpError::LpSessionProcessing), + } + } + pub fn session(&self) -> Result<&LpSession, LpError> { match &self.state { - LpState::ReadyToHandshake { session } - | LpState::KKTExchange { session } - | LpState::Handshaking { session } - | LpState::Transport { session } + LpState::Transport { session } | LpState::SubsessionHandshaking { session, .. } | LpState::ReadOnlyTransport { session } => Ok(session), LpState::Closed { .. } => Err(LpError::LpSessionClosed), @@ -233,10 +214,7 @@ impl LpStateMachine { /// ownership of the session to the caller. pub fn into_session(self) -> Result { match self.state { - LpState::ReadyToHandshake { session } - | LpState::KKTExchange { session } - | LpState::Handshaking { session } - | LpState::Transport { session } + LpState::Transport { session } | LpState::SubsessionHandshaking { session, .. } | LpState::ReadOnlyTransport { session } => Ok(*session), LpState::Closed { .. } => Err(LpError::LpSessionClosed), @@ -248,40 +226,13 @@ impl LpStateMachine { Ok(self.session()?.id()) } - /// Creates a new state machine from Ed25519 keys. - /// - /// # Arguments - /// - /// * `receiver_index` - Client-proposed session identifier (random 4 bytes) - /// * `is_initiator` - Whether this side initiates the handshake - /// * `local_peer` - This side's LP peer's keys - /// * `remote_peer` - The remote's LP peer's keys - /// * `salt` - Fresh salt for PSK derivation (must be unique per session) - /// * `protocol_version` - Protocol version to attach in all `LpPacket`s - pub fn new( - receiver_index: u32, - is_initiator: bool, - local_peer: LpLocalPeer, - remote_peer: LpRemotePeer, - salt: &[u8; 32], - protocol_version: u8, - ) -> Result { - // Create the session with both Ed25519 (for PSQ auth) and derived X25519 keys (for Noise) - // receiver_index is client-proposed, passed through directly - let session = LpSession::new( - receiver_index, - is_initiator, - local_peer, - remote_peer, - salt, - protocol_version, - )?; - - Ok(LpStateMachine { - state: LpState::ReadyToHandshake { + /// Creates a new state machine in `Transport` state post-KKT/PSQ handshake + pub fn new(session: LpSession) -> Self { + LpStateMachine { + state: LpState::Transport { session: Box::new(session), }, - }) + } } /// Creates a state machine in Transport state from a completed subsession handshake. @@ -318,258 +269,12 @@ impl LpStateMachine { // 2. Match on the owned current_state. Each arm calculates and returns the NEXT state. let next_state = match (current_state, input) { - // --- ReadyToHandshake State --- - (LpState::ReadyToHandshake { session }, LpInput::StartHandshake) => { - if session.is_initiator() { - // Initiator starts by requesting KEM key via KKT - match session.prepare_kkt_request() { - Some(Ok(kkt_message)) => { - match session.next_packet(kkt_message) { - Ok(kkt_packet) => { - result_action = Some(Ok(LpAction::SendPacket(kkt_packet))); - LpState::KKTExchange { session } // Transition to KKTExchange - } - Err(e) => { - let reason = e.to_string(); - result_action = Some(Err(e)); - LpState::Closed { reason } - } - } - } - Some(Err(e)) => { - let reason = e.to_string(); - result_action = Some(Err(e)); - LpState::Closed { reason } - } - None => { - // Should not happen for initiator - let err = LpError::Internal( - "prepare_kkt_request returned None for initiator".to_string(), - ); - let reason = err.to_string(); - result_action = Some(Err(err)); - LpState::Closed { reason } - } - } - } else { - // Responder waits for KKT request - LpState::KKTExchange { session } - // No action needed yet, result_action remains None. - } - } - - // --- KKTExchange State --- - (LpState::KKTExchange { session }, LpInput::ReceivePacket(packet)) => { - // Check if packet lp_id matches our session - if packet.header.receiver_idx() != session.id() { - result_action = Some(Err(LpError::UnknownSessionId(packet.header.receiver_idx()))); - LpState::KKTExchange { session } - } else { - - // Packet message is already parsed, match on it directly - match &packet.message { - LpMessage::KKTRequest(kkt_request) if !session.is_initiator() => { - // Responder processes KKT request - // Convert X25519 public key to KEM format for KKT response - - // Get local KEM key - match session.get_kem_key_handle() { - Err(err) => { - let reason = err.to_string(); - result_action = Some(Err(err)); - LpState::Closed { reason } - } - Ok(local_kem_psq_public) => { - // Convert to libcrux KEM public key - // V1 is X255519 - match libcrux_kem::PublicKey::decode( - libcrux_kem::Algorithm::X25519, - local_kem_psq_public.as_bytes(), - ) { - Ok(libcrux_public_key) => { - let responder_kem_pk = EncapsulationKey::X25519(libcrux_public_key); - - match session.process_kkt_request(&kkt_request.0, &responder_kem_pk) { - Ok(kkt_response_message) => { - match session.next_packet(kkt_response_message) { - Ok(response_packet) => { - result_action = Some(Ok(LpAction::SendPacket(response_packet))); - // After KKT exchange, move to Handshaking - LpState::Handshaking { session } - } - Err(e) => { - let reason = e.to_string(); - result_action = Some(Err(e)); - LpState::Closed { reason } - } - } - } - Err(e) => { - let reason = e.to_string(); - result_action = Some(Err(e)); - LpState::Closed { reason } - } - } - } - Err(e) => { - let reason = format!("Failed to convert X25519 to KEM: {:?}", e); - let err = LpError::Internal(reason.clone()); - result_action = Some(Err(err)); - LpState::Closed { reason } - } - } - }, - } - } - LpMessage::KKTResponse(kkt_response) if session.is_initiator() => { - match session.process_kkt_response(&kkt_response.0) { - Ok(()) => { - result_action = Some(Ok(LpAction::KKTComplete)); - // After successful KKT, move to Handshaking - LpState::Handshaking { session } - } - Err(e) => { - let reason = e.to_string(); - result_action = Some(Err(e)); - LpState::Closed { reason } - } - } - } - _ => { - // Wrong message type for KKT state - let err = LpError::InvalidStateTransition { - state: "KKTExchange".to_string(), - input: format!("Unexpected message type: {:?}", packet.message), - }; - let reason = err.to_string(); - result_action = Some(Err(err)); - LpState::Closed { reason } - } - } - } - } - - // Reject SendData during KKT exchange - (LpState::KKTExchange { session }, LpInput::SendData(_)) => { - result_action = Some(Err(LpError::InvalidStateTransition { - state: "KKTExchange".to_string(), - input: "SendData".to_string(), - })); - LpState::KKTExchange { session } - } - - // Reject StartHandshake if already in KKT exchange - (LpState::KKTExchange { session }, LpInput::StartHandshake) => { - result_action = Some(Err(LpError::InvalidStateTransition { - state: "KKTExchange".to_string(), - input: "StartHandshake".to_string(), - })); - LpState::KKTExchange { session } - } - - // --- Handshaking State --- - (LpState::Handshaking { session }, LpInput::ReceivePacket(packet)) => { - // Check if packet lp_id matches our session - if packet.header.receiver_idx() != session.id() { - result_action = Some(Err(LpError::UnknownSessionId(packet.header.receiver_idx()))); - // Don't change state, return the original state variant - LpState::Handshaking { session } - } else { - // --- Inline handle_handshake_packet logic --- - // 1. Check replay protection *before* processing - if let Err(e) = session.receiving_counter_quick_check(packet.header.counter) { - let _reason = e.to_string(); - result_action = Some(Err(e)); - LpState::Handshaking { session } - // LpState::Closed { reason } - } else { - // 2. Process the handshake message - match session.process_handshake_message(&packet.message) { - Ok(_) => { - // 3. Mark counter as received *after* successful processing - if let Err(e) = session.receiving_counter_mark(packet.header.counter) { - let _reason = e.to_string(); - result_action = Some(Err(e)); - // LpState::Closed { reason } - LpState::Handshaking { session } - } else { - // 4. First check if we need to send a handshake message (before checking completion) - match session.prepare_handshake_message() { - Some(Ok(message)) => { - match session.next_packet(message) { - Ok(response_packet) => { - result_action = Some(Ok(LpAction::SendPacket(response_packet))); - // Check if handshake became complete after preparing message - if session.is_handshake_complete() { - LpState::Transport { session } // Transition to Transport - } else { - LpState::Handshaking { session } // Remain Handshaking - } - } - Err(e) => { - let reason = e.to_string(); - result_action = Some(Err(e)); - LpState::Closed { reason } - } - } - } - Some(Err(e)) => { - let reason = e.to_string(); - result_action = Some(Err(e)); - LpState::Closed { reason } - } - None => { - // 5. No message to send - check if handshake is complete - if session.is_handshake_complete() { - result_action = Some(Ok(LpAction::HandshakeComplete)); - LpState::Transport { session } // Transition to Transport - } else { - // Handshake stalled unexpectedly - let err = LpError::NoiseError(NoiseError::Other( - "Handshake stalled unexpectedly".to_string(), - )); - let reason = err.to_string(); - result_action = Some(Err(err)); - LpState::Closed { reason } - } - } - } - } - } - Err(e) => { // Error from process_handshake_message - let reason = e.to_string(); - result_action = Some(Err(e)); - LpState::Closed { reason } - } - } - } - // --- End inline handle_handshake_packet logic --- - } - } - // Reject SendData during handshake - (LpState::Handshaking { session }, LpInput::SendData(_)) => { // Keep session if returning to this state - result_action = Some(Err(LpError::InvalidStateTransition { - state: "Handshaking".to_string(), - input: "SendData".to_string(), - })); - // Invalid input, remain in Handshaking state - LpState::Handshaking { session } - } - // Reject StartHandshake if already handshaking - (LpState::Handshaking { session }, LpInput::StartHandshake) => { // Keep session - result_action = Some(Err(LpError::InvalidStateTransition { - state: "Handshaking".to_string(), - input: "StartHandshake".to_string(), - })); - // Invalid input, remain in Handshaking state - LpState::Handshaking { session } - } - // --- Transport State --- - (LpState::Transport { session }, LpInput::ReceivePacket(packet)) => { + (LpState::Transport { mut session }, LpInput::ReceivePacket(packet)) => { // Check if packet lp_id matches our session if packet.header.receiver_idx() != session.id() { - result_action = Some(Err(LpError::UnknownSessionId(packet.header.receiver_idx()))); + result_action = + Some(Err(LpError::UnknownSessionId(packet.header.receiver_idx()))); LpState::Transport { session } } else { // Check message type - handle subsession initiation from peer @@ -586,12 +291,22 @@ impl LpStateMachine { // Prepare KK2 response match subsession.prepare_message() { Ok(kk2_payload) => { - let kk2_msg = LpMessage::SubsessionKK2(SubsessionKK2Data { payload: kk2_payload }); + let kk2_msg = LpMessage::SubsessionKK2( + SubsessionKK2Data { + payload: kk2_payload, + }, + ); match session.next_packet(kk2_msg) { Ok(response_packet) => { - result_action = Some(Ok(LpAction::SendPacket(response_packet))); + result_action = + Some(Ok(LpAction::SendPacket( + response_packet, + ))); // Stay in SubsessionHandshaking, wait for SubsessionReady - LpState::SubsessionHandshaking { session, subsession: Box::new(subsession) } + LpState::SubsessionHandshaking { + session, + subsession: Box::new(subsession), + } } Err(e) => { let reason = e.to_string(); @@ -624,7 +339,9 @@ impl LpStateMachine { // Normal encrypted data LpMessage::EncryptedData(_) => { // 1. Check replay protection - if let Err(e) = session.receiving_counter_quick_check(packet.header.counter) { + if let Err(e) = + session.receiving_counter_quick_check(packet.header.counter) + { result_action = Some(Err(e)); LpState::Transport { session } } else { @@ -632,16 +349,19 @@ impl LpStateMachine { match session.decrypt_data(&packet.message) { Ok(plaintext) => { // 3. Mark counter as received - if let Err(e) = session.receiving_counter_mark(packet.header.counter) { + if let Err(e) = + session.receiving_counter_mark(packet.header.counter) + { result_action = Some(Err(e)); LpState::Transport { session } } else { // 4. Deliver data - match plaintext.try_into() { + match plaintext.try_into() { Ok(data) => { - result_action = Some(Ok(LpAction::DeliverData(data))); + result_action = + Some(Ok(LpAction::DeliverData(data))); LpState::Transport { session } - }, + } Err(e) => { let reason = e.to_string(); result_action = Some(Err(e)); @@ -679,9 +399,9 @@ impl LpStateMachine { } } } - (LpState::Transport { session }, LpInput::SendData(data)) => { + (LpState::Transport { mut session }, LpInput::SendData(data)) => { // Encrypt and send application data - match self.prepare_data_packet(&session, data) { + match self.prepare_data_packet(&mut session, data) { Ok(packet) => result_action = Some(Ok(LpAction::SendPacket(packet))), Err(e) => { // If prepare fails, should we close? Let's report error and stay Transport for now. @@ -692,18 +412,9 @@ impl LpStateMachine { // Remain in transport state LpState::Transport { session } } - // Reject StartHandshake if already in transport - (LpState::Transport { session }, LpInput::StartHandshake) => { // Keep session - result_action = Some(Err(LpError::InvalidStateTransition { - state: "Transport".to_string(), - input: "StartHandshake".to_string(), - })); - // Invalid input, remain in Transport state - LpState::Transport { session } - } // --- Transport + InitiateSubsession → SubsessionHandshaking --- - (LpState::Transport { session }, LpInput::InitiateSubsession) => { + (LpState::Transport { mut session }, LpInput::InitiateSubsession) => { // Get next subsession index let subsession_index = session.next_subsession_index(); @@ -713,7 +424,9 @@ impl LpStateMachine { // Prepare KK1 message match subsession.prepare_message() { Ok(kk1_payload) => { - let kk1_msg = LpMessage::SubsessionKK1(SubsessionKK1Data { payload: kk1_payload }); + let kk1_msg = LpMessage::SubsessionKK1(SubsessionKK1Data { + payload: kk1_payload, + }); match session.next_packet(kk1_msg) { Ok(packet) => { // Emit SubsessionInitiated with packet and index @@ -721,7 +434,10 @@ impl LpStateMachine { packet, subsession_index, })); - LpState::SubsessionHandshaking { session, subsession: Box::new(subsession) } + LpState::SubsessionHandshaking { + session, + subsession: Box::new(subsession), + } } Err(e) => { let reason = e.to_string(); @@ -746,11 +462,21 @@ impl LpStateMachine { } // --- SubsessionHandshaking State --- - (LpState::SubsessionHandshaking { session, subsession }, LpInput::ReceivePacket(packet)) => { + ( + LpState::SubsessionHandshaking { + mut session, + subsession, + }, + LpInput::ReceivePacket(packet), + ) => { // Check if packet receiver_idx matches our session if packet.header.receiver_idx() != session.id() { - result_action = Some(Err(LpError::UnknownSessionId(packet.header.receiver_idx()))); - LpState::SubsessionHandshaking { session, subsession } + result_action = + Some(Err(LpError::UnknownSessionId(packet.header.receiver_idx()))); + LpState::SubsessionHandshaking { + session, + subsession, + } } else { match &packet.message { LpMessage::SubsessionKK1(kk1_data) if !subsession.is_initiator() => { @@ -761,12 +487,20 @@ impl LpStateMachine { Ok(_) => { match subsession.prepare_message() { Ok(kk2_payload) => { - let kk2_msg = LpMessage::SubsessionKK2(SubsessionKK2Data { payload: kk2_payload }); + let kk2_msg = + LpMessage::SubsessionKK2(SubsessionKK2Data { + payload: kk2_payload, + }); match session.next_packet(kk2_msg) { Ok(response_packet) => { - result_action = Some(Ok(LpAction::SendPacket(response_packet))); + result_action = Some(Ok(LpAction::SendPacket( + response_packet, + ))); // Stay in SubsessionHandshaking, wait for SubsessionReady - LpState::SubsessionHandshaking { session, subsession } + LpState::SubsessionHandshaking { + session, + subsession, + } } Err(e) => { let reason = e.to_string(); @@ -810,12 +544,24 @@ impl LpStateMachine { Ok(_) => { match new_subsession.prepare_message() { Ok(kk2_payload) => { - let kk2_msg = LpMessage::SubsessionKK2(SubsessionKK2Data { payload: kk2_payload }); + let kk2_msg = LpMessage::SubsessionKK2( + SubsessionKK2Data { + payload: kk2_payload, + }, + ); match session.next_packet(kk2_msg) { Ok(response_packet) => { - result_action = Some(Ok(LpAction::SendPacket(response_packet))); + result_action = + Some(Ok(LpAction::SendPacket( + response_packet, + ))); // Replace old initiator subsession with new responder subsession - LpState::SubsessionHandshaking { session, subsession: Box::new(new_subsession) } + LpState::SubsessionHandshaking { + session, + subsession: Box::new( + new_subsession, + ), + } } Err(e) => { let reason = e.to_string(); @@ -850,8 +596,12 @@ impl LpStateMachine { let abort_msg = LpMessage::SubsessionAbort; match session.next_packet(abort_msg) { Ok(abort_packet) => { - result_action = Some(Ok(LpAction::SendPacket(abort_packet))); - LpState::SubsessionHandshaking { session, subsession } + result_action = + Some(Ok(LpAction::SendPacket(abort_packet))); + LpState::SubsessionHandshaking { + session, + subsession, + } } Err(e) => { let reason = e.to_string(); @@ -872,16 +622,18 @@ impl LpStateMachine { session.demote(new_receiver_index); // Send SubsessionReady with new index - let ready_msg = LpMessage::SubsessionReady(SubsessionReadyData { - receiver_index: new_receiver_index, - }); + let ready_msg = + LpMessage::SubsessionReady(SubsessionReadyData { + receiver_index: new_receiver_index, + }); match session.next_packet(ready_msg) { Ok(ready_packet) => { - result_action = Some(Ok(LpAction::SubsessionComplete { - packet: Some(ready_packet), - subsession, - new_receiver_index, - })); + result_action = + Some(Ok(LpAction::SubsessionComplete { + packet: Some(ready_packet), + subsession, + new_receiver_index, + })); LpState::ReadOnlyTransport { session } } Err(e) => { @@ -893,7 +645,9 @@ impl LpStateMachine { } Ok(_) => { // Handshake not complete yet, shouldn't happen for KK - let err = LpError::Internal("Subsession handshake incomplete after KK2".to_string()); + let err = LpError::Internal( + "Subsession handshake incomplete after KK2".to_string(), + ); let reason = err.to_string(); result_action = Some(Err(err)); LpState::Closed { reason } @@ -908,24 +662,41 @@ impl LpStateMachine { LpMessage::EncryptedData(_) => { // Parent still processes normal traffic during subsession handshake // Same as Transport state handling - if let Err(e) = session.receiving_counter_quick_check(packet.header.counter) { + if let Err(e) = + session.receiving_counter_quick_check(packet.header.counter) + { result_action = Some(Err(e)); - LpState::SubsessionHandshaking { session, subsession } + LpState::SubsessionHandshaking { + session, + subsession, + } } else { match session.decrypt_data(&packet.message) { Ok(plaintext) => { - if let Err(e) = session.receiving_counter_mark(packet.header.counter) { + if let Err(e) = + session.receiving_counter_mark(packet.header.counter) + { result_action = Some(Err(e)); - LpState::SubsessionHandshaking { session, subsession } + LpState::SubsessionHandshaking { + session, + subsession, + } } else { match plaintext.try_into() { Ok(data) => { - result_action = Some(Ok(LpAction::DeliverData(data))); - LpState::SubsessionHandshaking { session, subsession } + result_action = + Some(Ok(LpAction::DeliverData(data))); + LpState::SubsessionHandshaking { + session, + subsession, + } } Err(err) => { result_action = Some(Err(err)); - LpState::SubsessionHandshaking { session, subsession } + LpState::SubsessionHandshaking { + session, + subsession, + } } } } @@ -954,7 +725,8 @@ impl LpStateMachine { } else { // Shouldn't happen - handshake should be complete after KK2 let err = LpError::Internal( - "Received SubsessionReady but handshake not complete".to_string(), + "Received SubsessionReady but handshake not complete" + .to_string(), ); let reason = err.to_string(); result_action = Some(Err(err)); @@ -975,7 +747,10 @@ impl LpStateMachine { // The winner's abort message arrived after we processed their KK1. // Silently ignore it - we're in the correct state. result_action = None; - LpState::SubsessionHandshaking { session, subsession } + LpState::SubsessionHandshaking { + session, + subsession, + } } _ => { // Wrong message type for subsession handshake @@ -992,40 +767,52 @@ impl LpStateMachine { } // Parent can still send data during subsession handshake - (LpState::SubsessionHandshaking { session, subsession }, LpInput::SendData(data)) => { - match self.prepare_data_packet(&session, data) { + ( + LpState::SubsessionHandshaking { + mut session, + subsession, + }, + LpInput::SendData(data), + ) => { + match self.prepare_data_packet(&mut session, data) { Ok(packet) => result_action = Some(Ok(LpAction::SendPacket(packet))), Err(e) => { result_action = Some(Err(e.into())); } } - LpState::SubsessionHandshaking { session, subsession } + LpState::SubsessionHandshaking { + session, + subsession, + } } // Reject other inputs during subsession handshake - (LpState::SubsessionHandshaking { session, subsession }, LpInput::StartHandshake) => { - result_action = Some(Err(LpError::InvalidStateTransition { - state: "SubsessionHandshaking".to_string(), - input: "StartHandshake".to_string(), - })); - LpState::SubsessionHandshaking { session, subsession } - } - - (LpState::SubsessionHandshaking { session, subsession }, LpInput::InitiateSubsession) => { + ( + LpState::SubsessionHandshaking { + session, + subsession, + }, + LpInput::InitiateSubsession, + ) => { result_action = Some(Err(LpError::InvalidStateTransition { state: "SubsessionHandshaking".to_string(), input: "InitiateSubsession".to_string(), })); - LpState::SubsessionHandshaking { session, subsession } + LpState::SubsessionHandshaking { + session, + subsession, + } } // --- ReadOnlyTransport State --- - (LpState::ReadOnlyTransport { session }, LpInput::ReceivePacket(packet)) => { + (LpState::ReadOnlyTransport { mut session }, LpInput::ReceivePacket(packet)) => { // Can still receive and decrypt, but state stays ReadOnlyTransport if packet.header.receiver_idx() != session.id() { - result_action = Some(Err(LpError::UnknownSessionId(packet.header.receiver_idx()))); + result_action = + Some(Err(LpError::UnknownSessionId(packet.header.receiver_idx()))); LpState::ReadOnlyTransport { session } - } else if let Err(e) = session.receiving_counter_quick_check(packet.header.counter) { + } else if let Err(e) = session.receiving_counter_quick_check(packet.header.counter) + { result_action = Some(Err(e)); LpState::ReadOnlyTransport { session } } else { @@ -1063,14 +850,6 @@ impl LpStateMachine { } // Reject other inputs in read-only mode - (LpState::ReadOnlyTransport { session }, LpInput::StartHandshake) => { - result_action = Some(Err(LpError::InvalidStateTransition { - state: "ReadOnlyTransport".to_string(), - input: "StartHandshake".to_string(), - })); - LpState::ReadOnlyTransport { session } - } - (LpState::ReadOnlyTransport { session }, LpInput::InitiateSubsession) => { result_action = Some(Err(LpError::InvalidStateTransition { state: "ReadOnlyTransport".to_string(), @@ -1081,17 +860,16 @@ impl LpStateMachine { // --- Close Transition (applies to ReadyToHandshake, KKTExchange, Handshaking, Transport, SubsessionHandshaking, ReadOnlyTransport) --- ( - LpState::ReadyToHandshake { .. } // We consume the session here - | LpState::KKTExchange { .. } - | LpState::Handshaking { .. } - | LpState::Transport { .. } + LpState::Transport { .. } | LpState::SubsessionHandshaking { .. } | LpState::ReadOnlyTransport { .. }, LpInput::Close, ) => { result_action = Some(Ok(LpAction::ConnectionClosed)); // Transition to Closed state - LpState::Closed { reason: "Closed by user".to_string() } + LpState::Closed { + reason: "Closed by user".to_string(), + } } // Ignore Close if already Closed (closed_state @ LpState::Closed { .. }, LpInput::Close) => { @@ -1147,7 +925,7 @@ impl LpStateMachine { // Kept as it doesn't mutate self.state fn prepare_data_packet( &self, - session: &LpSession, + session: &mut LpSession, data: LpData, ) -> Result { let encrypted_message = session.encrypt_data(Vec::::from(data).as_ref())?; @@ -1160,51 +938,19 @@ impl LpStateMachine { #[cfg(test)] mod tests { use super::*; - use crate::packet::version; - use crate::peer::mock_peers; + use crate::SessionsMock; #[test] fn test_state_machine_init() { - let (init, resp) = mock_peers(); + let mock_sessions = SessionsMock::mock_post_handshake(123); - // Test salt - let salt = [51u8; 32]; - - let receiver_index: u32 = 77777; - - let initiator_sm = LpStateMachine::new( - receiver_index, - true, - init.clone(), - resp.as_remote(), - &salt, - version::CURRENT, - ); - assert!(initiator_sm.is_ok()); - let initiator_sm = initiator_sm.unwrap(); - assert!(matches!( - initiator_sm.state, - LpState::ReadyToHandshake { .. } - )); + let initiator_sm = LpStateMachine::new(mock_sessions.initiator); + assert!(matches!(initiator_sm.state, LpState::Transport { .. })); let init_session = initiator_sm.session().unwrap(); - assert!(init_session.is_initiator()); - let responder_sm = LpStateMachine::new( - receiver_index, - false, - resp, - init.as_remote(), - &salt, - version::CURRENT, - ); - assert!(responder_sm.is_ok()); - let responder_sm = responder_sm.unwrap(); - assert!(matches!( - responder_sm.state, - LpState::ReadyToHandshake { .. } - )); + let responder_sm = LpStateMachine::new(mock_sessions.responder); + assert!(matches!(responder_sm.state, LpState::Transport { .. })); let resp_session = responder_sm.session().unwrap(); - assert!(!resp_session.is_initiator()); // Check both state machines use the same receiver_index assert_eq!(init_session.id(), resp_session.id()); @@ -1212,152 +958,17 @@ mod tests { #[test] fn test_state_machine_simplified_flow() { - let (init, resp) = mock_peers(); + let receiver_index: u32 = 123; + let mock_sessions = SessionsMock::mock_post_handshake(123); - // Test salt - let salt = [52u8; 32]; - let receiver_index: u32 = 88888; - - // Create state machines (already in ReadyToHandshake) - let mut initiator = LpStateMachine::new( - receiver_index, - true, // is_initiator - init.clone(), - resp.as_remote(), - &salt, - version::CURRENT, - ) - .unwrap(); - - let mut responder = LpStateMachine::new( - receiver_index, - false, // is_initiator - resp, - init.as_remote(), - &salt, - version::CURRENT, - ) - .unwrap(); + // Create state machines (already in Transport) + let mut initiator = LpStateMachine::new(mock_sessions.initiator); + let mut responder = LpStateMachine::new(mock_sessions.responder); assert_eq!(initiator.id().unwrap(), responder.id().unwrap()); - // --- KKT Exchange --- - println!("--- Step 1: Initiator starts handshake (sends KKT request) ---"); - let init_actions_1 = initiator.process_input(LpInput::StartHandshake); - let kkt_request_packet = if let Some(Ok(LpAction::SendPacket(packet))) = init_actions_1 { - packet.clone() - } else { - panic!("Initiator should send KKT request"); - }; - - assert!( - matches!(initiator.state, LpState::KKTExchange { .. }), - "Initiator should be in KKTExchange" - ); - assert_eq!( - kkt_request_packet.header.receiver_idx(), - receiver_index, - "KKT request packet has wrong receiver_index" - ); - - println!("--- Step 2: Responder starts handshake (waits for KKT) ---"); - let resp_actions_1 = responder.process_input(LpInput::StartHandshake); - assert!( - resp_actions_1.is_none(), - "Responder should produce 0 actions initially" - ); - assert!( - matches!(responder.state, LpState::KKTExchange { .. }), - "Responder should be in KKTExchange" - ); - - println!("--- Step 3: Responder receives KKT request, sends KKT response ---"); - let resp_actions_2 = responder.process_input(LpInput::ReceivePacket(kkt_request_packet)); - let kkt_response_packet = if let Some(Ok(LpAction::SendPacket(packet))) = resp_actions_2 { - packet.clone() - } else { - panic!("Responder should send KKT response"); - }; - assert!( - matches!(responder.state, LpState::Handshaking { .. }), - "Responder should be Handshaking after KKT" - ); - - println!("--- Step 4: Initiator receives KKT response (KKT complete) ---"); - let init_actions_2 = initiator.process_input(LpInput::ReceivePacket(kkt_response_packet)); - assert!( - matches!(init_actions_2, Some(Ok(LpAction::KKTComplete))), - "Initiator should signal KKT complete" - ); - assert!( - matches!(initiator.state, LpState::Handshaking { .. }), - "Initiator should be Handshaking after KKT" - ); - - // --- Noise Handshake Message Exchange --- - println!("--- Step 5: Responder receives Noise msg 1, sends Noise msg 2 ---"); - // Now both sides are in Handshaking, continue with Noise handshake - // Initiator needs to send first Noise message - // (In real flow, this might happen automatically or via another process_input call) - // For this test, we'll simulate the responder receiving the first Noise message - // Actually, let me check if initiator automatically sends the first Noise message... - // Looking at the old test, it seems packet 1 was the first Noise message. - // With KKT, we need the initiator to send the first Noise message now. - - // Initiator prepares and sends first Noise handshake message - let init_noise_msg = initiator.session().unwrap().prepare_handshake_message(); - let init_packet_1 = if let Some(Ok(msg)) = init_noise_msg { - initiator.session().unwrap().next_packet(msg).unwrap() - } else { - panic!("Initiator should have first Noise message"); - }; - - let resp_actions_3 = responder.process_input(LpInput::ReceivePacket(init_packet_1)); - let resp_packet_2 = if let Some(Ok(LpAction::SendPacket(packet))) = resp_actions_3 { - packet.clone() - } else { - panic!("Responder should send packet 2"); - }; - assert!( - matches!(responder.state, LpState::Handshaking { .. }), - "Responder still Handshaking" - ); - assert_eq!( - resp_packet_2.header.receiver_idx(), - receiver_index, - "Packet 2 has wrong receiver_index" - ); - - println!("--- Step 6: Initiator receives Noise msg 2, sends Noise msg 3 ---"); - let init_actions_3 = initiator.process_input(LpInput::ReceivePacket(resp_packet_2)); - let init_packet_3 = if let Some(Ok(LpAction::SendPacket(packet))) = init_actions_3 { - packet.clone() - } else { - panic!("Initiator should send Noise packet 3"); - }; - assert!( - matches!(initiator.state, LpState::Transport { .. }), - "Initiator should be Transport" - ); - assert_eq!( - init_packet_3.header.receiver_idx(), - receiver_index, - "Noise packet 3 has wrong receiver_index" - ); - - println!("--- Step 7: Responder receives Noise msg 3, completes handshake ---"); - let resp_actions_4 = responder.process_input(LpInput::ReceivePacket(init_packet_3)); - assert!( - matches!(resp_actions_4, Some(Ok(LpAction::HandshakeComplete))), - "Responder should complete handshake" - ); - assert!( - matches!(responder.state, LpState::Transport { .. }), - "Responder should be Transport" - ); - // --- Transport Phase --- - println!("--- Step 8: Initiator sends data ---"); + println!("--- Step 1: Initiator sends data ---"); let data_to_send_1 = LpData::new_opaque(b"hello responder".to_vec()); let init_actions_4 = initiator.process_input(LpInput::SendData(data_to_send_1.clone())); let data_packet_1 = if let Some(Ok(LpAction::SendPacket(packet))) = init_actions_4 { @@ -1367,7 +978,7 @@ mod tests { }; assert_eq!(data_packet_1.header.receiver_idx(), receiver_index); - println!("--- Step 9: Responder receives data ---"); + println!("--- Step 2: Responder receives data ---"); let resp_actions_5 = responder.process_input(LpInput::ReceivePacket(data_packet_1)); let resp_data_1 = if let Some(Ok(LpAction::DeliverData(data))) = resp_actions_5 { data @@ -1376,7 +987,7 @@ mod tests { }; assert_eq!(resp_data_1, data_to_send_1); - println!("--- Step 10: Responder sends data ---"); + println!("--- Step 3: Responder sends data ---"); let data_to_send_2 = LpData::new_opaque(b"hello initiator".to_vec()); let resp_actions_6 = responder.process_input(LpInput::SendData(data_to_send_2.clone())); let data_packet_2 = if let Some(Ok(LpAction::SendPacket(packet))) = resp_actions_6 { @@ -1386,7 +997,7 @@ mod tests { }; assert_eq!(data_packet_2.header.receiver_idx(), receiver_index); - println!("--- Step 11: Initiator receives data ---"); + println!("--- Step 4: Initiator receives data ---"); let init_actions_5 = initiator.process_input(LpInput::ReceivePacket(data_packet_2)); if let Some(Ok(LpAction::DeliverData(data))) = init_actions_5 { assert_eq!(data, data_to_send_2); @@ -1395,7 +1006,7 @@ mod tests { } // --- Close --- - println!("--- Step 12: Initiator closes ---"); + println!("--- Step 5: Initiator closes ---"); let init_actions_6 = initiator.process_input(LpInput::Close); assert!(matches!( init_actions_6, @@ -1403,7 +1014,7 @@ mod tests { )); assert!(matches!(initiator.state, LpState::Closed { .. })); - println!("--- Step 13: Responder closes ---"); + println!("--- Step 6: Responder closes ---"); let resp_actions_7 = responder.process_input(LpInput::Close); assert!(matches!( resp_actions_7, @@ -1412,277 +1023,14 @@ mod tests { assert!(matches!(responder.state, LpState::Closed { .. })); } - #[test] - fn test_kkt_exchange_initiator_flow() { - let (init, resp) = mock_peers(); - - let salt = [53u8; 32]; - let receiver_index: u32 = 99901; - - // Create initiator state machine - let mut initiator = LpStateMachine::new( - receiver_index, - true, - init, - resp.as_remote(), - &salt, - version::CURRENT, - ) - .unwrap(); - - // Verify initial state - assert!(matches!(initiator.state, LpState::ReadyToHandshake { .. })); - - // Step 1: Initiator starts handshake (should send KKT request) - let init_action = initiator.process_input(LpInput::StartHandshake); - assert!(matches!(init_action, Some(Ok(LpAction::SendPacket(_))))); - assert!(matches!(initiator.state, LpState::KKTExchange { .. })); - } - - #[test] - fn test_kkt_exchange_responder_flow() { - let (init, resp) = mock_peers(); - - let salt = [54u8; 32]; - let receiver_index: u32 = 99902; - - // Create responder state machine - let mut responder = LpStateMachine::new( - receiver_index, - false, - resp, - init.as_remote(), - &salt, - version::CURRENT, - ) - .unwrap(); - - // Verify initial state - assert!(matches!(responder.state, LpState::ReadyToHandshake { .. })); - - // Step 1: Responder starts handshake (should transition to KKTExchange without sending) - let resp_action = responder.process_input(LpInput::StartHandshake); - assert!(resp_action.is_none()); - assert!(matches!(responder.state, LpState::KKTExchange { .. })); - } - - #[test] - fn test_kkt_exchange_full_roundtrip() { - // Ed25519 keypairs for PSQ authentication and X25519 derivation - let (init, resp) = mock_peers(); - - let salt = [55u8; 32]; - let receiver_index: u32 = 99903; - - // Create both state machines - let mut initiator = LpStateMachine::new( - receiver_index, - true, - init.clone(), - resp.as_remote(), - &salt, - version::CURRENT, - ) - .unwrap(); - - let mut responder = LpStateMachine::new( - receiver_index, - false, - resp, - init.as_remote(), - &salt, - version::CURRENT, - ) - .unwrap(); - - // Step 1: Initiator starts handshake, sends KKT request - let init_action = initiator.process_input(LpInput::StartHandshake); - let kkt_request_packet = if let Some(Ok(LpAction::SendPacket(packet))) = init_action { - packet.clone() - } else { - panic!("Initiator should send KKT request"); - }; - assert!(matches!(initiator.state, LpState::KKTExchange { .. })); - - // Step 2: Responder transitions to KKTExchange - let resp_action = responder.process_input(LpInput::StartHandshake); - assert!(resp_action.is_none()); - assert!(matches!(responder.state, LpState::KKTExchange { .. })); - - // Step 3: Responder receives KKT request, sends KKT response - let resp_action = responder.process_input(LpInput::ReceivePacket(kkt_request_packet)); - let kkt_response_packet = if let Some(Ok(LpAction::SendPacket(packet))) = resp_action { - packet.clone() - } else { - panic!("Responder should send KKT response"); - }; - // After sending KKT response, responder moves to Handshaking - assert!(matches!(responder.state, LpState::Handshaking { .. })); - - // Step 4: Initiator receives KKT response, completes KKT - let init_action = initiator.process_input(LpInput::ReceivePacket(kkt_response_packet)); - - assert!(matches!(init_action, Some(Ok(LpAction::KKTComplete)))); - // After KKT complete, initiator moves to Handshaking - assert!(matches!(initiator.state, LpState::Handshaking { .. })); - } - - #[test] - fn test_kkt_exchange_close() { - let (init, resp) = mock_peers(); - - let salt = [56u8; 32]; - let receiver_index: u32 = 99904; - - // Create initiator state machine - let mut initiator = LpStateMachine::new( - receiver_index, - true, - init.clone(), - resp.as_remote(), - &salt, - version::CURRENT, - ) - .unwrap(); - - // Start handshake to enter KKTExchange state - initiator.process_input(LpInput::StartHandshake); - assert!(matches!(initiator.state, LpState::KKTExchange { .. })); - - // Close during KKT exchange - let close_action = initiator.process_input(LpInput::Close); - assert!(matches!(close_action, Some(Ok(LpAction::ConnectionClosed)))); - assert!(matches!(initiator.state, LpState::Closed { .. })); - } - - #[test] - fn test_kkt_exchange_rejects_invalid_inputs() { - let (init, resp) = mock_peers(); - - let salt = [57u8; 32]; - let receiver_index: u32 = 99905; - - // Create initiator state machine - let mut initiator = LpStateMachine::new( - receiver_index, - true, - init.clone(), - resp.as_remote(), - &salt, - version::CURRENT, - ) - .unwrap(); - - // Start handshake to enter KKTExchange state - initiator.process_input(LpInput::StartHandshake); - assert!(matches!(initiator.state, LpState::KKTExchange { .. })); - - // Try SendData during KKT exchange (should be rejected) - let send_data = LpData::new_opaque(vec![1, 2, 3]); - let send_action = initiator.process_input(LpInput::SendData(send_data)); - assert!(matches!( - send_action, - Some(Err(LpError::InvalidStateTransition { .. })) - )); - assert!(matches!(initiator.state, LpState::KKTExchange { .. })); // Still in KKTExchange - - // Try StartHandshake again during KKT exchange (should be rejected) - let start_action = initiator.process_input(LpInput::StartHandshake); - assert!(matches!( - start_action, - Some(Err(LpError::InvalidStateTransition { .. })) - )); - assert!(matches!(initiator.state, LpState::KKTExchange { .. })); // Still in KKTExchange - } - /// Helper function to complete a full handshake between initiator and responder, /// returning both in Transport state ready for subsession testing. fn setup_transport_sessions() -> (LpStateMachine, LpStateMachine) { - let (a, b) = mock_peers(); - - let salt = [60u8; 32]; - let receiver_index: u32 = 111111; - - // Create state machines - Alice is initiator, Bob is responder - let mut alice = LpStateMachine::new( - receiver_index, - true, - a.clone(), - b.as_remote(), - &salt, - version::CURRENT, + let sessions = SessionsMock::mock_post_handshake(12345); + ( + LpStateMachine::new(sessions.initiator), + LpStateMachine::new(sessions.responder), ) - .unwrap(); - - let mut bob = LpStateMachine::new( - receiver_index, - false, - b, - a.as_remote(), - &salt, - version::CURRENT, - ) - .unwrap(); - - // --- Complete KKT Exchange --- - // Alice starts handshake - let kkt_request = if let Some(Ok(LpAction::SendPacket(p))) = - alice.process_input(LpInput::StartHandshake) - { - p - } else { - panic!("Alice should send KKT request"); - }; - - // Bob starts handshake - let _ = bob.process_input(LpInput::StartHandshake); - - // Bob receives KKT request, sends response - let kkt_response = if let Some(Ok(LpAction::SendPacket(p))) = - bob.process_input(LpInput::ReceivePacket(kkt_request)) - { - p - } else { - panic!("Bob should send KKT response"); - }; - - // Alice receives KKT response - let _ = alice.process_input(LpInput::ReceivePacket(kkt_response)); - - // --- Complete Noise Handshake --- - // Alice prepares first Noise message - let noise1_msg = alice - .session() - .unwrap() - .prepare_handshake_message() - .unwrap() - .unwrap(); - let noise1_packet = alice.session().unwrap().next_packet(noise1_msg).unwrap(); - - // Bob receives noise1, sends noise2 - let noise2_packet = if let Some(Ok(LpAction::SendPacket(p))) = - bob.process_input(LpInput::ReceivePacket(noise1_packet)) - { - p - } else { - panic!("Bob should send Noise packet 2"); - }; - - // Alice receives noise2, sends noise3 - let noise3_packet = if let Some(Ok(LpAction::SendPacket(p))) = - alice.process_input(LpInput::ReceivePacket(noise2_packet)) - { - p - } else { - panic!("Alice should send Noise packet 3"); - }; - assert!(matches!(alice.state, LpState::Transport { .. })); - - // Bob receives noise3, completes handshake - let _ = bob.process_input(LpInput::ReceivePacket(noise3_packet)); - assert!(matches!(bob.state, LpState::Transport { .. })); - - (alice, bob) } #[test] diff --git a/common/test-utils/Cargo.toml b/common/test-utils/Cargo.toml index f89073afc7..ab509eb8f9 100644 --- a/common/test-utils/Cargo.toml +++ b/common/test-utils/Cargo.toml @@ -18,7 +18,7 @@ rand_chacha = { workspace = true } tokio = { workspace = true, features = ["sync", "time", "rt"] } tracing = { workspace = true } -nym-bin-common = { workspace = true, features = ["tracing"] } +nym-bin-common = { workspace = true, features = ["basic_tracing"] } [dev-dependencies] tokio = { workspace = true, features = ["full"] } diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index e912053e34..ca508afdac 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -95,6 +95,7 @@ nym-gateway-storage = { workspace = true, features = ["mock"] } nym-wireguard = { workspace = true, features = ["mock"] } mock_instant = { workspace = true } time = { workspace = true } +nym-lp = { path = "../common/nym-lp", features = ["mock"] } [lints] workspace = true diff --git a/gateway/src/node/lp_listener/data_handler.rs b/gateway/src/node/lp_listener/data_handler.rs index 2b2ce11c64..cbeb46b058 100644 --- a/gateway/src/node/lp_listener/data_handler.rs +++ b/gateway/src/node/lp_listener/data_handler.rs @@ -155,14 +155,11 @@ impl LpDataHandler { .value() .state .session() - .map_err(|e| GatewayError::LpProtocolError(format!("Session error: {}", e)))? - .outer_aead_key() - .ok_or_else(|| { - GatewayError::LpProtocolError("Session has no outer AEAD key".to_string()) - })?; + .map_err(|e| GatewayError::LpProtocolError(format!("Session error: {e}")))? + .outer_aead_key(); // Parse full packet with outer AEAD decryption - let lp_packet = nym_lp::codec::parse_lp_packet(packet, Some(&outer_key)).map_err(|e| { + let lp_packet = nym_lp::codec::parse_lp_packet(packet, Some(outer_key)).map_err(|e| { inc!("lp_data_decrypt_errors"); GatewayError::LpProtocolError(format!("Failed to decrypt LP packet: {}", e)) })?; diff --git a/gateway/src/node/lp_listener/handler.rs b/gateway/src/node/lp_listener/handler.rs index c29f9298f1..c65efc8443 100644 --- a/gateway/src/node/lp_listener/handler.rs +++ b/gateway/src/node/lp_listener/handler.rs @@ -1,20 +1,21 @@ // Copyright 2025 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use super::{LpHandlerState, ReceiverIndex}; +use super::{LpHandlerState, ReceiverIndex, TimestampedState}; use crate::error::GatewayError; +use bytes::BytesMut; use nym_crypto::asymmetric::{ed25519, x25519}; +use nym_lp::codec::serialize_lp_packet; use nym_lp::state_machine::{LpAction, LpData, LpDataKind, LpInput}; use nym_lp::{ - codec::OuterAeadKey, message::ForwardPacketData, packet::LpHeader, LpMessage, LpPacket, - OuterHeader, + message::ForwardPacketData, LpMessage, LpPacket, LpSession, LpStateMachine, OuterHeader, }; use nym_lp_transport::traits::LpTransport; use nym_metrics::{add_histogram_obs, inc}; use nym_registration_common::{LpRegistrationRequest, RegistrationStatus}; use std::net::SocketAddr; use std::time::Duration; -use tokio::io::{AsyncReadExt, AsyncWriteExt}; +use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; use tokio::net::TcpStream; use tokio::time::timeout; use tracing::*; @@ -79,6 +80,7 @@ pub struct LpConnectionHandler { remote_addr: SocketAddr, state: LpHandlerState, stats: ConnectionStats, + /// Bound receiver_idx for this connection (set after first packet). /// All subsequent packets on this connection must use this receiver_idx. /// Set from ClientHello's proposed receiver_index, or from header for non-bootstrap packets. @@ -92,7 +94,7 @@ pub struct LpConnectionHandler { impl LpConnectionHandler where - S: LpTransport + Unpin, + S: LpTransport + AsyncRead + AsyncWrite + Unpin, { pub fn new(stream: S, remote_addr: SocketAddr, state: LpHandlerState) -> Self { Self { @@ -122,6 +124,49 @@ where // State persists in LpHandlerState maps across packets // ============================================================ + // 1. complete KKT/PSQ handshake before doing anything else. + // bail if it takes too long + let timeout = self.state.lp_config.debug.handshake_ttl; + let local_peer = self.state.local_lp_peer.clone(); + let stream = &mut self.stream; + + // TODO: + let ciphersuite = LpSession::default_ciphersuite(); + let session = match tokio::time::timeout(timeout, async move { + LpSession::psq_handshake_responder(stream, ciphersuite, local_peer) + .complete_as_responder() + .await + }) + .await + { + Err(_timeout) => { + debug!( + "timed out attempting to complete KTT/PSQ handshake with {}", + self.remote_addr + ); + self.emit_lifecycle_metrics(false); + return Ok(()); + } + Ok(Err(handshake_failure)) => { + debug!( + "failed to complete KKT/PSQ handshake with {}: {handshake_failure}", + self.remote_addr + ); + self.emit_lifecycle_metrics(false); + return Ok(()); + } + Ok(Ok(session)) => session, + }; + let receiver_idx = session.id(); + + // 2. insert the state machine into the shared state + let state_machine = LpStateMachine::new(session); + self.state + .session_states + .insert(receiver_idx, TimestampedState::new(state_machine)); + self.bound_receiver_idx = Some(receiver_idx); + + // 3. handle any new incoming packet loop { // Step 1: Receive raw packet bytes and parse header only (for routing) let (raw_bytes, header) = match self.receive_raw_packet().await { @@ -140,9 +185,8 @@ where let receiver_idx = header.receiver_idx; - // Step 2: Validate or set binding (session-affine connection) - // Note: ClientHello (receiver_idx=0) defers binding to handle_client_hello() - if let Err(e) = self.validate_or_set_binding(receiver_idx) { + // Step 2: Validate the binding + if let Err(e) = self.validate_binding(receiver_idx) { self.emit_lifecycle_metrics(false); return Err(e); } @@ -158,6 +202,14 @@ where Ok(()) } + fn bound_receiver_index(&self) -> Result { + self.bound_receiver_idx.ok_or_else(|| { + GatewayError::LpProtocolError( + "missing bound receiver index after KKT/PSQ handshake".into(), + ) + }) + } + /// Check if an error indicates the connection was closed (EOF). /// AIDEV-NOTE: Uses string matching on error messages. Tokio's read_exact /// returns UnexpectedEof which gets formatted into the error message. @@ -172,43 +224,28 @@ where } } - /// Validate that the receiver_idx matches the bound session, or set binding if first packet. + /// Validate that the receiver_idx matches the bound session. /// /// Binding rules: /// - ClientHello (receiver_idx=0): binding deferred to handle_client_hello() which /// extracts receiver_index from payload /// - First non-bootstrap packet: sets binding from header's receiver_idx /// - Subsequent packets: must match bound receiver_idx - fn validate_or_set_binding(&mut self, receiver_idx: u32) -> Result<(), GatewayError> { - match self.bound_receiver_idx { - None => { - // First packet - don't bind if bootstrap (handle_client_hello sets binding) - if receiver_idx != nym_lp::BOOTSTRAP_RECEIVER_IDX { - self.bound_receiver_idx = Some(receiver_idx); - trace!( - "Bound connection from {} to receiver_idx={}", - self.remote_addr, - receiver_idx - ); - } - Ok(()) - } - Some(bound) => { - if receiver_idx == bound { - Ok(()) - } else { - warn!( - "Receiver_idx mismatch from {}: expected {}, got {}", - self.remote_addr, bound, receiver_idx - ); - inc!("lp_errors_receiver_idx_mismatch"); - Err(GatewayError::LpProtocolError(format!( - "receiver_idx mismatch: connection bound to {}, packet has {}", - bound, receiver_idx - ))) - } - } + fn validate_binding(&self, receiver_idx: u32) -> Result<(), GatewayError> { + let bound_receiver_idx = self.bound_receiver_index()?; + + if bound_receiver_idx != receiver_idx { + warn!( + "Receiver_idx mismatch from {}: expected {bound_receiver_idx}, got {receiver_idx}", + self.remote_addr + ); + inc!("lp_errors_receiver_idx_mismatch"); + return Err(GatewayError::LpProtocolError(format!( + "receiver_idx mismatch: connection bound to {bound_receiver_idx}, packet has {receiver_idx}", + ))); } + + Ok(()) } /// Process a single packet: lookup session, parse, route to handler. @@ -220,287 +257,35 @@ where ) -> Result<(), GatewayError> { // Get outer_aead_key based on receiver_idx // Header is always cleartext for routing. Payload is encrypted after PSK. - let outer_key: Option = if receiver_idx == nym_lp::BOOTSTRAP_RECEIVER_IDX { - // ClientHello - no encryption (PSK not yet derived) - None - } else if let Some(state_entry) = self.state.handshake_states.get(&receiver_idx) { - // Handshake in progress - check if PSK has been injected yet - state_entry - .value() - .state - .session() - .ok() - .and_then(|session| session.outer_aead_key()) - } else if let Some(session_entry) = self.state.session_states.get(&receiver_idx) { - // Established session - should always have PSK - session_entry - .value() - .state - .session() - .ok() - .and_then(|s| s.outer_aead_key()) - } else { - // Unknown session - will error during routing, parse cleartext - None + let Some(state_machine) = self.state.session_states.get(&receiver_idx) else { + // session might have gotten removed due to inactivity + return Err(GatewayError::LpConnectionError(format!( + "missing session state for {receiver_idx} - has it been removed due to inactivity?" + ))); }; + let outer_key = state_machine + .state + .session() + .map_err(|err| GatewayError::LpProtocolError(err.to_string()))? + .outer_aead_key(); + // Parse full packet with outer AEAD key - let packet = - nym_lp::codec::parse_lp_packet(&raw_bytes, outer_key.as_ref()).map_err(|e| { - inc!("lp_errors_parse_packet"); - GatewayError::LpProtocolError(format!("Failed to parse LP packet: {}", e)) - })?; + let packet = nym_lp::codec::parse_lp_packet(&raw_bytes, Some(outer_key)).map_err(|e| { + inc!("lp_errors_parse_packet"); + GatewayError::LpProtocolError(format!("Failed to parse LP packet: {e}")) + })?; + + drop(state_machine); trace!( - "Received packet from {} (receiver_idx={}, counter={}, encrypted={})", + "Received packet from {} (receiver_idx={}, counter={})", self.remote_addr, receiver_idx, packet.header().counter, - outer_key.is_some() ); - // Route packet based on receiver_idx - if receiver_idx == nym_lp::BOOTSTRAP_RECEIVER_IDX { - // ClientHello - first packet in handshake - self.handle_client_hello(packet).await - } else { - // Check if this is an in-progress handshake or established session - if self.state.handshake_states.contains_key(&receiver_idx) { - // Handshake in progress - self.handle_handshake_packet(receiver_idx, packet).await - } else if self.state.session_states.contains_key(&receiver_idx) { - // Established session - transport mode - self.handle_transport_packet(receiver_idx, packet).await - } else { - // Unknown session - possibly stale or client error - warn!( - "Received packet for unknown session {} from {}", - receiver_idx, self.remote_addr - ); - inc!("lp_errors_unknown_session"); - Err(GatewayError::LpProtocolError(format!( - "Unknown session ID: {}", - receiver_idx - ))) - } - } - } - - /// Handle ClientHello packet (receiver_idx=0, first packet) - async fn handle_client_hello(&mut self, packet: LpPacket) -> Result<(), GatewayError> { - use nym_lp::packet::LpHeader; - use nym_lp::state_machine::{LpInput, LpStateMachine}; - let remote = self.remote_addr; - - // if we managed to parse out the header, i.e. we have code supporting whatever - // protocol version has been sent - use that one instead - let protocol_version = packet.header().protocol_version; - - // Extract ClientHello data - let hello_data = match packet.message() { - LpMessage::ClientHello(hello_data) => hello_data, - other => { - inc!("lp_client_hello_failed"); - return Err(GatewayError::LpProtocolError(format!( - "Expected ClientHello, got {other}", - ))); - } - }; - - // Validate timestamp - let timestamp = hello_data.extract_timestamp(); - Self::validate_timestamp(timestamp, self.state.lp_config.debug.timestamp_tolerance)?; - - // Extract client-proposed receiver_index - let receiver_index = hello_data.receiver_index; - - // let client_ed25519_pubkey = hello_data.client_ed25519_public_key; - - debug!("Processing ClientHello from {remote} (proposed receiver_index={receiver_index})",); - - // Collision check for client-proposed receiver_index - // Check both handshake_states (in-progress) and session_states (established) - if self.state.handshake_states.contains_key(&receiver_index) - || self.state.session_states.contains_key(&receiver_index) - { - warn!("Receiver index collision: {receiver_index} from {remote}",); - inc!("lp_receiver_index_collision"); - - // Send Collision response to tell client to retry with new receiver_index - // No outer key - this is before PSK derivation - // Note: Do NOT set binding on collision - client may retry with new receiver_index - let collision_packet = LpPacket::new( - LpHeader::new(receiver_index, 0, protocol_version), - LpMessage::Collision, - ); - self.send_lp_packet(collision_packet, None).await?; - - return Ok(()); - } - - // Collision check passed - bind this connection to the receiver_index - // All subsequent packets on this connection must use this receiver_index - self.bound_receiver_idx = Some(receiver_index); - trace!("Bound connection from {remote} to receiver_idx={receiver_index} (via ClientHello)",); - - // Create state machine for this handshake using client-proposed receiver_index - let mut state_machine = LpStateMachine::new( - receiver_index, - false, // responder - self.state.local_lp_peer.clone(), - hello_data.to_remote_peer(), - &hello_data.salt, - protocol_version, - ) - .map_err(|e| { - inc!("lp_client_hello_failed"); - GatewayError::LpHandshakeError(format!("Failed to create state machine: {}", e)) - })?; - - debug!("Created handshake state for {remote} (receiver_index={receiver_index})",); - - // Transition state machine to KKTExchange (responder waits for client's KKT request) - // For responder, StartHandshake returns None (just transitions state) - // For initiator, StartHandshake returns SendPacket (KKT request) - if let Some(Err(e)) = state_machine.process_input(LpInput::StartHandshake) { - inc!("lp_client_hello_failed"); - return Err(GatewayError::LpHandshakeError(format!( - "StartHandshake failed: {e}", - ))); - // Responder (gateway) gets Ok but no packet to send - we just wait for client's next packet - } - - // Store state machine for subsequent handshake packets (KKT request with receiver_index=X) - self.state - .handshake_states - .insert(receiver_index, super::TimestampedState::new(state_machine)); - - debug!( - "Stored handshake state for {remote} (receiver_index={receiver_index}) - waiting for KKT request", - ); - - // Send Ack to confirm ClientHello received - // No outer key - this is before PSK derivation - let ack_packet = LpPacket::new( - LpHeader::new(receiver_index, 0, protocol_version), - LpMessage::Ack, - ); - self.send_lp_packet(ack_packet, None).await?; - - Ok(()) - } - - /// Handle handshake packet (receiver_idx!=0, handshake not complete) - async fn handle_handshake_packet( - &mut self, - receiver_idx: u32, - packet: LpPacket, - ) -> Result<(), GatewayError> { - debug!( - "Processing handshake packet from {} (receiver_idx={})", - self.remote_addr, receiver_idx - ); - - // Get mutable reference to state machine - let mut state_entry = self - .state - .handshake_states - .get_mut(&receiver_idx) - .ok_or_else(|| { - GatewayError::LpProtocolError(format!( - "Handshake state not found for session {}", - receiver_idx - )) - })?; - - let state_machine = &mut state_entry.value_mut().state; - - // Process packet through state machine - let action = state_machine - .process_input(LpInput::ReceivePacket(packet)) - .ok_or_else(|| { - GatewayError::LpHandshakeError("State machine returned no action".to_string()) - })? - .map_err(|e| GatewayError::LpHandshakeError(format!("Handshake error: {}", e)))?; - - // Get outer_aead_key from session (if PSK has been derived) - // PSK is derived after Noise msg 1 processing, so msg 2+ are encrypted - let should_send = match action { - LpAction::SendPacket(response_packet) => { - // Get key before dropping borrow - let outer_key = state_machine - .session() - .ok() - .and_then(|s| s.outer_aead_key()); - drop(state_entry); // Release borrow before send - Some((response_packet, outer_key)) - } - LpAction::HandshakeComplete => { - info!( - "Handshake completed for {} (receiver_idx={})", - self.remote_addr, receiver_idx - ); - - let session = state_entry.value().state.session().map_err(|err| { - GatewayError::LpHandshakeError(format!("no session available: {err}")) - })?; - - // Get outer key for Ack encryption before releasing borrow - let outer_key = session.outer_aead_key(); - - // Get previously negotiated protocol version for header creation - let negotiated_version = session.negotiated_version(); - - // Move state machine to session_states (already in Transport state) - // We keep the state machine (not just session) to enable - // subsession/rekeying support during transport phase - drop(state_entry); // Release mutable borrow - - let (_receiver_idx, timestamped_state) = self - .state - .handshake_states - .remove(&receiver_idx) - .ok_or_else(|| { - GatewayError::LpHandshakeError( - "Failed to remove handshake state".to_string(), - ) - })?; - - self.state - .session_states - .insert(receiver_idx, timestamped_state); - - inc!("lp_handshakes_success"); - - // Send Ack to confirm handshake completion to the client - let ack_packet = LpPacket::new( - LpHeader::new(receiver_idx, 0, negotiated_version), - LpMessage::Ack, - ); - trace!( - "Moved session {} to transport mode, sending Ack", - receiver_idx - ); - Some((ack_packet, outer_key)) - } - other => { - debug!("Received action during handshake: {:?}", other); - drop(state_entry); - None - } - }; - - // Send response packet if needed - if let Some((packet, outer_key)) = should_send { - self.send_lp_packet(packet, outer_key.as_ref()).await?; - trace!( - "Sent handshake response to {} (encrypted={})", - self.remote_addr, - outer_key.is_some() - ); - } - - Ok(()) + self.handle_transport_packet(receiver_idx, packet).await } /// Handle transport packet (receiver_idx!=0, session established) @@ -520,12 +305,8 @@ where receiver_idx: u32, packet: LpPacket, ) -> Result<(), GatewayError> { - use nym_lp::state_machine::{LpAction, LpInput}; - - debug!( - "Processing transport packet from {} (receiver_idx={})", - self.remote_addr, receiver_idx - ); + let remote = self.remote_addr; + debug!("Processing transport packet from {remote} (receiver_idx={receiver_idx})",); // Get state machine and process packet let mut state_entry = self @@ -533,7 +314,7 @@ where .session_states .get_mut(&receiver_idx) .ok_or_else(|| { - GatewayError::LpProtocolError(format!("Session not found: {}", receiver_idx)) + GatewayError::LpProtocolError(format!("Session not found: {receiver_idx}")) })?; // Update last activity timestamp @@ -547,31 +328,33 @@ where .ok_or_else(|| { GatewayError::LpProtocolError("No action from state machine".to_string()) })? - .map_err(|e| GatewayError::LpProtocolError(format!("State machine error: {}", e)))?; + .map_err(|e| GatewayError::LpProtocolError(format!("State machine error: {e}")))?; let lp_session = state_machine.session().map_err(|e| { - GatewayError::LpProtocolError(format!("Session unavailable after processing: {}", e)) + GatewayError::LpProtocolError(format!("Session unavailable after processing: {e}")) })?; // Get outer key before releasing borrow let outer_key = lp_session.outer_aead_key(); - drop(state_entry); match action { LpAction::SendPacket(response_packet) => { // Subsession KK2 response - gateway is responder // This means we received SubsessionKK1 and are responding - debug!( - "Sending subsession KK2 response to {} (receiver_idx={})", - self.remote_addr, receiver_idx - ); + debug!("Sending subsession KK2 response to {remote} (receiver_idx={receiver_idx})",); inc!("lp_subsession_kk2_sent"); - self.send_lp_packet(response_packet, outer_key.as_ref()) - .await?; + let mut packet_buf = BytesMut::new(); + serialize_lp_packet(&response_packet, &mut packet_buf, Some(outer_key)).map_err( + |e| GatewayError::LpProtocolError(format!("Failed to serialize packet: {}", e)), + )?; + + drop(state_entry); + self.send_serialised_packet(&packet_buf).await?; Ok(()) } LpAction::DeliverData(data) => { // Decrypted application data - process as registration/forwarding + drop(state_entry); self.handle_decrypted_payload(receiver_idx, data).await } LpAction::SubsessionComplete { @@ -580,23 +363,29 @@ where new_receiver_index, } => { // Subsession complete - promote to new session - self.handle_subsession_complete( - receiver_idx, - ready_packet, - *subsession, - new_receiver_index, - outer_key, - ) - .await + + // Send SubsessionReady packet if present (for initiator - gateway is responder, so typically None) + if let Some(ready_packet) = ready_packet { + let mut packet_buf = BytesMut::new(); + serialize_lp_packet(&ready_packet, &mut packet_buf, Some(outer_key)).map_err( + |e| { + GatewayError::LpProtocolError(format!( + "Failed to serialize packet: {e}", + )) + }, + )?; + drop(state_entry); + self.send_serialised_packet(&packet_buf).await?; + } else { + drop(state_entry); + } + self.handle_subsession_complete(receiver_idx, *subsession, new_receiver_index) + .await } other => { - warn!( - "Unexpected action in transport from {}: {:?}", - self.remote_addr, other - ); + warn!("Unexpected action in transport from {remote}: {other:?}",); Err(GatewayError::LpProtocolError(format!( - "Unexpected action: {:?}", - other + "Unexpected action: {other:?}", ))) } } @@ -653,10 +442,8 @@ where async fn handle_subsession_complete( &mut self, old_receiver_idx: u32, - ready_packet: Option, subsession: nym_lp::session::SubsessionHandshake, new_receiver_index: u32, - outer_key: Option, ) -> Result<(), GatewayError> { use nym_lp::state_machine::LpStateMachine; @@ -665,29 +452,18 @@ where self.remote_addr, old_receiver_idx, new_receiver_index ); - // Send SubsessionReady packet if present (for initiator - gateway is responder, so typically None) - if let Some(packet) = ready_packet { - self.send_lp_packet(packet, outer_key.as_ref()).await?; - } - // Create new state machine from completed subsession let new_state_machine = LpStateMachine::from_subsession(subsession, new_receiver_index) .map_err(|e| { GatewayError::LpProtocolError(format!( - "Failed to create session from subsession: {}", - e + "Failed to create session from subsession: {e}", )) })?; // Check for receiver_index collision before inserting // new_receiver_index is client-generated (rand::random() in state machine). // Collisions are statistically unlikely (1 in 4 billion) but could cause DoS if exploited. - if self.state.session_states.contains_key(&new_receiver_index) - || self - .state - .handshake_states - .contains_key(&new_receiver_index) - { + if self.state.session_states.contains_key(&new_receiver_index) { warn!( "Subsession receiver_index collision: {} from {}", new_receiver_index, self.remote_addr @@ -718,19 +494,19 @@ where serialised_response: Vec, response_kind: LpDataKind, ) -> Result<(), GatewayError> { - let session_entry = self + let mut session_entry = self .state .session_states - .get(&receiver_idx) + .get_mut(&receiver_idx) .ok_or_else(|| { GatewayError::LpProtocolError(format!("Session not found: {receiver_idx}")) })?; // Access session via state machine for subsession support let session = session_entry - .value() + .value_mut() .state - .session() + .session_mut() .map_err(|e| GatewayError::LpProtocolError(format!("Session error: {e}")))?; let wrapped_lp_data = LpData::new(response_kind, serialised_response); @@ -745,11 +521,17 @@ where })?; let outer_key = session.outer_aead_key(); + + // make sure to drop the entry before the .await call + // Serialize the packet (encrypted if outer_key provided) + let mut packet_buf = BytesMut::new(); + serialize_lp_packet(&response_packet, &mut packet_buf, Some(outer_key)).map_err(|e| { + GatewayError::LpProtocolError(format!("Failed to serialize packet: {}", e)) + })?; drop(session_entry); // Send response (encrypted with outer AEAD) - self.send_lp_packet(response_packet, outer_key.as_ref()) - .await?; + self.send_serialised_packet(&packet_buf).await?; Ok(()) } @@ -1163,42 +945,54 @@ where Ok((packet_buf, header)) } - /// Send an LP packet over the stream with proper length-prefixed framing. - /// - /// # Arguments - /// * `packet` - The LP packet to send - /// * `outer_key` - Optional outer AEAD key for encryption (None for cleartext, Some for encrypted) - async fn send_lp_packet( - &mut self, - packet: LpPacket, - outer_key: Option<&OuterAeadKey>, - ) -> Result<(), GatewayError> { - use bytes::BytesMut; - use nym_lp::codec::serialize_lp_packet; - - // Serialize the packet (encrypted if outer_key provided) - let mut packet_buf = BytesMut::new(); - serialize_lp_packet(&packet, &mut packet_buf, outer_key).map_err(|e| { - GatewayError::LpProtocolError(format!("Failed to serialize packet: {}", e)) - })?; - - // Send 4-byte length prefix (u32 big-endian) - let len = packet_buf.len() as u32; + /// Send a serialised LP packet over the stream with proper length-prefixed framing. + async fn send_serialised_packet(&mut self, packet_data: &[u8]) -> Result<(), GatewayError> { self.stream - .write_all(&len.to_be_bytes()) + .send_serialised_packet(packet_data) .await - .map_err(|e| { - GatewayError::LpConnectionError(format!("Failed to send packet length: {}", e)) + .map_err(|err| { + GatewayError::LpConnectionError(format!("failed to send LP packet: {err}")) })?; - // Send the actual packet data - self.stream.write_all(&packet_buf).await.map_err(|e| { - GatewayError::LpConnectionError(format!("Failed to send packet data: {}", e)) + // Track bytes sent (4 byte header + packet data) + self.stats.record_bytes_sent(4 + packet_data.len()); + + Ok(()) + } + + // only used in tests + #[cfg(test)] + async fn send_lp_packet(&mut self, packet: LpPacket) -> Result<(), GatewayError> { + let receiver_idx = self.bound_receiver_index()?; + + let mut session_entry = self + .state + .session_states + .get_mut(&receiver_idx) + .ok_or_else(|| { + GatewayError::LpProtocolError(format!("Session not found: {receiver_idx}")) + })?; + + // Access session via state machine for subsession support + let session = session_entry + .value_mut() + .state + .session_mut() + .map_err(|e| GatewayError::LpProtocolError(format!("Session error: {e}")))?; + + let outer_key = session.outer_aead_key(); + + let mut packet_buf = BytesMut::new(); + serialize_lp_packet(&packet, &mut packet_buf, Some(outer_key)).map_err(|e| { + GatewayError::LpProtocolError(format!("Failed to serialize packet: {e}",)) })?; - self.stream.flush().await.map_err(|e| { - GatewayError::LpConnectionError(format!("Failed to flush stream: {}", e)) - })?; + self.stream + .send_serialised_packet(&packet_buf) + .await + .map_err(|err| { + GatewayError::LpConnectionError(format!("failed to send LP packet: {err}")) + })?; // Track bytes sent (4 byte header + packet data) self.stats.record_bytes_sent(4 + packet_buf.len()); @@ -1243,12 +1037,12 @@ mod tests { use crate::node::lp_listener::{LpConfig, LpDebug}; use crate::node::ActiveClientsStore; use bytes::BytesMut; - use nym_lp::codec::{parse_lp_packet, serialize_lp_packet}; - use nym_lp::message::{ClientHelloData, EncryptedDataPayload, HandshakeData, LpMessage}; + use nym_lp::codec::{parse_lp_packet, serialize_lp_packet, OuterAeadKey}; + use nym_lp::message::{EncryptedDataPayload, LpMessage}; use nym_lp::packet::{LpHeader, LpPacket}; use nym_lp::peer::LpLocalPeer; + use nym_lp::SessionsMock; use std::sync::Arc; - use std::time::{SystemTime, UNIX_EPOCH}; use tokio::io::{AsyncRead, AsyncReadExt, AsyncWriteExt}; // ==================== Test Helpers ==================== @@ -1294,13 +1088,23 @@ mod tests { metrics: nym_node_metrics::NymNodeMetrics::default(), active_clients_store: ActiveClientsStore::new(), outbound_mix_sender: mix_sender, - handshake_states: Arc::new(dashmap::DashMap::new()), session_states: Arc::new(dashmap::DashMap::new()), forward_semaphore, peer_registrator: None, } } + fn add_dummy_lp_state(handler: &mut LpConnectionHandler, session: LpSession) { + let id = session.id(); + let state_machine = LpStateMachine::new(session); + handler.bound_receiver_idx = Some(id); + + handler + .state + .session_states + .insert(id, TimestampedState::new(state_machine)); + } + /// Helper to write an LP packet to a stream with proper framing async fn write_lp_packet_to_stream( stream: &mut W, @@ -1324,6 +1128,7 @@ mod tests { /// Helper to read an LP packet from a stream with proper framing async fn read_lp_packet_from_stream( stream: &mut R, + outer_aead_key: &OuterAeadKey, ) -> Result { // Read length prefix let mut len_buf = [0u8; 4]; @@ -1335,7 +1140,8 @@ mod tests { stream.read_exact(&mut packet_buf).await?; // Parse packet - parse_lp_packet(&packet_buf, None).map_err(|e| std::io::Error::other(e.to_string())) + parse_lp_packet(&packet_buf, Some(outer_aead_key)) + .map_err(|e| std::io::Error::other(e.to_string())) } // ==================== Existing Tests ==================== @@ -1534,21 +1340,27 @@ mod tests { let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); let addr = listener.local_addr().unwrap(); + let receiver_idx = 99; + let sessions = SessionsMock::mock_post_handshake(receiver_idx); + let init = sessions.initiator; + let resp = sessions.responder; + let server_task = tokio::spawn(async move { let (stream, remote_addr) = listener.accept().await.unwrap(); let state = create_minimal_test_state().await; let mut handler = LpConnectionHandler::new(stream, remote_addr, state); + add_dummy_lp_state(&mut handler, resp); let packet = LpPacket::new( LpHeader { protocol_version: 1, reserved: [0u8; 3], - receiver_idx: 99, + receiver_idx, counter: 5, }, LpMessage::Busy, ); - handler.send_lp_packet(packet, None).await + handler.send_lp_packet(packet).await }); let mut client_stream = TcpStream::connect(addr).await.unwrap(); @@ -1557,54 +1369,13 @@ mod tests { server_task.await.unwrap().unwrap(); // Client should receive it correctly - let received = read_lp_packet_from_stream(&mut client_stream) + let received = read_lp_packet_from_stream(&mut client_stream, init.outer_aead_key()) .await .unwrap(); - assert_eq!(received.header().receiver_idx, 99); + assert_eq!(received.header().receiver_idx, receiver_idx); assert_eq!(received.header().counter, 5); } - #[tokio::test] - async fn test_send_receive_handshake_message() { - use tokio::net::{TcpListener, TcpStream}; - - let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); - let addr = listener.local_addr().unwrap(); - - let handshake_data = vec![1, 2, 3, 4, 5, 6, 7, 8]; - let expected_data = handshake_data.clone(); - - let server_task = tokio::spawn(async move { - let (stream, remote_addr) = listener.accept().await.unwrap(); - let state = create_minimal_test_state().await; - let mut handler = LpConnectionHandler::new(stream, remote_addr, state); - - let packet = LpPacket::new( - LpHeader { - protocol_version: 1, - reserved: [0u8; 3], - receiver_idx: 100, - counter: 10, - }, - LpMessage::Handshake(HandshakeData(handshake_data)), - ); - handler.send_lp_packet(packet, None).await - }); - - let mut client_stream = TcpStream::connect(addr).await.unwrap(); - server_task.await.unwrap().unwrap(); - - let received = read_lp_packet_from_stream(&mut client_stream) - .await - .unwrap(); - assert_eq!(received.header().receiver_idx, 100); - assert_eq!(received.header().counter, 10); - match received.message() { - LpMessage::Handshake(data) => assert_eq!(data, &HandshakeData(expected_data)), - _ => panic!("Expected Handshake message"), - } - } - #[tokio::test] async fn test_send_receive_encrypted_data_message() { use tokio::net::{TcpListener, TcpStream}; @@ -1612,6 +1383,11 @@ mod tests { let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); let addr = listener.local_addr().unwrap(); + let receiver_idx = 200; + let sessions = SessionsMock::mock_post_handshake(receiver_idx); + let init = sessions.initiator; + let resp = sessions.responder; + let encrypted_payload = vec![42u8; 256]; let expected_payload = encrypted_payload.clone(); @@ -1619,23 +1395,24 @@ mod tests { let (stream, remote_addr) = listener.accept().await.unwrap(); let state = create_minimal_test_state().await; let mut handler = LpConnectionHandler::new(stream, remote_addr, state); + add_dummy_lp_state(&mut handler, resp); let packet = LpPacket::new( LpHeader { protocol_version: 1, reserved: [0u8; 3], - receiver_idx: 200, + receiver_idx, counter: 20, }, LpMessage::EncryptedData(EncryptedDataPayload(encrypted_payload)), ); - handler.send_lp_packet(packet, None).await + handler.send_lp_packet(packet).await }); let mut client_stream = TcpStream::connect(addr).await.unwrap(); server_task.await.unwrap().unwrap(); - let received = read_lp_packet_from_stream(&mut client_stream) + let received = read_lp_packet_from_stream(&mut client_stream, init.outer_aead_key()) .await .unwrap(); assert_eq!(received.header().receiver_idx, 200); @@ -1647,199 +1424,4 @@ mod tests { _ => panic!("Expected EncryptedData message"), } } - - #[tokio::test] - async fn test_send_receive_client_hello_message() { - use nym_lp::message::ClientHelloData; - use tokio::net::{TcpListener, TcpStream}; - - let timestamp = SystemTime::now() - .duration_since(UNIX_EPOCH) - .expect("System time before UNIX epoch") - .as_secs(); - - let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); - let addr = listener.local_addr().unwrap(); - - let mut rng = rand::thread_rng(); - let ed25519 = ed25519::KeyPair::new(&mut rng); - let x25519 = ed25519.to_x25519(); - - let client_key = *x25519.public_key(); - let client_ed25519_key = *ed25519.public_key(); - - let hello_data = - ClientHelloData::new_with_fresh_salt(client_key, client_ed25519_key, timestamp); - let expected_salt = hello_data.salt; // Clone salt before moving hello_data - - let server_task = tokio::spawn(async move { - let (stream, remote_addr) = listener.accept().await.unwrap(); - let state = create_minimal_test_state().await; - let mut handler = LpConnectionHandler::new(stream, remote_addr, state); - - let packet = LpPacket::new( - LpHeader { - protocol_version: 1, - reserved: [0u8; 3], - receiver_idx: 300, - counter: 30, - }, - LpMessage::ClientHello(hello_data), - ); - handler.send_lp_packet(packet, None).await - }); - - let mut client_stream = TcpStream::connect(addr).await.unwrap(); - server_task.await.unwrap().unwrap(); - - let received = read_lp_packet_from_stream(&mut client_stream) - .await - .unwrap(); - assert_eq!(received.header().receiver_idx, 300); - assert_eq!(received.header().counter, 30); - match received.message() { - LpMessage::ClientHello(data) => { - assert_eq!(data.client_lp_public_key, client_key); - assert_eq!(data.salt, expected_salt); - } - _ => panic!("Expected ClientHello message"), - } - } - - // ==================== receive_client_hello Tests ==================== - - #[tokio::test] - async fn test_receive_client_hello_valid() { - use tokio::net::{TcpListener, TcpStream}; - - let timestamp = SystemTime::now() - .duration_since(UNIX_EPOCH) - .expect("System time before UNIX epoch") - .as_secs(); - - let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); - let addr = listener.local_addr().unwrap(); - - let server_task = tokio::spawn(async move { - let (stream, remote_addr) = listener.accept().await.unwrap(); - let state = create_minimal_test_state().await; - let mut handler = LpConnectionHandler::new(stream, remote_addr, state); - handler.receive_client_hello().await - }); - - let mut client_stream = TcpStream::connect(addr).await.unwrap(); - - // Create and send valid ClientHello - // Create separate Ed25519 keypair and derive X25519 from it (like production code) - use nym_crypto::asymmetric::ed25519; - use rand::rngs::OsRng; - - let client_ed25519_keypair = ed25519::KeyPair::new(&mut OsRng); - let client_x25519_public = client_ed25519_keypair.public_key().to_x25519().unwrap(); - - let hello_data = ClientHelloData::new_with_fresh_salt( - client_x25519_public, - *client_ed25519_keypair.public_key(), - timestamp, - ); - let packet = LpPacket::new( - LpHeader { - protocol_version: 1, - reserved: [0u8; 3], - receiver_idx: 0, - counter: 0, - }, - LpMessage::ClientHello(hello_data.clone()), - ); - write_lp_packet_to_stream(&mut client_stream, &packet) - .await - .unwrap(); - - // Handler should receive and parse it - let result = server_task.await.unwrap(); - assert!(result.is_ok(), "Expected Ok, got: {:?}", result); - - let (x25519_pubkey, ed25519_pubkey, salt) = result.unwrap(); - assert_eq!(x25519_pubkey.as_bytes(), &client_x25519_public.to_bytes()); - assert_eq!( - ed25519_pubkey.to_bytes(), - client_ed25519_keypair.public_key().to_bytes() - ); - assert_eq!(salt, hello_data.salt); - } - - #[tokio::test] - async fn test_receive_client_hello_timestamp_too_old() { - use std::time::{SystemTime, UNIX_EPOCH}; - use tokio::net::{TcpListener, TcpStream}; - - let timestamp = SystemTime::now() - .duration_since(UNIX_EPOCH) - .expect("System time before UNIX epoch") - .as_secs(); - - let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); - let addr = listener.local_addr().unwrap(); - - let server_task = tokio::spawn(async move { - let (stream, remote_addr) = listener.accept().await.unwrap(); - let state = create_minimal_test_state().await; - let mut handler = LpConnectionHandler::new(stream, remote_addr, state); - handler.receive_client_hello().await - }); - - let mut client_stream = TcpStream::connect(addr).await.unwrap(); - - // Create ClientHello with old timestamp - // Use proper separate Ed25519 and X25519 keys (like production code) - use nym_crypto::asymmetric::ed25519; - use rand::rngs::OsRng; - - let client_ed25519_keypair = ed25519::KeyPair::new(&mut OsRng); - let client_x25519_public = client_ed25519_keypair.public_key().to_x25519().unwrap(); - - let mut hello_data = ClientHelloData::new_with_fresh_salt( - client_x25519_public, - *client_ed25519_keypair.public_key(), - timestamp, - ); - - // Manually set timestamp to be very old (100 seconds ago) - let old_timestamp = SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_secs() - - 100; - hello_data.salt[..8].copy_from_slice(&old_timestamp.to_le_bytes()); - - let packet = LpPacket::new( - LpHeader { - protocol_version: 1, - reserved: [0u8; 3], - receiver_idx: 0, - counter: 0, - }, - LpMessage::ClientHello(hello_data), - ); - write_lp_packet_to_stream(&mut client_stream, &packet) - .await - .unwrap(); - - // Should fail with timestamp error - let result = server_task.await.unwrap(); - assert!(result.is_err()); - // Note: Can't use unwrap_err() directly because PublicKey doesn't implement Debug - // Just check that it failed - match result { - Err(e) => { - let err_msg = format!("{}", e); - assert!( - err_msg.contains("too old"), - "Expected 'too old' in error, got: {}", - err_msg - ); - } - Ok(_) => panic!("Expected error but got success"), - } - } } diff --git a/gateway/src/node/lp_listener/mod.rs b/gateway/src/node/lp_listener/mod.rs index 367e16e9bf..976eb2afa7 100644 --- a/gateway/src/node/lp_listener/mod.rs +++ b/gateway/src/node/lp_listener/mod.rs @@ -362,15 +362,6 @@ pub struct LpHandlerState { /// from LP clients into the mixnet for routing. pub outbound_mix_sender: MixForwardingSender, - /// In-progress handshakes keyed by session_id - /// - /// Session ID is deterministically computed from both parties' X25519 keys immediately - /// after ClientHello. Used during handshake phase. After handshake completes, - /// state moves to session_states map. - /// - /// Wrapped in TimestampedState for TTL-based cleanup of stale handshakes. - pub handshake_states: Arc>>, - /// Established sessions keyed by session_id /// /// Used after handshake completes (session_id is deterministically computed from @@ -504,7 +495,7 @@ impl LpListener { handler::LpConnectionHandler::new(stream, remote_addr, self.handler_state.clone()); let metrics = self.handler_state.metrics.clone(); - self.shutdown.try_spawn_named( + self.shutdown.try_spawn_named_with_shutdown( async move { let result = handler.handle().await; @@ -559,7 +550,6 @@ impl LpListener { /// /// The task automatically stops when the shutdown signal is received. fn spawn_state_cleanup_task(&self) -> tokio::task::JoinHandle<()> { - let handshake_states = Arc::clone(&self.handler_state.handshake_states); let session_states = Arc::clone(&self.handler_state.session_states); let dbg_cfg = self.handler_state.lp_config.debug; @@ -576,13 +566,7 @@ impl LpListener { ); self.shutdown.try_spawn_named( - cleanup_task::cleanup_loop( - handshake_states, - session_states, - dbg_cfg, - shutdown, - metrics, - ), + cleanup_task::cleanup_loop(session_states, dbg_cfg, shutdown, metrics), "LP::StateCleanup", ) } @@ -606,29 +590,16 @@ pub(crate) mod cleanup_task { use tracing::{debug, info}; async fn perform_cleanup( - handshake_states: &Arc>>, session_states: &Arc>>, cfg: LpDebug, ) { - let handshake_ttl = cfg.handshake_ttl; let session_ttl = cfg.session_ttl; let demoted_session_ttl = cfg.demoted_session_ttl; let start = std::time::Instant::now(); - let mut hs_removed = 0u64; let mut ss_removed = 0u64; let mut demoted_removed = 0u64; - // Remove stale handshakes (based on age since creation) - handshake_states.retain(|_, timestamped| { - if timestamped.age() > handshake_ttl { - hs_removed += 1; - false - } else { - true - } - }); - // Remove stale sessions (based on time since last activity) // Use shorter TTL for demoted (ReadOnlyTransport) sessions session_states.retain(|_, timestamped| { @@ -651,17 +622,14 @@ pub(crate) mod cleanup_task { } }); - if hs_removed > 0 || ss_removed > 0 || demoted_removed > 0 { + if ss_removed > 0 || demoted_removed > 0 { let duration = start.elapsed(); info!( - "LP state cleanup: removed {hs_removed} handshakes, {ss_removed} sessions, {demoted_removed} demoted (took {:.3}s)", + "LP state cleanup: {ss_removed} sessions, {demoted_removed} demoted (took {:.3}s)", duration.as_secs_f64() ); // Track metrics - if hs_removed > 0 { - inc_by!("lp_states_cleanup_handshake_removed", hs_removed as i64); - } if ss_removed > 0 { inc_by!("lp_states_cleanup_session_removed", ss_removed as i64); } @@ -679,7 +647,6 @@ pub(crate) mod cleanup_task { /// Demoted sessions (ReadOnlyTransport) use shorter TTL since they /// only need to drain in-flight packets after subsession promotion. pub(crate) async fn cleanup_loop( - handshake_states: Arc>>, session_states: Arc>>, cfg: LpDebug, shutdown: nym_task::ShutdownToken, @@ -697,7 +664,7 @@ pub(crate) mod cleanup_task { break; } _ = cleanup_interval.tick() => { - perform_cleanup(&handshake_states, &session_states, cfg).await; + perform_cleanup(&session_states, cfg).await; } } } diff --git a/gateway/src/node/mod.rs b/gateway/src/node/mod.rs index d8376289a3..cf8d303300 100644 --- a/gateway/src/node/mod.rs +++ b/gateway/src/node/mod.rs @@ -362,7 +362,6 @@ impl GatewayTasksBuilder { peer_registrator, lp_config: self.config.lp, outbound_mix_sender: self.mix_packet_sender.clone(), - handshake_states: Arc::new(dashmap::DashMap::new()), session_states: Arc::new(dashmap::DashMap::new()), forward_semaphore: Arc::new(Semaphore::new( self.config.lp.debug.max_concurrent_forwards, diff --git a/integration-tests/src/lp_registration.rs b/integration-tests/src/lp_registration.rs index 15074efc0e..cf3658f8fe 100644 --- a/integration-tests/src/lp_registration.rs +++ b/integration-tests/src/lp_registration.rs @@ -237,9 +237,6 @@ mod tests { // TODO: might be needed later on for mixnet registration outbound_mix_sender: mix_sender, - // we start with empty state - handshake_states: Arc::new(Default::default()), - // we start with empty state session_states: Arc::new(Default::default()), diff --git a/nym-registration-client/src/lp_client/client.rs b/nym-registration-client/src/lp_client/client.rs index 1ae732dfb6..25f3265878 100644 --- a/nym-registration-client/src/lp_client/client.rs +++ b/nym-registration-client/src/lp_client/client.rs @@ -8,19 +8,18 @@ use super::error::{LpClientError, Result}; use crate::lp_client::helpers::{ LpDataDeliverExt, LpDataSendExt, convert_forward_data, try_convert_forward_response, }; -use crate::lp_client::state_machine_helpers::{ - extract_forwarded_response, get_recv_key, get_send_key, prepare_send_packet, -}; +use crate::lp_client::nested_session::connection::NestedConnection; +use crate::lp_client::state_machine_helpers::{extract_forwarded_response, prepare_send_packet}; use bytes::BytesMut; use nym_bandwidth_controller::{BandwidthTicketProvider, DEFAULT_TICKETS_TO_SPEND}; use nym_credentials_interface::TicketType; use nym_crypto::asymmetric::{ed25519, x25519}; -use nym_lp::LpPacket; use nym_lp::codec::{OuterAeadKey, parse_lp_packet, serialize_lp_packet}; use nym_lp::message::ForwardPacketData; use nym_lp::packet::version; use nym_lp::peer::{LpLocalPeer, LpRemotePeer}; use nym_lp::state_machine::{LpAction, LpData, LpInput, LpStateMachine}; +use nym_lp::{LpPacket, LpSession}; use nym_lp_transport::traits::LpTransport; use nym_registration_common::dvpn::LpDvpnRegistrationResponseMessageContent; use nym_registration_common::{ @@ -31,7 +30,7 @@ use nym_wireguard_types::PeerPublicKey; use rand::{CryptoRng, RngCore}; use std::net::SocketAddr; use std::sync::Arc; -use std::time::{Duration, SystemTime, UNIX_EPOCH}; +use std::time::Duration; use tokio::net::TcpStream; use tracing::warn; @@ -67,7 +66,7 @@ pub struct LpRegistrationClient { state_machine: Option, /// Configuration for timeouts and TCP parameters. - config: LpRegistrationConfig, + pub(crate) config: LpRegistrationConfig, /// Persistent TCP stream for the connection. /// Opened on first use, closed after registration. @@ -119,6 +118,19 @@ where } } + /// Attempt to use this `LpRegistrationClient` as transport for `NestedSession` + pub fn as_nested_connection( + &mut self, + exit_identity: ed25519::PublicKey, + exit_address: SocketAddr, + ) -> NestedConnection<'_, S> { + NestedConnection { + exit_identity, + exit_address, + outer_client: self, + } + } + /// Creates a new LP registration client with default configuration. /// /// # Arguments @@ -145,15 +157,7 @@ where ) } - fn state_machine(&self) -> Result<&LpStateMachine> { - self.state_machine.as_ref().ok_or_else(|| { - LpClientError::transport( - "State machine not available - has the handshake been completed?", - ) - }) - } - - fn state_machine_mut(&mut self) -> Result<&mut LpStateMachine> { + pub(crate) fn state_machine_mut(&mut self) -> Result<&mut LpStateMachine> { self.state_machine.as_mut().ok_or_else(|| { LpClientError::transport( "State machine not available - has the handshake been completed?", @@ -169,11 +173,7 @@ where /// Returns whether the client has completed the handshake and is ready for registration. pub fn is_handshake_complete(&self) -> bool { - self.state_machine - .as_ref() - .and_then(|sm| sm.session().ok()) - .map(|s| s.is_handshake_complete()) - .unwrap_or(false) + self.state_machine.is_some() } /// Returns the gateway LP address this client is configured for. @@ -287,27 +287,20 @@ where /// /// # Errors /// Returns an error if not connected or if send fails. - async fn try_send_packet(&mut self, packet: &LpPacket) -> Result<()> { - let state_machine = self.state_machine()?; - let send_key = get_send_key(state_machine); - self.try_send_packet_with_key(packet, send_key.as_ref()) - .await - } + pub(crate) async fn try_send_packet(&mut self, packet: &LpPacket) -> Result<()> { + // can't use getters due to borrow checker (i.e. requiring full borrows for function calls) + let stream = self + .stream + .as_mut() + .ok_or_else(|| LpClientError::transport("Cannot send: not connected"))?; - /// Sends an LP packet (and optionally encrypted) on the persistent stream. - /// - /// # Arguments - /// * `packet` - The LP packet to send - /// * `outer_key` - Optional outer AEAD key for encryption - /// - /// # Errors - /// Returns an error if not connected or if send fails. - async fn try_send_packet_with_key( - &mut self, - packet: &LpPacket, - outer_key: Option<&OuterAeadKey>, - ) -> Result<()> { - let stream = self.stream_mut()?; + let state_machine = self.state_machine.as_ref().ok_or_else(|| { + LpClientError::transport( + "State machine not available - has the handshake been completed?", + ) + })?; + + let outer_key = state_machine.session()?.outer_aead_key(); Self::send_packet_with_key(stream, packet, outer_key).await } @@ -315,25 +308,19 @@ where /// /// # Errors /// Returns an error if not connected or if receive fails. - async fn try_receive_packet(&mut self) -> Result { - let state_machine = self.state_machine()?; - let recv_key = get_recv_key(state_machine); + pub(crate) async fn try_receive_packet(&mut self) -> Result { + let stream = self + .stream + .as_mut() + .ok_or_else(|| LpClientError::transport("Cannot send: not connected"))?; - self.try_receive_packet_with_key(recv_key.as_ref()).await - } + let state_machine = self.state_machine.as_ref().ok_or_else(|| { + LpClientError::transport( + "State machine not available - has the handshake been completed?", + ) + })?; - /// Receives an LP packet from the persistent stream. - /// - /// # Arguments - /// * `outer_key` - Optional outer AEAD key for decryption - /// - /// # Errors - /// Returns an error if not connected or if receive fails. - async fn try_receive_packet_with_key( - &mut self, - outer_key: Option<&OuterAeadKey>, - ) -> Result { - let stream = self.stream_mut()?; + let outer_key = state_machine.session()?.outer_aead_key(); Self::receive_packet_with_key(stream, outer_key).await } @@ -420,256 +407,28 @@ where // Ensure we have a TCP connection self.ensure_connected().await?; - let timestamp = SystemTime::now() - .duration_since(UNIX_EPOCH) - .map_err(|_| LpClientError::Other("System time before UNIX epoch".into()))? - .as_secs(); + let local_peer = self.lp_local_peer.clone(); + let remote_peer = self.gateway_lp_peer.clone(); + let protocol_version = self.gateway_supported_lp_protocol_version; + let connection = self.stream_mut()?; - // Step 1: Generate ClientHelloData with fresh salt and both public keys - let client_hello_data = self.lp_local_peer.build_client_hello_data(timestamp); - let salt = client_hello_data.salt; - let receiver_index = client_hello_data.receiver_index; - - tracing::trace!( - "Generated ClientHello with timestamp: {}, receiver_index: {}", - client_hello_data.extract_timestamp(), - receiver_index - ); - - // Step 2: Send ClientHello and receive Ack (persistent connection) - let client_hello_header = nym_lp::packet::LpHeader::new( - nym_lp::BOOTSTRAP_RECEIVER_IDX, // session_id not yet established - 0, // counter starts at 0 - self.gateway_supported_lp_protocol_version, - ); - let client_hello_packet = nym_lp::LpPacket::new( - client_hello_header, - nym_lp::LpMessage::ClientHello(client_hello_data), - ); - - // Send ClientHello (no outer key - before PSK) - self.try_send_packet_with_key(&client_hello_packet, None) - .await?; - // Receive Ack (no outer key - before PSK) - let ack_response = self.try_receive_packet_with_key(None).await?; - - // Verify we received Ack - // this confirms that gateway is fine with our suggested protocol version - // in the future we probably have some fancier negotiation - match ack_response.message() { - nym_lp::LpMessage::Ack => { - tracing::debug!("Received Ack for ClientHello"); - } - other => { - return Err(LpClientError::Transport(format!( - "Expected Ack for ClientHello, got: {:?}", - other - ))); - } - } - - // Step 3: Create state machine as initiator with Ed25519 keys - // PSK derivation happens internally in the state machine constructor - let mut state_machine = LpStateMachine::new( - receiver_index, - true, // is_initiator - self.lp_local_peer.clone(), - self.gateway_lp_peer.clone(), - &salt, - self.gateway_supported_lp_protocol_version, - )?; - - // Step 4: Start handshake - get first packet to send (KKT request) - let mut pending_packet: Option = None; - if let Some(action) = state_machine.process_input(LpInput::StartHandshake) { - match action? { - LpAction::SendPacket(packet) => { - pending_packet = Some(packet); - } - other => { - return Err(LpClientError::Transport(format!( - "Unexpected action at handshake start: {:?}", - other - ))); - } - } - } - - // Step 5: Handshake loop - all packets on persistent connection - loop { - // Send pending packet if we have one - if let Some(packet) = pending_packet.take() { - // Get outer keys from session: - // - send_key: outer_aead_key_for_sending() returns None until PSQ complete - // - recv_key: outer_aead_key() returns key as soon as PSK is derived - let send_key = state_machine - .session() - .ok() - .and_then(|s| s.outer_aead_key_for_sending()); - let recv_key = state_machine - .session() - .ok() - .and_then(|s| s.outer_aead_key()); - - tracing::trace!( - "Sending handshake packet (send_key={}, recv_key={})", - send_key.is_some(), - recv_key.is_some() - ); - self.try_send_packet_with_key(&packet, send_key.as_ref()) - .await?; - let response = self.try_receive_packet_with_key(recv_key.as_ref()).await?; - tracing::trace!("Received handshake response"); - - // Process the received packet - if let Some(action) = state_machine.process_input(LpInput::ReceivePacket(response)) - { - match action? { - LpAction::SendPacket(response_packet) => { - // Queue the response packet to send on next iteration - pending_packet = Some(response_packet); - - // Check if handshake completed after queueing this packet - if state_machine.session()?.is_handshake_complete() { - // Send the final packet before breaking - if let Some(final_packet) = pending_packet.take() { - let send_key = state_machine - .session() - .ok() - .and_then(|s| s.outer_aead_key_for_sending()); - let recv_key = state_machine - .session() - .ok() - .and_then(|s| s.outer_aead_key()); - tracing::trace!("Sending final handshake packet"); - self.try_send_packet_with_key(&final_packet, send_key.as_ref()) - .await?; - let ack_response = - self.try_receive_packet_with_key(recv_key.as_ref()).await?; - - // Validate Ack response - match ack_response.message() { - nym_lp::LpMessage::Ack => { - tracing::debug!( - "Received Ack for final handshake packet" - ); - } - other => { - return Err(LpClientError::Transport(format!( - "Expected Ack for final handshake packet, got: {:?}", - other - ))); - } - } - } - tracing::info!("LP handshake completed after sending final packet"); - break; - } - } - LpAction::HandshakeComplete => { - tracing::info!("LP handshake completed successfully"); - break; - } - LpAction::KKTComplete => { - tracing::info!("KKT exchange completed, starting Noise handshake"); - // After KKT completes, initiator must send first Noise handshake message - let noise_msg = state_machine - .session()? - .prepare_handshake_message() - .ok_or_else(|| { - LpClientError::transport("No handshake message available after KKT") - })??; - let noise_packet = state_machine.session()?.next_packet(noise_msg)?; - pending_packet = Some(noise_packet); - } - other => { - tracing::trace!("Received action during handshake: {:?}", other); - } - } - } - } else { - // No pending packet and not complete - something is wrong - return Err(LpClientError::transport( - "Handshake stalled: no packet to send", - )); - } - } + // TODO: + let ciphersuite = LpSession::default_ciphersuite(); + let session = LpSession::complete_as_initiator( + connection, + ciphersuite, + local_peer, + remote_peer, + protocol_version, + ) + .complete_as_initiator() + .await?; // Store the state machine (with established session) for later use - self.state_machine = Some(state_machine); + self.state_machine = Some(LpStateMachine::new(session)); Ok(()) } - /// Opens a TCP connection, sends one packet, receives one response, closes. - /// - /// This implements the packet-per-connection model where each LP packet - /// exchange uses its own TCP connection. The connection is closed when - /// this method returns (stream dropped). - /// - /// # Arguments - /// * `address` - Gateway LP listener address - /// * `packet` - The LP packet to send - /// * `outer_key` - Optional outer AEAD key (None before PSK, Some after) - /// * `config` - Configuration for timeouts and TCP parameters - /// - /// # Errors - /// Returns an error if connection, send, or receive fails. - /// - /// # Outer AEAD Keys - /// - /// Send and receive use separate keys because during the PSQ handshake: - /// - Initiator derives PSK when preparing msg 1, but must send it cleartext - /// (responder hasn't derived PSK yet) - /// - Responder sends msg 2 encrypted (both have PSK now) - /// - Initiator can decrypt msg 2 (has had PSK since preparing msg 1) - /// - /// Use `outer_aead_key_for_sending()` for `send_key` (gates on PSQ completion) - /// and `outer_aead_key()` for `recv_key` (available as soon as PSK derived). - /// - /// # Note - /// This method is kept for reference but is no longer used. The persistent - /// connection model uses `send_packet()` and `receive_packet()` instead. - #[allow(dead_code)] - async fn connect_send_receive( - address: SocketAddr, - packet: &LpPacket, - send_key: Option<&OuterAeadKey>, - recv_key: Option<&OuterAeadKey>, - config: &LpRegistrationConfig, - ) -> Result { - // 1. Connect with timeout - let mut stream = tokio::time::timeout(config.connect_timeout, S::connect(address)) - .await - .map_err(|_| LpClientError::TcpConnection { - address: address.to_string(), - source: std::io::Error::new( - std::io::ErrorKind::TimedOut, - format!("Connection timeout after {:?}", config.connect_timeout), - ), - })? - .map_err(|source| LpClientError::TcpConnection { - address: address.to_string(), - source, - })?; - - // 2. Set TCP_NODELAY - stream - .set_no_delay(config.tcp_nodelay) - .map_err(|source| LpClientError::TcpConnection { - address: address.to_string(), - source, - })?; - - // 3. Send packet with send_key - Self::send_packet_with_key(&mut stream, packet, send_key).await?; - - // 4. Receive response with recv_key - let response = Self::receive_packet_with_key(&mut stream, recv_key).await?; - - // Connection drops when stream goes out of scope - Ok(response) - } - /// Sends an LP packet over a TCP stream with length-prefixed framing. /// /// Format: 4-byte big-endian u32 length + packet bytes @@ -684,10 +443,10 @@ where async fn send_packet_with_key( stream: &mut S, packet: &LpPacket, - outer_key: Option<&OuterAeadKey>, + outer_key: &OuterAeadKey, ) -> Result<()> { let mut packet_buf = BytesMut::new(); - serialize_lp_packet(packet, &mut packet_buf, outer_key) + serialize_lp_packet(packet, &mut packet_buf, Some(outer_key)) .map_err(|e| LpClientError::Transport(format!("Failed to serialize packet: {e}")))?; stream @@ -709,16 +468,13 @@ where /// - Network read fails /// - Packet size exceeds maximum (64KB) /// - Packet parsing/decryption fails - async fn receive_packet_with_key( - stream: &mut S, - outer_key: Option<&OuterAeadKey>, - ) -> Result { + async fn receive_packet_with_key(stream: &mut S, outer_key: &OuterAeadKey) -> Result { let packet_buf = stream .receive_raw_packet() .await .map_err(|err| LpClientError::transport(err.to_string()))?; - let packet = parse_lp_packet(&packet_buf, outer_key) + let packet = parse_lp_packet(&packet_buf, Some(outer_key)) .map_err(|e| LpClientError::Transport(format!("Failed to parse packet: {e}")))?; Ok(packet) @@ -1061,47 +817,30 @@ where // 1. Serialize the ForwardPacketData let input = convert_forward_data(forward_data)?; - // 2. Encrypt and prepare packet via state machine (scoped borrow) - let (forward_packet, send_key, recv_key) = { - let state_machine = self.state_machine.as_mut().ok_or_else(|| { - LpClientError::transport("Cannot send forward packet: handshake not completed") + // 2. Encrypt and prepare packet via state machine + let state_machine = self.state_machine_mut()?; + + let action = state_machine + .process_input(input) + .ok_or_else(|| LpClientError::transport("State machine returned no action"))? + .map_err(|e| { + LpClientError::Transport(format!("Failed to encrypt ForwardPacket: {e}")) })?; - let action = state_machine - .process_input(input) - .ok_or_else(|| LpClientError::transport("State machine returned no action"))? - .map_err(|e| { - LpClientError::Transport(format!("Failed to encrypt ForwardPacket: {e}")) - })?; - - let forward_packet = match action { - LpAction::SendPacket(packet) => packet, - other => { - return Err(LpClientError::Transport(format!( - "Unexpected action when sending ForwardPacket: {:?}", - other - ))); - } - }; - - // Get outer keys from session - let send_key = state_machine - .session() - .ok() - .and_then(|s| s.outer_aead_key_for_sending()); - let recv_key = state_machine - .session() - .ok() - .and_then(|s| s.outer_aead_key()); - - (forward_packet, send_key, recv_key) - }; // state_machine borrow ends here + let forward_packet = match action { + LpAction::SendPacket(packet) => packet, + other => { + return Err(LpClientError::Transport(format!( + "Unexpected action when sending ForwardPacket: {:?}", + other + ))); + } + }; // 3. Send and receive on persistent connection with timeout let response_packet = tokio::time::timeout(self.config.forward_timeout, async { - self.try_send_packet_with_key(&forward_packet, send_key.as_ref()) - .await?; - self.try_receive_packet_with_key(recv_key.as_ref()).await + self.try_send_packet(&forward_packet).await?; + self.try_receive_packet().await }) .await .map_err(|_| { @@ -1185,14 +924,11 @@ where }; // Get outer AEAD key for encryption - let outer_key = state_machine - .session() - .ok() - .and_then(|s| s.outer_aead_key_for_sending()); + let outer_key = state_machine.session()?.outer_aead_key(); // Serialize the packet with outer AEAD encryption let mut buf = BytesMut::new(); - serialize_lp_packet(&packet, &mut buf, outer_key.as_ref()) + serialize_lp_packet(&packet, &mut buf, Some(outer_key)) .map_err(|e| LpClientError::Transport(format!("Failed to serialize LP packet: {e}")))?; Ok(buf.to_vec()) diff --git a/nym-registration-client/src/lp_client/nested_session/connection.rs b/nym-registration-client/src/lp_client/nested_session/connection.rs new file mode 100644 index 0000000000..fd0f673677 --- /dev/null +++ b/nym-registration-client/src/lp_client/nested_session/connection.rs @@ -0,0 +1,135 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::lp_client::helpers::{convert_forward_data, try_convert_forward_response}; +use crate::{LpClientError, LpRegistrationClient}; +use nym_crypto::asymmetric::ed25519; +use nym_lp::message::ForwardPacketData; +use nym_lp::state_machine::{LpAction, LpInput}; +use nym_lp_transport::traits::LpTransport; +use std::io; +use std::net::SocketAddr; + +/// Attempt to treat the inner client as a LP connection +pub struct NestedConnection<'a, S> { + /// Remote Ed25519 public key + pub(crate) exit_identity: ed25519::PublicKey, + + /// Exit gateway's LP address (e.g., "2.2.2.2:41264") + pub(crate) exit_address: SocketAddr, + + pub(crate) outer_client: &'a mut LpRegistrationClient, +} + +impl<'a, S> NestedConnection<'a, S> { + async fn send_serialised_packet(&mut self, packet_data: &[u8]) -> Result<(), LpClientError> + where + S: LpTransport + Unpin, + { + let forward_packet_data = + ForwardPacketData::new(self.exit_identity, self.exit_address, packet_data.to_vec()); + + let target_address = self.exit_address; + + tracing::debug!( + "Sending ForwardPacket to {target_address} ({} inner bytes, persistent connection)", + forward_packet_data.inner_packet_bytes.len() + ); + + // 1. Serialize the ForwardPacketData + let input = convert_forward_data(forward_packet_data)?; + + // 2. Encrypt and prepare packet via state machine + let state_machine = self.outer_client.state_machine_mut()?; + + let action = state_machine + .process_input(input) + .ok_or_else(|| LpClientError::transport("State machine returned no action"))? + .map_err(|e| { + LpClientError::Transport(format!("Failed to encrypt ForwardPacket: {e}")) + })?; + + let forward_packet = match action { + LpAction::SendPacket(packet) => packet, + other => { + return Err(LpClientError::Transport(format!( + "Unexpected action when sending ForwardPacket: {:?}", + other + ))); + } + }; + + // 3. Send the packet with timeout + let timeout = self.outer_client.config.forward_timeout; + tokio::time::timeout(timeout, async { + self.outer_client.try_send_packet(&forward_packet).await + }) + .await + .map_err(|_| { + LpClientError::Transport(format!("Forward packet timeout after {timeout:?}",)) + })??; + + Ok(()) + } + + async fn receive_raw_packet(&mut self) -> Result, LpClientError> + where + S: LpTransport + Unpin, + { + // 1. Receive the packet with timeout + let timeout = self.outer_client.config.forward_timeout; + let response_packet = tokio::time::timeout(timeout, async { + self.outer_client.try_receive_packet().await + }) + .await + .map_err(|_| { + LpClientError::Transport(format!("Forward packet timeout after {timeout:?}",)) + })??; + + // 2. Decrypt via state machine (re-borrow) + let state_machine = self.outer_client.state_machine_mut()?; + let action = state_machine + .process_input(LpInput::ReceivePacket(response_packet)) + .ok_or_else(|| LpClientError::transport("State machine returned no action"))? + .map_err(|e| { + LpClientError::Transport(format!("Failed to decrypt forward response: {e}")) + })?; + + // 3. Extract decrypted response data + let response_data = try_convert_forward_response(action)?; + + tracing::debug!( + "Successfully received forward response from {} ({} bytes)", + self.exit_address, + response_data.len() + ); + + Ok(response_data) + } +} + +impl<'a, S> LpTransport for NestedConnection<'a, S> +where + S: LpTransport + Unpin, +{ + #[allow(clippy::unimplemented)] + async fn connect(_: SocketAddr) -> std::io::Result { + // this really breaks the pattern and should be refactored + // since this function should never be called + unimplemented!("cannot establish nested connection without an outer client") + } + + fn set_no_delay(&mut self, _: bool) -> std::io::Result<()> { + Ok(()) + } + + async fn send_serialised_packet(&mut self, packet_data: &[u8]) -> std::io::Result<()> { + self.send_serialised_packet(packet_data) + .await + .map_err(io::Error::other) + } + + async fn receive_raw_packet(&mut self) -> std::io::Result> { + self.receive_raw_packet().await.map_err(io::Error::other) + } +} diff --git a/nym-registration-client/src/lp_client/nested_session.rs b/nym-registration-client/src/lp_client/nested_session/mod.rs similarity index 71% rename from nym-registration-client/src/lp_client/nested_session.rs rename to nym-registration-client/src/lp_client/nested_session/mod.rs index 631206785c..7ee62c844c 100644 --- a/nym-registration-client/src/lp_client/nested_session.rs +++ b/nym-registration-client/src/lp_client/nested_session/mod.rs @@ -22,8 +22,7 @@ use super::client::LpRegistrationClient; use super::error::{LpClientError, Result}; use crate::lp_client::helpers::{LpDataDeliverExt, LpDataSendExt}; use crate::lp_client::state_machine_helpers::{ - extract_forwarded_response, get_recv_key, get_send_key, prepare_serialised_send_packet, - serialize_packet, + extract_forwarded_response, prepare_serialised_send_packet, }; use nym_bandwidth_controller::{BandwidthTicketProvider, DEFAULT_TICKETS_TO_SPEND}; use nym_credentials_interface::TicketType; @@ -32,8 +31,8 @@ use nym_lp::codec::{OuterAeadKey, parse_lp_packet}; use nym_lp::message::ForwardPacketData; use nym_lp::packet::version; use nym_lp::peer::{LpLocalPeer, LpRemotePeer}; -use nym_lp::state_machine::{LpAction, LpData, LpInput, LpStateMachine}; -use nym_lp::{LpMessage, LpPacket}; +use nym_lp::state_machine::{LpData, LpStateMachine}; +use nym_lp::{LpPacket, LpSession}; use nym_lp_transport::traits::LpTransport; use nym_registration_common::dvpn::LpDvpnRegistrationResponseMessageContent; use nym_registration_common::{ @@ -44,9 +43,10 @@ use nym_wireguard_types::PeerPublicKey; use rand::{CryptoRng, RngCore}; use std::net::SocketAddr; use std::sync::Arc; -use std::time::{SystemTime, UNIX_EPOCH}; use tracing::warn; +pub(crate) mod connection; + /// Manages a nested LP session where the client establishes a handshake with /// an exit gateway by forwarding packets through an entry gateway. /// @@ -140,8 +140,8 @@ impl NestedLpSession { /// Attempt to parse received bytes into an LpPacket fn parse_received_lp_packet(&self, response_bytes: Vec) -> Result { let state_machine = self.state_machine()?; - let outer_key = get_recv_key(state_machine); - Self::parse_packet(&response_bytes, outer_key.as_ref()) + let outer_key = state_machine.session()?.outer_aead_key(); + Self::parse_packet(&response_bytes, Some(outer_key)) } /// Attempt to wrap the provided `LpData` into a `ForwardPacketData` @@ -193,155 +193,26 @@ impl NestedLpSession { self.exit_address ); - let timestamp = SystemTime::now() - .duration_since(UNIX_EPOCH) - .map_err(|_| LpClientError::Other("System time before UNIX epoch".into()))? - .as_secs(); + let mut nested_connection = + outer_client.as_nested_connection(self.gateway_lp_peer.ed25519(), self.exit_address); - // Step 1: Generate ClientHello for exit gateway - let client_hello_data = self.lp_local_peer.build_client_hello_data(timestamp); - let salt = client_hello_data.salt; - let receiver_index = client_hello_data.receiver_index; + let local_peer = self.lp_local_peer.clone(); + let remote_peer = self.gateway_lp_peer.clone(); + let protocol_version = self.gateway_supported_lp_protocol_version; - tracing::trace!( - "Generated ClientHello for exit gateway (timestamp: {})", - client_hello_data.extract_timestamp() - ); - - // Step 2: Send ClientHello to exit gateway via forwarding - let client_hello_header = nym_lp::packet::LpHeader::new( - nym_lp::BOOTSTRAP_RECEIVER_IDX, // Use constant for bootstrap session - 0, // counter starts at 0 - self.gateway_supported_lp_protocol_version, - ); - let client_hello_packet = nym_lp::LpPacket::new( - client_hello_header, - LpMessage::ClientHello(client_hello_data), - ); - - // Serialize and forward ClientHello (no state machine yet, no outer key) - let client_hello_bytes = serialize_packet(&client_hello_packet, None)?; - let forward_packet_data = ForwardPacketData::new( - self.gateway_lp_peer.ed25519(), - self.exit_address, - client_hello_bytes, - ); - - let response_bytes = outer_client - .send_forward_packet_with_response(forward_packet_data) - .await?; - - // Parse and validate Ack response (cleartext, no outer key before PSK derivation) - // this confirms that gateway is fine with our suggested protocol version - // in the future we probably have some fancier negotiation - let ack_response = Self::parse_packet(&response_bytes, None)?; - match ack_response.message() { - LpMessage::Ack => { - tracing::debug!("Received Ack for ClientHello from exit gateway"); - } - LpMessage::Collision => { - return Err(LpClientError::Transport(format!( - "Exit gateway returned Collision - receiver_index {receiver_index} already in use", - ))); - } - other => { - return Err(LpClientError::Transport(format!( - "Expected Ack for ClientHello from exit gateway, got: {:?}", - other - ))); - } - } - - // Step 3: Create state machine for exit gateway handshake - let mut state_machine = LpStateMachine::new( - receiver_index, - true, // is_initiator - self.lp_local_peer.clone(), - self.gateway_lp_peer.clone(), - &salt, - self.gateway_supported_lp_protocol_version, - )?; - - // Step 4: Get initial packet from StartHandshake - let mut pending_packet: Option = None; - if let Some(action) = state_machine.process_input(LpInput::StartHandshake) { - match action? { - LpAction::SendPacket(packet) => { - pending_packet = Some(packet); - } - other => { - return Err(LpClientError::Transport(format!( - "Unexpected action at handshake start: {other:?}", - ))); - } - } - } - - // Step 5: Handshake loop - each packet on new connection via forwarding - loop { - if let Some(packet) = pending_packet.take() { - tracing::trace!("Sending handshake packet to exit via forwarding"); - let response = self - .send_and_receive_via_forward(outer_client, &state_machine, &packet) - .await?; - tracing::trace!("Received handshake response from exit"); - - // Process the received packet - if let Some(action) = state_machine.process_input(LpInput::ReceivePacket(response)) - { - match action? { - LpAction::SendPacket(response_packet) => { - pending_packet = Some(response_packet); - - // Check if handshake completed - send final packet if so - if state_machine.session()?.is_handshake_complete() { - if let Some(final_packet) = pending_packet.take() { - tracing::trace!("Sending final handshake packet to exit"); - let _ = self - .send_and_receive_via_forward( - outer_client, - &state_machine, - &final_packet, - ) - .await?; - } - tracing::info!("Nested LP handshake completed with exit gateway"); - break; - } - } - LpAction::HandshakeComplete => { - tracing::info!("Nested LP handshake completed with exit gateway"); - break; - } - LpAction::KKTComplete => { - tracing::info!("KKT exchange completed with exit, starting Noise"); - // After KKT completes, initiator must send first Noise handshake message - let noise_msg = state_machine - .session()? - .prepare_handshake_message() - .ok_or_else(|| { - LpClientError::Transport( - "No handshake message available after KKT".to_string(), - ) - })??; - let noise_packet = state_machine.session()?.next_packet(noise_msg)?; - pending_packet = Some(noise_packet); - } - other => { - tracing::trace!("Received action during handshake: {:?}", other); - } - } - } - } else { - // No pending packet and not complete - something is wrong - return Err(LpClientError::Transport( - "Nested handshake stalled: no packet to send".to_string(), - )); - } - } + let ciphersuite = LpSession::default_ciphersuite(); + let session = LpSession::complete_as_initiator( + &mut nested_connection, + ciphersuite, + local_peer, + remote_peer, + protocol_version, + ) + .complete_as_initiator() + .await?; // Store the state machine (with established session) for later use - self.state_machine = Some(state_machine); + self.state_machine = Some(LpStateMachine::new(session)); Ok(()) } @@ -660,36 +531,6 @@ impl NestedLpSession { })) } - /// Sends a packet via forwarding through the entry gateway and returns the parsed response. - /// - /// This helper consolidates the send/receive pattern used throughout the handshake: - /// 1. Gets outer AEAD key from state machine (if available) - /// 2. Serializes the packet with outer encryption - /// 3. Forwards via entry gateway - /// 4. Parses and returns the response - async fn send_and_receive_via_forward( - &self, - outer_client: &mut LpRegistrationClient, - state_machine: &LpStateMachine, - packet: &LpPacket, - ) -> Result - where - S: LpTransport + Unpin, - { - let send_key = get_send_key(state_machine); - let packet_bytes = serialize_packet(packet, send_key.as_ref())?; - let forward_data = ForwardPacketData::new( - self.gateway_lp_peer.ed25519(), - self.exit_address, - packet_bytes, - ); - let response_bytes = outer_client - .send_forward_packet_with_response(forward_data) - .await?; - let recv_key = get_recv_key(state_machine); - Self::parse_packet(&response_bytes, recv_key.as_ref()) - } - /// Parses an LP packet from bytes. /// /// # Arguments diff --git a/nym-registration-client/src/lp_client/state_machine_helpers.rs b/nym-registration-client/src/lp_client/state_machine_helpers.rs index 47da7c1255..b8be242621 100644 --- a/nym-registration-client/src/lp_client/state_machine_helpers.rs +++ b/nym-registration-client/src/lp_client/state_machine_helpers.rs @@ -7,26 +7,6 @@ use nym_lp::codec::{OuterAeadKey, serialize_lp_packet}; use nym_lp::state_machine::{LpAction, LpData, LpInput}; use nym_lp::{LpPacket, LpStateMachine}; -/// Gets the outer AEAD key for sending (encryption) from the state machine. -/// -/// Returns `None` during early handshake before PSK derivation. -pub(crate) fn get_send_key(state_machine: &LpStateMachine) -> Option { - state_machine - .session() - .ok() - .and_then(|s| s.outer_aead_key_for_sending()) -} - -/// Gets the outer AEAD key for receiving (decryption) from the state machine. -/// -/// Returns `None` during early handshake before PSK derivation. -pub(crate) fn get_recv_key(state_machine: &LpStateMachine) -> Option { - state_machine - .session() - .ok() - .and_then(|s| s.outer_aead_key()) -} - /// Serializes an LP packet to bytes. /// /// # Arguments @@ -79,9 +59,9 @@ pub(crate) fn prepare_serialised_send_packet( state_machine: &mut LpStateMachine, ) -> Result, LpClientError> { let packet = prepare_send_packet(data, state_machine)?; + let send_key = state_machine.session()?.outer_aead_key(); - let send_key = get_send_key(state_machine); - serialize_packet(&packet, send_key.as_ref()) + serialize_packet(&packet, Some(send_key)) } /// Attempt to recover received `LpData` from the received `LpPacket` diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 423c497a0c..dd7d19c7f7 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -81,7 +81,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ "crypto-common", - "generic-array 0.14.7", + "generic-array", ] [[package]] @@ -106,7 +106,7 @@ dependencies = [ "cipher", "ctr", "ghash", - "subtle 2.6.1", + "subtle", ] [[package]] @@ -259,7 +259,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" dependencies = [ "base64ct", - "blake2 0.10.6", + "blake2", "cpufeatures", "password-hash", ] @@ -703,7 +703,7 @@ dependencies = [ "ripemd", "secp256k1", "sha2 0.10.9", - "subtle 2.6.1", + "subtle", "zeroize", ] @@ -752,18 +752,6 @@ dependencies = [ "serde", ] -[[package]] -name = "blake2" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" -dependencies = [ - "byte-tools", - "crypto-mac", - "digest 0.8.1", - "opaque-debug 0.2.3", -] - [[package]] name = "blake2" version = "0.10.6" @@ -790,7 +778,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array 0.14.7", + "generic-array", ] [[package]] @@ -799,7 +787,7 @@ version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array 0.14.7", + "generic-array", ] [[package]] @@ -876,12 +864,6 @@ version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" - [[package]] name = "bytemuck" version = "1.22.0" @@ -1051,16 +1033,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" -[[package]] -name = "chacha" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddf3c081b5fba1e5615640aae998e0fbd10c24cbd897ee39ed754a77601a4862" -dependencies = [ - "byteorder", - "keystream", -] - [[package]] name = "chrono" version = "0.4.40" @@ -1467,9 +1439,9 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ - "generic-array 0.14.7", + "generic-array", "rand_core 0.6.4", - "subtle 2.6.1", + "subtle", "zeroize", ] @@ -1479,21 +1451,11 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array 0.14.7", + "generic-array", "rand_core 0.6.4", "typenum", ] -[[package]] -name = "crypto-mac" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" -dependencies = [ - "generic-array 0.12.4", - "subtle 1.0.0", -] - [[package]] name = "cssparser" version = "0.27.2" @@ -1559,7 +1521,7 @@ dependencies = [ "fiat-crypto", "rustc_version", "serde", - "subtle 2.6.1", + "subtle", "zeroize", ] @@ -1800,22 +1762,13 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -dependencies = [ - "generic-array 0.12.4", -] - [[package]] name = "digest" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.7", + "generic-array", ] [[package]] @@ -1827,7 +1780,7 @@ dependencies = [ "block-buffer 0.10.4", "const-oid", "crypto-common", - "subtle 2.6.1", + "subtle", ] [[package]] @@ -2019,7 +1972,7 @@ dependencies = [ "rand_core 0.6.4", "serde", "sha2 0.10.9", - "subtle 2.6.1", + "subtle", "zeroize", ] @@ -2054,7 +2007,7 @@ dependencies = [ "crypto-bigint", "digest 0.10.7", "ff", - "generic-array 0.14.7", + "generic-array", "group", "hkdf", "pem-rfc7468", @@ -2062,7 +2015,7 @@ dependencies = [ "rand_core 0.6.4", "sec1", "serdect 0.2.0", - "subtle 2.6.1", + "subtle", "zeroize", ] @@ -2242,7 +2195,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" dependencies = [ "rand_core 0.6.4", - "subtle 2.6.1", + "subtle", ] [[package]] @@ -2601,15 +2554,6 @@ dependencies = [ "windows 0.58.0", ] -[[package]] -name = "generic-array" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" -dependencies = [ - "typenum", -] - [[package]] name = "generic-array" version = "0.14.7" @@ -2675,7 +2619,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" dependencies = [ - "opaque-debug 0.3.1", + "opaque-debug", "polyval", ] @@ -2789,7 +2733,7 @@ checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core 0.6.4", - "subtle 2.6.1", + "subtle", ] [[package]] @@ -3547,7 +3491,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" dependencies = [ - "generic-array 0.14.7", + "generic-array", ] [[package]] @@ -3808,12 +3752,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "keystream" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33070833c9ee02266356de0c43f723152bd38bd96ddf52c82b3af10c9138b28" - [[package]] name = "kuchikiki" version = "0.8.2" @@ -3905,18 +3843,6 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" -[[package]] -name = "lioness" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae926706ba42c425c9457121178330d75e273df2e82e28b758faf3de3a9acb9" -dependencies = [ - "arrayref", - "blake2 0.8.1", - "chacha", - "keystream", -] - [[package]] name = "litemap" version = "0.7.5" @@ -4336,7 +4262,7 @@ dependencies = [ "rand_core 0.6.4", "serde", "serdect 0.3.0", - "subtle 2.6.1", + "subtle", "zeroize", ] @@ -4370,7 +4296,7 @@ dependencies = [ "rand 0.8.5", "serde", "sha2 0.10.9", - "subtle 2.6.1", + "subtle", "thiserror 2.0.12", "zeroize", ] @@ -4431,7 +4357,6 @@ dependencies = [ "ed25519-dalek", "jwt-simple", "nym-pemstore", - "nym-sphinx-types", "rand 0.8.5", "serde", "serde_bytes", @@ -4681,21 +4606,13 @@ dependencies = [ "time", ] -[[package]] -name = "nym-sphinx-types" -version = "1.20.4" -dependencies = [ - "sphinx-packet", - "thiserror 2.0.12", -] - [[package]] name = "nym-store-cipher" version = "1.20.4" dependencies = [ "aes-gcm", "argon2", - "generic-array 0.14.7", + "generic-array", "getrandom 0.2.15", "rand 0.8.5", "serde", @@ -5113,12 +5030,6 @@ dependencies = [ "portable-atomic", ] -[[package]] -name = "opaque-debug" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" - [[package]] name = "opaque-debug" version = "0.3.1" @@ -5322,7 +5233,7 @@ checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" dependencies = [ "base64ct", "rand_core 0.6.4", - "subtle 2.6.1", + "subtle", ] [[package]] @@ -5698,7 +5609,7 @@ checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" dependencies = [ "cfg-if", "cpufeatures", - "opaque-debug 0.3.1", + "opaque-debug", "universal-hash", ] @@ -6031,16 +5942,6 @@ dependencies = [ "getrandom 0.3.2", ] -[[package]] -name = "rand_distr" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" -dependencies = [ - "num-traits", - "rand 0.8.5", -] - [[package]] name = "rand_hc" version = "0.2.0" @@ -6290,7 +6191,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ "hmac", - "subtle 2.6.1", + "subtle", ] [[package]] @@ -6364,7 +6265,7 @@ dependencies = [ "sha2 0.10.9", "signature", "spki", - "subtle 2.6.1", + "subtle", "zeroize", ] @@ -6439,7 +6340,7 @@ dependencies = [ "ring", "rustls-pki-types", "rustls-webpki 0.103.9", - "subtle 2.6.1", + "subtle", "zeroize", ] @@ -6631,10 +6532,10 @@ checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", - "generic-array 0.14.7", + "generic-array", "pkcs8", "serdect 0.2.0", - "subtle 2.6.1", + "subtle", "zeroize", ] @@ -6939,7 +6840,7 @@ dependencies = [ "cfg-if", "cpufeatures", "digest 0.9.0", - "opaque-debug 0.3.1", + "opaque-debug", ] [[package]] @@ -7098,32 +6999,6 @@ dependencies = [ "system-deps", ] -[[package]] -name = "sphinx-packet" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c26f0c20d909fdda1c5d0ece3973127ca421984d55b000215df365e93722fc6e" -dependencies = [ - "aes", - "arrayref", - "blake2 0.8.1", - "bs58", - "byteorder", - "chacha", - "ctr", - "curve25519-dalek", - "digest 0.10.7", - "hkdf", - "hmac", - "lioness", - "rand 0.8.5", - "rand_distr", - "sha2 0.10.9", - "subtle 2.6.1", - "x25519-dalek", - "zeroize", -] - [[package]] name = "spin" version = "0.9.8" @@ -7204,12 +7079,6 @@ dependencies = [ "syn 2.0.100", ] -[[package]] -name = "subtle" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" - [[package]] name = "subtle" version = "2.6.1" @@ -7798,7 +7667,7 @@ dependencies = [ "serde_repr", "sha2 0.10.9", "signature", - "subtle 2.6.1", + "subtle", "subtle-encoding", "tendermint-proto", "time", @@ -7853,7 +7722,7 @@ dependencies = [ "serde", "serde_bytes", "serde_json", - "subtle 2.6.1", + "subtle", "subtle-encoding", "tendermint", "tendermint-config", @@ -8437,7 +8306,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ "crypto-common", - "subtle 2.6.1", + "subtle", ] [[package]] From 5fc2936d3f32f2b84598b9254ee3388384e5d8cd Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Wed, 11 Feb 2026 11:52:55 +0000 Subject: [PATCH 51/56] Max/quick patch docs (#6447) * patch missing file + remove gitignore config * patch missing file + remove gitignore config --- .gitignore | 1 - .../docs/components/outputs/api-scraping-outputs/time-now.md | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 documentation/docs/components/outputs/api-scraping-outputs/time-now.md diff --git a/.gitignore b/.gitignore index fa4df4495d..988c9e1691 100644 --- a/.gitignore +++ b/.gitignore @@ -67,7 +67,6 @@ nym-api/redocly/formatted-openapi.json *.profraw .beads CLAUDE.md -docs .claude .superego diff --git a/documentation/docs/components/outputs/api-scraping-outputs/time-now.md b/documentation/docs/components/outputs/api-scraping-outputs/time-now.md new file mode 100644 index 0000000000..1aaa64f171 --- /dev/null +++ b/documentation/docs/components/outputs/api-scraping-outputs/time-now.md @@ -0,0 +1 @@ +Wednesday, February 11th 2026, 11:35:05 UTC From e7fcaa980f2dc4385ed6d3acc2cf48a2be54b373 Mon Sep 17 00:00:00 2001 From: Jack Wampler Date: Wed, 11 Feb 2026 07:04:53 -0700 Subject: [PATCH 52/56] HTTP & DNS Improvements (#6423) * Improve HTTP use of connection pooling (#6375) * add swap to system resolver instead of fallback (#6376) * add header tracking outer host name used in stealth requests (#6389) * Rotate urls on parse failure (#6383) * Add shared settings for stealth policy across HTTP clients (#6388) * Better controls for global interaction w/ static DNS (#6374) --- common/http-api-client/src/dns.rs | 296 +++++++++++----- common/http-api-client/src/dns/constants.rs | 6 + .../src/dns/static_resolver.rs | 331 +++++++++++++++--- common/http-api-client/src/fronted.rs | 233 +++++++++++- common/http-api-client/src/lib.rs | 269 +++++++++----- common/http-api-client/src/tests.rs | 5 +- common/http-api-client/src/url.rs | 10 + 7 files changed, 908 insertions(+), 242 deletions(-) diff --git a/common/http-api-client/src/dns.rs b/common/http-api-client/src/dns.rs index 0d61c75362..b055dbfd0c 100644 --- a/common/http-api-client/src/dns.rs +++ b/common/http-api-client/src/dns.rs @@ -46,7 +46,10 @@ use std::{ collections::HashMap, net::{IpAddr, SocketAddr}, str::FromStr, - sync::{Arc, LazyLock}, + sync::{ + Arc, LazyLock, + atomic::{AtomicBool, Ordering::Relaxed}, + }, time::Duration, }; @@ -70,14 +73,23 @@ pub(crate) const DEFAULT_QUERY_TIMEOUT: Duration = Duration::from_secs(5); impl ClientBuilder { /// Override the DNS resolver implementation used by the underlying http client. + /// This forces the use of an independent request executor (via [`Self::non_shared`]). pub fn dns_resolver(mut self, resolver: Arc) -> Self { - self.reqwest_client_builder = self.reqwest_client_builder.dns_resolver(resolver); + self = self.non_shared(); + // because of the call to non-shared this conditional should always run. + if let Some(rb) = self.reqwest_client_builder { + self.reqwest_client_builder = Some(rb.dns_resolver(resolver)); + } self.use_secure_dns = false; self } - /// Override the DNS resolver implementation used by the underlying http client. + /// Override the DNS resolver implementation used by the underlying http client. If + /// [`Self::dns_resolver`] is called directly that will take priority over this, there is no + /// need to call both. + /// This forces the use of an independent request executor (via [`Self::non_shared`]). pub fn no_hickory_dns(mut self) -> Self { + self = self.non_shared(); self.use_secure_dns = false; self } @@ -129,7 +141,8 @@ pub struct HickoryDnsResolver { // Tokio Runtime in initialization, so we must delay the actual // construction of the resolver. state: Arc>, - fallback: Option>>, + use_system: Arc, + system_resolver: Arc>, static_base: Option>>, use_shared: bool, /// Overall timeout for dns lookup associated with any individual host resolution. For example, @@ -141,7 +154,8 @@ impl Default for HickoryDnsResolver { fn default() -> Self { Self { state: Default::default(), - fallback: Default::default(), + use_system: Arc::new(AtomicBool::new(false)), + system_resolver: Default::default(), static_base: Some(Default::default()), use_shared: true, overall_dns_timeout: DEFAULT_OVERALL_LOOKUP_TIMEOUT, @@ -151,16 +165,28 @@ impl Default for HickoryDnsResolver { impl Resolve for HickoryDnsResolver { fn resolve(&self, name: Name) -> Resolving { - let resolver = self.state.clone(); - let maybe_fallback = self.fallback.clone(); - let maybe_static = self.static_base.clone(); + let use_system = self.use_system.load(std::sync::atomic::Ordering::Relaxed); let use_shared = self.use_shared; + let resolver = if use_system { + match self + .system_resolver + .get_or_try_init(|| HickoryDnsResolver::new_resolver_system(use_shared)) + { + Ok(r) => r.clone(), + Err(e) => return Box::pin(return_err(e)), + } + } else { + self.state + .get_or_init(|| HickoryDnsResolver::new_resolver(use_shared)) + .clone() + }; + + let maybe_static = self.static_base.clone(); let overall_dns_timeout = self.overall_dns_timeout; Box::pin(async move { resolve( name, resolver, - maybe_fallback, maybe_static, use_shared, overall_dns_timeout, @@ -171,16 +197,17 @@ impl Resolve for HickoryDnsResolver { } } +async fn return_err(e: ResolveError) -> Result> { + Err(Box::new(e) as Box) +} + async fn resolve( name: Name, - resolver: Arc>, - maybe_fallback: Option>>, + resolver: TokioResolver, maybe_static: Option>>, independent: bool, overall_dns_timeout: Duration, ) -> Result { - let resolver = resolver.get_or_init(|| HickoryDnsResolver::new_resolver(independent)); - // try checking the static table to see if any of the addresses in the table have been // looked up previously within the timeout to where we are not yet ready to try the // default resolver yet again. @@ -214,22 +241,6 @@ async fn resolve( } }; - // If the primary resolver encountered an error, attempt a lookup using the fallback - // resolver if one is configured. - if let Some(ref fallback) = maybe_fallback { - let resolver = - fallback.get_or_try_init(|| HickoryDnsResolver::new_resolver_system(independent))?; - - let resolve_fut = - tokio::time::timeout(overall_dns_timeout, resolver.lookup_ip(name.as_str())); - if let Ok(Ok(lookup)) = resolve_fut.await { - let addrs: Addrs = Box::new(SocketAddrs { - iter: lookup.into_iter(), - }); - return Ok(addrs); - } - } - // If no record has been found and a static map of fallback addresses is configured // check the table for our entry if let Some(ref static_resolver) = maybe_static { @@ -258,6 +269,11 @@ impl Iterator for SocketAddrs { } impl HickoryDnsResolver { + /// Returns an instance of the shared resolver. + pub fn shared() -> Self { + SHARED_RESOLVER.clone() + } + /// Attempt to resolve a domain name to a set of ['IpAddr']s pub async fn resolve_str( &self, @@ -265,10 +281,20 @@ impl HickoryDnsResolver { ) -> Result + use<>, ResolveError> { let n = Name::from_str(name).map_err(|_| ResolveError::InvalidNameError(name.to_string()))?; + let use_system = self.use_system.load(std::sync::atomic::Ordering::Relaxed); + let resolver = if use_system { + self.system_resolver + .get_or_try_init(|| HickoryDnsResolver::new_resolver_system(self.use_shared))? + .clone() + } else { + self.state + .get_or_init(|| HickoryDnsResolver::new_resolver(self.use_shared)) + .clone() + }; + resolve( n, - self.state.clone(), - self.fallback.clone(), + resolver, self.static_base.clone(), self.use_shared, self.overall_dns_timeout, @@ -298,13 +324,11 @@ impl HickoryDnsResolver { fn new_resolver_system(use_shared: bool) -> Result { // using a closure here is slightly gross, but this makes sure that if the // lazy-init returns an error it can be handled by the client - if !use_shared || SHARED_RESOLVER.fallback.is_none() { + if !use_shared { new_resolver_system() } else { Ok(SHARED_RESOLVER - .fallback - .as_ref() - .unwrap() + .system_resolver .get_or_try_init(new_resolver_system)? .clone()) } @@ -320,45 +344,80 @@ impl HickoryDnsResolver { } } - /// Enable fallback to the system default resolver if the primary (DoX) resolver fails - pub fn enable_system_fallback(&mut self) -> Result<(), ResolveError> { - self.fallback = Some(Default::default()); - let _ = self - .fallback - .as_ref() - .unwrap() - .get_or_try_init(new_resolver_system)?; + /// Swap the primary internal resolver to the system resolver rather than the + /// configured custom resolver. + pub fn use_system_resolver(&self) { + self.use_system.store(true, Relaxed); - // IF THIS INSTANCE IS A FRONT FOR THE SHARED RESOLVER SHOULDN'T THIS FN ENABLE THE SYSTEM FALLBACK FOR THE SHARED RESOLVER TOO? - // if self.use_shared { - // SHARED_RESOLVER.enable_system_fallback()?; - // } - Ok(()) + if self.use_shared { + SHARED_RESOLVER.use_system_resolver(); + } } - /// Disable fallback resolution. If the primary resolver fails the error is - /// returned immediately - pub fn disable_system_fallback(&mut self) { - self.fallback = None; + /// Swap the primary internal resolver to the configured custom resolver rather than the + /// system resolver. + pub fn use_configured_resolver(&self) { + self.use_system.store(false, Relaxed); - // // IF THIS INSTANCE IS A FRONT FOR THE SHARED RESOLVER SHOULDN'T THIS FN ENABLE THE SYSTEM FALLBACK FOR THE SHARED RESOLVER TOO? - // if self.use_shared { - // SHARED_RESOLVER.fallback = None; - // } + if self.use_shared { + SHARED_RESOLVER.use_configured_resolver(); + } } - /// Get the current map of hostname to address in use by the fallback static lookup if one + /// Clear entries from the static table that would return entries during the pre-resolve stage. + /// This means that all lookups will attempt to use the network resolver again before the static + /// table is consulted. + /// + /// Entries elevated to pre-resolve from fallback (added from default or using + /// [`set_fallback`]`) will have their cache timeout cleared. Entries added directly to + /// pre-resolve (using [`Self::set_static_preresolve`]) will be removed. + pub fn clear_preresolve(&self) { + debug!("clearing pre-resolve table"); + if let Some(cell) = &self.static_base + && let Some(static_base) = cell.get() + { + static_base.clear_preresolve() + } + } + + /// Get the current map of hostnames to addresses used in the fallback static lookup stage if one /// exists. pub fn get_static_fallbacks(&self) -> Option>> { - Some(self.static_base.as_ref()?.get()?.get_addrs()) + Some(self.static_base.as_ref()?.get()?.get_fallback_addrs()) } /// Set (or overwrite) the map of addresses used in the fallback static hostname lookup - pub fn set_static_fallbacks(&mut self, addrs: HashMap>) { - let cell = OnceCell::new(); - cell.set(StaticResolver::new(addrs)) - .expect("infallible assign"); - self.static_base = Some(Arc::new(cell)); + pub fn set_fallback_addrs(&mut self, addrs: HashMap>) { + debug!("setting fallback entries for {:?}", addrs.keys()); + if self.static_base.is_none() { + let cell = OnceCell::new(); + self.static_base = Some(Arc::new(cell)); + } + self.static_base + .as_ref() + .unwrap() + .get_or_init(|| Self::new_static_fallback(self.use_shared)) + .set_fallback(addrs); + } + + /// Get the current map of hostnames to addresses used in the preresolve static lookup stage + /// if one exists. + pub fn get_static_preresolve(&self) -> Option>> { + Some(self.static_base.as_ref()?.get()?.get_preresolve_addrs()) + } + + /// Set (or overwrite) the map of addresses used in the preresolve static hostname lookup + pub fn set_static_preresolve(&mut self, addrs: HashMap>) { + debug!("setting pre-resolve entries for {:?}", addrs.keys()); + if self.static_base.is_none() { + let cell = OnceCell::new(); + self.static_base = Some(Arc::new(cell)); + } + self.static_base + .as_ref() + .unwrap() + .get_or_init(|| Self::new_static_fallback(self.use_shared)) + .set_preresolve(addrs); } /// Successfully resolved addresses are cached for a minimum of 30 minutes @@ -495,7 +554,7 @@ fn new_resolver_system() -> Result { } fn new_default_static_fallback() -> StaticResolver { - StaticResolver::new(constants::default_static_addrs()) + StaticResolver::new().with_fallback(constants::default_static_addrs()) } /// Do a trial resolution using each nameserver individually to test which are working and which @@ -532,10 +591,7 @@ mod test { use super::*; use itertools::Itertools; use std::collections::HashMap; - use std::{ - net::{IpAddr, Ipv4Addr, Ipv6Addr}, - time::Instant, - }; + use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; /// IP addresses guaranteed to fail attempts to resolve /// @@ -597,7 +653,7 @@ mod test { let example_ip6: IpAddr = "dead::beef".parse().unwrap(); addr_map.insert(example_domain.to_string(), vec![example_ip4, example_ip6]); - resolver.set_static_fallbacks(addr_map); + resolver.set_fallback_addrs(addr_map); let mut addrs = resolver.resolve_str(example_domain).await?; assert!(addrs.contains(&example_ip4)); @@ -738,18 +794,19 @@ mod test { } #[tokio::test] - #[ignore] - // this test is dependent of external network setup -- i.e. blocking all traffic to the default - // resolvers. Otherwise the default resolvers will succeed without using the static fallback, - // making the test pointless + #[cfg(any())] // #[ignore] we run --ignore in CI/CD assuming it just means slow -_- + // This test impacts the state of the shared resolver and as such is disabled to avoid + // interference with other tests. + // + // this test is dependent of external network setup -- i.e. blocking all traffic to the + // default resolvers. Otherwise the default resolvers will succeed without using the static + // fallback, making the test pointless async fn dns_lookup_failure_on_shared() -> Result<(), ResolveError> { - let time_start = Instant::now(); - let r = OnceCell::new(); - r.set(build_broken_resolver().expect("failed to build resolver")) - .expect("broken resolver init error"); + let resolver1 = HickoryDnsResolver::shared(); - // create a new resolver that won't mess with the shared resolver used by other tests - let resolver = HickoryDnsResolver::default(); + let time_start = std::time::Instant::now(); + // create a new resolver that uses the shared resolver + let resolver = HickoryDnsResolver::shared(); // successful lookup using fallback to static resolver let domain = "rpc.nymtech.net"; @@ -758,9 +815,27 @@ mod test { .await .expect("failed to resolve address in static lookup"); - println!( - "{}ms resolved {domain}", - (Instant::now() - time_start).as_millis() + let lookup_dur = Instant::now() - time_start; + assert!( + lookup_dur > resolver.overall_dns_timeout, + "expected lookup timeout - took {}ms", + (lookup_dur).as_millis() + ); + + let time_start = std::time::Instant::now(); + // successful lookup using pre-resolve entry promoted from fallback + let domain = "rpc.nymtech.net"; + let _ = resolver1 + .resolve_str(domain) + .await + .expect("domain expected to be in pre-resolve"); + + // this lookup should basically be instant as we are using pre-resolve + let lookup_dur = std::time::Instant::now() - time_start; + assert!( + lookup_dur < Duration::from_millis(10), + "expected instant - took {}ms", + (lookup_dur).as_millis() ); // unsuccessful lookup - primary times out, and not in static table @@ -771,5 +846,62 @@ mod test { // assert!(result.is_err_and(|e| matches!(e, ResolveError::ResolveError(e) if e.is_nx_domain()))); Ok(()) } + + #[tokio::test] + #[cfg(any())] // #[ignore] we run --ignore in CI/CD assuming it just means slow -_- + // This test impacts the state of the shared resolver and as such is disabled to avoid + // interference with other tests. + async fn setting_dns_fallbacks_with_shared_resolver() -> Result<(), ResolveError> { + let resolver1 = HickoryDnsResolver::shared(); + + // create a new resolver that uses the shared resolver + let mut resolver = HickoryDnsResolver::shared(); + + let example_domains = [ + String::from("static1.nymvpn.com"), + String::from("static2.nymvpn.com"), + ]; + let mut addr_map1 = HashMap::new(); + addr_map1.insert( + example_domains[0].clone(), + vec![Ipv4Addr::new(10, 10, 10, 10).into()], + ); + addr_map1.insert( + example_domains[1].clone(), + vec![Ipv4Addr::new(1, 1, 1, 1).into()], + ); + + resolver.set_static_preresolve(addr_map1); + + let time_start = std::time::Instant::now(); + // successful lookup using pre-resolve entry promoted from fallback + let _ = resolver1 + .resolve_str(&example_domains[0]) + .await + .expect("domain expected to be in pre-resolve"); + + // this lookup should basically be instant as we are using pre-resolve + let lookup_dur = std::time::Instant::now() - time_start; + assert!( + lookup_dur < Duration::from_millis(10), + "expected instant - took {}ms", + (lookup_dur).as_millis() + ); + + // After clearing the pre-resolve in one instance of the shared resolver ... + resolver.clear_preresolve(); + + // ... other instances have their pre-resolve entries cleared. + let prereslve_lookup = resolver1 + .static_base + .as_ref() + .unwrap() + .get() + .unwrap() + .pre_resolve(&example_domains[0]); + assert!(prereslve_lookup.is_none()); + + Ok(()) + } } } diff --git a/common/http-api-client/src/dns/constants.rs b/common/http-api-client/src/dns/constants.rs index b13d6f3fde..5a7c35037f 100644 --- a/common/http-api-client/src/dns/constants.rs +++ b/common/http-api-client/src/dns/constants.rs @@ -72,6 +72,12 @@ pub const NYM_RPC_IPS: &[IpAddr] = &[ )), ]; +#[allow(unused)] +pub fn empty_static_addrs() -> HashMap> { + HashMap::new() +} + +#[allow(unused)] pub fn default_static_addrs() -> HashMap> { let mut m = HashMap::new(); m.insert(NYM_API_DOMAIN.to_string(), NYM_API_IPS.to_vec()); diff --git a/common/http-api-client/src/dns/static_resolver.rs b/common/http-api-client/src/dns/static_resolver.rs index 8660044735..7c2dbed576 100644 --- a/common/http-api-client/src/dns/static_resolver.rs +++ b/common/http-api-client/src/dns/static_resolver.rs @@ -14,42 +14,78 @@ const DEFAULT_PRE_RESOLVE_TIMEOUT: Duration = super::DEFAULT_POSITIVE_LOOKUP_CAC #[derive(Debug, Default, Clone)] pub struct StaticResolver { - static_addr_map: Arc>>, + fallback_addr_map: Arc>>>, + preresolve_addr_map: Arc>>, pre_resolve_timeout: Option, } +#[derive(Debug, Clone, Default)] +enum PreResolveStatus { + #[default] + Valid, + ValidUntil(Instant), +} + #[derive(Debug, Clone, Default)] struct Entry { - valid_for_pre_resolve_until: Option, + status: PreResolveStatus, addrs: Vec, } impl Entry { fn new(addrs: Vec) -> Self { Self { - valid_for_pre_resolve_until: None, + status: PreResolveStatus::Valid, addrs, } } + + fn new_timeout(addrs: Vec, timeout: Duration) -> Self { + Self { + status: PreResolveStatus::ValidUntil(Instant::now() + timeout), + addrs, + } + } + + fn is_valid(&self) -> bool { + match self.status { + PreResolveStatus::Valid => true, + PreResolveStatus::ValidUntil(t) => t > Instant::now(), + } + } } impl StaticResolver { - pub fn new(static_entries: HashMap>) -> StaticResolver { - debug!("building static resolver"); - let static_entries = static_entries - .into_iter() - .map(|(name, ips)| (name, Entry::new(ips))) - .collect(); + pub fn new() -> StaticResolver { Self { - static_addr_map: Arc::new(Mutex::new(static_entries)), + fallback_addr_map: Arc::new(Mutex::new(HashMap::new())), + preresolve_addr_map: Arc::new(Mutex::new(HashMap::new())), pre_resolve_timeout: Some(DEFAULT_PRE_RESOLVE_TIMEOUT), } } - /// Return the full set of domain names and associated addresses stored in this static lookup table - pub fn get_addrs(&self) -> HashMap> { + /// Initialize the contents of the pre-resolve table for this instance of the static resolver + #[allow(unused)] + pub fn with_preresolve(mut self, entries: HashMap>) -> Self { + let entries = entries + .into_iter() + .map(|(name, ips)| (name, Entry::new(ips))) + .collect(); + self.preresolve_addr_map = Arc::new(Mutex::new(entries)); + self + } + + /// Initialize the contenes of the fallback table for this instance of the static resolver + pub fn with_fallback(mut self, entries: HashMap>) -> Self { + self.fallback_addr_map = Arc::new(Mutex::new(entries)); + self + } + + /// Return the set of domain names and associated addresses stored in the pre-resolve static + /// lookup table + pub fn get_preresolve_addrs(&self) -> HashMap> { let mut out = HashMap::new(); - self.static_addr_map + self.preresolve_addr_map .lock() .unwrap() .iter() @@ -59,6 +95,38 @@ impl StaticResolver { out } + /// Return the set of domain names and associated addresses stored in the fallback static lookup + /// table + pub fn get_fallback_addrs(&self) -> HashMap> { + self.fallback_addr_map.lock().unwrap().clone() + } + + /// Set (or overwrite) the map of static addresses to be returned only after attempting a lookup + /// over the network resolver. + pub fn set_fallback(&self, addrs: HashMap>) { + self.fallback_addr_map.lock().unwrap().extend(addrs); + } + + /// Clear entries from the static table that would return entries during the pre-resolve stage. + /// This means that all lookups will attempt to use the network resolver again before the static + /// table is consulted. + /// + /// Entries elevated to pre-resolve from fallback (added from default or using + /// [`set_fallback`]`) will have their cache timeout cleared. Entries added directly to + /// pre-resolve (using [`Self::preresolve_to_addrs`]) will be removed. + pub fn clear_preresolve(&self) { + *self.preresolve_addr_map.lock().unwrap() = HashMap::new(); + } + + /// Set (or overwrite) the map of static addresses and mark these domains to be returned + /// WITHOUT attempting a lookup over the network resolver. + pub fn set_preresolve(&self, addrs: HashMap>) { + let mut current_map = self.preresolve_addr_map.lock().unwrap(); + for (domain, ips) in addrs.into_iter() { + _ = current_map.insert(domain, Entry::new(ips)) + } + } + /// Change the timeout for which domains can be pre-resolved after they are looked up in the /// static lookup table. #[allow(unused)] @@ -71,44 +139,58 @@ impl StaticResolver { /// recently (within the configured timeout) looked it up previously in this static table using /// a regular resolve. pub fn pre_resolve(&self, name: &str) -> Option> { - debug!("found {name:?} in pre-resolve static table resolver"); - - self.pre_resolve_timeout?; - - self.static_addr_map + self.preresolve_addr_map .lock() .unwrap() .get(name) - .filter(|e| { - e.valid_for_pre_resolve_until - .is_some_and(|t| t > Instant::now()) + .filter(|entry| entry.is_valid()) + .map(|entry| { + debug!("pre-resolve lookup hit for \"{name:?}\" in static table resolver"); + entry.addrs.clone() }) - .map(|e| e.addrs.clone()) } #[allow(unused)] pub fn resolve_str(&self, name: &str) -> Option> { Self::resolve_inner( - self.static_addr_map.lock().unwrap(), + self.fallback_addr_map.lock().unwrap(), + self.preresolve_addr_map.lock().unwrap(), name, self.pre_resolve_timeout, ) - .map(|e| e.addrs) } fn resolve_inner( - mut table: MutexGuard<'_, HashMap>, + fallback_table: MutexGuard<'_, HashMap>>, + mut preresolve_table: MutexGuard<'_, HashMap>, name: &str, - timeout: Option, - ) -> Option { - let resolved = table.get_mut(name)?; + pre_resolve_cache_timeout: Option, + ) -> Option> { + let resolved = fallback_table.get(name)?; - debug!("found {name:?} in static table resolver"); + debug!("lookup hit for \"{name:?}\" in static table resolver"); - if let Some(pre_resolve_timeout) = timeout { - // We had to look this entry up and a pre-resolve duration is defined, so it will - // trigger in pre-resolve lookups for the next _timeout_ window. - resolved.valid_for_pre_resolve_until = Some(Instant::now() + pre_resolve_timeout); + // We had to look this entry up and a pre-resolve duration is defined, so it will + // trigger in pre-resolve lookups for the next _timeout_ window if it wasn't already + // triggering. + if let Some(pre_resolve_timeout) = pre_resolve_cache_timeout { + match preresolve_table.get_mut(name) { + None => { + _ = preresolve_table.insert( + name.to_string(), + Entry::new_timeout(resolved.clone(), pre_resolve_timeout), + ); + } + // Not sure how we would get cases where this is Some( ) -- it requires having a + // Valid entry in the preresolve table and still doing a lookup against fallback. + Some(entry) if matches!(entry.status, PreResolveStatus::ValidUntil(_)) => { + _ = preresolve_table.insert( + name.to_string(), + Entry::new_timeout(resolved.clone(), pre_resolve_timeout), + ); + } + _ => {} + } } Some(resolved.clone()) } @@ -117,13 +199,23 @@ impl StaticResolver { impl Resolve for StaticResolver { fn resolve(&self, name: Name) -> Resolving { debug!("looking up {name:?} in static resolver"); - let addr_map = self.static_addr_map.clone(); + // these should clone arcs, not the actual tables + let fallback_addr_map = self.fallback_addr_map.clone(); + let presesolve_addr_map = self.preresolve_addr_map.clone(); let timeout = self.pre_resolve_timeout; + // Also the returned future doesn't try to take the lock on the tables until the + // future is awaited, so no blocking issues. Box::pin(async move { - let addr_map = addr_map.lock().unwrap(); - let lookup = match Self::resolve_inner(addr_map, name.as_str(), timeout) { + let fallback_addr_map = fallback_addr_map.lock().unwrap(); + let presesolve_addr_map = presesolve_addr_map.lock().unwrap(); + let lookup = match Self::resolve_inner( + fallback_addr_map, + presesolve_addr_map, + name.as_str(), + timeout, + ) { None => return Err(ResolveError::StaticLookupMiss.into()), - Some(entry) => entry.addrs, + Some(addrs) => addrs, }; let addrs: Addrs = Box::new( lookup @@ -142,6 +234,7 @@ mod test { use super::*; use std::error::Error as StdError; + use std::net::Ipv4Addr; use std::str::FromStr; #[tokio::test] @@ -149,7 +242,7 @@ mod test { let example_domain = String::from("static.nymvpn.com"); // lookup for domain for which there is no entry - let resolver = StaticResolver::new(HashMap::new()); + let resolver = StaticResolver::new(); let url = reqwest::dns::Name::from_str(&example_domain).unwrap(); let result = resolver.resolve(url).await; @@ -166,7 +259,7 @@ mod test { addr_map.insert(example_domain.clone(), vec![example_ip4, example_ip6]); let url = reqwest::dns::Name::from_str(&example_domain).unwrap(); - let resolver = StaticResolver::new(addr_map); + let resolver = StaticResolver::new().with_fallback(addr_map); let mut addrs = resolver.resolve(url).await?; assert!(addrs.contains(&SocketAddr::new(example_ip4, 0))); assert!(addrs.contains(&SocketAddr::new(example_ip6, 0))); @@ -175,7 +268,7 @@ mod test { } #[test] - fn static_lookup_pre_resolve() { + fn elevate_fallback_to_pre_resolve() { let example_duration = Duration::from_secs(3); let example_domain = String::from("static.nymvpn.com"); let mut addr_map = HashMap::new(); @@ -183,24 +276,23 @@ mod test { let example_ip6: IpAddr = "dead::beef".parse().unwrap(); addr_map.insert(example_domain.clone(), vec![example_ip4, example_ip6]); - let resolver = StaticResolver::new(addr_map).with_pre_resolve_timeout(example_duration); + let resolver = StaticResolver::new() + .with_fallback(addr_map) + .with_pre_resolve_timeout(example_duration); // ensure that attempting to pre-resolve without first resolving returns none let result = resolver.pre_resolve(&example_domain); assert!(result.is_none()); // resolving should now update the pre-resolve validity timeout for the entry - let entry = StaticResolver::resolve_inner( - resolver.static_addr_map.lock().unwrap(), - &example_domain, - Some(example_duration), - ) - .expect("missing entry???!!!!"); - assert!( - entry - .valid_for_pre_resolve_until - .is_some_and(|t| t < Instant::now() + example_duration) - ); + let _addrs = resolver + .resolve_str(&example_domain) + .expect("entry should exist"); + assert!(matches!( + resolver.preresolve_status(&example_domain), + Some(PreResolveStatus::ValidUntil(t)) + if t < Instant::now() + example_duration + )); // check that pre-resolve now returns the expected record let addrs = resolver @@ -214,4 +306,139 @@ mod test { let result = resolver.pre_resolve(&example_domain); assert!(result.is_none()); } + + #[test] + fn set_and_use_preresolve() { + let example_duration = Duration::from_secs(3); + let example_domains = [ + String::from("static1.nymvpn.com"), + String::from("static2.nymvpn.com"), + String::from("preresolve.nymvpn.com"), + ]; + let mut addr_map1 = HashMap::new(); + addr_map1.insert( + example_domains[0].clone(), + vec![Ipv4Addr::new(10, 10, 10, 10).into()], + ); + addr_map1.insert( + example_domains[1].clone(), + vec![Ipv4Addr::new(1, 1, 1, 1).into()], + ); + + let mut addr_map2 = HashMap::new(); + addr_map2.insert( + example_domains[1].clone(), + vec![Ipv4Addr::new(1, 1, 1, 1).into()], + ); + addr_map2.insert( + example_domains[2].clone(), + vec![Ipv4Addr::new(8, 8, 8, 8).into()], + ); + + let resolver = StaticResolver::new() + .with_fallback(addr_map1) + .with_pre_resolve_timeout(example_duration); + + // Attempting to pre-resolve without setting the table returns none + let result = resolver.pre_resolve(&example_domains[0]); + assert!(result.is_none()); + + resolver.set_preresolve(addr_map2); + + // After setting the pre-resolve, addresses in the the table are returned + let result = resolver.pre_resolve(&example_domains[1]); + assert!(result.is_some()); + + // If the domain wasn't in the pre-resolve table it returns none. + let result = resolver.pre_resolve(&example_domains[0]); + assert!(result.is_none()); + + resolver.clear_preresolve(); + } + + #[test] + fn preresolve_with_fallback() { + let example_duration = Duration::from_secs(3); + let example_domains = [ + String::from("static1.nymvpn.com"), + String::from("static2.nymvpn.com"), + String::from("preresolve.nymvpn.com"), + ]; + let mut addr_map1 = HashMap::new(); + addr_map1.insert( + example_domains[0].clone(), + vec![Ipv4Addr::new(10, 10, 10, 10).into()], + ); + addr_map1.insert( + example_domains[1].clone(), + vec![Ipv4Addr::new(1, 1, 1, 1).into()], + ); + + let mut addr_map2 = HashMap::new(); + addr_map2.insert( + example_domains[1].clone(), + vec![Ipv4Addr::new(1, 1, 1, 1).into()], + ); + addr_map2.insert( + example_domains[2].clone(), + vec![Ipv4Addr::new(8, 8, 8, 8).into()], + ); + + let resolver = StaticResolver::new() + .with_fallback(addr_map1) + .with_preresolve(addr_map2) + .with_pre_resolve_timeout(example_duration); + + // when using both pre-resolve and fallback elevating entries from fallback to pre-resolve + // leaves the entries as `Valid`. + assert!(matches!( + resolver.preresolve_status(&example_domains[1]), + Some(PreResolveStatus::Valid) + )); + let _addrs = resolver + .resolve_str(&example_domains[1]) + .expect("entry should exist"); + assert!(matches!( + resolver.preresolve_status(&example_domains[1]), + Some(PreResolveStatus::Valid) + )); + + // entries not already in pre-resolve get elevated with a timeout. + assert!(!resolver.preresolve_contains(&example_domains[0])); + let _addrs = resolver + .resolve_str(&example_domains[0]) + .expect("entry should exist"); + assert!(resolver.preresolve_contains(&example_domains[0])); + assert!(matches!( + resolver.preresolve_status(&example_domains[0]), + Some(PreResolveStatus::ValidUntil(_)) + )); + + // clearing the pre-resolve table doesn't impact the fallback table. + resolver.clear_preresolve(); + assert!(!resolver.preresolve_contains(&example_domains[0])); + assert!(!resolver.preresolve_contains(&example_domains[1])); + assert!(!resolver.preresolve_contains(&example_domains[2])); + assert!(!resolver.fallback_contains(&example_domains[0])); + assert!(!resolver.fallback_contains(&example_domains[1])); + } + + /// convenience functions for testing + impl StaticResolver { + fn preresolve_status(&self, name: &str) -> Option { + self.preresolve_addr_map + .lock() + .unwrap() + .get(name) + .map(|e| e.status.clone()) + } + + fn preresolve_contains(&self, name: &str) -> bool { + self.preresolve_addr_map.lock().unwrap().contains_key(name) + } + + fn fallback_contains(&self, name: &str) -> bool { + self.preresolve_addr_map.lock().unwrap().contains_key(name) + } + } } diff --git a/common/http-api-client/src/fronted.rs b/common/http-api-client/src/fronted.rs index be884264cf..e7da0a36c0 100644 --- a/common/http-api-client/src/fronted.rs +++ b/common/http-api-client/src/fronted.rs @@ -3,15 +3,21 @@ //! Utilities for and implementation of request tunneling -use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::{ + Arc, LazyLock, RwLock, + atomic::{AtomicBool, Ordering}, +}; use tracing::warn; -use crate::ClientBuilder; +use crate::{Client, ClientBuilder}; + +static SHARED_FRONTING_POLICY: LazyLock>> = + LazyLock::new(|| Arc::new(RwLock::new(FrontPolicy::Off))); // #[cfg(feature = "tunneling")] #[derive(Debug)] pub(crate) struct Front { - pub(crate) policy: FrontPolicy, + pub(crate) policy: Arc>, enabled: AtomicBool, } @@ -19,7 +25,7 @@ impl Clone for Front { fn clone(&self) -> Self { Self { policy: self.policy.clone(), - enabled: AtomicBool::new(self.enabled.load(Ordering::Relaxed)), + enabled: AtomicBool::new(false), } } } @@ -27,13 +33,30 @@ impl Clone for Front { impl Front { pub(crate) fn new(policy: FrontPolicy) -> Self { Self { - enabled: AtomicBool::new(policy == FrontPolicy::Always), + enabled: AtomicBool::new(false), + policy: Arc::new(RwLock::new(policy)), + } + } + + pub(crate) fn off() -> Self { + Self::new(FrontPolicy::Off) + } + + pub(crate) fn shared() -> Self { + let policy = SHARED_FRONTING_POLICY.clone(); + Self { + enabled: AtomicBool::new(false), policy, } } + pub(crate) fn set_policy(&self, policy: FrontPolicy) { + *self.policy.write().unwrap() = policy; + self.enabled.store(false, Ordering::Relaxed); + } + pub(crate) fn is_enabled(&self) -> bool { - match self.policy { + match *self.policy.read().unwrap() { FrontPolicy::Off => false, FrontPolicy::OnRetry => self.enabled.load(Ordering::Relaxed), FrontPolicy::Always => true, @@ -46,14 +69,13 @@ impl Front { if self.is_enabled() { return; } - if matches!(self.policy, FrontPolicy::OnRetry) { + if matches!(*self.policy.read().unwrap(), FrontPolicy::OnRetry) { self.enabled.store(true, Ordering::Relaxed); } } } #[derive(Debug, Default, PartialEq, Clone)] -#[cfg(feature = "tunneling")] /// Policy for when to use domain fronting for HTTP requests. pub enum FrontPolicy { /// Always use domain fronting for all requests. @@ -66,29 +88,208 @@ pub enum FrontPolicy { } impl ClientBuilder { - /// Enable and configure request tunneling for API requests. - #[cfg(feature = "tunneling")] - pub fn with_fronting(mut self, policy: FrontPolicy) -> Self { - let front = Front::new(policy); + /// Enable and configure request tunneling for API requests. If no front policy is + /// provided the shared fronting policy will be used. + pub fn with_fronting(mut self, policy: Option) -> Self { + let front = if let Some(p) = policy { + Front::new(p) + } else { + Front::shared() + }; // Check if any of the supplied urls even support fronting if !self.urls.iter().any(|url| url.has_front()) { warn!( - "fronting is enabled, but none of the supplied urls have configured fronting domains" + "fronting is enabled, but none of the supplied urls have configured fronting domains: {:?}", + self.urls ); } - self.front = Some(front); + self.front = front; self } } +impl Client { + /// Set the policy for enabling fronting. If fronting was previously unset this will set it, and + /// make it possible to enable (i.e [`FrontPolicy::Off`] will not enable it). + /// + /// Calling this function sets a custom policy for this client, disconnecting it from the shared + /// fronting policy -- i.e. changes applied through [`Client::set_shared_front_policy`] will not + /// be impact this client. + pub fn set_front_policy(&mut self, policy: FrontPolicy) { + self.front.set_policy(policy) + } + + /// Set the fronting policy for this client to follow the shared policy. + pub fn use_shared_front_policy(&mut self) { + self.front = Front::shared(); + } + + /// Set the fronting policy for all clients using the shared policy. + // + // NOTE: this does not reset the per-instance enabled flag like it will when using + // [`Front::set_front_policy`]. So if a client is using shared policy with the `OnRetry` policy + // and this function is used to swap that policy away from and then back to `OnRetry` the + // fronting will still be enabled. Noting this here just in case this triggers any corner cases + // down the road. + pub fn set_shared_front_policy(policy: FrontPolicy) { + *SHARED_FRONTING_POLICY.write().unwrap() = policy; + } +} + #[cfg(test)] mod tests { use super::*; use crate::{ApiClientCore, NO_PARAMS, Url}; + impl Front { + pub(crate) fn policy(&self) -> FrontPolicy { + self.policy.read().unwrap().clone() + } + } + + /// Policy can be set for an independent client and the update is applied properly + #[test] + fn set_policy_independent_client() { + let url1 = Url::new( + "https://validator.global.ssl.fastly.net", + Some(vec!["https://yelp.global.ssl.fastly.net"]), + ) + .unwrap(); + + let mut client1 = ClientBuilder::new(url1.clone()) + .unwrap() + .with_fronting(Some(FrontPolicy::Off)) + .build() + .unwrap(); + assert!(client1.front.policy() == FrontPolicy::Off); + + let client2 = ClientBuilder::new(url1.clone()) + .unwrap() + .with_fronting(Some(FrontPolicy::OnRetry)) + .build() + .unwrap(); + + // Ensure that setting the policy for a client it gets properly applied. + client1.set_front_policy(FrontPolicy::Always); + assert!(client1.front.policy() == FrontPolicy::Always); + + // ensure that setting the policy in a client NOT using the shared policy does NOT update + // the policy used by another client. + assert!(client2.front.policy() == FrontPolicy::OnRetry); + + // Ensure that the policy takes effect and is applied when setting host headers on outgoing + // requests + let req = client1 + .create_request(reqwest::Method::GET, &["/"], NO_PARAMS, None::<&()>) + .unwrap() + .build() + .unwrap(); + + let expected_host = url1.host_str().unwrap(); + assert!( + req.headers() + .get(reqwest::header::HOST) + .is_some_and(|h| h.to_str().unwrap() == expected_host), + "{:?} != {:?}", + expected_host, + req, + ); + + let expected_front = url1.front_str().unwrap(); + assert!( + req.url() + .host() + .is_some_and(|url| url.to_string() == expected_front), + "{:?} != {:?}", + expected_front, + req, + ); + } + + /// Policy can be set for the shared client and the update is applied properly + // NOTE THIS TEST IS DISABLED BECAUSE IT INTERACTS WITH THE SHARED POLICY AND AS SUCH CAN HAVE + // AN IMPACT ON OTHER TESTS + #[test] + #[cfg(any())] // #[ignore] we run --ignore in CI/CD assuming it just means slow -_- + fn set_policy_shared_client() { + let url1 = Url::new( + "https://validator.global.ssl.fastly.net", + Some(vec!["https://yelp.global.ssl.fastly.net"]), + ) + .unwrap(); + + Client::set_shared_front_policy(FrontPolicy::Off); + assert!(*SHARED_FRONTING_POLICY.read().unwrap() == FrontPolicy::Off); + + let client1 = ClientBuilder::new(url1.clone()) + .unwrap() + .with_fronting(None) + .build() + .unwrap(); + assert!(client1.front.policy() == FrontPolicy::Off); + + let mut client2 = ClientBuilder::new(url1.clone()) + .unwrap() + .with_fronting(Some(FrontPolicy::Off)) + .build() + .unwrap(); + + // Ensure that setting the shared policy gets properly applied + Client::set_shared_front_policy(FrontPolicy::Always); + assert!(client1.front.policy() == FrontPolicy::Always); + + // Setting the shared policy should NOT update clients NOT using the shared policy. + assert!(client2.front.policy() == FrontPolicy::Off); + + // Ensure that the policy takes effect and is applied when setting host headers on outgoing + // requests + let req = client1 + .create_request(reqwest::Method::GET, &["/"], NO_PARAMS, None::<&()>) + .unwrap() + .build() + .unwrap(); + + let expected_host = url1.host_str().unwrap(); + assert!( + req.headers() + .get(reqwest::header::HOST) + .is_some_and(|h| h.to_str().unwrap() == expected_host), + "{:?} != {:?}", + expected_host, + req, + ); + + let expected_front = url1.front_str().unwrap(); + assert!( + req.url() + .host() + .is_some_and(|url| url.to_string() == expected_front), + "{:?} != {:?}", + expected_front, + req, + ); + + // ensure that setting to the shared policy works + client2.use_shared_front_policy(); + assert!(client2.front.policy() == FrontPolicy::Always); + + // ensure that if the policy is OnRetry then the `enabled` fields are still independent, + // despite the policy being shared. + Client::set_shared_front_policy(FrontPolicy::OnRetry); + assert!(client1.front.policy() == FrontPolicy::OnRetry); + assert!(client2.front.policy() == FrontPolicy::OnRetry); + + assert!(!client1.front.is_enabled()); + assert!(!client2.front.is_enabled()); + + client1.front.retry_enable(); + assert!(client1.front.is_enabled()); + assert!(!client2.front.is_enabled()); + } + #[tokio::test] async fn nym_api_works() { let url1 = Url::new( @@ -104,7 +305,7 @@ mod tests { let client = ClientBuilder::new(url1) .expect("bad url") - .with_fronting(FrontPolicy::Always) + .with_fronting(Some(FrontPolicy::Always)) .build() .expect("failed to build client"); @@ -140,7 +341,7 @@ mod tests { let client = ClientBuilder::new_with_urls(vec![url1, url2]) .expect("bad url") - .with_fronting(FrontPolicy::Always) + .with_fronting(Some(FrontPolicy::Always)) .build() .expect("failed to build client"); diff --git a/common/http-api-client/src/lib.rs b/common/http-api-client/src/lib.rs index 06a0511564..20b2ffcfd7 100644 --- a/common/http-api-client/src/lib.rs +++ b/common/http-api-client/src/lib.rs @@ -136,6 +136,7 @@ //! ``` #![warn(missing_docs)] +use http::header::USER_AGENT; pub use inventory; pub use reqwest; pub use reqwest::ClientBuilder as ReqwestClientBuilder; @@ -147,6 +148,7 @@ pub mod registry; use crate::path::RequestPath; use async_trait::async_trait; use bytes::Bytes; +use cfg_if::cfg_if; use http::HeaderMap; use http::header::{ACCEPT, CONTENT_TYPE}; use itertools::Itertools; @@ -161,9 +163,7 @@ use std::time::Duration; use thiserror::Error; use tracing::{debug, instrument, warn}; -#[cfg(not(target_arch = "wasm32"))] -use std::net::SocketAddr; -use std::sync::Arc; +use std::sync::{Arc, LazyLock}; #[cfg(feature = "tunneling")] mod fronted; @@ -195,6 +195,8 @@ use nym_http_api_client_macro::client_defaults; /// high and chatty protocols take a while to complete. pub const DEFAULT_TIMEOUT: Duration = Duration::from_secs(30); +const NYM_OUTER_SNI_HEADER: &str = "NYM-ORIGINAL-OUTER-SNI"; + #[cfg(not(target_arch = "wasm32"))] client_defaults!( priority = -100; @@ -206,6 +208,24 @@ client_defaults!( user_agent = format!("nym-http-api-client/{}", env!("CARGO_PKG_VERSION")) ); +static SHARED_CLIENT: LazyLock = LazyLock::new(|| { + tracing::info!("Initializing shared HTTP client"); + cfg_if! { + if #[cfg(target_arch = "wasm32")] { + reqwest::ClientBuilder::new().build() + .expect("failed to initialize shared http client") + } else { + let mut builder = default_builder(); + + builder = builder.dns_resolver(Arc::new(HickoryDnsResolver::default())); + + builder + .build() + .expect("failed to initialize shared http client") + } + } +}); + /// Collection of URL Path Segments pub type PathSegments<'a> = &'a [&'a str]; /// Collection of HTTP Request Parameters @@ -327,6 +347,12 @@ pub enum HttpClientError { source: reqwest::Error, }, + #[error("failed to parse header value: {source}")] + InvalidHeaderValue { + #[source] + source: http::Error, + }, + #[error("failed to send request for {url}: {source}")] RequestSendFailure { url: Box, @@ -554,6 +580,19 @@ pub trait ApiClientCore { let req = self.create_request(method, path, params, json_body)?; self.send(req).await } + + /// If multiple base urls are available rotate to next (e.g. when the current one resulted in an error) + /// + /// Takes an optional URL argument. If this is none, the current host will be updated automatically. + /// If a url is provided first check that the CURRENT host matches the hostname in the URL before + /// triggering a rotation. This is meant to prevent parallel requests that fail from rotating the host + /// multiple times. + fn maybe_rotate_hosts(&self, offending_url: Option); + + /// If the fronting policy for the client is set to `OnRetry` this function will enable the + /// fronting if not already enabled. + #[cfg(feature = "tunneling")] + fn maybe_enable_fronting(&self, context: impl std::fmt::Debug); } /// A `ClientBuilder` can be used to create a [`Client`] with custom configuration applied consistently @@ -562,16 +601,18 @@ pub struct ClientBuilder { urls: Vec, timeout: Option, - custom_user_agent: bool, - reqwest_client_builder: reqwest::ClientBuilder, + custom_user_agent: Option, + reqwest_client_builder: Option, #[allow(dead_code)] // not dead code, just unused in wasm use_secure_dns: bool, #[cfg(feature = "tunneling")] - front: Option, + front: fronted::Front, retry_limit: usize, serialization: SerializationFormat, + + error: Option, } impl ClientBuilder { @@ -642,10 +683,10 @@ impl ClientBuilder { let mut builder = Self::new_with_urls(urls)?; - // Enable domain fronting by default (on retry) + // Enable domain fronting using the shared fronting policy #[cfg(feature = "tunneling")] { - builder = builder.with_fronting(FrontPolicy::OnRetry); + builder = builder.with_fronting(None); } Ok(builder) @@ -659,26 +700,31 @@ impl ClientBuilder { let urls = Self::check_urls(urls); - #[cfg(target_arch = "wasm32")] - let reqwest_client_builder = reqwest::ClientBuilder::new(); - - #[cfg(not(target_arch = "wasm32"))] - let reqwest_client_builder = default_builder(); - Ok(ClientBuilder { urls, timeout: None, - custom_user_agent: false, - reqwest_client_builder, + custom_user_agent: None, + reqwest_client_builder: None, use_secure_dns: true, #[cfg(feature = "tunneling")] - front: None, + front: fronted::Front::off(), retry_limit: 0, serialization: SerializationFormat::Json, + error: None, }) } + /// Configure use of an independent HTTP request executor. This prevents use of beneficial + /// features like connection pooling under the hood. + #[cfg(not(target_arch = "wasm32"))] + pub fn non_shared(mut self) -> Self { + if self.reqwest_client_builder.is_none() { + self.reqwest_client_builder = Some(default_builder()); + } + self + } + /// Add an additional URL to the set usable by this constructed `Client` pub fn add_url(mut self, url: Url) -> Self { self.urls.push(url); @@ -723,7 +769,7 @@ impl ClientBuilder { /// Provide a pre-configured [`reqwest::ClientBuilder`] pub fn with_reqwest_builder(mut self, reqwest_builder: reqwest::ClientBuilder) -> Self { - self.reqwest_client_builder = reqwest_builder; + self.reqwest_client_builder = Some(reqwest_builder); self } @@ -733,18 +779,12 @@ impl ClientBuilder { V: TryInto, V::Error: Into, { - self.custom_user_agent = true; - self.reqwest_client_builder = self.reqwest_client_builder.user_agent(value); - self - } - - /// Override DNS resolution for specific domains to particular IP addresses. - /// - /// Set the port to `0` to use the conventional port for the given scheme (e.g. 80 for http). - /// Ports in the URL itself will always be used instead of the port in the overridden addr. - #[cfg(not(target_arch = "wasm32"))] - pub fn resolve_to_addrs(mut self, domain: &str, addrs: &[SocketAddr]) -> ClientBuilder { - self.reqwest_client_builder = self.reqwest_client_builder.resolve_to_addrs(domain, addrs); + match value.try_into() { + Ok(v) => self.custom_user_agent = Some(v), + Err(err) => { + self.error = Some(HttpClientError::InvalidHeaderValue { source: err.into() }) + } + } self } @@ -761,30 +801,33 @@ impl ClientBuilder { /// Returns a Client that uses this ClientBuilder configuration. pub fn build(self) -> Result { + if let Some(err) = self.error { + return Err(err); + } + #[cfg(target_arch = "wasm32")] - let reqwest_client = self.reqwest_client_builder.build()?; + let reqwest_client = Some(reqwest::ClientBuilder::new().build()?); - // TODO: we should probably be propagating the error rather than panicking, - // but that'd break bunch of things due to type changes #[cfg(not(target_arch = "wasm32"))] - let reqwest_client = { - let mut builder = self.reqwest_client_builder; + let reqwest_client = self + .reqwest_client_builder + .map(|mut builder| { + // unless explicitly disabled use the DoT/DoH enabled resolver + if self.use_secure_dns { + builder = builder.dns_resolver(Arc::new(HickoryDnsResolver::default())); + } - // unless explicitly disabled use the DoT/DoH enabled resolver - if self.use_secure_dns { - builder = builder.dns_resolver(Arc::new(HickoryDnsResolver::default())); - } - - builder - .build() - .map_err(HttpClientError::reqwest_client_build_error)? - }; + builder + .build() + .map_err(HttpClientError::reqwest_client_build_error) + }) + .transpose()?; let client = Client { base_urls: self.urls, current_idx: Arc::new(AtomicUsize::new(0)), reqwest_client, - using_secure_dns: self.use_secure_dns, + custom_user_agent: self.custom_user_agent, #[cfg(feature = "tunneling")] front: self.front, @@ -804,11 +847,11 @@ impl ClientBuilder { pub struct Client { base_urls: Vec, current_idx: Arc, - reqwest_client: reqwest::Client, - using_secure_dns: bool, + reqwest_client: Option, + custom_user_agent: Option, #[cfg(feature = "tunneling")] - front: Option, + front: fronted::Front, #[cfg(target_arch = "wasm32")] request_timeout: Duration, @@ -862,8 +905,8 @@ impl Client { Client { base_urls: vec![new_url], current_idx: Arc::new(Default::default()), - reqwest_client: self.reqwest_client.clone(), - using_secure_dns: self.using_secure_dns, + reqwest_client: None, + custom_user_agent: None, #[cfg(feature = "tunneling")] front: self.front.clone(), @@ -897,9 +940,7 @@ impl Client { #[cfg(feature = "tunneling")] fn matches_current_host(&self, url: &Url) -> bool { - if let Some(ref front) = self.front - && front.is_enabled() - { + if self.front.is_enabled() { url.host_str() == self.current_url().front_str() } else { url.host_str() == self.current_url().host_str() @@ -926,9 +967,7 @@ impl Client { } #[cfg(feature = "tunneling")] - if let Some(ref front) = self.front - && front.is_enabled() - { + if self.front.is_enabled() { // if we are using fronting, try updating to the next front let url = self.current_url(); @@ -948,9 +987,7 @@ impl Client { // if fronting is enabled we want to update to a host that has fronts configured #[cfg(feature = "tunneling")] - if let Some(ref front) = self.front - && front.is_enabled() - { + if self.front.is_enabled() { while next != orig { if self.base_urls[next].has_front() { // we have a front for the next host, so we can use it @@ -981,14 +1018,12 @@ impl Client { /// this method. For example, if the client is configured to rotate hosts after each error, this /// method should be called after the host has been updated -- i.e. as part of the subsequent /// send. - fn apply_hosts_to_req(&self, r: &mut reqwest::Request) -> (&str, Option<&str>) { + pub(crate) fn apply_hosts_to_req(&self, r: &mut reqwest::Request) -> (&str, Option<&str>) { let url = self.current_url(); r.url_mut().set_host(url.host_str()).unwrap(); #[cfg(feature = "tunneling")] - if let Some(ref front) = self.front - && front.is_enabled() - { + if self.front.is_enabled() { if let Some(front_host) = url.front_str() { if let Some(actual_host) = url.host_str() { tracing::debug!( @@ -1008,6 +1043,13 @@ impl Client { .headers_mut() .insert(reqwest::header::HOST, actual_host_header); + // Set a custom header to capture the outer host (used in the SNI) of the request + let front_host_header: HeaderValue = + front_host.parse().unwrap_or(HeaderValue::from_static("")); + _ = r + .headers_mut() + .insert(NYM_OUTER_SNI_HEADER, front_host_header); + return (url.as_str(), url.front_str()); } else { tracing::debug!( @@ -1048,12 +1090,21 @@ impl ApiClientCore for Client { self.apply_hosts_to_req(&mut req); - let mut rb = RequestBuilder::from_parts(self.reqwest_client.clone(), req); + let client = if let Some(client) = &self.reqwest_client { + client.clone() + } else { + SHARED_CLIENT.clone() + }; + let mut rb = RequestBuilder::from_parts(client, req); rb = rb .header(ACCEPT, self.serialization.content_type()) .header(CONTENT_TYPE, self.serialization.content_type()); + if let Some(user_agent) = &self.custom_user_agent { + rb = rb.header(USER_AGENT, user_agent.clone()); + } + if let Some(body) = body { match self.serialization { SerializationFormat::Json => { @@ -1096,16 +1147,19 @@ impl ApiClientCore for Client { #[cfg(target_arch = "wasm32")] let response: Result = { - Ok(wasmtimer::tokio::timeout( - self.request_timeout, - self.reqwest_client.execute(req), + let client = self.reqwest_client.as_ref().unwrap_or(&*SHARED_CLIENT); + Ok( + wasmtimer::tokio::timeout(self.request_timeout, client.execute(req)) + .await + .map_err(|_timeout| HttpClientError::RequestTimeout)??, ) - .await - .map_err(|_timeout| HttpClientError::RequestTimeout)??) }; #[cfg(not(target_arch = "wasm32"))] - let response = self.reqwest_client.execute(req).await; + let response = { + let client = self.reqwest_client.as_ref().unwrap_or(&*SHARED_CLIENT); + client.execute(req).await + }; match response { Ok(resp) => return Ok(resp), @@ -1121,20 +1175,10 @@ impl ApiClientCore for Client { if is_network_err { // if we have multiple urls, update to the next - self.update_host(Some(url.clone())); + self.maybe_rotate_hosts(Some(url.clone())); #[cfg(feature = "tunneling")] - if let Some(ref front) = self.front { - // If fronting is set to be enabled on error, enable domain fronting as we - // have encountered an error. - let was_enabled = front.is_enabled(); - front.retry_enable(); - if !was_enabled && front.is_enabled() { - tracing::info!( - "Domain fronting activated after connection failure: {err}", - ); - } - } + self.maybe_enable_fronting(("network", url.as_str(), &err)); } if attempts < self.retry_limit { @@ -1158,6 +1202,21 @@ impl ApiClientCore for Client { } } } + + fn maybe_rotate_hosts(&self, offending: Option) { + self.update_host(offending); + } + + #[cfg(feature = "tunneling")] + fn maybe_enable_fronting(&self, context: impl std::fmt::Debug) { + // If fronting is set to be OnRetry, enable domain fronting as we + // have encountered an error. + let was_enabled = self.front.is_enabled(); + self.front.retry_enable(); + if !was_enabled && self.front.is_enabled() { + tracing::debug!("Domain fronting activated after failure: {context:?}",); + } + } } /// Common usage functionality for the http client. @@ -1310,6 +1369,35 @@ pub trait ApiClient: ApiClientCore { self.get_response(path, params).await } + /// Attempt to parse a response object from an HTTP response + async fn parse_response( + &self, + res: Response, + allow_empty: bool, + ) -> Result + where + T: DeserializeOwned, + { + let url = Url::from(res.url()); + parse_response(res, allow_empty).await.inspect_err(|e| { + if matches!( + // if we encounter a read error while we attempt to parse it could be caused by censorship and we should + // rotate hosts / enable fronting. + e, + HttpClientError::ResponseReadFailure { + url: _, + headers: _, + status: _, + source: _, + } + ) { + self.maybe_rotate_hosts(Some(url.clone())); + #[cfg(feature = "tunneling")] + self.maybe_enable_fronting(("parse/read", url.as_str(), e)); + } + }) + } + /// 'get' data from the segment-defined path, e.g. `["api", "v1", "mixnodes"]`, with tuple /// defined key-value parameters, e.g. `[("since", "12345")]`. Attempt to parse the response /// into the provided type `T` based on the content type header @@ -1327,7 +1415,8 @@ pub trait ApiClient: ApiClientCore { let res = self .send_request(reqwest::Method::GET, path, params, None::<&()>) .await?; - parse_response(res, false).await + + self.parse_response(res, false).await } /// 'post' json data to the segment-defined path, e.g. `["api", "v1", "mixnodes"]`, with tuple @@ -1349,7 +1438,7 @@ pub trait ApiClient: ApiClientCore { let res = self .send_request(reqwest::Method::POST, path, params, Some(json_body)) .await?; - parse_response(res, false).await + self.parse_response(res, false).await } /// 'delete' json data from the segment-defined path, e.g. `["api", "v1", "mixnodes"]`, with @@ -1369,7 +1458,7 @@ pub trait ApiClient: ApiClientCore { let res = self .send_request(reqwest::Method::DELETE, path, params, None::<&()>) .await?; - parse_response(res, false).await + self.parse_response(res, false).await } /// 'patch' json data at the segment-defined path, e.g. `["api", "v1", "mixnodes"]`, with tuple @@ -1391,7 +1480,7 @@ pub trait ApiClient: ApiClientCore { let res = self .send_request(reqwest::Method::PATCH, path, params, Some(json_body)) .await?; - parse_response(res, false).await + self.parse_response(res, false).await } /// `get` json data from the provided absolute endpoint, e.g. `"/api/v1/mixnodes?since=12345"`. @@ -1403,7 +1492,7 @@ pub trait ApiClient: ApiClientCore { { let req = self.create_request_endpoint(reqwest::Method::GET, endpoint, None::<&()>)?; let res = self.send(req).await?; - parse_response(res, false).await + self.parse_response(res, false).await } /// `post` json data to the provided absolute endpoint, e.g. `"/api/v1/mixnodes?since=12345"`. @@ -1420,7 +1509,7 @@ pub trait ApiClient: ApiClientCore { { let req = self.create_request_endpoint(reqwest::Method::POST, endpoint, Some(json_body))?; let res = self.send(req).await?; - parse_response(res, false).await + self.parse_response(res, false).await } /// `delete` json data from the provided absolute endpoint, e.g. @@ -1432,7 +1521,7 @@ pub trait ApiClient: ApiClientCore { { let req = self.create_request_endpoint(reqwest::Method::DELETE, endpoint, None::<&()>)?; let res = self.send(req).await?; - parse_response(res, false).await + self.parse_response(res, false).await } /// `patch` json data at the provided absolute endpoint, e.g. `"/api/v1/mixnodes?since=12345"`. @@ -1450,7 +1539,7 @@ pub trait ApiClient: ApiClientCore { let req = self.create_request_endpoint(reqwest::Method::PATCH, endpoint, Some(json_body))?; let res = self.send(req).await?; - parse_response(res, false).await + self.parse_response(res, false).await } } diff --git a/common/http-api-client/src/tests.rs b/common/http-api-client/src/tests.rs index b287f5fe78..9a72dfd72a 100644 --- a/common/http-api-client/src/tests.rs +++ b/common/http-api-client/src/tests.rs @@ -89,7 +89,8 @@ fn sanitizing_urls() { // - on error without retries is where we have multiple urls, is the url updated? #[tokio::test] -#[ignore] // test relies on external services being available and behaving in a specific way. +#[cfg(any())] // #[ignore] we run ignore assuming it just means slow in Ci/CD -_- +// test relies on external services being available and behaving in a specific way. async fn api_client_retry() -> Result<(), Box> { let client = ClientBuilder::new_with_urls(vec![ "http://broken.nym.test".parse()?, // This should fail because of DNS NXDomain (rotate) @@ -199,7 +200,7 @@ fn fronted_host_updating() { let url = Url::new("http://nym-api.test", Some(vec!["http://cdn1.test"])).unwrap(); let mut client = ClientBuilder::new(url) .unwrap() - .with_fronting(crate::fronted::FrontPolicy::Always) + .with_fronting(Some(crate::fronted::FrontPolicy::Always)) .build() .unwrap(); diff --git a/common/http-api-client/src/url.rs b/common/http-api-client/src/url.rs index 8b3b1a65b8..065df2558e 100644 --- a/common/http-api-client/src/url.rs +++ b/common/http-api-client/src/url.rs @@ -123,6 +123,16 @@ impl From for Url { } } +impl From<&reqwest::Url> for Url { + fn from(url: &url::Url) -> Self { + Self { + url: url.clone(), + fronts: None, + current_front: Arc::new(AtomicUsize::new(0)), + } + } +} + impl AsRef for Url { fn as_ref(&self) -> &url::Url { &self.url From 4897cb0ce404bc7047fd232c830144fc19393a3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 11 Feb 2026 15:57:47 +0000 Subject: [PATCH 53/56] feat: introduce on-disk cache persistance for major nym-api caches (#6302) This includes: - mixnet contract cache - described nodes cache - nodes annotations cache (performance) those changes include taking some code developed for the purposes of #6277 --- Cargo.lock | 1 + common/ecash-signer-check/Cargo.toml | 1 + common/ecash-signer-check/src/lib.rs | 14 +- nym-api/src/ecash/tests/mod.rs | 6 +- nym-api/src/epoch_operations/helpers.rs | 11 +- .../rewarded_set_assignment.rs | 2 +- .../src/mixnet_contract_cache/cache/data.rs | 4 +- .../src/mixnet_contract_cache/cache/mod.rs | 12 +- nym-api/src/mixnet_contract_cache/mod.rs | 3 + .../src/network_monitor/monitor/preparer.rs | 2 +- nym-api/src/node_describe_cache/cache.rs | 3 +- nym-api/src/node_describe_cache/provider.rs | 17 +- .../node_performance/contract_cache/data.rs | 3 + nym-api/src/node_status_api/cache/data.rs | 12 +- nym-api/src/node_status_api/cache/mod.rs | 66 ++++--- .../src/node_status_api/cache/refresher.rs | 47 ++++- nym-api/src/node_status_api/mod.rs | 3 + nym-api/src/node_status_api/models.rs | 7 - nym-api/src/nym_nodes/handlers/v1.rs | 12 +- nym-api/src/signers_cache/cache/mod.rs | 2 + nym-api/src/support/caching/cache.rs | 169 +++++++++++++++++- nym-api/src/support/caching/refresher.rs | 36 +++- nym-api/src/support/cli/run.rs | 78 +++++--- nym-api/src/support/config/mod.rs | 10 +- nym-api/src/support/config/persistence.rs | 30 ++-- nym-api/src/support/config/template.rs | 6 + nym-api/src/support/http/state/mod.rs | 13 -- .../v2/nym_nodes/semi_skimmed/mod.rs | 5 +- .../v2/nym_nodes/skimmed/helpers.rs | 12 +- 29 files changed, 436 insertions(+), 151 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 87a66eb9f4..8bca7fa945 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6383,6 +6383,7 @@ dependencies = [ "nym-network-defaults", "nym-validator-client", "semver 1.0.27", + "serde", "thiserror 2.0.17", "tokio", "tracing", diff --git a/common/ecash-signer-check/Cargo.toml b/common/ecash-signer-check/Cargo.toml index 8549930a03..976df1bf55 100644 --- a/common/ecash-signer-check/Cargo.toml +++ b/common/ecash-signer-check/Cargo.toml @@ -15,6 +15,7 @@ description = "Functions to interact with zknym signers, checking their status a futures = { workspace = true } thiserror = { workspace = true } semver = { workspace = true } +serde = { workspace = true } tokio = { workspace = true, features = ["time"] } tracing = { workspace = true } url = { workspace = true } diff --git a/common/ecash-signer-check/src/lib.rs b/common/ecash-signer-check/src/lib.rs index 47e6d68875..05a3be5ba5 100644 --- a/common/ecash-signer-check/src/lib.rs +++ b/common/ecash-signer-check/src/lib.rs @@ -3,14 +3,9 @@ use crate::client_check::check_client; use futures::stream::{FuturesUnordered, StreamExt}; +use nym_ecash_signer_check_types::status::{SignerResult, Status}; use nym_network_defaults::NymNetworkDetails; use nym_validator_client::QueryHttpRpcNyxdClient; -use nym_validator_client::nyxd::contract_traits::{DkgQueryClient, PagedDkgQueryClient}; -use std::collections::HashMap; -use url::Url; - -pub use error::SignerCheckError; -use nym_ecash_signer_check_types::status::{SignerResult, Status}; use nym_validator_client::ecash::models::EcashSignerStatusResponse; use nym_validator_client::models::{ ChainBlocksStatusResponse, ChainStatusResponse, SignerInformationResponse, @@ -18,6 +13,12 @@ use nym_validator_client::models::{ use nym_validator_client::nyxd::contract_traits::dkg_query_client::{ ContractVKShare, DealerDetails, Epoch, }; +use nym_validator_client::nyxd::contract_traits::{DkgQueryClient, PagedDkgQueryClient}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use url::Url; + +pub use error::SignerCheckError; mod client_check; pub mod error; @@ -31,6 +32,7 @@ pub type TypedSignerResult = SignerResult< pub type LocalChainStatus = Status; pub type SigningStatus = Status; +#[derive(Serialize, Deserialize)] pub struct SignersTestResult { pub threshold: Option, pub results: Vec, diff --git a/nym-api/src/ecash/tests/mod.rs b/nym-api/src/ecash/tests/mod.rs index a9cf2e87f8..4df9966f5d 100644 --- a/nym-api/src/ecash/tests/mod.rs +++ b/nym-api/src/ecash/tests/mod.rs @@ -5,11 +5,9 @@ use crate::ecash::api_routes::handlers::ecash_routes; use crate::ecash::error::{EcashError, Result}; use crate::ecash::keys::KeyPairWithEpoch; use crate::ecash::state::EcashState; -use crate::mixnet_contract_cache::cache::MixnetContractCache; use crate::network::models::NetworkDetails; use crate::node_describe_cache::cache::DescribedNodes; use crate::node_status_api::handlers::unstable; -use crate::node_status_api::NodeStatusCache; use crate::status::ApiStatusState; use crate::support::caching::cache::SharedCache; use crate::support::config; @@ -1284,8 +1282,8 @@ impl TestFixture { ecash_signers_cache: Default::default(), address_info_cache: AddressInfoCache::new(Duration::from_secs(42), 1000), forced_refresh: ForcedRefresh::new(true), - mixnet_contract_cache: MixnetContractCache::new(), - node_status_cache: NodeStatusCache::new(), + mixnet_contract_cache: SharedCache::new().into(), + node_status_cache: SharedCache::new().into(), storage, described_nodes_cache: SharedCache::::new(), network_details: NetworkDetails::new( diff --git a/nym-api/src/epoch_operations/helpers.rs b/nym-api/src/epoch_operations/helpers.rs index 5f1e5a2f6b..a353dc0d29 100644 --- a/nym-api/src/epoch_operations/helpers.rs +++ b/nym-api/src/epoch_operations/helpers.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::epoch_operations::EpochAdvancer; -use crate::support::caching::Cache; +use crate::support::caching::cache::UninitialisedCache; use cosmwasm_std::{Decimal, Fraction}; use nym_api_requests::models::NodeAnnotation; use nym_mixnet_contract_common::helpers::IntoBaseDecimal; @@ -210,10 +210,13 @@ fn determine_per_node_work( impl EpochAdvancer { fn load_performance( - status_cache: &Option>>>, + status_cache: &Result< + RwLockReadGuard<'_, HashMap>, + UninitialisedCache, + >, node_id: NodeId, ) -> NodeWithPerformance { - let Some(status_cache) = status_cache.as_ref() else { + let Ok(status_cache) = status_cache.as_ref() else { return NodeWithPerformance::new_zero(node_id); }; @@ -239,7 +242,7 @@ impl EpochAdvancer { let standby_node_work_factor = nodes_work.standby; let status_cache = self.status_cache.node_annotations().await; - if status_cache.is_none() { + if status_cache.is_err() { error!("there are no node annotations available"); }; diff --git a/nym-api/src/epoch_operations/rewarded_set_assignment.rs b/nym-api/src/epoch_operations/rewarded_set_assignment.rs index d513579ef2..a1f315da69 100644 --- a/nym-api/src/epoch_operations/rewarded_set_assignment.rs +++ b/nym-api/src/epoch_operations/rewarded_set_assignment.rs @@ -214,7 +214,7 @@ impl EpochAdvancer { #[allow(clippy::unwrap_used)] let described_cache = self.described_cache.get().await.unwrap(); - let Some(status_cache) = self.status_cache.node_annotations().await else { + let Ok(status_cache) = self.status_cache.node_annotations().await else { warn!("there are no node annotations available"); return Vec::new(); }; diff --git a/nym-api/src/mixnet_contract_cache/cache/data.rs b/nym-api/src/mixnet_contract_cache/cache/data.rs index be411b5fe9..6c2b68c84e 100644 --- a/nym-api/src/mixnet_contract_cache/cache/data.rs +++ b/nym-api/src/mixnet_contract_cache/cache/data.rs @@ -7,8 +7,9 @@ use nym_mixnet_contract_common::{ NymNodeDetails, RewardingParams, }; use nym_topology::CachedEpochRewardedSet; +use serde::{Deserialize, Serialize}; -#[derive(Clone)] +#[derive(Clone, Serialize, Deserialize)] pub(crate) struct ConfigScoreData { pub(crate) config_score_params: ConfigScoreParams, pub(crate) nym_node_version_history: Vec, @@ -27,6 +28,7 @@ impl From for ConfigScoreDataResponse { } } +#[derive(Serialize, Deserialize)] pub(crate) struct MixnetContractCacheData { pub(crate) rewarding_denom: String, diff --git a/nym-api/src/mixnet_contract_cache/cache/mod.rs b/nym-api/src/mixnet_contract_cache/cache/mod.rs index 7168a77acf..707f0324fd 100644 --- a/nym-api/src/mixnet_contract_cache/cache/mod.rs +++ b/nym-api/src/mixnet_contract_cache/cache/mod.rs @@ -14,6 +14,8 @@ use nym_mixnet_contract_common::{ }; use nym_topology::CachedEpochRewardedSet; use nym_validator_client::nyxd::Coin; +use std::path::Path; +use std::time::Duration; use time::OffsetDateTime; use tokio::sync::RwLockReadGuard; @@ -27,10 +29,16 @@ pub struct MixnetContractCache { pub(crate) inner: SharedCache, } +impl From> for MixnetContractCache { + fn from(inner: SharedCache) -> Self { + MixnetContractCache { inner } + } +} + impl MixnetContractCache { - pub(crate) fn new() -> Self { + pub(crate) fn new>(store_path: P, max_cache_age: Duration) -> Self { MixnetContractCache { - inner: SharedCache::new(), + inner: SharedCache::new_with_persistent(store_path, max_cache_age, None), } } diff --git a/nym-api/src/mixnet_contract_cache/mod.rs b/nym-api/src/mixnet_contract_cache/mod.rs index 9911c55683..58bb10e663 100644 --- a/nym-api/src/mixnet_contract_cache/mod.rs +++ b/nym-api/src/mixnet_contract_cache/mod.rs @@ -7,6 +7,7 @@ use crate::mixnet_contract_cache::cache::MixnetContractCache; use crate::support::caching::refresher::CacheRefresher; use crate::support::{config, nyxd}; use nym_validator_client::nyxd::error::NyxdError; +use std::path::PathBuf; pub(crate) mod cache; pub(crate) mod handlers; @@ -15,6 +16,7 @@ pub(crate) fn build_refresher( config: &config::MixnetContractCache, nym_contract_cache_state: &MixnetContractCache, nyxd_client: nyxd::Client, + on_disk_file: PathBuf, ) -> CacheRefresher { CacheRefresher::new_with_initial_value( Box::new(MixnetContractDataProvider::new(nyxd_client)), @@ -22,4 +24,5 @@ pub(crate) fn build_refresher( nym_contract_cache_state.inner(), ) .named("mixnet-contract-cache-refresher") + .with_persistent_cache(on_disk_file) } diff --git a/nym-api/src/network_monitor/monitor/preparer.rs b/nym-api/src/network_monitor/monitor/preparer.rs index d2d23a9715..11cb040073 100644 --- a/nym-api/src/network_monitor/monitor/preparer.rs +++ b/nym-api/src/network_monitor/monitor/preparer.rs @@ -233,7 +233,7 @@ impl PacketPreparer { // routes so that they wouldn't be reused pub(crate) async fn prepare_test_routes(&self, n: usize) -> Option> { let descriptions = self.described_cache.get().await.ok()?; - let statuses = self.node_status_cache.node_annotations().await?; + let statuses = self.node_status_cache.node_annotations().await.ok()?; let mixing_nym_nodes = descriptions.mixing_nym_nodes(); // last I checked `gatewaying` wasn't a word : ) diff --git a/nym-api/src/node_describe_cache/cache.rs b/nym-api/src/node_describe_cache/cache.rs index 0e00b986d6..a6f3d651dd 100644 --- a/nym-api/src/node_describe_cache/cache.rs +++ b/nym-api/src/node_describe_cache/cache.rs @@ -3,10 +3,11 @@ use nym_api_requests::models::{DescribedNodeTypeV2, NymNodeDataV2, NymNodeDescriptionV2}; use nym_mixnet_contract_common::NodeId; +use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::net::IpAddr; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct DescribedNodes { pub(crate) nodes: HashMap, pub(crate) addresses_cache: HashMap, diff --git a/nym-api/src/node_describe_cache/provider.rs b/nym-api/src/node_describe_cache/provider.rs index b0ed9713d9..b3010cf35b 100644 --- a/nym-api/src/node_describe_cache/provider.rs +++ b/nym-api/src/node_describe_cache/provider.rs @@ -12,6 +12,7 @@ use crate::support::config::DEFAULT_NODE_DESCRIBE_BATCH_SIZE; use async_trait::async_trait; use futures::{stream, StreamExt}; use std::collections::HashMap; +use std::path::PathBuf; use tracing::{error, info}; pub struct NodeDescriptionProvider { @@ -90,23 +91,11 @@ impl CacheItemProvider for NodeDescriptionProvider { } } -// currently dead code : ( -#[allow(dead_code)] -pub(crate) fn new_refresher( - config: &config::DescribeCache, - contract_cache: MixnetContractCache, -) -> CacheRefresher { - CacheRefresher::new( - NodeDescriptionProvider::new(contract_cache, config.debug.allow_illegal_ips) - .with_batch_size(config.debug.batch_size), - config.debug.caching_interval, - ) -} - pub(crate) fn new_provider_with_initial_value( config: &config::DescribeCache, contract_cache: MixnetContractCache, initial: SharedCache, + on_disk_file: PathBuf, ) -> CacheRefresher { CacheRefresher::new_with_initial_value( Box::new( @@ -116,4 +105,6 @@ pub(crate) fn new_provider_with_initial_value( config.debug.caching_interval, initial, ) + .named("node-self-described-data-refresher") + .with_persistent_cache(on_disk_file) } diff --git a/nym-api/src/node_performance/contract_cache/data.rs b/nym-api/src/node_performance/contract_cache/data.rs index 985ee0a4d7..346532bada 100644 --- a/nym-api/src/node_performance/contract_cache/data.rs +++ b/nym-api/src/node_performance/contract_cache/data.rs @@ -7,8 +7,10 @@ use nym_contracts_common::NaiveFloat; use nym_mixnet_contract_common::reward_params::Performance; use nym_mixnet_contract_common::{EpochId, NodeId}; use nym_validator_client::nyxd::contract_traits::performance_query_client::NodePerformance; +use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, HashMap}; +#[derive(Serialize, Deserialize)] pub(crate) struct PerformanceContractEpochCacheData { pub(crate) epoch_id: EpochId, pub(crate) median_performance: HashMap, @@ -30,6 +32,7 @@ impl PerformanceContractEpochCacheData { } } +#[derive(Serialize, Deserialize)] pub(crate) struct PerformanceContractCacheData { pub(crate) epoch_performance: BTreeMap, } diff --git a/nym-api/src/node_status_api/cache/data.rs b/nym-api/src/node_status_api/cache/data.rs index 1a174eae6b..0457d4c8c8 100644 --- a/nym-api/src/node_status_api/cache/data.rs +++ b/nym-api/src/node_status_api/cache/data.rs @@ -1,20 +1,20 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use crate::support::caching::Cache; use nym_api_requests::models::NodeAnnotation; use nym_mixnet_contract_common::NodeId; +use serde::{Deserialize, Serialize}; use std::collections::HashMap; -#[derive(Default)] +#[derive(Default, Serialize, Deserialize)] #[allow(deprecated)] pub(crate) struct NodeStatusCacheData { /// Basic annotation for nym-nodes - pub(crate) node_annotations: Cache>, + pub(crate) node_annotations: HashMap, } -impl NodeStatusCacheData { - pub fn new() -> Self { - Self::default() +impl From> for NodeStatusCacheData { + fn from(node_annotations: HashMap) -> Self { + NodeStatusCacheData { node_annotations } } } diff --git a/nym-api/src/node_status_api/cache/mod.rs b/nym-api/src/node_status_api/cache/mod.rs index 32fd552f18..9a16762c32 100644 --- a/nym-api/src/node_status_api/cache/mod.rs +++ b/nym-api/src/node_status_api/cache/mod.rs @@ -3,19 +3,18 @@ use self::data::NodeStatusCacheData; use crate::node_performance::provider::PerformanceRetrievalFailure; -use crate::support::caching::cache::UninitialisedCache; +use crate::support::caching::cache::{SharedCache, UninitialisedCache}; use crate::support::caching::Cache; use nym_api_requests::models::NodeAnnotation; use nym_mixnet_contract_common::NodeId; use std::collections::HashMap; -use std::{sync::Arc, time::Duration}; +use std::path::Path; +use std::time::Duration; use thiserror::Error; +use time::OffsetDateTime; use tokio::sync::RwLockReadGuard; -use tokio::{sync::RwLock, time}; use tracing::error; -const CACHE_TIMEOUT_MS: u64 = 100; - mod config_score; pub mod data; pub mod refresher; @@ -44,43 +43,64 @@ impl From for NodeStatusCacheError { /// The cache can be triggered to update on contract cache changes, and/or periodically on a timer. #[derive(Clone)] pub struct NodeStatusCache { - inner: Arc>, + inner: SharedCache, +} + +impl From> for NodeStatusCache { + fn from(inner: SharedCache) -> Self { + NodeStatusCache { inner } + } } impl NodeStatusCache { /// Creates a new cache with no data. - pub(crate) fn new() -> NodeStatusCache { + pub(crate) fn new>(store_path: P, max_cache_age: Duration) -> NodeStatusCache { NodeStatusCache { - inner: Arc::new(RwLock::new(NodeStatusCacheData::new())), + inner: SharedCache::new_with_persistent( + store_path, + max_cache_age, + Some(HashMap::new().into()), + ), } } + pub async fn cache_timestamp(&self) -> OffsetDateTime { + let Ok(cache) = self.inner.get().await else { + return OffsetDateTime::UNIX_EPOCH; + }; + + cache.timestamp() + } + /// Updates the cache with the latest data. async fn update(&self, node_annotations: HashMap) { - match time::timeout(Duration::from_millis(CACHE_TIMEOUT_MS), self.inner.write()).await { - Ok(mut cache) => { - cache.node_annotations.unchecked_update(node_annotations); - } - Err(e) => error!("{e}"), + if self + .inner + .try_overwrite_old_value(node_annotations, "node-status") + .await + .is_err() + { + error!("failed to update node status cache!") } } + pub(crate) async fn cache( + &self, + ) -> Result>, UninitialisedCache> { + self.inner.get().await + } + async fn get<'a, T: 'a>( &'a self, - fn_arg: impl FnOnce(&NodeStatusCacheData) -> &Cache, - ) -> Option>> { - match time::timeout(Duration::from_millis(CACHE_TIMEOUT_MS), self.inner.read()).await { - Ok(cache) => Some(RwLockReadGuard::map(cache, |item| fn_arg(item))), - Err(e) => { - error!("{e}"); - None - } - } + fn_arg: impl FnOnce(&Cache) -> &T, + ) -> Result, UninitialisedCache> { + let guard = self.inner.get().await?; + Ok(RwLockReadGuard::map(guard, fn_arg)) } pub(crate) async fn node_annotations( &self, - ) -> Option>>> { + ) -> Result>, UninitialisedCache> { self.get(|c| &c.node_annotations).await } } diff --git a/nym-api/src/node_status_api/cache/refresher.rs b/nym-api/src/node_status_api/cache/refresher.rs index 0da2748846..e79e458b42 100644 --- a/nym-api/src/node_status_api/cache/refresher.rs +++ b/nym-api/src/node_status_api/cache/refresher.rs @@ -8,6 +8,7 @@ use crate::node_performance::provider::{NodePerformanceProvider, NodesRoutingSco use crate::node_status_api::cache::config_score::calculate_config_score; use crate::node_status_api::models::Uptime; use crate::support::caching::cache::SharedCache; +use crate::support::caching::refresher::RefreshRequester; use crate::{ mixnet_contract_cache::cache::MixnetContractCache, node_status_api::cache::NodeStatusCacheError, support::caching::CacheNotification, @@ -18,10 +19,11 @@ use nym_mixnet_contract_common::{NodeId, NymNodeDetails}; use nym_task::ShutdownToken; use nym_topology::CachedEpochRewardedSet; use std::collections::HashMap; +use std::path::PathBuf; use std::time::Duration; use tokio::sync::watch; use tokio::time; -use tracing::{info, trace, warn}; +use tracing::{error, info, trace, warn}; // Long running task responsible for keeping the node status cache up-to-date. pub struct NodeStatusCacheRefresher { @@ -32,13 +34,27 @@ pub struct NodeStatusCacheRefresher { // Sources for when refreshing data mixnet_contract_cache: MixnetContractCache, described_cache: SharedCache, + + /// channel notifying us when mixnet cache has been refreshed, + /// so that this cache could also be recreated mixnet_contract_cache_listener: watch::Receiver, + + /// channel notifying us when the describe cache has been refreshed, + /// so that this cache could also be recreated describe_cache_listener: watch::Receiver, + /// channel explicitly requesting cache refresh. it does not follow the usual rate limiting + refresh_requester: RefreshRequester, + + /// Path to an on-disk location where the contents of the retrieved items should be written + /// upon refresh + on_disk_file: PathBuf, + performance_provider: Box, } impl NodeStatusCacheRefresher { + #[allow(clippy::too_many_arguments)] pub(crate) fn new( cache: NodeStatusCache, fallback_caching_interval: Duration, @@ -47,6 +63,7 @@ impl NodeStatusCacheRefresher { contract_cache_listener: watch::Receiver, describe_cache_listener: watch::Receiver, performance_provider: Box, + on_disk_file: PathBuf, ) -> Self { Self { cache, @@ -55,6 +72,8 @@ impl NodeStatusCacheRefresher { described_cache, mixnet_contract_cache_listener: contract_cache_listener, describe_cache_listener, + refresh_requester: Default::default(), + on_disk_file, performance_provider, } } @@ -89,6 +108,23 @@ impl NodeStatusCacheRefresher { } } } + // note: `Notify` is not cancellation safe, HOWEVER, there's only one listener, + // so it doesn't matter if we lose our queue position + _ = self.refresh_requester.notified() => { + tokio::select! { + // perform full refresh regardless of the rates + _ = self.refresh() => { + last_update = OffsetDateTime::now_utc(); + fallback_interval.reset(); + }, + _ = shutdown_token.cancelled() => { + trace!("NodeStatusCacheRefresher: Received shutdown"); + break; + } + } + } + + // ... however, if we don't receive any notifications we fall back to periodic // refreshes _ = fallback_interval.tick() => { @@ -219,6 +255,15 @@ impl NodeStatusCacheRefresher { // Update the cache self.cache.update(node_annotations).await; + + // attempt to update on-disk cache + let Ok(new_cached) = self.cache.cache().await else { + error!("the node status cache is still not initialised!"); + return Ok(()); + }; + // error reporting is handled by the serialise function itself + let _ = new_cached.try_serialise_to_file(&self.on_disk_file); + Ok(()) } } diff --git a/nym-api/src/node_status_api/mod.rs b/nym-api/src/node_status_api/mod.rs index 7820d9a953..c296ae402a 100644 --- a/nym-api/src/node_status_api/mod.rs +++ b/nym-api/src/node_status_api/mod.rs @@ -12,6 +12,7 @@ use crate::{ }; pub(crate) use cache::NodeStatusCache; use nym_task::ShutdownManager; +use std::path::PathBuf; use std::time::Duration; use tokio::sync::watch; @@ -39,6 +40,7 @@ pub(crate) fn start_cache_refresh( performance_provider: Box, nym_contract_cache_listener: watch::Receiver, described_cache_cache_listener: watch::Receiver, + on_disk_file: PathBuf, shutdown_manager: &ShutdownManager, ) { let mut nym_api_cache_refresher = NodeStatusCacheRefresher::new( @@ -49,6 +51,7 @@ pub(crate) fn start_cache_refresh( nym_contract_cache_listener, described_cache_cache_listener, performance_provider, + on_disk_file, ); let shutdown_listener = shutdown_manager.clone_shutdown_token(); tokio::spawn(async move { nym_api_cache_refresher.run(shutdown_listener).await }); diff --git a/nym-api/src/node_status_api/models.rs b/nym-api/src/node_status_api/models.rs index 791582ce04..371cd992b1 100644 --- a/nym-api/src/node_status_api/models.rs +++ b/nym-api/src/node_status_api/models.rs @@ -346,13 +346,6 @@ impl AxumErrorResponse { } } - pub(crate) fn internal() -> Self { - Self { - message: RequestError::new("Internal server error"), - status: StatusCode::INTERNAL_SERVER_ERROR, - } - } - pub(crate) fn not_implemented() -> Self { Self { message: RequestError::empty(), diff --git a/nym-api/src/nym_nodes/handlers/v1.rs b/nym-api/src/nym_nodes/handlers/v1.rs index 02878bcaa6..8cd5b46368 100644 --- a/nym-api/src/nym_nodes/handlers/v1.rs +++ b/nym-api/src/nym_nodes/handlers/v1.rs @@ -279,11 +279,7 @@ async fn get_node_annotation( ) -> AxumResult> { let output = output.output.unwrap_or_default(); - let annotations = state - .node_status_cache - .node_annotations() - .await - .ok_or_else(AxumErrorResponse::internal)?; + let annotations = state.node_status_cache().node_annotations().await?; Ok(output.to_response(AnnotationResponse { node_id, @@ -312,11 +308,7 @@ async fn get_current_node_performance( ) -> AxumResult> { let output = output.output.unwrap_or_default(); - let annotations = state - .node_status_cache - .node_annotations() - .await - .ok_or_else(AxumErrorResponse::internal)?; + let annotations = state.node_status_cache().node_annotations().await?; Ok(output.to_response(NodePerformanceResponse { node_id, diff --git a/nym-api/src/signers_cache/cache/mod.rs b/nym-api/src/signers_cache/cache/mod.rs index a44ab4da1b..1f5947be5e 100644 --- a/nym-api/src/signers_cache/cache/mod.rs +++ b/nym-api/src/signers_cache/cache/mod.rs @@ -2,10 +2,12 @@ // SPDX-License-Identifier: GPL-3.0-only use nym_ecash_signer_check::SignersTestResult; +use serde::{Deserialize, Serialize}; pub(crate) mod data; pub(crate) mod refresher; +#[derive(Serialize, Deserialize)] pub(crate) struct SignersCacheData { pub(crate) signers_results: SignersTestResult, } diff --git a/nym-api/src/support/caching/cache.rs b/nym-api/src/support/caching/cache.rs index 40d7a59ef1..964deb0963 100644 --- a/nym-api/src/support/caching/cache.rs +++ b/nym-api/src/support/caching/cache.rs @@ -1,13 +1,19 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only +use bincode::Options; +use serde::de::DeserializeOwned; +use serde::{Deserialize, Serialize}; +use std::fs; +use std::fs::File; use std::ops::Deref; +use std::path::Path; use std::sync::Arc; use std::time::Duration; use thiserror::Error; use time::OffsetDateTime; use tokio::sync::{RwLock, RwLockMappedWriteGuard, RwLockReadGuard, RwLockWriteGuard}; -use tracing::debug; +use tracing::{debug, error}; #[derive(Debug, Error)] #[error("the cache item has not been initialised")] @@ -32,6 +38,41 @@ impl SharedCache { SharedCache::default() } + #[track_caller] + pub(crate) fn new_with_persistent>( + store_path: P, + max_cache_age: Duration, + fallback_value: Option, + ) -> Self + where + T: DeserializeOwned, + { + // attempt to load data from disk + let Ok(disk_cached) = Cache::::try_deserialise_from_file(store_path) else { + // if failed, fallback to fresh state + // (the file might not have existed, for example on initial run) + return if let Some(fallback_value) = fallback_value { + Self::new_with_value(fallback_value) + } else { + Self::new() + }; + }; + // check if the entry is not too stale + if disk_cached.has_expired(max_cache_age, None) { + // if too old, fallback to fresh state + debug!("cache has expired"); + return if let Some(fallback_value) = fallback_value { + Self::new_with_value(fallback_value) + } else { + Self::new() + }; + } + // use loaded value + SharedCache(Arc::new(RwLock::new(CachedItem { + inner: Some(disk_cached), + }))) + } + pub(crate) fn new_with_value(value: T) -> Self { SharedCache(Arc::new(RwLock::new(CachedItem { inner: Some(Cache::new(value)), @@ -230,6 +271,35 @@ impl Cache { pub fn timestamp(&self) -> OffsetDateTime { self.as_at } + + #[track_caller] + pub(crate) fn try_serialise_to_file>(&self, path: P) -> std::io::Result<()> + where + T: Serialize, + { + SerialisableCache { + value: &self.value, + as_at: self.as_at, + } + .try_serialise_to_file(path) + } + + #[track_caller] + pub(crate) fn try_deserialise_from_file>(path: P) -> std::io::Result + where + T: DeserializeOwned, + { + let path = path.as_ref(); + if !path.exists() { + debug!("cached file does not exist at: {}", path.display()); + return Err(std::io::Error::other("cached file does not exist")); + } + + DeserialisedCache::try_deserialise_from_file(path).map(|d| Cache { + value: d.value, + as_at: d.as_at, + }) + } } impl Deref for Cache { @@ -251,3 +321,100 @@ where } } } + +#[derive(Serialize)] +struct SerialisableCache<'a, T> { + value: &'a T, + + #[serde(with = "time::serde::rfc3339")] + as_at: OffsetDateTime, +} + +impl<'a, T> SerialisableCache<'a, T> { + #[track_caller] + fn try_serialise_to_file>(self, path: P) -> std::io::Result<()> + where + T: Serialize, + { + use ::bincode::Options; + + let serialiser = make_bincode_serializer(); + let path = path.as_ref(); + + if let Some(parent) = path.parent() { + fs::create_dir_all(parent)?; + } + + let file = match File::create(path) { + Ok(file) => file, + Err(err) => { + error!("failed to create persistent cache file at {path:?}: {err}",); + return Err(err); + } + }; + + serialiser.serialize_into(file, &self).map_err(|err| { + error!("failed to serialise persistent cache file at {path:?}: {err}"); + std::io::Error::other(err) + }) + } +} + +#[derive(Deserialize)] +struct DeserialisedCache { + value: T, + + #[serde(with = "time::serde::rfc3339")] + as_at: OffsetDateTime, +} + +impl DeserialisedCache { + #[track_caller] + fn try_deserialise_from_file>(path: P) -> std::io::Result + where + T: DeserializeOwned, + { + use ::bincode::Options; + + let serialiser = make_bincode_serializer(); + let path = path.as_ref(); + + let file = match File::open(path) { + Ok(file) => file, + Err(err) => { + error!("failed to open persistent cache file at {path:?}: {err}",); + return Err(err); + } + }; + + serialiser.deserialize_from(file).map_err(|err| { + error!("failed to deserialised persistent cache file at {path:?}: {err}"); + std::io::Error::other(err) + }) + } +} + +fn make_bincode_serializer() -> impl ::bincode::Options { + ::bincode::DefaultOptions::new() + .with_little_endian() + .with_varint_encoding() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn deserialisation_is_reciprocal() { + let tmp = tempfile::NamedTempFile::new().unwrap(); + let dummy_data = Cache { + value: "foomp".to_string(), + as_at: OffsetDateTime::now_utc(), + }; + + dummy_data.try_serialise_to_file(tmp.path()).unwrap(); + let de = Cache::::try_deserialise_from_file(tmp.path()).unwrap(); + assert_eq!(dummy_data.value, de.value); + assert_eq!(dummy_data.as_at, de.as_at); + } +} diff --git a/nym-api/src/support/caching/refresher.rs b/nym-api/src/support/caching/refresher.rs index 2b21397c89..627a9ee73c 100644 --- a/nym-api/src/support/caching/refresher.rs +++ b/nym-api/src/support/caching/refresher.rs @@ -5,8 +5,11 @@ use crate::support::caching::cache::SharedCache; use crate::support::caching::CacheNotification; use async_trait::async_trait; use nym_task::ShutdownToken; +use serde::Serialize; +use std::path::PathBuf; use std::sync::Arc; use std::time::Duration; +use tokio::sync::futures::Notified; use tokio::sync::{watch, Notify}; use tokio::time::interval; use tracing::{debug, error, info, trace, warn}; @@ -20,6 +23,10 @@ impl RefreshRequester { pub(crate) fn request_cache_refresh(&self) { self.0.notify_waiters() } + + pub(crate) fn notified(&self) -> Notified<'_> { + self.0.notified() + } } impl Default for RefreshRequester { @@ -37,6 +44,10 @@ impl Default for RefreshRequester { /// the entire value, and we might want to just insert a new entry pub struct CacheRefresher { name: String, + + /// Path to an on-disk location where the contents of the retrieved items should be written + /// upon refresh + on_disk_file: Option, refreshing_interval: Duration, refresh_notification_sender: watch::Sender, @@ -69,6 +80,7 @@ impl CacheRefresher where E: std::error::Error, S: Into, + T: Serialize, { pub(crate) fn new_boxed( item_provider: Box + Send + Sync>, @@ -78,6 +90,7 @@ where CacheRefresher { name: "GenericCacheRefresher".to_string(), + on_disk_file: None, refreshing_interval, refresh_notification_sender, update_fn: None, @@ -86,7 +99,6 @@ where refresh_requester: Default::default(), } } - pub(crate) fn new

(item_provider: P, refreshing_interval: Duration) -> Self where P: CacheItemProvider + Send + Sync + 'static, @@ -103,6 +115,7 @@ where CacheRefresher { name: "GenericCacheRefresher".to_string(), + on_disk_file: None, refreshing_interval, refresh_notification_sender, update_fn: None, @@ -129,6 +142,12 @@ where self } + #[must_use] + pub(crate) fn with_persistent_cache(mut self, storage_path: PathBuf) -> Self { + self.on_disk_file = Some(storage_path); + self + } + pub(crate) fn update_watcher(&self) -> CacheUpdateWatcher { self.refresh_notification_sender.subscribe() } @@ -194,6 +213,19 @@ where } } + async fn try_flush_to_disk(&self) { + // if specified, attempt to flush data onto disk + let Some(disk_cache) = self.on_disk_file.as_ref() else { + return; + }; + let Ok(new_cached) = self.shared_cache.get().await else { + error!("the {} cache is still not initialised!", self.name); + return; + }; + // error reporting is handled by the serialise function itself + let _ = new_cached.try_serialise_to_file(disk_cache); + } + async fn do_refresh_cache(&mut self) { let updated_items = match self.provider.try_refresh().await { Err(err) => { @@ -213,6 +245,8 @@ where self.overwrite_cache(updated_items.into()).await; } + self.try_flush_to_disk().await; + if !self.refresh_notification_sender.is_closed() && self .refresh_notification_sender diff --git a/nym-api/src/support/cli/run.rs b/nym-api/src/support/cli/run.rs index 6c8750149a..625e711935 100644 --- a/nym-api/src/support/cli/run.rs +++ b/nym-api/src/support/cli/run.rs @@ -150,17 +150,60 @@ async fn start_nym_api_tasks(config: &Config) -> anyhow::Result let router = RouterBuilder::with_default_routes(config.network_monitor.enabled); - let mixnet_contract_cache_state = MixnetContractCache::new(); - let node_status_cache_state = NodeStatusCache::new(); let mix_denom = network_details.network.chain_details.mix_denom.base.clone(); - let described_nodes_cache = SharedCache::::new(); - let node_info_cache = unstable::NodeInfoCache::default(); + let storage_cfg = &config.base.storage_paths; + // ===== START: attempt to build up initial caches based on prior data + // + // MIXNET CONTRACT + let mixnet_path = storage_cfg.cache_file("mixnet_contract"); + let ttl = config.mixnet_contract_cache.debug.caching_interval; + let mixnet_contract_cache_state = MixnetContractCache::new(&mixnet_path, ttl); let mixnet_contract_cache_refresher = mixnet_contract_cache::build_refresher( &config.mixnet_contract_cache, &mixnet_contract_cache_state.clone(), nyxd_client.clone(), + mixnet_path, ); + + // DESCRIBED NODES + let described_path = storage_cfg.cache_file("described_nodes"); + let ttl = config.describe_cache.debug.caching_interval; + let described_nodes_cache = + SharedCache::::new_with_persistent(&described_path, ttl, None); + let describe_cache_refresher = node_describe_cache::provider::new_provider_with_initial_value( + &config.describe_cache, + mixnet_contract_cache_state.clone(), + described_nodes_cache.clone(), + described_path, + ); + + // NODES ANNOTATIONS + let annotations_path = storage_cfg.cache_file("node_annotations"); + let ttl = config.node_status_api.debug.caching_interval; + let node_status_cache_state = NodeStatusCache::new(&annotations_path, ttl); + + // note: can't create the cache refresher the same way as above as it's using a different structure + // unfortunately + + // ===== END: attempt to build up initial caches based on prior data + + // not a 'persistent' cache that's updated on a timer like the above - it's just use for retrieving database information + // for unstable routes regarding test runs. + let node_info_cache = unstable::NodeInfoCache::default(); + + // not as data sensitive as others + // check if signers cache is enabled, and if so, start the refresher + let ecash_signers_cache = if config.signers_cache.enabled { + signers_cache::start_refresher( + &config.signers_cache, + nyxd_client.clone(), + &shutdown_manager, + ) + } else { + SharedCache::new() + }; + let mixnet_contract_cache_refresh_requester = mixnet_contract_cache_refresher.refresh_requester(); @@ -211,17 +254,6 @@ async fn start_nym_api_tasks(config: &Config) -> anyhow::Result None }; - // check if signers cache is enabled, and if so, start the refresher - let ecash_signers_cache = if config.signers_cache.enabled { - signers_cache::start_refresher( - &config.signers_cache, - nyxd_client.clone(), - &shutdown_manager, - ) - } else { - SharedCache::new() - }; - ecash_state.spawn_background_cleaner(); let router = router.with_state(AppState { nyxd_client: nyxd_client.clone(), @@ -243,17 +275,6 @@ async fn start_nym_api_tasks(config: &Config) -> anyhow::Result ecash_state: Arc::new(ecash_state), }); - // start note describe cache refresher - // we should be doing the below, but can't due to our current startup structure - // let refresher = node_describe_cache::new_refresher(&config.topology_cacher); - // let cache = refresher.get_shared_cache(); - let describe_cache_refresher = node_describe_cache::provider::new_provider_with_initial_value( - &config.describe_cache, - mixnet_contract_cache_state.clone(), - described_nodes_cache.clone(), - ) - .named("node-self-described-data-refresher"); - let describe_cache_refresh_requester = describe_cache_refresher.refresh_requester(); let describe_cache_watcher = @@ -300,6 +321,7 @@ async fn start_nym_api_tasks(config: &Config) -> anyhow::Result performance_provider, contract_cache_watcher.clone(), describe_cache_watcher, + annotations_path, &shutdown_manager, ); @@ -379,11 +401,11 @@ async fn start_nym_api_tasks(config: &Config) -> anyhow::Result pub(crate) async fn execute(args: Args) -> anyhow::Result<()> { // args take precedence over env - let config = try_load_current_config(&args.id)? + let mut config = try_load_current_config(&args.id)? .override_with_env() .override_with_args(args); - config.validate()?; + config.validate_and_fixup()?; let mut shutdown_manager = start_nym_api_tasks(&config).await?; shutdown_manager.run_until_shutdown().await; diff --git a/nym-api/src/support/config/mod.rs b/nym-api/src/support/config/mod.rs index 6bea4240b3..9e3b9f8e11 100644 --- a/nym-api/src/support/config/mod.rs +++ b/nym-api/src/support/config/mod.rs @@ -21,7 +21,7 @@ use std::io; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::path::{Path, PathBuf}; use std::time::Duration; -use tracing::debug; +use tracing::{debug, warn}; use url::Url; use zeroize::{Zeroize, ZeroizeOnDrop}; @@ -166,7 +166,7 @@ impl Config { } } - pub fn validate(&self) -> anyhow::Result<()> { + pub fn validate_and_fixup(&mut self) -> anyhow::Result<()> { let can_sign = self.base.mnemonic.is_some(); if !can_sign && self.rewarding.enabled { @@ -177,6 +177,12 @@ impl Config { bail!("can't enable coconut signer without providing a mnemonic") } + if self.base.storage_paths.persistent_cache_directory == PathBuf::default() { + warn!("[base.storage_paths].persistent_cache_directory has not been set correctly - using default value instead"); + self.base.storage_paths.persistent_cache_directory = + NymApiPaths::new_default(&self.base.id).persistent_cache_directory; + } + self.ecash_signer.validate()?; Ok(()) diff --git a/nym-api/src/support/config/persistence.rs b/nym-api/src/support/config/persistence.rs index 8e401457a5..07dbf49de0 100644 --- a/nym-api/src/support/config/persistence.rs +++ b/nym-api/src/support/config/persistence.rs @@ -18,28 +18,10 @@ pub const DEFAULT_DKG_PUBLIC_KEY_WITH_PROOF_FILENAME: &str = "dkg_public_key_wit // don't want to be changing the defaults in case something breaks..., but it should be called ecash.pem instead pub const DEFAULT_ECASH_KEY_FILENAME: &str = "coconut.pem"; +pub const DEFAULT_CACHES_DIRECTORY: &str = ".cache"; pub const DEFAULT_PRIVATE_IDENTITY_KEY_FILENAME: &str = "private_identity.pem"; pub const DEFAULT_PUBLIC_IDENTITY_KEY_FILENAME: &str = "public_identity.pem"; -// #[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] -// pub struct NymApiPathfinder { -// pub network_monitor: NetworkMonitorPathfinder, -// -// pub node_status_api: NodeStatusAPIPathfinder, -// -// pub coconut: CoconutSignerPathfinder, -// } -// -// impl NymApiPathfinder { -// pub fn new_default>(id: P) -> Self { -// NymApiPathfinder { -// network_monitor: NetworkMonitorPathfinder::new_default(id.as_ref()), -// node_status_api: NodeStatusAPIPathfinder::new_default(id.as_ref()), -// coconut: CoconutSignerPathfinder::new_default(id.as_ref()), -// } -// } -// } - #[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] pub struct NetworkMonitorPaths { // TODO: this should contain the path to the database holding the results, but changing it would break backwards compatibility @@ -106,6 +88,11 @@ impl EcashSignerPaths { #[derive(Debug, Default, Deserialize, PartialEq, Eq, Serialize)] #[serde(default)] pub struct NymApiPaths { + /// Path to directory containing persistent caches of, for example, + /// the describe information, performance, etc. + /// It is used for restarting the nym-api and preserving the data + pub persistent_cache_directory: PathBuf, + /// Path to file containing private identity key of the nym-api. pub private_identity_key_file: PathBuf, @@ -118,11 +105,16 @@ impl NymApiPaths { let data_dir = default_data_directory(id); NymApiPaths { + persistent_cache_directory: data_dir.join(DEFAULT_CACHES_DIRECTORY), private_identity_key_file: data_dir.join(DEFAULT_PRIVATE_IDENTITY_KEY_FILENAME), public_identity_key_file: data_dir.join(DEFAULT_PUBLIC_IDENTITY_KEY_FILENAME), } } + pub fn cache_file(&self, name: impl AsRef) -> PathBuf { + self.persistent_cache_directory.join(name) + } + pub fn load_identity(&self) -> anyhow::Result { let keypaths = nym_pemstore::KeyPairPath::new( &self.private_identity_key_file, diff --git a/nym-api/src/support/config/template.rs b/nym-api/src/support/config/template.rs index ab94753047..3a4132a947 100644 --- a/nym-api/src/support/config/template.rs +++ b/nym-api/src/support/config/template.rs @@ -22,6 +22,12 @@ bind_address = '{{ base.bind_address }}' mnemonic = '{{ base.mnemonic }}' [base.storage_paths] + +# Path to directory containing persistent caches of, for example, +# the describe information, performance, etc. +# It is used for restarting the nym-api and preserving the data +persistent_cache_directory = '{{ base.storage_paths.persistent_cache_directory }}' + # Path to file containing private identity key of the nym-api. private_identity_key_file = '{{ base.storage_paths.private_identity_key_file }}' diff --git a/nym-api/src/support/http/state/mod.rs b/nym-api/src/support/http/state/mod.rs index f0ac2d121b..1ae60a7fd7 100644 --- a/nym-api/src/support/http/state/mod.rs +++ b/nym-api/src/support/http/state/mod.rs @@ -20,11 +20,8 @@ use crate::support::storage; use crate::unstable_routes::v1::account::cache::AddressInfoCache; use crate::unstable_routes::v1::account::models::NyxAccountDetails; use axum::extract::FromRef; -use nym_api_requests::models::NodeAnnotation; use nym_crypto::asymmetric::ed25519; -use nym_mixnet_contract_common::NodeId; use nym_topology::CachedEpochRewardedSet; -use std::collections::HashMap; use std::sync::Arc; use tokio::sync::RwLockReadGuard; @@ -158,16 +155,6 @@ impl AppState { Ok(self.nym_contract_cache().cached_rewarded_set().await?) } - pub(crate) async fn node_annotations( - &self, - ) -> Result>>, AxumErrorResponse> - { - self.node_status_cache() - .node_annotations() - .await - .ok_or_else(AxumErrorResponse::internal) - } - pub(crate) async fn get_address_info( self, account_id: nym_validator_client::nyxd::AccountId, diff --git a/nym-api/src/unstable_routes/v2/nym_nodes/semi_skimmed/mod.rs b/nym-api/src/unstable_routes/v2/nym_nodes/semi_skimmed/mod.rs index 555718f50d..7375dd9e8d 100644 --- a/nym-api/src/unstable_routes/v2/nym_nodes/semi_skimmed/mod.rs +++ b/nym-api/src/unstable_routes/v2/nym_nodes/semi_skimmed/mod.rs @@ -90,7 +90,8 @@ pub(super) async fn nodes_expanded( let describe_cache = state.describe_nodes_cache_data().await?; let all_nym_nodes = describe_cache.all_nym_nodes(); - let annotations = state.node_annotations().await?; + let status_cache = &state.node_status_cache(); + let annotations = status_cache.node_annotations().await?; let contract_cache = state.nym_contract_cache(); let current_key_rotation = contract_cache.current_key_rotation_id().await?; @@ -107,7 +108,7 @@ pub(super) async fn nodes_expanded( // min of all caches let refreshed_at = refreshed_at([ rewarded_set.timestamp(), - annotations.timestamp(), + status_cache.cache_timestamp().await, describe_cache.timestamp(), ]); diff --git a/nym-api/src/unstable_routes/v2/nym_nodes/skimmed/helpers.rs b/nym-api/src/unstable_routes/v2/nym_nodes/skimmed/helpers.rs index 3456c82444..a510f534d3 100644 --- a/nym-api/src/unstable_routes/v2/nym_nodes/skimmed/helpers.rs +++ b/nym-api/src/unstable_routes/v2/nym_nodes/skimmed/helpers.rs @@ -101,7 +101,8 @@ where let rewarded_set = state.rewarded_set().await?; // 2. grab all annotations so that we could attach scores to the [nym] nodes - let annotations = state.node_annotations().await?; + let status_cache = &state.node_status_cache(); + let annotations = status_cache.node_annotations().await?; // 3. implicitly grab the relevant described nodes // (ideally it'd be tied directly to the NI iterator, but I couldn't defeat the compiler) @@ -138,7 +139,7 @@ where // min of all caches let refreshed_at = refreshed_at([ rewarded_set.timestamp(), - annotations.timestamp(), + status_cache.cache_timestamp().await, describe_cache.timestamp(), ]); @@ -155,7 +156,7 @@ where // min of all caches let refreshed_at = refreshed_at([ rewarded_set.timestamp(), - annotations.timestamp(), + status_cache.cache_timestamp().await, describe_cache.timestamp(), ]); @@ -183,7 +184,8 @@ pub(crate) async fn nodes_basic( let describe_cache = state.describe_nodes_cache_data().await?; let all_nym_nodes = describe_cache.all_nym_nodes(); - let annotations = state.node_annotations().await?; + let status_cache = &state.node_status_cache(); + let annotations = status_cache.node_annotations().await?; let interval = state.nym_contract_cache().current_interval().await?; let current_key_rotation = state.nym_contract_cache().current_key_rotation_id().await?; @@ -199,7 +201,7 @@ pub(crate) async fn nodes_basic( // min of all caches let refreshed_at = refreshed_at([ rewarded_set.timestamp(), - annotations.timestamp(), + status_cache.cache_timestamp().await, describe_cache.timestamp(), ]); From a4950485d1c1ca68dbae435a7d6a8f59d37061e2 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Fri, 13 Feb 2026 09:04:15 +0100 Subject: [PATCH 54/56] bump versions --- Cargo.lock | 14 +++++++------- clients/native/Cargo.toml | 2 +- clients/socks5/Cargo.toml | 2 +- nym-api/Cargo.toml | 2 +- nym-node/Cargo.toml | 2 +- service-providers/network-requester/Cargo.toml | 2 +- tools/nym-cli/Cargo.toml | 2 +- tools/nymvisor/Cargo.toml | 2 +- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8bca7fa945..f6bb76641b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5408,7 +5408,7 @@ dependencies = [ [[package]] name = "nym-api" -version = "1.1.73" +version = "1.1.74" dependencies = [ "anyhow", "async-trait", @@ -5653,7 +5653,7 @@ dependencies = [ [[package]] name = "nym-cli" -version = "1.1.70" +version = "1.1.71" dependencies = [ "anyhow", "base64 0.22.1", @@ -5736,7 +5736,7 @@ dependencies = [ [[package]] name = "nym-client" -version = "1.1.70" +version = "1.1.71" dependencies = [ "bs58", "clap", @@ -7148,7 +7148,7 @@ dependencies = [ [[package]] name = "nym-network-requester" -version = "1.1.71" +version = "1.1.72" dependencies = [ "addr", "anyhow", @@ -7198,7 +7198,7 @@ dependencies = [ [[package]] name = "nym-node" -version = "1.25.0" +version = "1.26.0" dependencies = [ "anyhow", "arc-swap", @@ -7741,7 +7741,7 @@ dependencies = [ [[package]] name = "nym-socks5-client" -version = "1.1.70" +version = "1.1.71" dependencies = [ "bs58", "clap", @@ -8564,7 +8564,7 @@ dependencies = [ [[package]] name = "nymvisor" -version = "0.1.35" +version = "0.1.36" dependencies = [ "anyhow", "bytes", diff --git a/clients/native/Cargo.toml b/clients/native/Cargo.toml index e5b4f09d84..e0ac34bec8 100644 --- a/clients/native/Cargo.toml +++ b/clients/native/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-client" -version = "1.1.70" +version = "1.1.71" 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 aa09c09ca3..e1bded672c 100644 --- a/clients/socks5/Cargo.toml +++ b/clients/socks5/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-socks5-client" -version = "1.1.70" +version = "1.1.71" 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/nym-api/Cargo.toml b/nym-api/Cargo.toml index 5ad7fb4ecb..5357e1e94e 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -4,7 +4,7 @@ [package] name = "nym-api" license = "GPL-3.0" -version = "1.1.73" +version = "1.1.74" authors.workspace = true edition = "2021" rust-version.workspace = true diff --git a/nym-node/Cargo.toml b/nym-node/Cargo.toml index d2dd9f0951..90f451deb4 100644 --- a/nym-node/Cargo.toml +++ b/nym-node/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-node" -version = "1.25.0" +version = "1.26.0" authors.workspace = true repository.workspace = true homepage.workspace = true diff --git a/service-providers/network-requester/Cargo.toml b/service-providers/network-requester/Cargo.toml index 8d79940d1a..abf59b66f3 100644 --- a/service-providers/network-requester/Cargo.toml +++ b/service-providers/network-requester/Cargo.toml @@ -4,7 +4,7 @@ [package] name = "nym-network-requester" license = "GPL-3.0" -version = "1.1.71" +version = "1.1.72" authors.workspace = true edition.workspace = true rust-version = "1.85" diff --git a/tools/nym-cli/Cargo.toml b/tools/nym-cli/Cargo.toml index 02ec79ce93..bc102b46bd 100644 --- a/tools/nym-cli/Cargo.toml +++ b/tools/nym-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-cli" -version = "1.1.70" +version = "1.1.71" authors.workspace = true edition = "2021" license.workspace = true diff --git a/tools/nymvisor/Cargo.toml b/tools/nymvisor/Cargo.toml index 6a6fd475cc..e5a62b3d63 100644 --- a/tools/nymvisor/Cargo.toml +++ b/tools/nymvisor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nymvisor" -version = "0.1.35" +version = "0.1.36" authors.workspace = true repository.workspace = true homepage.workspace = true From 5b62fd76ba5378d95f4a09742afa9474f7f78541 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Tue, 24 Feb 2026 11:29:04 +0100 Subject: [PATCH 55/56] update changelog --- CHANGELOG.md | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d58c32a7e5..481fcecf93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,84 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// ## [Unreleased] +## [2026.4-quark] (2026-02-24) + +- Otel minimal v2 ([#6464]) +- Enhance CI workflow with feature inputs ([#6462]) +- Chore/revert 6433 ([#6445]) +- Lp/stateless handshake ([#6437]) +- build(deps-dev): bump webpack from 5.98.0 to 5.105.0 in /wasm/client/internal-dev ([#6435]) +- build(deps-dev): bump webpack from 5.102.1 to 5.104.1 ([#6432]) +- build(deps-dev): bump webpack from 5.98.0 to 5.105.0 in /wasm/mix-fetch/internal-dev ([#6431]) +- build(deps-dev): bump webpack from 5.94.0 to 5.104.1 in /nym-credential-proxy/vpn-api-lib-wasm/internal-dev ([#6430]) +- build(deps-dev): bump webpack from 5.77.0 to 5.104.1 in /wasm/zknym-lib/internal-dev ([#6429]) +- build(deps-dev): bump webpack from 5.76.0 to 5.105.0 in /clients/native/examples/js-examples/websocket ([#6428]) +- HTTP & DNS Improvements ([#6423]) +- Endpoint for exit GW IPs ([#6418]) +- build(deps): bump bytes from 1.6.0 to 1.11.1 in /contracts ([#6416]) +- build(deps): bump @isaacs/brace-expansion from 5.0.0 to 5.0.1 ([#6415]) +- build(deps): bump bytes from 1.11.0 to 1.11.1 ([#6414]) +- build(deps): bump mikefarah/yq from 4.50.1 to 4.52.2 ([#6407]) +- build(deps-dev): bump eslint from 8.57.1 to 9.26.0 ([#6405]) +- Update reqwest to v0.13.1 ([#6401]) +- build(deps): bump next from 15.5.9 to 16.1.5 in /documentation/docs ([#6387]) +- build(deps): bump next from 15.4.10 to 16.1.5 in /nym-node-status-api/nym-node-status-ui ([#6385]) +- build(deps): bump lodash from 4.17.21 to 4.17.23 ([#6369]) +- build(deps): bump lodash-es from 4.17.21 to 4.17.23 ([#6360]) +- build(deps-dev): bump lodash from 4.17.21 to 4.17.23 in /sdk/typescript/codegen/contract-clients ([#6359]) +- build(deps): bump lodash from 4.17.21 to 4.17.23 in /sdk/typescript/packages/nodejs-client ([#6354]) +- build(deps): bump lodash from 4.17.21 to 4.17.23 in /documentation/docs ([#6353]) +- build(deps): bump lodash from 4.17.21 to 4.17.23 in /clients/native/examples/js-examples/websocket ([#6351]) +- build(deps): bump lodash-es from 4.17.21 to 4.17.23 in /documentation/docs ([#6350]) +- build(deps): bump diff from 5.2.0 to 5.2.2 in /documentation/docs ([#6345]) +- Max/crates publishing tweaks ([#6343]) +- build(deps): bump h3 from 1.15.4 to 1.15.5 ([#6339]) +- build(deps): bump h3 from 1.15.4 to 1.15.5 in /documentation/docs ([#6332]) +- build(deps): bump undici from 6.21.3 to 6.23.0 in /documentation/docs ([#6325]) +- build(deps): bump rsa from 0.9.8 to 0.9.10 ([#6311]) +- build(deps): bump qs and express in /wasm/mix-fetch/internal-dev ([#6308]) +- build(deps): bump qs and express in /clients/native/examples/js-examples/websocket ([#6307]) +- feat: introduce on-disk cache persistance for major nym-api caches ([#6302]) +- Fix migrations in the Data Observatory ([#6271]) + +[#6464]: https://github.com/nymtech/nym/pull/6464 +[#6462]: https://github.com/nymtech/nym/pull/6462 +[#6445]: https://github.com/nymtech/nym/pull/6445 +[#6437]: https://github.com/nymtech/nym/pull/6437 +[#6435]: https://github.com/nymtech/nym/pull/6435 +[#6432]: https://github.com/nymtech/nym/pull/6432 +[#6431]: https://github.com/nymtech/nym/pull/6431 +[#6430]: https://github.com/nymtech/nym/pull/6430 +[#6429]: https://github.com/nymtech/nym/pull/6429 +[#6428]: https://github.com/nymtech/nym/pull/6428 +[#6423]: https://github.com/nymtech/nym/pull/6423 +[#6418]: https://github.com/nymtech/nym/pull/6418 +[#6416]: https://github.com/nymtech/nym/pull/6416 +[#6415]: https://github.com/nymtech/nym/pull/6415 +[#6414]: https://github.com/nymtech/nym/pull/6414 +[#6407]: https://github.com/nymtech/nym/pull/6407 +[#6405]: https://github.com/nymtech/nym/pull/6405 +[#6401]: https://github.com/nymtech/nym/pull/6401 +[#6387]: https://github.com/nymtech/nym/pull/6387 +[#6385]: https://github.com/nymtech/nym/pull/6385 +[#6369]: https://github.com/nymtech/nym/pull/6369 +[#6360]: https://github.com/nymtech/nym/pull/6360 +[#6359]: https://github.com/nymtech/nym/pull/6359 +[#6354]: https://github.com/nymtech/nym/pull/6354 +[#6353]: https://github.com/nymtech/nym/pull/6353 +[#6351]: https://github.com/nymtech/nym/pull/6351 +[#6350]: https://github.com/nymtech/nym/pull/6350 +[#6345]: https://github.com/nymtech/nym/pull/6345 +[#6343]: https://github.com/nymtech/nym/pull/6343 +[#6339]: https://github.com/nymtech/nym/pull/6339 +[#6332]: https://github.com/nymtech/nym/pull/6332 +[#6325]: https://github.com/nymtech/nym/pull/6325 +[#6311]: https://github.com/nymtech/nym/pull/6311 +[#6308]: https://github.com/nymtech/nym/pull/6308 +[#6307]: https://github.com/nymtech/nym/pull/6307 +[#6302]: https://github.com/nymtech/nym/pull/6302 +[#6271]: https://github.com/nymtech/nym/pull/6271 + ## [2026.3-parmigiano] (2026-02-10) - chore: disable LP on parmigiano branch ([#6422]) From a2081af6038ef3ef40b3d9368299d2676a2fbb6a Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Tue, 24 Feb 2026 12:02:35 +0100 Subject: [PATCH 56/56] . --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 481fcecf93..11ed1bb017 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,6 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// ## [2026.4-quark] (2026-02-24) -- Otel minimal v2 ([#6464]) - Enhance CI workflow with feature inputs ([#6462]) - Chore/revert 6433 ([#6445]) - Lp/stateless handshake ([#6437]) @@ -44,7 +43,6 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// - feat: introduce on-disk cache persistance for major nym-api caches ([#6302]) - Fix migrations in the Data Observatory ([#6271]) -[#6464]: https://github.com/nymtech/nym/pull/6464 [#6462]: https://github.com/nymtech/nym/pull/6462 [#6445]: https://github.com/nymtech/nym/pull/6445 [#6437]: https://github.com/nymtech/nym/pull/6437