Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 81e72ba61b | |||
| 0e3ffb749e | |||
| bd2e6ee812 | |||
| 9856198356 | |||
| 5c33846e57 | |||
| 5d45544c27 | |||
| aa6a79cb3e | |||
| b3a940770a | |||
| e980f76a81 | |||
| 9b38fef28f | |||
| 43910ca635 | |||
| d3ccd7575a | |||
| 422f889df7 | |||
| c9e96edc35 | |||
| 7768317046 | |||
| 0ebbb1a540 | |||
| 827c13b69e | |||
| bb06a1b7a8 | |||
| e783a5fced | |||
| 8a24b45b5d | |||
| 10e4eba727 | |||
| 8ebf482f36 | |||
| 6940ca427e | |||
| 24f877fda5 |
@@ -10,7 +10,7 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: arc-ubuntu-22.04
|
||||
runs-on: arc-linux-latest
|
||||
env:
|
||||
RUSTUP_PERMIT_COPY_RENAME: 1
|
||||
defaults:
|
||||
|
||||
Generated
+1
-2
@@ -5746,7 +5746,6 @@ dependencies = [
|
||||
"criterion",
|
||||
"ff",
|
||||
"group",
|
||||
"lazy_static",
|
||||
"nym-contracts-common",
|
||||
"nym-pemstore",
|
||||
"rand 0.8.5",
|
||||
@@ -6598,7 +6597,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-node-status-api"
|
||||
version = "4.0.7-test2"
|
||||
version = "4.0.9"
|
||||
dependencies = [
|
||||
"ammonia",
|
||||
"anyhow",
|
||||
|
||||
@@ -892,7 +892,7 @@ where
|
||||
// Create a shutdown tracker for this client - either as a child of provided tracker
|
||||
// or get one from the registry
|
||||
let shutdown_tracker = match self.shutdown {
|
||||
Some(parent_tracker) => parent_tracker.child_tracker(),
|
||||
Some(parent_tracker) => parent_tracker.clone(),
|
||||
None => nym_task::get_sdk_shutdown_tracker()?,
|
||||
};
|
||||
|
||||
@@ -926,7 +926,7 @@ where
|
||||
self.user_agent.clone(),
|
||||
generate_client_stats_id(*self_address.identity()),
|
||||
input_sender.clone(),
|
||||
&shutdown_tracker.child_tracker(),
|
||||
&shutdown_tracker.clone(),
|
||||
);
|
||||
|
||||
// needs to be started as the first thing to block if required waiting for the gateway
|
||||
@@ -936,7 +936,7 @@ where
|
||||
shared_topology_accessor.clone(),
|
||||
self_address.gateway(),
|
||||
self.wait_for_gateway,
|
||||
&shutdown_tracker.child_tracker(),
|
||||
&shutdown_tracker.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -956,7 +956,7 @@ where
|
||||
stats_reporter.clone(),
|
||||
#[cfg(unix)]
|
||||
self.connection_fd_callback,
|
||||
&shutdown_tracker.child_tracker(),
|
||||
&shutdown_tracker.clone(),
|
||||
)
|
||||
.await?;
|
||||
let gateway_ws_fd = gateway_transceiver.ws_fd();
|
||||
@@ -964,7 +964,7 @@ where
|
||||
let reply_storage = Self::setup_persistent_reply_storage(
|
||||
reply_storage_backend,
|
||||
key_rotation_config,
|
||||
&shutdown_tracker.child_tracker(),
|
||||
&shutdown_tracker.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -975,7 +975,7 @@ where
|
||||
reply_storage.key_storage(),
|
||||
reply_controller_sender.clone(),
|
||||
stats_reporter.clone(),
|
||||
&shutdown_tracker.child_tracker(),
|
||||
&shutdown_tracker.clone(),
|
||||
);
|
||||
|
||||
// The message_sender is the transmitter for any component generating sphinx packets
|
||||
@@ -983,10 +983,8 @@ where
|
||||
// traffic stream.
|
||||
// The MixTrafficController then sends the actual traffic
|
||||
|
||||
let (message_sender, client_request_sender) = Self::start_mix_traffic_controller(
|
||||
gateway_transceiver,
|
||||
&shutdown_tracker.child_tracker(),
|
||||
);
|
||||
let (message_sender, client_request_sender) =
|
||||
Self::start_mix_traffic_controller(gateway_transceiver, &shutdown_tracker.clone());
|
||||
|
||||
// Channels that the websocket listener can use to signal downstream to the real traffic
|
||||
// controller that connections are closed.
|
||||
@@ -1015,7 +1013,7 @@ where
|
||||
shared_lane_queue_lengths.clone(),
|
||||
client_connection_rx,
|
||||
stats_reporter.clone(),
|
||||
&shutdown_tracker.child_tracker(),
|
||||
&shutdown_tracker.clone(),
|
||||
);
|
||||
|
||||
if !self
|
||||
@@ -1031,7 +1029,7 @@ where
|
||||
shared_topology_accessor.clone(),
|
||||
message_sender,
|
||||
stats_reporter.clone(),
|
||||
&shutdown_tracker.child_tracker(),
|
||||
&shutdown_tracker.clone(),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -155,6 +155,7 @@ impl MixTrafficController {
|
||||
error!("Failed to send sphinx packet to the gateway {MAX_FAILURE_COUNT} times in a row - assuming the gateway is dead");
|
||||
// Do we need to handle the embedded mixnet client case
|
||||
// separately?
|
||||
self.shutdown_token.cancel();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ use cosmrs::tx;
|
||||
use cosmrs::tx::SignDoc;
|
||||
use nym_config::defaults;
|
||||
use thiserror::Error;
|
||||
use zeroize::{Zeroize, ZeroizeOnDrop};
|
||||
use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing};
|
||||
|
||||
type Secp256k1Keypair = (SigningKey, PublicKey);
|
||||
|
||||
@@ -128,9 +128,20 @@ impl DirectSecp256k1HdWallet {
|
||||
Ok(accounts)
|
||||
}
|
||||
|
||||
pub fn secret(&self) -> &bip39::Mnemonic {
|
||||
&self.secret
|
||||
}
|
||||
|
||||
#[deprecated(
|
||||
note = "use either .secret() for obtaining &bip39::Mnemonic or .mnemonic_string() for Zeroizing wrapper around the String"
|
||||
)]
|
||||
pub fn mnemonic(&self) -> String {
|
||||
self.secret.to_string()
|
||||
}
|
||||
|
||||
pub fn mnemonic_string(&self) -> Zeroizing<String> {
|
||||
Zeroizing::new(self.secret.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
|
||||
@@ -18,6 +18,6 @@ pub fn create_account(args: Args, prefix: &str) {
|
||||
let wallet = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic);
|
||||
|
||||
// Output address and mnemonics into separate lines for easier parsing
|
||||
println!("{}", wallet.mnemonic());
|
||||
println!("{}", wallet.mnemonic_string().as_str());
|
||||
println!("{}", wallet.try_derive_accounts().unwrap()[0].address());
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ nym-contracts-common = { path = "../cosmwasm-smart-contracts/contracts-common",
|
||||
bs58 = { workspace = true }
|
||||
|
||||
|
||||
lazy_static = { workspace = true }
|
||||
rand = { workspace = true }
|
||||
rand_chacha = { workspace = true }
|
||||
rand_core = { workspace = true }
|
||||
|
||||
@@ -13,9 +13,9 @@ use rand::CryptoRng;
|
||||
use rand_core::RngCore;
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Neg;
|
||||
use zeroize::Zeroize;
|
||||
use zeroize::{Zeroize, ZeroizeOnDrop};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Zeroize, ZeroizeOnDrop)]
|
||||
pub struct Ciphertexts {
|
||||
pub rr: [G1Projective; NUM_CHUNKS],
|
||||
pub ss: [G1Projective; NUM_CHUNKS],
|
||||
@@ -164,8 +164,7 @@ impl Ciphertexts {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Zeroize)]
|
||||
#[zeroize(drop)]
|
||||
#[derive(Zeroize, ZeroizeOnDrop)]
|
||||
/// Randomness generated during ciphertext generation that is required for proofs of knowledge.
|
||||
///
|
||||
/// It must be handled with extreme care as its misuse might help malicious parties to recover
|
||||
@@ -399,7 +398,7 @@ pub fn baby_step_giant_step(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::bte::{keygen, setup, DEFAULT_BSGS_TABLE};
|
||||
use crate::bte::{keygen, setup, BSGS_TABLE};
|
||||
use rand_core::SeedableRng;
|
||||
|
||||
fn verify_hazmat_rand(ciphertext: &Ciphertexts, randomness: &HazmatRandomness) {
|
||||
@@ -457,8 +456,6 @@ mod tests {
|
||||
let (decryption_key1, public_key1) = keygen(¶ms, &mut rng);
|
||||
let (decryption_key2, public_key2) = keygen(¶ms, &mut rng);
|
||||
|
||||
let lookup_table = &DEFAULT_BSGS_TABLE;
|
||||
|
||||
for _ in 0..10 {
|
||||
let m1 = Share::random(&mut rng);
|
||||
let m2 = Share::random(&mut rng);
|
||||
@@ -467,22 +464,12 @@ mod tests {
|
||||
let (ciphertext, hazmat) = encrypt_shares(shares, ¶ms, &mut rng);
|
||||
verify_hazmat_rand(&ciphertext, &hazmat);
|
||||
|
||||
let recovered1 = decrypt_share(
|
||||
¶ms,
|
||||
&decryption_key1,
|
||||
0,
|
||||
&ciphertext,
|
||||
Some(lookup_table),
|
||||
)
|
||||
.unwrap();
|
||||
let recovered2 = decrypt_share(
|
||||
¶ms,
|
||||
&decryption_key2,
|
||||
1,
|
||||
&ciphertext,
|
||||
Some(lookup_table),
|
||||
)
|
||||
.unwrap();
|
||||
let recovered1 =
|
||||
decrypt_share(¶ms, &decryption_key1, 0, &ciphertext, Some(&BSGS_TABLE))
|
||||
.unwrap();
|
||||
let recovered2 =
|
||||
decrypt_share(¶ms, &decryption_key2, 1, &ciphertext, Some(&BSGS_TABLE))
|
||||
.unwrap();
|
||||
assert_eq!(m1, recovered1);
|
||||
assert_eq!(m2, recovered2);
|
||||
}
|
||||
@@ -498,8 +485,6 @@ mod tests {
|
||||
let (decryption_key1, public_key1) = keygen(¶ms, &mut rng);
|
||||
let (decryption_key2, public_key2) = keygen(¶ms, &mut rng);
|
||||
|
||||
let lookup_table = &DEFAULT_BSGS_TABLE;
|
||||
|
||||
for _ in 0..10 {
|
||||
let m1 = Share::random(&mut rng);
|
||||
let m2 = Share::random(&mut rng);
|
||||
@@ -508,22 +493,12 @@ mod tests {
|
||||
let (ciphertext, hazmat) = encrypt_shares(shares, ¶ms, &mut rng);
|
||||
verify_hazmat_rand(&ciphertext, &hazmat);
|
||||
|
||||
let recovered1 = decrypt_share(
|
||||
¶ms,
|
||||
&decryption_key1,
|
||||
0,
|
||||
&ciphertext,
|
||||
Some(lookup_table),
|
||||
)
|
||||
.unwrap();
|
||||
let recovered2 = decrypt_share(
|
||||
¶ms,
|
||||
&decryption_key2,
|
||||
1,
|
||||
&ciphertext,
|
||||
Some(lookup_table),
|
||||
)
|
||||
.unwrap();
|
||||
let recovered1 =
|
||||
decrypt_share(¶ms, &decryption_key1, 0, &ciphertext, Some(&BSGS_TABLE))
|
||||
.unwrap();
|
||||
let recovered2 =
|
||||
decrypt_share(¶ms, &decryption_key2, 1, &ciphertext, Some(&BSGS_TABLE))
|
||||
.unwrap();
|
||||
assert_eq!(m1, recovered1);
|
||||
assert_eq!(m2, recovered2);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ use group::GroupEncoding;
|
||||
use nym_pemstore::traits::{PemStorableKey, PemStorableKeyPair};
|
||||
use rand::CryptoRng;
|
||||
use rand_core::RngCore;
|
||||
use zeroize::Zeroize;
|
||||
use zeroize::{Zeroize, ZeroizeOnDrop};
|
||||
|
||||
// produces public key and a decryption key for the root of the tree
|
||||
pub fn keygen(
|
||||
@@ -48,7 +48,7 @@ pub fn keygen(
|
||||
(dk, key_with_proof)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Zeroize)]
|
||||
pub struct PublicKey(pub(crate) G1Projective);
|
||||
|
||||
impl PublicKey {
|
||||
@@ -57,7 +57,7 @@ impl PublicKey {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Zeroize, ZeroizeOnDrop)]
|
||||
pub struct PublicKeyWithProof {
|
||||
pub(crate) key: PublicKey,
|
||||
pub(crate) proof: ProofOfDiscreteLog,
|
||||
@@ -136,8 +136,7 @@ impl PublicKeyWithProof {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Zeroize)]
|
||||
#[zeroize(drop)]
|
||||
#[derive(Debug, Zeroize, ZeroizeOnDrop)]
|
||||
#[cfg_attr(test, derive(PartialEq, Eq))]
|
||||
pub struct DecryptionKey {
|
||||
// g1^rho
|
||||
@@ -242,6 +241,7 @@ impl DecryptionKey {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Zeroize, ZeroizeOnDrop)]
|
||||
pub struct KeyPair {
|
||||
pub(crate) private_key: DecryptionKey,
|
||||
pub(crate) public_key: PublicKeyWithProof,
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use std::sync::LazyLock;
|
||||
|
||||
use crate::bte::encryption::BabyStepGiantStepLookup;
|
||||
use crate::utils::hash_g2;
|
||||
use crate::{Chunk, Share};
|
||||
use bls12_381::{G1Affine, G2Affine, G2Prepared, G2Projective, Gt};
|
||||
use group::Curve;
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
pub mod encryption;
|
||||
pub mod keys;
|
||||
@@ -16,14 +18,12 @@ pub mod proof_sharing;
|
||||
pub use encryption::{decrypt_share, encrypt_shares, Ciphertexts};
|
||||
pub use keys::{keygen, DecryptionKey, PublicKey, PublicKeyWithProof};
|
||||
|
||||
lazy_static! {
|
||||
pub(crate) static ref PAIRING_BASE: Gt =
|
||||
bls12_381::pairing(&G1Affine::generator(), &G2Affine::generator());
|
||||
pub(crate) static ref G2_GENERATOR_PREPARED: G2Prepared =
|
||||
G2Prepared::from(G2Affine::generator());
|
||||
pub(crate) static ref DEFAULT_BSGS_TABLE: encryption::BabyStepGiantStepLookup =
|
||||
encryption::BabyStepGiantStepLookup::default();
|
||||
}
|
||||
pub(crate) static PAIRING_BASE: LazyLock<Gt> =
|
||||
LazyLock::new(|| bls12_381::pairing(&G1Affine::generator(), &G2Affine::generator()));
|
||||
pub(crate) static G2_GENERATOR_PREPARED: LazyLock<G2Prepared> =
|
||||
LazyLock::new(|| G2Prepared::from(G2Affine::generator()));
|
||||
pub static BSGS_TABLE: LazyLock<BabyStepGiantStepLookup> =
|
||||
LazyLock::new(BabyStepGiantStepLookup::default);
|
||||
|
||||
// Domain tries to follow guidelines specified by:
|
||||
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-3.1
|
||||
|
||||
@@ -12,6 +12,7 @@ use ff::Field;
|
||||
use group::{Group, GroupEncoding};
|
||||
use rand::{CryptoRng, Rng};
|
||||
use rand_core::{RngCore, SeedableRng};
|
||||
use zeroize::{Zeroize, ZeroizeOnDrop};
|
||||
|
||||
const CHUNKING_ORACLE_DOMAIN: &[u8] =
|
||||
b"NYM_COCONUT_NIDKG_V01_CS01_SHA-256_CHACHA20_CHUNKING_ORACLE";
|
||||
@@ -67,7 +68,7 @@ impl<'a> Instance<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Zeroize, ZeroizeOnDrop)]
|
||||
pub struct ProofOfChunking {
|
||||
y0: G1Projective,
|
||||
bb: Vec<G1Projective>,
|
||||
|
||||
@@ -7,14 +7,14 @@ use ff::Field;
|
||||
use group::GroupEncoding;
|
||||
use rand::CryptoRng;
|
||||
use rand_core::RngCore;
|
||||
use zeroize::Zeroize;
|
||||
use zeroize::{Zeroize, ZeroizeOnDrop};
|
||||
|
||||
// Domain tries to follow guidelines specified by:
|
||||
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-3.1
|
||||
const DISCRETE_LOG_DOMAIN: &[u8] =
|
||||
b"NYM_COCONUT_NIDKG_V01_CS01_WITH_BLS12381_XMD:SHA-256_SSWU_RO_PROOF_DISCRETE_LOG";
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Zeroize, ZeroizeOnDrop)]
|
||||
pub struct ProofOfDiscreteLog {
|
||||
pub(crate) rand_commitment: G1Projective,
|
||||
pub(crate) response: Scalar,
|
||||
@@ -52,9 +52,9 @@ impl ProofOfDiscreteLog {
|
||||
let public_bytes = public.to_bytes();
|
||||
let rand_commit_bytes = rand_commit.to_bytes();
|
||||
|
||||
let mut bytes = Vec::with_capacity(96);
|
||||
bytes.extend_from_slice(public_bytes.as_ref());
|
||||
bytes.extend_from_slice(rand_commit_bytes.as_ref());
|
||||
let mut bytes = [0u8; 96];
|
||||
bytes[0..48].copy_from_slice(public_bytes.as_ref());
|
||||
bytes[48..96].copy_from_slice(rand_commit_bytes.as_ref());
|
||||
|
||||
hash_to_scalar(bytes, DISCRETE_LOG_DOMAIN)
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ use group::GroupEncoding;
|
||||
use rand::CryptoRng;
|
||||
use rand_core::RngCore;
|
||||
use std::collections::BTreeMap;
|
||||
use zeroize::{Zeroize, ZeroizeOnDrop};
|
||||
|
||||
// Domain tries to follow guidelines specified by:
|
||||
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-3.1
|
||||
@@ -77,7 +78,7 @@ impl<'a> Instance<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Zeroize, ZeroizeOnDrop)]
|
||||
pub struct ProofOfSecretSharing {
|
||||
ff: G1Projective,
|
||||
aa: G2Projective,
|
||||
|
||||
@@ -18,7 +18,7 @@ use rand_core::RngCore;
|
||||
use std::collections::BTreeMap;
|
||||
use zeroize::Zeroize;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Zeroize)]
|
||||
#[cfg_attr(test, derive(PartialEq, Eq))]
|
||||
pub struct RecoveredVerificationKeys {
|
||||
pub recovered_master: G2Projective,
|
||||
@@ -83,7 +83,7 @@ impl RecoveredVerificationKeys {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Zeroize)]
|
||||
pub struct Dealing {
|
||||
pub public_coefficients: PublicCoefficients,
|
||||
pub ciphertexts: Ciphertexts,
|
||||
|
||||
@@ -9,9 +9,9 @@ use group::GroupEncoding;
|
||||
use rand::CryptoRng;
|
||||
use rand_core::RngCore;
|
||||
use std::ops::{Add, Index, IndexMut};
|
||||
use zeroize::Zeroize;
|
||||
use zeroize::{Zeroize, ZeroizeOnDrop};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Zeroize, ZeroizeOnDrop)]
|
||||
pub struct PublicCoefficients {
|
||||
pub(crate) coefficients: Vec<G2Projective>,
|
||||
}
|
||||
@@ -111,8 +111,7 @@ impl IndexMut<usize> for PublicCoefficients {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Zeroize)]
|
||||
#[zeroize(drop)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Zeroize, ZeroizeOnDrop)]
|
||||
pub struct Polynomial {
|
||||
coefficients: Vec<Scalar>,
|
||||
}
|
||||
|
||||
@@ -6,14 +6,13 @@ use crate::error::DkgError;
|
||||
use crate::interpolation::perform_lagrangian_interpolation_at_origin;
|
||||
use crate::NodeIndex;
|
||||
use bls12_381::Scalar;
|
||||
use zeroize::Zeroize;
|
||||
use zeroize::{Zeroize, ZeroizeOnDrop};
|
||||
|
||||
// if this type is changed, one must ensure all values can fit in it
|
||||
pub type Chunk = u16;
|
||||
|
||||
#[derive(PartialEq, Eq, Debug, Zeroize)]
|
||||
#[derive(PartialEq, Eq, Debug, Zeroize, ZeroizeOnDrop)]
|
||||
#[cfg_attr(test, derive(Clone))]
|
||||
#[zeroize(drop)]
|
||||
pub struct Share(pub(crate) Scalar);
|
||||
|
||||
pub fn combine_shares(shares: Vec<Share>, node_indices: &[NodeIndex]) -> Result<Scalar, DkgError> {
|
||||
@@ -66,9 +65,8 @@ impl From<Scalar> for Share {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Zeroize)]
|
||||
#[derive(Default, Zeroize, ZeroizeOnDrop)]
|
||||
#[cfg_attr(test, derive(Clone))]
|
||||
#[zeroize(drop)]
|
||||
pub(crate) struct ChunkedShare {
|
||||
pub(crate) chunks: [Chunk; NUM_CHUNKS],
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import { Alert, AlertTitle } from '@mui/material';
|
||||
import { Wallet } from '@cosmos-kit/core';
|
||||
import { CosmosKitLedger } from './ledger';
|
||||
import { CosmosKitSign } from './sign';
|
||||
import type { SignerOptions } from '@cosmos-kit/core';
|
||||
|
||||
const CosmosKitSetup: FC<{ children: React.ReactNode }> = ({ children }) => {
|
||||
const assetsFixedUp = React.useMemo(() => {
|
||||
@@ -40,14 +41,16 @@ const CosmosKitSetup: FC<{ children: React.ReactNode }> = ({ children }) => {
|
||||
return chains;
|
||||
}, [chains]);
|
||||
|
||||
|
||||
// components/cosmos-kit/index.tsx
|
||||
|
||||
return (
|
||||
<ChainProvider
|
||||
chains={chainsFixedUp}
|
||||
assetLists={assetsFixedUp}
|
||||
wallets={[...ledger, ...keplr]}
|
||||
signerOptions={{
|
||||
preferredSignType: () => 'amino',
|
||||
}}
|
||||
signerOptions={{ preferredSignType: () => 'amino' }}
|
||||
throwErrors={false}
|
||||
>
|
||||
{children}
|
||||
</ChainProvider>
|
||||
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
import { Steps } from 'nextra/components';
|
||||
import { Callout } from 'nextra/components';
|
||||
import { AccordionTemplate } from 'components/accordion-template.tsx';
|
||||
|
||||
<Callout type="info" emoji="ℹ️">
|
||||
**QUIC bridge is a requirement for all nodes which enable Wireguard functionality. Note that it this feature is compatible with nodes from `v1.18.0` (platform release [`v2025.17-isabirra`](https://github.com/nymtech/nym/releases/tag/nym-binaries-v2025.17-isabirra)) and newer!**
|
||||
</ Callout>
|
||||
|
||||
Nym Network uses various [transport bridges](https://github.com/nymtech/nym-bridges/blob/main/README.md) for routing the packets. Right now operators need to configure [our implementation](https://github.com/nymtech/nym-bridges/tree/main/nym-bridge) of general-purpose transport layer network protocol called [QUIC](https://en.wikipedia.org/wiki/QUIC).
|
||||
|
||||
Operators can use [Nym Bridge Configuration Tool](https://github.com/nymtech/nym-bridges/tree/main/bridge-cfg) and compile the [Bridge Runner binary](https://github.com/nymtech/nym-bridges/tree/main/nym-bridge) themselves.
|
||||
|
||||
**We recommend a more convenient QUIC bridge deployment using a script [`quic_bridge_deployment.sh`](https://github.com/nymtech/nym/blob/develop/scripts/nym-node-setup/quic_bridge_deployment.sh), following the steps below.**
|
||||
|
||||
<Steps>
|
||||
###### 1. Download [`quic_bridge_deployment.sh`](https://github.com/nymtech/nym/blob/develop/scripts/nym-node-setup/quic_bridge_deployment.sh) script
|
||||
- SSH to your server
|
||||
- Download the script and make executable
|
||||
```sh
|
||||
wget https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/nym-node-setup/quic_bridge_deployment.sh && \
|
||||
chmod +x quic_bridge_deployment.sh
|
||||
```
|
||||
|
||||
|
||||
###### 2. Run the script with `full_bridge_setup` command
|
||||
- Optional: open `tmux` in case you will need to run another commands on the VPS
|
||||
- Run the script with a command `full_bridge_setup`
|
||||
```sh
|
||||
./nym-node-setup/quic_bridge_deployment.sh full_bridge_setup
|
||||
```
|
||||
|
||||
###### 3. Follow the interactive prompts
|
||||
- When you are asked for bridge binary URL, look here for one to match your system: [builds.ci.nymte.ch/QUIC](https://builds.ci.nymte.ch/QUIC/)
|
||||
- When you are asked to enter forward address, it's your IPv4 used for bonding the node, alongside port `:51822` (an example: `172.232.238.161:51822`)
|
||||
- To find out your IP address you can always run:
|
||||
- IPv4: `curl -4 https://ifconfig.co/ip`
|
||||
- IPv6: `curl -6 https://ifconfig.co/ip`
|
||||
- **For all prompts with default options, we highly recommend to stick to default (press enter)**
|
||||
|
||||
###### 4. Restart the node service
|
||||
- When done with the deployment, please restart your node systemd service
|
||||
```sh
|
||||
service nym-node restart && journalctl -u nym-node.service -f --all
|
||||
```
|
||||
</Steps>
|
||||
|
||||
Congratulation, you deployed QUIC transport bridge! The script offers a standalone tweaks and checks, you can always run it without any argument to see all the options:
|
||||
```sh
|
||||
./quic_bridge_deployment.sh
|
||||
```
|
||||
<br/>
|
||||
<AccordionTemplate name="Command output">
|
||||
```shell
|
||||
root@localhost:~# ./quic_bridge_deployment.sh
|
||||
iptables-persistent is already installed.
|
||||
Usage: ./quic_bridge_deployment.sh [command] [options]
|
||||
|
||||
Nym QUIC Bridge Deployment Helper Script
|
||||
|
||||
Bridge Installation & Configuration:
|
||||
check_bridge_installation - Check bridge installation status
|
||||
show_bridge_config - Display bridge configuration files
|
||||
show_bridge_keys - Display bridge key information
|
||||
show_bridge_info - Show comprehensive bridge information
|
||||
verify_bridge_prerequisites - Verify all prerequisites are met
|
||||
|
||||
Bridge Setup Commands:
|
||||
install_bridge_binary - Download and install nym-bridge binary
|
||||
generate_bridge_keys - Generate ED25519 bridge identity keys
|
||||
create_client_params - Create client_bridge_params.json
|
||||
create_bridge_config - Create bridges.toml configuration
|
||||
create_bridge_service - Create systemd service file
|
||||
full_bridge_setup - Interactive full bridge setup wizard
|
||||
|
||||
Network Configuration Commands:
|
||||
adjust_ip_forwarding - Enable IPv4 and IPv6 forwarding
|
||||
apply_bridge_iptables_rules - Apply iptables rules for QUIC bridge (nymwg)
|
||||
configure_dns_and_icmp - Allow ICMP ping tests and configure DNS
|
||||
remove_duplicate_bridge_rules - Remove duplicate iptables rules for nymwg
|
||||
|
||||
Network Inspection Commands:
|
||||
fetch_and_display_ipv6 - Show IPv6 on default network device
|
||||
fetch_wg_ipv6_address - Fetch IPv6 for nymwg interface
|
||||
check_bridge_iptables - Check iptables rules for nymwg
|
||||
check_ipv6_ipv4_forwarding - Check IPv4 and IPv6 forwarding status
|
||||
check_ip_routing - Display IP routing tables
|
||||
|
||||
Testing Commands:
|
||||
perform_pings - Test IPv4 and IPv6 connectivity
|
||||
test_bridge_connectivity - Comprehensive bridge connectivity test
|
||||
|
||||
Service Management Commands:
|
||||
check_bridge_service_status - Check nym-bridge and nym-node service status
|
||||
show_bridge_logs [lines] - Show recent nym-bridge logs (default: 50 lines)
|
||||
|
||||
Quick Start:
|
||||
1. Run 'verify_bridge_prerequisites' to check prerequisites
|
||||
2. Run 'check_bridge_installation' to verify installation
|
||||
3. Run 'test_bridge_connectivity' to test connectivity
|
||||
```
|
||||
</AccordionTemplate>
|
||||
|
||||
### Fixing Metadata Port Showing Not Open in Probe Results
|
||||
If you have followed the steps outlined above, but the metadata port is not shown as open in either the Node Status API's probe results or an explorer that gets its data from the API, see below:
|
||||
|
||||
<Steps>
|
||||
###### 1.
|
||||
Ensure that in your `config.toml` file, this value is set to the default one - any other value here will cause the metadata endpoint to fail:
|
||||
|
||||
```
|
||||
# Private IP address of the wireguard gateway.
|
||||
# default: '10.1.0.1'
|
||||
private_ipv4 = '10.1.0.1'
|
||||
```
|
||||
|
||||
Then restart your node.
|
||||
|
||||
###### 2.
|
||||
Run this command if not already done:
|
||||
```
|
||||
ufw allow in on nymwg to any port 51830 proto tcp
|
||||
```
|
||||
|
||||
Check if the port is open with:
|
||||
```
|
||||
iptables -S | grep 51830
|
||||
```
|
||||
|
||||
Then ensure the metadata endpoint is listening from the correct address with:
|
||||
```
|
||||
netstat -an | egrep LISTEN | egrep "51830"
|
||||
```
|
||||
|
||||
###### 3.
|
||||
Once the Node Status API has run a probe on your node, the probe results will reflect this - `can_query_metadata_v4` will have `true` as a value.
|
||||
|
||||
The quickest way to check this is by using the [NymVPN API](https://nymvpn.com/api/public/v1/directory/gateways?show_vpn_only=true) and checking the same field:
|
||||
|
||||

|
||||
|
||||
</Steps>
|
||||
@@ -1 +1 @@
|
||||
Sunday, October 5th 2025, 09:29:02 UTC
|
||||
Monday, October 13th 2025, 13:24:56 UTC
|
||||
|
||||
@@ -24,11 +24,11 @@
|
||||
"@cosmjs/encoding": "^0.32.2",
|
||||
"@cosmjs/proto-signing": "^0.32.2",
|
||||
"@cosmjs/stargate": "^0.32.2",
|
||||
"@cosmos-kit/core": "^2.8.9",
|
||||
"@cosmos-kit/core": "^2.16.3",
|
||||
"@cosmos-kit/keplr": "^2.6.9",
|
||||
"@cosmos-kit/keplr-extension": "^2.7.9",
|
||||
"@cosmos-kit/ledger": "^2.6.9",
|
||||
"@cosmos-kit/react": "^2.10.11",
|
||||
"@cosmos-kit/react": "^2.22.3",
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@interchain-ui/react": "^1.8.0",
|
||||
@@ -54,12 +54,15 @@
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next/swc-linux-x64-gnu": "15.5.0",
|
||||
"@types/node": "18.11.10",
|
||||
"@types/react": "^18.3.26",
|
||||
"@types/react-dom": "^18.3.7",
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"eslint": "8.46.0",
|
||||
"eslint-config-next": "13.4.13",
|
||||
"raw-loader": "^4.0.2",
|
||||
"typescript": "^4.9.3"
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"private": false
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { AccordionTemplate } from 'components/accordion-template.tsx';
|
||||
import { Steps } from 'nextra/components';
|
||||
import AbuseResponse from 'components/operators/templates/dmca_response.md';
|
||||
import OperatorIntroduction from 'components/operators/templates/provider_introduction.md';
|
||||
import QuicDeploymentSteps from 'components/operators/snippets/quic-bridge-deployment-script-setup.mdx';
|
||||
|
||||
|
||||
export const TestingSteps = () => (
|
||||
@@ -48,6 +49,10 @@ This page displays a full list of all the changes during our release cycle from
|
||||
|
||||
<VarInfo />
|
||||
|
||||
## QUIC Transport Bridge Deployment
|
||||
|
||||
<QuicDeploymentSteps />
|
||||
|
||||
## `v2025.17-isabirra`
|
||||
|
||||
- [Release Binaries](https://github.com/nymtech/nym/releases/tag/nym-binaries-v2025.17-isabirra)
|
||||
|
||||
@@ -8,6 +8,7 @@ import ExitPolicyStatusOutput from 'components/operators/snippets/wg-exit-policy
|
||||
import ExitPolicyTestOutput from 'components/operators/snippets/wg-exit-policy-test-output.mdx';
|
||||
import ExitPolicyTestServer from 'components/operators/snippets/wg-exit-policy-testing-from-server.mdx';
|
||||
import ExitPolicyTestOutside from 'components/operators/snippets/wg-exit-policy-testing-from-outside.mdx';
|
||||
import QuicDeploymentSteps from 'components/operators/snippets/quic-bridge-deployment-script-setup.mdx';
|
||||
|
||||
|
||||
export const ManagerIPOutput = () => (
|
||||
@@ -534,6 +535,9 @@ You can validate the application of the IP tables routes on your `nym-node` by c
|
||||
|
||||
Your node has successfully implemented wireguard exit policy with the same routing permissions like [Nym exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) used on 5-hop (Mixnet).
|
||||
|
||||
## QUIC Transport Bridge Deployment
|
||||
|
||||
<QuicDeploymentSteps />
|
||||
|
||||
## Running `nym-node` as a non-root
|
||||
|
||||
|
||||
Generated
+208
-152
@@ -36,11 +36,11 @@ importers:
|
||||
specifier: ^0.32.2
|
||||
version: 0.32.4
|
||||
'@cosmos-kit/core':
|
||||
specifier: ^2.8.9
|
||||
specifier: ^2.16.3
|
||||
version: 2.16.3
|
||||
'@cosmos-kit/keplr':
|
||||
specifier: ^2.6.9
|
||||
version: 2.15.3(@cosmjs/amino@0.32.4)(@cosmjs/proto-signing@0.32.4)(@walletconnect/sign-client@2.21.8(typescript@4.9.5)(zod@3.25.76))(@walletconnect/types@2.21.8)(starknet@7.6.4)(typescript@4.9.5)(zod@3.25.76)
|
||||
version: 2.15.3(@cosmjs/amino@0.32.4)(@cosmjs/proto-signing@0.32.4)(@walletconnect/sign-client@2.21.8(typescript@5.9.3)(zod@3.25.76))(@walletconnect/types@2.21.8)(starknet@7.6.4)(typescript@5.9.3)(zod@3.25.76)
|
||||
'@cosmos-kit/keplr-extension':
|
||||
specifier: ^2.7.9
|
||||
version: 2.15.3(@cosmjs/amino@0.32.4)(@cosmjs/proto-signing@0.32.4)(starknet@7.6.4)
|
||||
@@ -48,38 +48,41 @@ importers:
|
||||
specifier: ^2.6.9
|
||||
version: 2.14.3(@cosmjs/amino@0.32.4)(@cosmjs/crypto@0.32.4)(@cosmjs/encoding@0.32.4)(@cosmjs/proto-signing@0.32.4)
|
||||
'@cosmos-kit/react':
|
||||
specifier: ^2.10.11
|
||||
version: 2.22.3(@cosmjs/amino@0.32.4)(@cosmjs/proto-signing@0.32.4)(@interchain-ui/react@1.26.3(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)
|
||||
specifier: ^2.22.3
|
||||
version: 2.22.3(@cosmjs/amino@0.32.4)(@cosmjs/proto-signing@0.32.4)(@interchain-ui/react@1.26.3(@types/react@18.3.26)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@emotion/react':
|
||||
specifier: ^11.11.1
|
||||
version: 11.14.0(react@18.3.1)
|
||||
version: 11.14.0(@types/react@18.3.26)(react@18.3.1)
|
||||
'@emotion/styled':
|
||||
specifier: ^11.11.0
|
||||
version: 11.14.1(@emotion/react@11.14.0(react@18.3.1))(react@18.3.1)
|
||||
version: 11.14.1(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1)
|
||||
'@interchain-ui/react':
|
||||
specifier: ^1.8.0
|
||||
version: 1.26.3(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
version: 1.26.3(@types/react@18.3.26)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@mui/icons-material':
|
||||
specifier: ^5.14.9
|
||||
version: 5.18.0(@mui/material@5.18.0(@emotion/react@11.14.0(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(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)
|
||||
version: 5.18.0(@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.26)(react@18.3.1)
|
||||
'@mui/lab':
|
||||
specifier: ^5.0.0-alpha.145
|
||||
version: 5.0.0-alpha.177(@emotion/react@11.14.0(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(react@18.3.1))(react@18.3.1))(@mui/material@5.18.0(@emotion/react@11.14.0(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(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: 5.0.0-alpha.177(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1))(@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@mui/material':
|
||||
specifier: ^5.14.8
|
||||
version: 5.18.0(@emotion/react@11.14.0(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
version: 5.18.0(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@nextui-org/accordion':
|
||||
specifier: ^2.0.40
|
||||
version: 2.2.7(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@nextui-org/react':
|
||||
specifier: ^2.4.8
|
||||
version: 2.6.11(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@4.1.12)
|
||||
version: 2.6.11(@types/react@18.3.26)(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@4.1.12)
|
||||
'@nymproject/contract-clients':
|
||||
specifier: '>=1.2.4-rc.2 || ^1'
|
||||
version: 1.4.1
|
||||
'@nymproject/mix-fetch-full-fat':
|
||||
specifier: file:../../dist/wasm/mix-fetch
|
||||
version: '@nymproject/mix-fetch-wasm@file:../../dist/wasm/mix-fetch'
|
||||
specifier: '>=1.2.4-rc.2 || ^1'
|
||||
version: 1.2.3
|
||||
'@nymproject/sdk-full-fat':
|
||||
specifier: file:../../dist/wasm/client
|
||||
version: '@nymproject/nym-client-wasm@file:../../dist/wasm/client'
|
||||
specifier: '>=1.2.4-rc.2 || ^1'
|
||||
version: 1.2.3
|
||||
'@redocly/cli':
|
||||
specifier: ^1.25.15
|
||||
version: 1.34.5(ajv@8.17.1)
|
||||
@@ -117,9 +120,18 @@ importers:
|
||||
specifier: ^9.0.0
|
||||
version: 9.0.1
|
||||
devDependencies:
|
||||
'@next/swc-linux-x64-gnu':
|
||||
specifier: 15.5.0
|
||||
version: 15.5.0
|
||||
'@types/node':
|
||||
specifier: 18.11.10
|
||||
version: 18.11.10
|
||||
'@types/react':
|
||||
specifier: ^18.3.26
|
||||
version: 18.3.26
|
||||
'@types/react-dom':
|
||||
specifier: ^18.3.7
|
||||
version: 18.3.7(@types/react@18.3.26)
|
||||
copy-webpack-plugin:
|
||||
specifier: ^11.0.0
|
||||
version: 11.0.0(webpack@5.101.3)
|
||||
@@ -128,13 +140,13 @@ importers:
|
||||
version: 8.46.0
|
||||
eslint-config-next:
|
||||
specifier: 13.4.13
|
||||
version: 13.4.13(eslint@8.46.0)(typescript@4.9.5)
|
||||
version: 13.4.13(eslint@8.46.0)(typescript@5.9.3)
|
||||
raw-loader:
|
||||
specifier: ^4.0.2
|
||||
version: 4.0.2(webpack@5.101.3)
|
||||
typescript:
|
||||
specifier: ^4.9.3
|
||||
version: 4.9.5
|
||||
specifier: ^5.9.3
|
||||
version: 5.9.3
|
||||
|
||||
packages:
|
||||
|
||||
@@ -1664,11 +1676,14 @@ packages:
|
||||
resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==}
|
||||
engines: {node: '>=12.4.0'}
|
||||
|
||||
'@nymproject/mix-fetch-wasm@file:../../dist/wasm/mix-fetch':
|
||||
resolution: {directory: ../../dist/wasm/mix-fetch, type: directory}
|
||||
'@nymproject/contract-clients@1.4.1':
|
||||
resolution: {integrity: sha512-HuJZ4Hv+Rl6ZZEtCHKgurNLJapM+QQRJlGkevFH2a4UdqUqF9omUkUi3AVes4679dPoSFgvA7plyVSDBdbgV6w==}
|
||||
|
||||
'@nymproject/nym-client-wasm@file:../../dist/wasm/client':
|
||||
resolution: {directory: ../../dist/wasm/client, type: directory}
|
||||
'@nymproject/mix-fetch-full-fat@1.2.3':
|
||||
resolution: {integrity: sha512-5yAQhw33LC0cNsyV0Rj+LIa2kvJY+8jsfgOSr1aeKNfQ7dG4fngWkKnGUbPGzhUTJjqgXPTwNVeJSd6hwGim+g==}
|
||||
|
||||
'@nymproject/sdk-full-fat@1.2.3':
|
||||
resolution: {integrity: sha512-lheA1Zk020o2t95FPVZfdUR0aSI52aD0aJQs074fjH16QkoNNEMotzhJGAnsnnczVg3bpddKghNpCLyDOWvg9A==}
|
||||
|
||||
'@opentelemetry/api-logs@0.53.0':
|
||||
resolution: {integrity: sha512-8HArjKx+RaAI8uEIgcORbZIPklyh1YLjPSBus8hjRmvLi6DeFzgOcdZ7KwPabKj8mXF8dX0hyfAyGfycz0DbFw==}
|
||||
@@ -2844,13 +2859,18 @@ packages:
|
||||
'@types/prop-types@15.7.15':
|
||||
resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==}
|
||||
|
||||
'@types/react-dom@18.3.7':
|
||||
resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==}
|
||||
peerDependencies:
|
||||
'@types/react': ^18.0.0
|
||||
|
||||
'@types/react-transition-group@4.4.12':
|
||||
resolution: {integrity: sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
|
||||
'@types/react@19.1.10':
|
||||
resolution: {integrity: sha512-EhBeSYX0Y6ye8pNebpKrwFJq7BoQ8J5SO6NlvNwwHjSj6adXJViPQrKlsyPw7hLBLvckEMO1yxeGdR82YBBlDg==}
|
||||
'@types/react@18.3.26':
|
||||
resolution: {integrity: sha512-RFA/bURkcKzx/X9oumPG9Vp3D3JUgus/d0b67KB0t5S/raciymilkOa66olh78MUI92QLbEJevO7rvqU/kjwKA==}
|
||||
|
||||
'@types/stylis@4.2.5':
|
||||
resolution: {integrity: sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==}
|
||||
@@ -6386,9 +6406,9 @@ packages:
|
||||
typeforce@1.18.0:
|
||||
resolution: {integrity: sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==}
|
||||
|
||||
typescript@4.9.5:
|
||||
resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==}
|
||||
engines: {node: '>=4.2.0'}
|
||||
typescript@5.9.3:
|
||||
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
|
||||
ufo@1.6.1:
|
||||
@@ -7159,16 +7179,16 @@ snapshots:
|
||||
- uploadthing
|
||||
- utf-8-validate
|
||||
|
||||
'@cosmos-kit/keplr-mobile@2.15.3(@cosmjs/amino@0.32.4)(@cosmjs/proto-signing@0.32.4)(@walletconnect/sign-client@2.21.8(typescript@4.9.5)(zod@3.25.76))(@walletconnect/types@2.21.8)(starknet@7.6.4)(typescript@4.9.5)(zod@3.25.76)':
|
||||
'@cosmos-kit/keplr-mobile@2.15.3(@cosmjs/amino@0.32.4)(@cosmjs/proto-signing@0.32.4)(@walletconnect/sign-client@2.21.8(typescript@5.9.3)(zod@3.25.76))(@walletconnect/types@2.21.8)(starknet@7.6.4)(typescript@5.9.3)(zod@3.25.76)':
|
||||
dependencies:
|
||||
'@chain-registry/keplr': 1.74.313
|
||||
'@cosmjs/amino': 0.32.4
|
||||
'@cosmjs/proto-signing': 0.32.4
|
||||
'@cosmos-kit/core': 2.16.3
|
||||
'@cosmos-kit/keplr-extension': 2.15.3(@cosmjs/amino@0.32.4)(@cosmjs/proto-signing@0.32.4)(starknet@7.6.4)
|
||||
'@cosmos-kit/walletconnect': 2.13.3(@cosmjs/amino@0.32.4)(@walletconnect/types@2.21.8)(typescript@4.9.5)(zod@3.25.76)
|
||||
'@cosmos-kit/walletconnect': 2.13.3(@cosmjs/amino@0.32.4)(@walletconnect/types@2.21.8)(typescript@5.9.3)(zod@3.25.76)
|
||||
'@keplr-wallet/provider-extension': 0.12.264(starknet@7.6.4)
|
||||
'@keplr-wallet/wc-client': 0.12.264(@walletconnect/sign-client@2.21.8(typescript@4.9.5)(zod@3.25.76))(@walletconnect/types@2.21.8)(starknet@7.6.4)
|
||||
'@keplr-wallet/wc-client': 0.12.264(@walletconnect/sign-client@2.21.8(typescript@5.9.3)(zod@3.25.76))(@walletconnect/types@2.21.8)(starknet@7.6.4)
|
||||
transitivePeerDependencies:
|
||||
- '@azure/app-configuration'
|
||||
- '@azure/cosmos'
|
||||
@@ -7199,10 +7219,10 @@ snapshots:
|
||||
- utf-8-validate
|
||||
- zod
|
||||
|
||||
'@cosmos-kit/keplr@2.15.3(@cosmjs/amino@0.32.4)(@cosmjs/proto-signing@0.32.4)(@walletconnect/sign-client@2.21.8(typescript@4.9.5)(zod@3.25.76))(@walletconnect/types@2.21.8)(starknet@7.6.4)(typescript@4.9.5)(zod@3.25.76)':
|
||||
'@cosmos-kit/keplr@2.15.3(@cosmjs/amino@0.32.4)(@cosmjs/proto-signing@0.32.4)(@walletconnect/sign-client@2.21.8(typescript@5.9.3)(zod@3.25.76))(@walletconnect/types@2.21.8)(starknet@7.6.4)(typescript@5.9.3)(zod@3.25.76)':
|
||||
dependencies:
|
||||
'@cosmos-kit/keplr-extension': 2.15.3(@cosmjs/amino@0.32.4)(@cosmjs/proto-signing@0.32.4)(starknet@7.6.4)
|
||||
'@cosmos-kit/keplr-mobile': 2.15.3(@cosmjs/amino@0.32.4)(@cosmjs/proto-signing@0.32.4)(@walletconnect/sign-client@2.21.8(typescript@4.9.5)(zod@3.25.76))(@walletconnect/types@2.21.8)(starknet@7.6.4)(typescript@4.9.5)(zod@3.25.76)
|
||||
'@cosmos-kit/keplr-mobile': 2.15.3(@cosmjs/amino@0.32.4)(@cosmjs/proto-signing@0.32.4)(@walletconnect/sign-client@2.21.8(typescript@5.9.3)(zod@3.25.76))(@walletconnect/types@2.21.8)(starknet@7.6.4)(typescript@5.9.3)(zod@3.25.76)
|
||||
transitivePeerDependencies:
|
||||
- '@azure/app-configuration'
|
||||
- '@azure/cosmos'
|
||||
@@ -7270,11 +7290,13 @@ snapshots:
|
||||
- uploadthing
|
||||
- utf-8-validate
|
||||
|
||||
'@cosmos-kit/react-lite@2.16.3(@cosmjs/amino@0.32.4)(@cosmjs/proto-signing@0.32.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
'@cosmos-kit/react-lite@2.16.3(@cosmjs/amino@0.32.4)(@cosmjs/proto-signing@0.32.4)(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@chain-registry/types': 0.46.15
|
||||
'@cosmos-kit/core': 2.16.3
|
||||
'@dao-dao/cosmiframe': 1.0.0(@cosmjs/amino@0.32.4)(@cosmjs/proto-signing@0.32.4)
|
||||
'@types/react': 18.3.26
|
||||
'@types/react-dom': 18.3.7(@types/react@18.3.26)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
transitivePeerDependencies:
|
||||
@@ -7304,13 +7326,15 @@ snapshots:
|
||||
- uploadthing
|
||||
- utf-8-validate
|
||||
|
||||
'@cosmos-kit/react@2.22.3(@cosmjs/amino@0.32.4)(@cosmjs/proto-signing@0.32.4)(@interchain-ui/react@1.26.3(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)':
|
||||
'@cosmos-kit/react@2.22.3(@cosmjs/amino@0.32.4)(@cosmjs/proto-signing@0.32.4)(@interchain-ui/react@1.26.3(@types/react@18.3.26)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@chain-registry/types': 0.46.15
|
||||
'@cosmos-kit/core': 2.16.3
|
||||
'@cosmos-kit/react-lite': 2.16.3(@cosmjs/amino@0.32.4)(@cosmjs/proto-signing@0.32.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@interchain-ui/react': 1.26.3(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@cosmos-kit/react-lite': 2.16.3(@cosmjs/amino@0.32.4)(@cosmjs/proto-signing@0.32.4)(@types/react-dom@18.3.7(@types/react@18.3.26))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@interchain-ui/react': 1.26.3(@types/react@18.3.26)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@react-icons/all-files': 4.1.0(react@18.3.1)
|
||||
'@types/react': 18.3.26
|
||||
'@types/react-dom': 18.3.7(@types/react@18.3.26)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
transitivePeerDependencies:
|
||||
@@ -7340,14 +7364,14 @@ snapshots:
|
||||
- uploadthing
|
||||
- utf-8-validate
|
||||
|
||||
'@cosmos-kit/walletconnect@2.13.3(@cosmjs/amino@0.32.4)(@walletconnect/types@2.21.8)(typescript@4.9.5)(zod@3.25.76)':
|
||||
'@cosmos-kit/walletconnect@2.13.3(@cosmjs/amino@0.32.4)(@walletconnect/types@2.21.8)(typescript@5.9.3)(zod@3.25.76)':
|
||||
dependencies:
|
||||
'@cosmjs/amino': 0.32.4
|
||||
'@cosmjs/proto-signing': 0.32.4
|
||||
'@cosmos-kit/core': 2.16.3
|
||||
'@walletconnect/sign-client': 2.21.8(typescript@4.9.5)(zod@3.25.76)
|
||||
'@walletconnect/sign-client': 2.21.8(typescript@5.9.3)(zod@3.25.76)
|
||||
'@walletconnect/types': 2.21.8
|
||||
'@walletconnect/utils': 2.21.8(typescript@4.9.5)(zod@3.25.76)
|
||||
'@walletconnect/utils': 2.21.8(typescript@5.9.3)(zod@3.25.76)
|
||||
events: 3.3.0
|
||||
transitivePeerDependencies:
|
||||
- '@azure/app-configuration'
|
||||
@@ -7436,7 +7460,7 @@ snapshots:
|
||||
|
||||
'@emotion/memoize@0.9.0': {}
|
||||
|
||||
'@emotion/react@11.14.0(react@18.3.1)':
|
||||
'@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.3
|
||||
'@emotion/babel-plugin': 11.13.5
|
||||
@@ -7447,6 +7471,8 @@ snapshots:
|
||||
'@emotion/weak-memoize': 0.4.0
|
||||
hoist-non-react-statics: 3.3.2
|
||||
react: 18.3.1
|
||||
optionalDependencies:
|
||||
'@types/react': 18.3.26
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -7460,16 +7486,18 @@ snapshots:
|
||||
|
||||
'@emotion/sheet@1.4.0': {}
|
||||
|
||||
'@emotion/styled@11.14.1(@emotion/react@11.14.0(react@18.3.1))(react@18.3.1)':
|
||||
'@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.3
|
||||
'@emotion/babel-plugin': 11.13.5
|
||||
'@emotion/is-prop-valid': 1.3.1
|
||||
'@emotion/react': 11.14.0(react@18.3.1)
|
||||
'@emotion/react': 11.14.0(@types/react@18.3.26)(react@18.3.1)
|
||||
'@emotion/serialize': 1.3.3
|
||||
'@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@18.3.1)
|
||||
'@emotion/utils': 1.4.2
|
||||
react: 18.3.1
|
||||
optionalDependencies:
|
||||
'@types/react': 18.3.26
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -7702,7 +7730,7 @@ snapshots:
|
||||
'@img/sharp-win32-x64@0.34.3':
|
||||
optional: true
|
||||
|
||||
'@interchain-ui/react@1.26.3(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
'@interchain-ui/react@1.26.3(@types/react@18.3.26)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@floating-ui/core': 1.7.3
|
||||
'@floating-ui/dom': 1.7.3
|
||||
@@ -7731,7 +7759,7 @@ snapshots:
|
||||
react-aria: 3.42.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
react-stately: 3.40.0(react@18.3.1)
|
||||
zustand: 4.5.7(immer@10.1.1)(react@18.3.1)
|
||||
zustand: 4.5.7(@types/react@18.3.26)(immer@10.1.1)(react@18.3.1)
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
- babel-plugin-macros
|
||||
@@ -7864,11 +7892,11 @@ snapshots:
|
||||
big-integer: 1.6.52
|
||||
utility-types: 3.11.0
|
||||
|
||||
'@keplr-wallet/wc-client@0.12.264(@walletconnect/sign-client@2.21.8(typescript@4.9.5)(zod@3.25.76))(@walletconnect/types@2.21.8)(starknet@7.6.4)':
|
||||
'@keplr-wallet/wc-client@0.12.264(@walletconnect/sign-client@2.21.8(typescript@5.9.3)(zod@3.25.76))(@walletconnect/types@2.21.8)(starknet@7.6.4)':
|
||||
dependencies:
|
||||
'@keplr-wallet/provider': 0.12.264(starknet@7.6.4)
|
||||
'@keplr-wallet/types': 0.12.264(starknet@7.6.4)
|
||||
'@walletconnect/sign-client': 2.21.8(typescript@4.9.5)(zod@3.25.76)
|
||||
'@walletconnect/sign-client': 2.21.8(typescript@5.9.3)(zod@3.25.76)
|
||||
'@walletconnect/types': 2.21.8
|
||||
buffer: 6.0.3
|
||||
deepmerge: 4.3.1
|
||||
@@ -7938,56 +7966,61 @@ snapshots:
|
||||
'@mdx-js/react@2.3.0(react@18.3.1)':
|
||||
dependencies:
|
||||
'@types/mdx': 2.0.13
|
||||
'@types/react': 19.1.10
|
||||
'@types/react': 18.3.26
|
||||
react: 18.3.1
|
||||
|
||||
'@msgpack/msgpack@3.1.2': {}
|
||||
|
||||
'@mui/base@5.0.0-beta.40-1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
'@mui/base@5.0.0-beta.40-1(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.3
|
||||
'@floating-ui/react-dom': 2.1.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@mui/types': 7.2.24
|
||||
'@mui/utils': 5.17.1(react@18.3.1)
|
||||
'@mui/types': 7.2.24(@types/react@18.3.26)
|
||||
'@mui/utils': 5.17.1(@types/react@18.3.26)(react@18.3.1)
|
||||
'@popperjs/core': 2.11.8
|
||||
clsx: 2.1.1
|
||||
prop-types: 15.8.1
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
'@mui/core-downloads-tracker@5.18.0': {}
|
||||
|
||||
'@mui/icons-material@5.18.0(@mui/material@5.18.0(@emotion/react@11.14.0(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(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)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.3
|
||||
'@mui/material': 5.18.0(@emotion/react@11.14.0(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(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
|
||||
|
||||
'@mui/lab@5.0.0-alpha.177(@emotion/react@11.14.0(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(react@18.3.1))(react@18.3.1))(@mui/material@5.18.0(@emotion/react@11.14.0(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(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:
|
||||
'@babel/runtime': 7.28.3
|
||||
'@mui/base': 5.0.0-beta.40-1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@mui/material': 5.18.0(@emotion/react@11.14.0(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@mui/system': 5.18.0(@emotion/react@11.14.0(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
||||
'@mui/types': 7.2.24
|
||||
'@mui/utils': 5.17.1(react@18.3.1)
|
||||
clsx: 2.1.1
|
||||
prop-types: 15.8.1
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
optionalDependencies:
|
||||
'@emotion/react': 11.14.0(react@18.3.1)
|
||||
'@emotion/styled': 11.14.1(@emotion/react@11.14.0(react@18.3.1))(react@18.3.1)
|
||||
'@types/react': 18.3.26
|
||||
|
||||
'@mui/material@5.18.0(@emotion/react@11.14.0(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
'@mui/core-downloads-tracker@5.18.0': {}
|
||||
|
||||
'@mui/icons-material@5.18.0(@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.26)(react@18.3.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.3
|
||||
'@mui/material': 5.18.0(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
react: 18.3.1
|
||||
optionalDependencies:
|
||||
'@types/react': 18.3.26
|
||||
|
||||
'@mui/lab@5.0.0-alpha.177(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1))(@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.3
|
||||
'@mui/base': 5.0.0-beta.40-1(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@mui/material': 5.18.0(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@mui/system': 5.18.0(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1)
|
||||
'@mui/types': 7.2.24(@types/react@18.3.26)
|
||||
'@mui/utils': 5.17.1(@types/react@18.3.26)(react@18.3.1)
|
||||
clsx: 2.1.1
|
||||
prop-types: 15.8.1
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
optionalDependencies:
|
||||
'@emotion/react': 11.14.0(@types/react@18.3.26)(react@18.3.1)
|
||||
'@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1)
|
||||
'@types/react': 18.3.26
|
||||
|
||||
'@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.3
|
||||
'@mui/core-downloads-tracker': 5.18.0
|
||||
'@mui/system': 5.18.0(@emotion/react@11.14.0(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
||||
'@mui/types': 7.2.24
|
||||
'@mui/utils': 5.17.1(react@18.3.1)
|
||||
'@mui/system': 5.18.0(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1)
|
||||
'@mui/types': 7.2.24(@types/react@18.3.26)
|
||||
'@mui/utils': 5.17.1(@types/react@18.3.26)(react@18.3.1)
|
||||
'@popperjs/core': 2.11.8
|
||||
'@types/react-transition-group': 4.4.12
|
||||
'@types/react-transition-group': 4.4.12(@types/react@18.3.26)
|
||||
clsx: 2.1.1
|
||||
csstype: 3.1.3
|
||||
prop-types: 15.8.1
|
||||
@@ -7996,17 +8029,20 @@ snapshots:
|
||||
react-is: 19.1.1
|
||||
react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
optionalDependencies:
|
||||
'@emotion/react': 11.14.0(react@18.3.1)
|
||||
'@emotion/styled': 11.14.1(@emotion/react@11.14.0(react@18.3.1))(react@18.3.1)
|
||||
'@emotion/react': 11.14.0(@types/react@18.3.26)(react@18.3.1)
|
||||
'@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1)
|
||||
'@types/react': 18.3.26
|
||||
|
||||
'@mui/private-theming@5.17.1(react@18.3.1)':
|
||||
'@mui/private-theming@5.17.1(@types/react@18.3.26)(react@18.3.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.3
|
||||
'@mui/utils': 5.17.1(react@18.3.1)
|
||||
'@mui/utils': 5.17.1(@types/react@18.3.26)(react@18.3.1)
|
||||
prop-types: 15.8.1
|
||||
react: 18.3.1
|
||||
optionalDependencies:
|
||||
'@types/react': 18.3.26
|
||||
|
||||
'@mui/styled-engine@5.18.0(@emotion/react@11.14.0(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(react@18.3.1))(react@18.3.1))(react@18.3.1)':
|
||||
'@mui/styled-engine@5.18.0(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.3
|
||||
'@emotion/cache': 11.14.0
|
||||
@@ -8015,35 +8051,40 @@ snapshots:
|
||||
prop-types: 15.8.1
|
||||
react: 18.3.1
|
||||
optionalDependencies:
|
||||
'@emotion/react': 11.14.0(react@18.3.1)
|
||||
'@emotion/styled': 11.14.1(@emotion/react@11.14.0(react@18.3.1))(react@18.3.1)
|
||||
'@emotion/react': 11.14.0(@types/react@18.3.26)(react@18.3.1)
|
||||
'@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1)
|
||||
|
||||
'@mui/system@5.18.0(@emotion/react@11.14.0(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(react@18.3.1))(react@18.3.1))(react@18.3.1)':
|
||||
'@mui/system@5.18.0(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.3
|
||||
'@mui/private-theming': 5.17.1(react@18.3.1)
|
||||
'@mui/styled-engine': 5.18.0(@emotion/react@11.14.0(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
||||
'@mui/types': 7.2.24
|
||||
'@mui/utils': 5.17.1(react@18.3.1)
|
||||
'@mui/private-theming': 5.17.1(@types/react@18.3.26)(react@18.3.1)
|
||||
'@mui/styled-engine': 5.18.0(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1))(react@18.3.1)
|
||||
'@mui/types': 7.2.24(@types/react@18.3.26)
|
||||
'@mui/utils': 5.17.1(@types/react@18.3.26)(react@18.3.1)
|
||||
clsx: 2.1.1
|
||||
csstype: 3.1.3
|
||||
prop-types: 15.8.1
|
||||
react: 18.3.1
|
||||
optionalDependencies:
|
||||
'@emotion/react': 11.14.0(react@18.3.1)
|
||||
'@emotion/styled': 11.14.1(@emotion/react@11.14.0(react@18.3.1))(react@18.3.1)
|
||||
'@emotion/react': 11.14.0(@types/react@18.3.26)(react@18.3.1)
|
||||
'@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@18.3.26)(react@18.3.1))(@types/react@18.3.26)(react@18.3.1)
|
||||
'@types/react': 18.3.26
|
||||
|
||||
'@mui/types@7.2.24': {}
|
||||
'@mui/types@7.2.24(@types/react@18.3.26)':
|
||||
optionalDependencies:
|
||||
'@types/react': 18.3.26
|
||||
|
||||
'@mui/utils@5.17.1(react@18.3.1)':
|
||||
'@mui/utils@5.17.1(@types/react@18.3.26)(react@18.3.1)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.3
|
||||
'@mui/types': 7.2.24
|
||||
'@mui/types': 7.2.24(@types/react@18.3.26)
|
||||
'@types/prop-types': 15.7.15
|
||||
clsx: 2.1.1
|
||||
prop-types: 15.8.1
|
||||
react: 18.3.1
|
||||
react-is: 19.1.1
|
||||
optionalDependencies:
|
||||
'@types/react': 18.3.26
|
||||
|
||||
'@napi-rs/simple-git-android-arm-eabi@0.1.22':
|
||||
optional: true
|
||||
@@ -8133,8 +8174,7 @@ snapshots:
|
||||
'@next/swc-linux-arm64-musl@15.5.0':
|
||||
optional: true
|
||||
|
||||
'@next/swc-linux-x64-gnu@15.5.0':
|
||||
optional: true
|
||||
'@next/swc-linux-x64-gnu@15.5.0': {}
|
||||
|
||||
'@next/swc-linux-x64-musl@15.5.0':
|
||||
optional: true
|
||||
@@ -8199,12 +8239,12 @@ snapshots:
|
||||
- '@nextui-org/theme'
|
||||
- framer-motion
|
||||
|
||||
'@nextui-org/autocomplete@2.3.9(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
'@nextui-org/autocomplete@2.3.9(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(@types/react@18.3.26)(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@nextui-org/aria-utils': 2.2.7(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@nextui-org/button': 2.2.9(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@nextui-org/form': 2.1.8(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@nextui-org/input': 2.4.8(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@nextui-org/input': 2.4.8(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@nextui-org/listbox': 2.3.9(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@nextui-org/popover': 2.3.9(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@nextui-org/react-utils': 2.1.3(react@18.3.1)
|
||||
@@ -8516,7 +8556,7 @@ snapshots:
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
'@nextui-org/input@2.4.8(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
'@nextui-org/input@2.4.8(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@nextui-org/form': 2.1.8(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@nextui-org/react-utils': 2.1.3(react@18.3.1)
|
||||
@@ -8534,7 +8574,7 @@ snapshots:
|
||||
'@react-types/textfield': 3.10.0(react@18.3.1)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
react-textarea-autosize: 8.5.9(react@18.3.1)
|
||||
react-textarea-autosize: 8.5.9(@types/react@18.3.26)(react@18.3.1)
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
|
||||
@@ -8734,11 +8774,11 @@ snapshots:
|
||||
'@nextui-org/shared-utils': 2.1.2
|
||||
react: 18.3.1
|
||||
|
||||
'@nextui-org/react@2.6.11(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@4.1.12)':
|
||||
'@nextui-org/react@2.6.11(@types/react@18.3.26)(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@4.1.12)':
|
||||
dependencies:
|
||||
'@nextui-org/accordion': 2.2.7(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@nextui-org/alert': 2.2.9(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@nextui-org/autocomplete': 2.3.9(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@nextui-org/autocomplete': 2.3.9(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(@types/react@18.3.26)(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@nextui-org/avatar': 2.2.6(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@nextui-org/badge': 2.2.5(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@nextui-org/breadcrumbs': 2.2.6(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@@ -8756,7 +8796,7 @@ snapshots:
|
||||
'@nextui-org/form': 2.1.8(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@nextui-org/framer-utils': 2.1.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@nextui-org/image': 2.2.5(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@nextui-org/input': 2.4.8(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@nextui-org/input': 2.4.8(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(@types/react@18.3.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@nextui-org/input-otp': 2.1.8(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@nextui-org/kbd': 2.2.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@nextui-org/link': 2.2.7(@nextui-org/system@2.4.6(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(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))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@nextui-org/theme@2.4.5(tailwindcss@4.1.12))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@@ -9205,9 +9245,11 @@ snapshots:
|
||||
|
||||
'@nolyfill/is-core-module@1.0.39': {}
|
||||
|
||||
'@nymproject/mix-fetch-wasm@file:../../dist/wasm/mix-fetch': {}
|
||||
'@nymproject/contract-clients@1.4.1': {}
|
||||
|
||||
'@nymproject/nym-client-wasm@file:../../dist/wasm/client': {}
|
||||
'@nymproject/mix-fetch-full-fat@1.2.3': {}
|
||||
|
||||
'@nymproject/sdk-full-fat@1.2.3': {}
|
||||
|
||||
'@opentelemetry/api-logs@0.53.0':
|
||||
dependencies:
|
||||
@@ -11169,10 +11211,17 @@ snapshots:
|
||||
|
||||
'@types/prop-types@15.7.15': {}
|
||||
|
||||
'@types/react-transition-group@4.4.12': {}
|
||||
|
||||
'@types/react@19.1.10':
|
||||
'@types/react-dom@18.3.7(@types/react@18.3.26)':
|
||||
dependencies:
|
||||
'@types/react': 18.3.26
|
||||
|
||||
'@types/react-transition-group@4.4.12(@types/react@18.3.26)':
|
||||
dependencies:
|
||||
'@types/react': 18.3.26
|
||||
|
||||
'@types/react@18.3.26':
|
||||
dependencies:
|
||||
'@types/prop-types': 15.7.15
|
||||
csstype: 3.1.3
|
||||
|
||||
'@types/stylis@4.2.5': {}
|
||||
@@ -11184,16 +11233,16 @@ snapshots:
|
||||
|
||||
'@types/unist@3.0.3': {}
|
||||
|
||||
'@typescript-eslint/parser@6.21.0(eslint@8.46.0)(typescript@4.9.5)':
|
||||
'@typescript-eslint/parser@6.21.0(eslint@8.46.0)(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': 6.21.0
|
||||
'@typescript-eslint/types': 6.21.0
|
||||
'@typescript-eslint/typescript-estree': 6.21.0(typescript@4.9.5)
|
||||
'@typescript-eslint/typescript-estree': 6.21.0(typescript@5.9.3)
|
||||
'@typescript-eslint/visitor-keys': 6.21.0
|
||||
debug: 4.4.1
|
||||
eslint: 8.46.0
|
||||
optionalDependencies:
|
||||
typescript: 4.9.5
|
||||
typescript: 5.9.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -11204,7 +11253,7 @@ snapshots:
|
||||
|
||||
'@typescript-eslint/types@6.21.0': {}
|
||||
|
||||
'@typescript-eslint/typescript-estree@6.21.0(typescript@4.9.5)':
|
||||
'@typescript-eslint/typescript-estree@6.21.0(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 6.21.0
|
||||
'@typescript-eslint/visitor-keys': 6.21.0
|
||||
@@ -11213,9 +11262,9 @@ snapshots:
|
||||
is-glob: 4.0.3
|
||||
minimatch: 9.0.3
|
||||
semver: 7.7.2
|
||||
ts-api-utils: 1.4.3(typescript@4.9.5)
|
||||
ts-api-utils: 1.4.3(typescript@5.9.3)
|
||||
optionalDependencies:
|
||||
typescript: 4.9.5
|
||||
typescript: 5.9.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -11314,7 +11363,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@vanilla-extract/css': 1.17.4(babel-plugin-macros@3.1.0)
|
||||
|
||||
'@walletconnect/core@2.21.8(typescript@4.9.5)(zod@3.25.76)':
|
||||
'@walletconnect/core@2.21.8(typescript@5.9.3)(zod@3.25.76)':
|
||||
dependencies:
|
||||
'@walletconnect/heartbeat': 1.2.2
|
||||
'@walletconnect/jsonrpc-provider': 1.0.14
|
||||
@@ -11328,7 +11377,7 @@ snapshots:
|
||||
'@walletconnect/safe-json': 1.0.2
|
||||
'@walletconnect/time': 1.0.2
|
||||
'@walletconnect/types': 2.21.8
|
||||
'@walletconnect/utils': 2.21.8(typescript@4.9.5)(zod@3.25.76)
|
||||
'@walletconnect/utils': 2.21.8(typescript@5.9.3)(zod@3.25.76)
|
||||
'@walletconnect/window-getters': 1.0.1
|
||||
es-toolkit: 1.39.3
|
||||
events: 3.3.0
|
||||
@@ -11455,16 +11504,16 @@ snapshots:
|
||||
dependencies:
|
||||
tslib: 1.14.1
|
||||
|
||||
'@walletconnect/sign-client@2.21.8(typescript@4.9.5)(zod@3.25.76)':
|
||||
'@walletconnect/sign-client@2.21.8(typescript@5.9.3)(zod@3.25.76)':
|
||||
dependencies:
|
||||
'@walletconnect/core': 2.21.8(typescript@4.9.5)(zod@3.25.76)
|
||||
'@walletconnect/core': 2.21.8(typescript@5.9.3)(zod@3.25.76)
|
||||
'@walletconnect/events': 1.0.1
|
||||
'@walletconnect/heartbeat': 1.2.2
|
||||
'@walletconnect/jsonrpc-utils': 1.0.8
|
||||
'@walletconnect/logger': 2.1.2
|
||||
'@walletconnect/time': 1.0.2
|
||||
'@walletconnect/types': 2.21.8
|
||||
'@walletconnect/utils': 2.21.8(typescript@4.9.5)(zod@3.25.76)
|
||||
'@walletconnect/utils': 2.21.8(typescript@5.9.3)(zod@3.25.76)
|
||||
events: 3.3.0
|
||||
transitivePeerDependencies:
|
||||
- '@azure/app-configuration'
|
||||
@@ -11550,7 +11599,7 @@ snapshots:
|
||||
- ioredis
|
||||
- uploadthing
|
||||
|
||||
'@walletconnect/utils@2.21.8(typescript@4.9.5)(zod@3.25.76)':
|
||||
'@walletconnect/utils@2.21.8(typescript@5.9.3)(zod@3.25.76)':
|
||||
dependencies:
|
||||
'@msgpack/msgpack': 3.1.2
|
||||
'@noble/ciphers': 1.3.0
|
||||
@@ -11571,7 +11620,7 @@ snapshots:
|
||||
detect-browser: 5.3.0
|
||||
query-string: 7.1.3
|
||||
uint8arrays: 3.1.1
|
||||
viem: 2.31.0(typescript@4.9.5)(zod@3.25.76)
|
||||
viem: 2.31.0(typescript@5.9.3)(zod@3.25.76)
|
||||
transitivePeerDependencies:
|
||||
- '@azure/app-configuration'
|
||||
- '@azure/cosmos'
|
||||
@@ -11692,9 +11741,9 @@ snapshots:
|
||||
fs-extra: 10.1.0
|
||||
yargs: 17.7.2
|
||||
|
||||
abitype@1.0.8(typescript@4.9.5)(zod@3.25.76):
|
||||
abitype@1.0.8(typescript@5.9.3)(zod@3.25.76):
|
||||
optionalDependencies:
|
||||
typescript: 4.9.5
|
||||
typescript: 5.9.3
|
||||
zod: 3.25.76
|
||||
|
||||
abort-controller@3.0.0:
|
||||
@@ -12710,20 +12759,20 @@ snapshots:
|
||||
|
||||
escape-string-regexp@5.0.0: {}
|
||||
|
||||
eslint-config-next@13.4.13(eslint@8.46.0)(typescript@4.9.5):
|
||||
eslint-config-next@13.4.13(eslint@8.46.0)(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@next/eslint-plugin-next': 13.4.13
|
||||
'@rushstack/eslint-patch': 1.12.0
|
||||
'@typescript-eslint/parser': 6.21.0(eslint@8.46.0)(typescript@4.9.5)
|
||||
'@typescript-eslint/parser': 6.21.0(eslint@8.46.0)(typescript@5.9.3)
|
||||
eslint: 8.46.0
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(eslint@8.46.0))(eslint@8.46.0)
|
||||
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.46.0)(typescript@4.9.5))(eslint-import-resolver-typescript@3.10.1)(eslint@8.46.0)
|
||||
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.46.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(eslint@8.46.0))(eslint@8.46.0))(eslint@8.46.0)
|
||||
eslint-plugin-jsx-a11y: 6.10.2(eslint@8.46.0)
|
||||
eslint-plugin-react: 7.37.5(eslint@8.46.0)
|
||||
eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.46.0)
|
||||
optionalDependencies:
|
||||
typescript: 4.9.5
|
||||
typescript: 5.9.3
|
||||
transitivePeerDependencies:
|
||||
- eslint-import-resolver-webpack
|
||||
- eslint-plugin-import-x
|
||||
@@ -12748,22 +12797,22 @@ snapshots:
|
||||
tinyglobby: 0.2.14
|
||||
unrs-resolver: 1.11.1
|
||||
optionalDependencies:
|
||||
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.46.0)(typescript@4.9.5))(eslint-import-resolver-typescript@3.10.1)(eslint@8.46.0)
|
||||
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.46.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(eslint@8.46.0))(eslint@8.46.0))(eslint@8.46.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.46.0)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(eslint@8.46.0))(eslint@8.46.0))(eslint@8.46.0):
|
||||
eslint-module-utils@2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.46.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(eslint@8.46.0))(eslint@8.46.0))(eslint@8.46.0):
|
||||
dependencies:
|
||||
debug: 3.2.7
|
||||
optionalDependencies:
|
||||
'@typescript-eslint/parser': 6.21.0(eslint@8.46.0)(typescript@4.9.5)
|
||||
'@typescript-eslint/parser': 6.21.0(eslint@8.46.0)(typescript@5.9.3)
|
||||
eslint: 8.46.0
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(eslint@8.46.0))(eslint@8.46.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.46.0)(typescript@4.9.5))(eslint-import-resolver-typescript@3.10.1)(eslint@8.46.0):
|
||||
eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.21.0(eslint@8.46.0)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(eslint@8.46.0))(eslint@8.46.0))(eslint@8.46.0):
|
||||
dependencies:
|
||||
'@rtsao/scc': 1.1.0
|
||||
array-includes: 3.1.9
|
||||
@@ -12774,7 +12823,7 @@ snapshots:
|
||||
doctrine: 2.1.0
|
||||
eslint: 8.46.0
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.46.0)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(eslint@8.46.0))(eslint@8.46.0))(eslint@8.46.0)
|
||||
eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.21.0(eslint@8.46.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(eslint@8.46.0))(eslint@8.46.0))(eslint@8.46.0)
|
||||
hasown: 2.0.2
|
||||
is-core-module: 2.16.1
|
||||
is-glob: 4.0.3
|
||||
@@ -12786,7 +12835,7 @@ snapshots:
|
||||
string.prototype.trimend: 1.0.9
|
||||
tsconfig-paths: 3.15.0
|
||||
optionalDependencies:
|
||||
'@typescript-eslint/parser': 6.21.0(eslint@8.46.0)(typescript@4.9.5)
|
||||
'@typescript-eslint/parser': 6.21.0(eslint@8.46.0)(typescript@5.9.3)
|
||||
transitivePeerDependencies:
|
||||
- eslint-import-resolver-typescript
|
||||
- eslint-import-resolver-webpack
|
||||
@@ -14655,7 +14704,7 @@ snapshots:
|
||||
object-keys: 1.1.1
|
||||
safe-push-apply: 1.0.0
|
||||
|
||||
ox@0.7.1(typescript@4.9.5)(zod@3.25.76):
|
||||
ox@0.7.1(typescript@5.9.3)(zod@3.25.76):
|
||||
dependencies:
|
||||
'@adraffy/ens-normalize': 1.11.0
|
||||
'@noble/ciphers': 1.3.0
|
||||
@@ -14663,10 +14712,10 @@ snapshots:
|
||||
'@noble/hashes': 1.8.0
|
||||
'@scure/bip32': 1.7.0
|
||||
'@scure/bip39': 1.6.0
|
||||
abitype: 1.0.8(typescript@4.9.5)(zod@3.25.76)
|
||||
abitype: 1.0.8(typescript@5.9.3)(zod@3.25.76)
|
||||
eventemitter3: 5.0.1
|
||||
optionalDependencies:
|
||||
typescript: 4.9.5
|
||||
typescript: 5.9.3
|
||||
transitivePeerDependencies:
|
||||
- zod
|
||||
|
||||
@@ -14978,12 +15027,12 @@ snapshots:
|
||||
prop-types: 15.8.1
|
||||
react: 18.3.1
|
||||
|
||||
react-textarea-autosize@8.5.9(react@18.3.1):
|
||||
react-textarea-autosize@8.5.9(@types/react@18.3.26)(react@18.3.1):
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.3
|
||||
react: 18.3.1
|
||||
use-composed-ref: 1.4.0(react@18.3.1)
|
||||
use-latest: 1.3.0(react@18.3.1)
|
||||
use-composed-ref: 1.4.0(@types/react@18.3.26)(react@18.3.1)
|
||||
use-latest: 1.3.0(@types/react@18.3.26)(react@18.3.1)
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
|
||||
@@ -15710,9 +15759,9 @@ snapshots:
|
||||
|
||||
trough@2.2.0: {}
|
||||
|
||||
ts-api-utils@1.4.3(typescript@4.9.5):
|
||||
ts-api-utils@1.4.3(typescript@5.9.3):
|
||||
dependencies:
|
||||
typescript: 4.9.5
|
||||
typescript: 5.9.3
|
||||
|
||||
ts-dedent@2.2.0: {}
|
||||
|
||||
@@ -15776,7 +15825,7 @@ snapshots:
|
||||
|
||||
typeforce@1.18.0: {}
|
||||
|
||||
typescript@4.9.5: {}
|
||||
typescript@5.9.3: {}
|
||||
|
||||
ufo@1.6.1: {}
|
||||
|
||||
@@ -15945,18 +15994,24 @@ snapshots:
|
||||
|
||||
url-template@2.0.8: {}
|
||||
|
||||
use-composed-ref@1.4.0(react@18.3.1):
|
||||
use-composed-ref@1.4.0(@types/react@18.3.26)(react@18.3.1):
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
optionalDependencies:
|
||||
'@types/react': 18.3.26
|
||||
|
||||
use-isomorphic-layout-effect@1.2.1(react@18.3.1):
|
||||
use-isomorphic-layout-effect@1.2.1(@types/react@18.3.26)(react@18.3.1):
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
optionalDependencies:
|
||||
'@types/react': 18.3.26
|
||||
|
||||
use-latest@1.3.0(react@18.3.1):
|
||||
use-latest@1.3.0(@types/react@18.3.26)(react@18.3.1):
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
use-isomorphic-layout-effect: 1.2.1(react@18.3.1)
|
||||
use-isomorphic-layout-effect: 1.2.1(@types/react@18.3.26)(react@18.3.1)
|
||||
optionalDependencies:
|
||||
'@types/react': 18.3.26
|
||||
|
||||
use-sync-external-store@1.5.0(react@18.3.1):
|
||||
dependencies:
|
||||
@@ -16010,18 +16065,18 @@ snapshots:
|
||||
'@types/unist': 3.0.3
|
||||
vfile-message: 4.0.3
|
||||
|
||||
viem@2.31.0(typescript@4.9.5)(zod@3.25.76):
|
||||
viem@2.31.0(typescript@5.9.3)(zod@3.25.76):
|
||||
dependencies:
|
||||
'@noble/curves': 1.9.1
|
||||
'@noble/hashes': 1.8.0
|
||||
'@scure/bip32': 1.7.0
|
||||
'@scure/bip39': 1.6.0
|
||||
abitype: 1.0.8(typescript@4.9.5)(zod@3.25.76)
|
||||
abitype: 1.0.8(typescript@5.9.3)(zod@3.25.76)
|
||||
isows: 1.0.7(ws@8.18.2)
|
||||
ox: 0.7.1(typescript@4.9.5)(zod@3.25.76)
|
||||
ox: 0.7.1(typescript@5.9.3)(zod@3.25.76)
|
||||
ws: 8.18.2
|
||||
optionalDependencies:
|
||||
typescript: 4.9.5
|
||||
typescript: 5.9.3
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- utf-8-validate
|
||||
@@ -16195,10 +16250,11 @@ snapshots:
|
||||
|
||||
zod@3.25.76: {}
|
||||
|
||||
zustand@4.5.7(immer@10.1.1)(react@18.3.1):
|
||||
zustand@4.5.7(@types/react@18.3.26)(immer@10.1.1)(react@18.3.1):
|
||||
dependencies:
|
||||
use-sync-external-store: 1.5.0(react@18.3.1)
|
||||
optionalDependencies:
|
||||
'@types/react': 18.3.26
|
||||
immer: 10.1.1
|
||||
react: 18.3.1
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
@@ -51,12 +51,12 @@ impl AuthClientMixnetListener {
|
||||
}
|
||||
|
||||
async fn run(mut self) -> Self {
|
||||
let mixnet_cancel_token = self.mixnet_client.cancellation_token();
|
||||
self.shutdown_token.run_until_cancelled(async {
|
||||
let shutdown_event = self.mixnet_client.shutdown_event();
|
||||
loop {
|
||||
tokio::select! {
|
||||
biased;
|
||||
_ = mixnet_cancel_token.cancelled() => {
|
||||
_ = shutdown_event.wait() => {
|
||||
tracing::debug!("AuthClientMixnetListener: mixnet client was shutdown");
|
||||
break;
|
||||
}
|
||||
@@ -100,9 +100,7 @@ impl AuthClientMixnetListener {
|
||||
|
||||
// Disconnects the mixnet client and effectively drop itself, since it doesn't work without one, and reconnecting isn't supported
|
||||
pub async fn disconnect_mixnet_client(self) {
|
||||
if !self.mixnet_client.cancellation_token().is_cancelled() {
|
||||
self.mixnet_client.disconnect().await;
|
||||
}
|
||||
self.mixnet_client.disconnect().await;
|
||||
}
|
||||
|
||||
pub fn start(self) -> AuthClientMixnetListenerHandle {
|
||||
@@ -110,14 +108,14 @@ impl AuthClientMixnetListener {
|
||||
let message_sender = self.input_message_tx.clone();
|
||||
// Allows stopping only this, e.g. if we don't need it in the new bandwidth controller
|
||||
let cancellation_token = self.shutdown_token.clone();
|
||||
let mixnet_cancellation_token = self.mixnet_client.cancellation_token();
|
||||
// let mixnet_cancellation_token = self.mixnet_client.cancellation_token();
|
||||
let handle = tokio::spawn(self.run());
|
||||
|
||||
AuthClientMixnetListenerHandle {
|
||||
message_broadcast,
|
||||
message_sender,
|
||||
cancellation_token,
|
||||
mixnet_cancellation_token,
|
||||
// mixnet_cancellation_token,
|
||||
handle,
|
||||
}
|
||||
}
|
||||
@@ -127,7 +125,7 @@ pub struct AuthClientMixnetListenerHandle {
|
||||
message_broadcast: MixnetMessageBroadcastSender,
|
||||
message_sender: MixnetMessageInputSender,
|
||||
cancellation_token: CancellationToken,
|
||||
mixnet_cancellation_token: CancellationToken,
|
||||
// mixnet_cancellation_token: CancellationToken,
|
||||
handle: JoinHandle<AuthClientMixnetListener>,
|
||||
}
|
||||
|
||||
@@ -140,9 +138,9 @@ impl AuthClientMixnetListenerHandle {
|
||||
self.message_broadcast.subscribe()
|
||||
}
|
||||
|
||||
pub fn mixnet_cancel_token(&self) -> CancellationToken {
|
||||
self.mixnet_cancellation_token.clone()
|
||||
}
|
||||
// pub fn mixnet_cancel_token(&self) -> CancellationToken {
|
||||
// self.mixnet_cancellation_token.clone()
|
||||
// }
|
||||
|
||||
pub async fn stop(self) {
|
||||
// If shutdown was externally called, that call is a no-op
|
||||
|
||||
@@ -7,6 +7,7 @@ use nym_config::defaults::setup_env;
|
||||
use nym_gateway_probe::nodes::NymApiDirectory;
|
||||
use nym_gateway_probe::{CredentialArgs, NetstackArgs, ProbeResult, TestedNode};
|
||||
use nym_sdk::mixnet::NodeIdentity;
|
||||
use std::path::Path;
|
||||
use std::{path::PathBuf, sync::OnceLock};
|
||||
use tracing::*;
|
||||
|
||||
@@ -69,6 +70,8 @@ struct CliArgs {
|
||||
credential_args: CredentialArgs,
|
||||
}
|
||||
|
||||
const DEFAULT_CONFIG_DIR: &str = "/tmp/nym-gateway-probe/config/";
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
enum Commands {
|
||||
/// Run the probe locally
|
||||
@@ -77,8 +80,8 @@ enum Commands {
|
||||
#[arg(long)]
|
||||
mnemonic: String,
|
||||
|
||||
#[arg(long, default_value = "/tmp/nym-gateway-probe/config/")]
|
||||
config_dir: PathBuf,
|
||||
#[arg(long)]
|
||||
config_dir: Option<PathBuf>,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -144,8 +147,17 @@ pub(crate) async fn run() -> anyhow::Result<ProbeResult> {
|
||||
mnemonic,
|
||||
config_dir,
|
||||
}) => {
|
||||
let config_dir = config_dir
|
||||
.clone()
|
||||
.unwrap_or_else(|| Path::new(DEFAULT_CONFIG_DIR).join(&network.network_name));
|
||||
|
||||
info!(
|
||||
"using the following directory for the probe config: {}",
|
||||
config_dir.display()
|
||||
);
|
||||
|
||||
Box::pin(trial.probe_run_locally(
|
||||
config_dir,
|
||||
&config_dir,
|
||||
mnemonic,
|
||||
directory,
|
||||
nyxd_url,
|
||||
|
||||
@@ -133,8 +133,7 @@ impl IprClientConnect {
|
||||
|
||||
let timeout = sleep(IPR_CONNECT_TIMEOUT);
|
||||
tokio::pin!(timeout);
|
||||
|
||||
let mixnet_cancel_token = self.mixnet_client.cancellation_token();
|
||||
let shutdown_event = self.mixnet_client.shutdown_event();
|
||||
|
||||
loop {
|
||||
tokio::select! {
|
||||
@@ -142,15 +141,14 @@ impl IprClientConnect {
|
||||
error!("Cancelled while waiting for reply to connect request");
|
||||
return Err(Error::Cancelled);
|
||||
},
|
||||
|
||||
_ = mixnet_cancel_token.cancelled() => {
|
||||
error!("Mixnet client stopped while waiting for reply to connect request");
|
||||
return Err(Error::Cancelled);
|
||||
},
|
||||
_ = &mut timeout => {
|
||||
error!("Timed out waiting for reply to connect request");
|
||||
return Err(Error::TimeoutWaitingForConnectResponse);
|
||||
},
|
||||
_ = shutdown_event.wait() => {
|
||||
error!("Mixnet client stopped while waiting for reply to connect request");
|
||||
return Err(Error::Cancelled);
|
||||
},
|
||||
msgs = self.mixnet_client.wait_for_messages() => match msgs {
|
||||
None => {
|
||||
return Err(Error::NoMixnetMessagesReceived);
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT epoch_id as \"epoch_id: u32\", serialised_key, serialization_revision as \"serialization_revision: u8\"\n FROM master_verification_key WHERE epoch_id = ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "epoch_id: u32",
|
||||
"ordinal": 0,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "serialised_key",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "serialization_revision: u8",
|
||||
"ordinal": 2,
|
||||
"type_info": "Integer"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "0112296b190328a3856d1adf51aafa2525da6c0b871633aad80ad555db9cf47c"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n INSERT INTO ecash_deposit_usage (deposit_id, ticketbooks_requested_on, client_pubkey, request_uuid)\n VALUES (?, ?, ?, ?)\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 4
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "1fc72f8ba24039548047e1766c9105614dea7fd301f0ec38bfe85bfe546dad40"
|
||||
}
|
||||
+2
-8
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT\n node_id,\n ed25519_identity_pubkey,\n total_stake,\n ip_addresses as \"ip_addresses!: serde_json::Value\",\n mix_port,\n x25519_sphinx_pubkey,\n node_role as \"node_role: serde_json::Value\",\n supported_roles as \"supported_roles: serde_json::Value\",\n entry as \"entry: serde_json::Value\",\n performance,\n self_described as \"self_described: serde_json::Value\",\n bond_info as \"bond_info: serde_json::Value\",\n http_api_port\n FROM\n nym_nodes\n ORDER BY\n node_id\n ",
|
||||
"query": "SELECT\n node_id,\n ed25519_identity_pubkey,\n total_stake,\n ip_addresses as \"ip_addresses!: serde_json::Value\",\n mix_port,\n x25519_sphinx_pubkey,\n node_role as \"node_role: serde_json::Value\",\n supported_roles as \"supported_roles: serde_json::Value\",\n entry as \"entry: serde_json::Value\",\n performance,\n self_described as \"self_described: serde_json::Value\",\n bond_info as \"bond_info: serde_json::Value\"\n FROM\n nym_nodes\n WHERE\n self_described IS NOT NULL\n AND\n bond_info IS NOT NULL\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -62,11 +62,6 @@
|
||||
"ordinal": 11,
|
||||
"name": "bond_info: serde_json::Value",
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "http_api_port",
|
||||
"type_info": "Int4"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -84,9 +79,8 @@
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "3ddc12cc4e1796b787a50c40560d2bd71d1cfe5f5265e6f161b3122d1317a421"
|
||||
"hash": "283f49a65c7d70bf271702ff6a5c7ad6e68c81932d295ff18ed198c54706a57c"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n DELETE FROM blinded_shares WHERE created < ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "28681fcd8e2d4326f628681b8f2a317aabce063a650be362d3a8ed83cc7c3549"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n INSERT INTO global_expiration_date_signatures(expiration_date, epoch_id, serialised_signatures, serialization_revision)\n VALUES (?, ?, ?, ?)\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 4
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "2930ca6e3875c74acb7abb9ad889f166ad7f57681f76a1d0c7723d007c1f2c1e"
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT error_message\n FROM blinded_shares\n WHERE id = ?;\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "error_message",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "396f40c33f0f62796eb7449d640bd97845350f4fb9f806c60b93c7cebd5e410d"
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT serialised_signatures, serialization_revision as \"serialization_revision: u8\"\n FROM global_expiration_date_signatures\n WHERE expiration_date = ? AND epoch_id = ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "serialised_signatures",
|
||||
"ordinal": 0,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "serialization_revision: u8",
|
||||
"ordinal": 1,
|
||||
"type_info": "Integer"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "3cc446220668fb3e02f0578104291d2a2af57656b405212af414d765b2263347"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n DELETE FROM partial_blinded_wallet_failure WHERE created < ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "52b378e282d93db941eff53b5b311e5732ece0bf84ea98f2328b20add8f2b5ef"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "INSERT INTO master_verification_key(epoch_id, serialised_key, serialization_revision) VALUES (?, ?, ?)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 3
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "70d8f240ad6edda6b8c7f2e800e7fca89d80869484f2f3c66cabb898f0298c62"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n INSERT INTO partial_blinded_wallet_failure(corresponding_deposit, epoch_id, expiration_date, node_id, created, failure_message)\n VALUES (?, ?, ?, ?, ?, ?)\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 6
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "97d97ebb6bc8f4114fdea9ebc9f57f91a11f5057273cb70bd0e629712d17dd41"
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT epoch_id as \"epoch_id: u32\", serialised_signatures, serialization_revision as \"serialization_revision: u8\"\n FROM global_coin_index_signatures WHERE epoch_id = ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "epoch_id: u32",
|
||||
"ordinal": 0,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "serialised_signatures",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "serialization_revision: u8",
|
||||
"ordinal": 2,
|
||||
"type_info": "Integer"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "a8b7ce0fe4755c28b96d1e503e313ab15fed747fb0cee1c9f949fb58461b3f79"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n DELETE FROM partial_blinded_wallet WHERE created < ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "b8257a0832d0124f0a8aaaf81dc6a811c593aea8febf1f891117e5e84213f147"
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT\n t1.node_id as \"node_id!\",\n t1.blinded_signature as \"blinded_signature!\",\n t1.epoch_id as \"epoch_id!\",\n t1.expiration_date as \"expiration_date!: Date\"\n FROM partial_blinded_wallet as t1\n JOIN ecash_deposit_usage as t2\n on t1.corresponding_deposit = t2.deposit_id\n JOIN blinded_shares as t3\n ON t2.request_uuid = t3.request_uuid\n WHERE t3.device_id = ? AND t3.credential_id = ?;\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "node_id!",
|
||||
"ordinal": 0,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "blinded_signature!",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "epoch_id!",
|
||||
"ordinal": 2,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "expiration_date!: Date",
|
||||
"ordinal": 3,
|
||||
"type_info": "Date"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "c2b841762bdb963fff337ef5c8ec9f560017b4da6b0303ea0397d9568229e167"
|
||||
}
|
||||
+2
-8
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT\n node_id,\n ed25519_identity_pubkey,\n total_stake,\n ip_addresses as \"ip_addresses!: serde_json::Value\",\n mix_port,\n x25519_sphinx_pubkey,\n node_role as \"node_role: serde_json::Value\",\n supported_roles as \"supported_roles: serde_json::Value\",\n entry as \"entry: serde_json::Value\",\n performance,\n self_described as \"self_described: serde_json::Value\",\n bond_info as \"bond_info: serde_json::Value\",\n http_api_port\n FROM\n nym_nodes\n WHERE\n self_described IS NOT NULL\n AND\n bond_info IS NOT NULL\n ",
|
||||
"query": "SELECT\n node_id,\n ed25519_identity_pubkey,\n total_stake,\n ip_addresses as \"ip_addresses!: serde_json::Value\",\n mix_port,\n x25519_sphinx_pubkey,\n node_role as \"node_role: serde_json::Value\",\n supported_roles as \"supported_roles: serde_json::Value\",\n entry as \"entry: serde_json::Value\",\n performance,\n self_described as \"self_described: serde_json::Value\",\n bond_info as \"bond_info: serde_json::Value\"\n FROM\n nym_nodes\n ORDER BY\n node_id\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -62,11 +62,6 @@
|
||||
"ordinal": 11,
|
||||
"name": "bond_info: serde_json::Value",
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"ordinal": 12,
|
||||
"name": "http_api_port",
|
||||
"type_info": "Int4"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -84,9 +79,8 @@
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "0b51df277ed66c6553f66af9b135342dee177abc1c92e4a89147de3c22d3d1a5"
|
||||
"hash": "c48d04fc3de59dd484f0a63d40336ced54e08785f77e9ef85f3157d004ec85dc"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "INSERT INTO global_coin_index_signatures(epoch_id, serialised_signatures, serialization_revision) VALUES (?, ?, ?)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 3
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "d3510846941fa2525926b9bfbcdabd806877ce914b514d4f7cd6be318c4debe6"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n INSERT INTO partial_blinded_wallet(corresponding_deposit, epoch_id, expiration_date, node_id, created, blinded_signature)\n VALUES (?, ?, ?, ?, ?, ?)\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 6
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "db176e98198fe594d88eb860d918f633a94d18a19b7f0f96935a62560def7d0f"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n UPDATE ecash_deposit_usage\n SET ticketbook_request_error = ?\n WHERE deposit_id = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "e584253e3856355899537eb8fc152f2bfed2d918b894ec0f588e38dd5e8ad726"
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT t1.node_id, t1.blinded_signature, t1.epoch_id, t1.expiration_date as \"expiration_date!: Date\"\n FROM partial_blinded_wallet as t1\n JOIN ecash_deposit_usage as t2\n on t1.corresponding_deposit = t2.deposit_id\n JOIN blinded_shares as t3\n ON t2.request_uuid = t3.request_uuid\n WHERE t3.id = ?;\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "node_id",
|
||||
"ordinal": 0,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "blinded_signature",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "epoch_id",
|
||||
"ordinal": 2,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "expiration_date!: Date",
|
||||
"ordinal": 3,
|
||||
"type_info": "Date"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "e77ffab19b099b84470fe5611716a2e314787586a46cffd074abb67f2f4d109e"
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT error_message\n FROM blinded_shares\n WHERE device_id = ? AND credential_id = ?;\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "error_message",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "ef60c2683211cc4ec2d3e46392518a1f62fa67dfe8f130deb876ebee11bf1602"
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-node-status-api"
|
||||
version = "4.0.7-test2"
|
||||
version = "4.0.9"
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
homepage.workspace = true
|
||||
|
||||
-2
@@ -1,2 +0,0 @@
|
||||
ALTER TABLE nym_nodes
|
||||
ADD COLUMN http_api_port INTEGER;
|
||||
@@ -381,7 +381,7 @@ impl ScrapeNodeKind {
|
||||
pub(crate) struct ScraperNodeInfo {
|
||||
pub node_kind: ScrapeNodeKind,
|
||||
pub hosts: Vec<String>,
|
||||
pub http_api_port: Option<u16>,
|
||||
pub http_api_port: i64,
|
||||
}
|
||||
|
||||
impl ScraperNodeInfo {
|
||||
@@ -395,21 +395,8 @@ impl ScraperNodeInfo {
|
||||
format!("http://{}", host),
|
||||
]);
|
||||
|
||||
if let Some(custom_http_api_port) = self.http_api_port {
|
||||
urls = Vec::new();
|
||||
for host in &self.hosts {
|
||||
urls.append(&mut vec![format!(
|
||||
"http://{}:{}",
|
||||
host, custom_http_api_port
|
||||
)]);
|
||||
}
|
||||
|
||||
// do not fall back to default ports, if the operator sets a custom http api port
|
||||
// in their bond, use it and error out if it's not available
|
||||
// this will correctly handle cases where some operators run multiple nodes
|
||||
// on a single IP address and assign different custom http port apis at bond time
|
||||
|
||||
// urls.insert(0, format!("http://{}:{}", host, custom_http_api_port));
|
||||
if self.http_api_port != DEFAULT_NYM_NODE_HTTP_PORT as i64 {
|
||||
urls.insert(0, format!("http://{}:{}", host, self.http_api_port));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,7 +423,6 @@ pub(crate) struct NymNodeDto {
|
||||
pub performance: String,
|
||||
pub self_described: Option<serde_json::Value>,
|
||||
pub bond_info: Option<serde_json::Value>,
|
||||
pub http_api_port: Option<i32>,
|
||||
}
|
||||
|
||||
#[allow(dead_code)] // it's not dead code but clippy doesn't detect usage in sqlx macros
|
||||
@@ -454,7 +440,6 @@ pub(crate) struct NymNodeInsertRecord {
|
||||
pub entry: Option<serde_json::Value>,
|
||||
pub self_described: Option<serde_json::Value>,
|
||||
pub bond_info: Option<serde_json::Value>,
|
||||
pub http_api_port: Option<i32>,
|
||||
pub last_updated_utc: i64,
|
||||
}
|
||||
|
||||
@@ -471,12 +456,6 @@ impl NymNodeInsertRecord {
|
||||
.map(|info| decimal_to_i64(info.total_stake()))
|
||||
.unwrap_or(0);
|
||||
let entry = serialize_opt_to_value!(skimmed_node.entry)?;
|
||||
let http_api_port = bond_info.and_then(|bond| {
|
||||
bond.bond_information
|
||||
.node
|
||||
.custom_http_port
|
||||
.map(|port| port as i32)
|
||||
});
|
||||
let bond_info = serialize_opt_to_value!(bond_info)?;
|
||||
let self_described = serialize_opt_to_value!(self_described)?;
|
||||
|
||||
@@ -493,7 +472,6 @@ impl NymNodeInsertRecord {
|
||||
entry,
|
||||
self_described,
|
||||
bond_info,
|
||||
http_api_port,
|
||||
last_updated_utc: now,
|
||||
};
|
||||
|
||||
|
||||
@@ -35,8 +35,7 @@ pub(crate) async fn get_all_nym_nodes(pool: &DbPool) -> anyhow::Result<Vec<NymNo
|
||||
entry as "entry: serde_json::Value",
|
||||
performance,
|
||||
self_described as "self_described: serde_json::Value",
|
||||
bond_info as "bond_info: serde_json::Value",
|
||||
http_api_port
|
||||
bond_info as "bond_info: serde_json::Value"
|
||||
FROM
|
||||
nym_nodes
|
||||
ORDER BY
|
||||
@@ -73,8 +72,7 @@ pub(crate) async fn get_described_bonded_nym_nodes(
|
||||
entry as "entry: serde_json::Value",
|
||||
performance,
|
||||
self_described as "self_described: serde_json::Value",
|
||||
bond_info as "bond_info: serde_json::Value",
|
||||
http_api_port
|
||||
bond_info as "bond_info: serde_json::Value"
|
||||
FROM
|
||||
nym_nodes
|
||||
WHERE
|
||||
|
||||
@@ -21,11 +21,10 @@ pub(crate) async fn get_nodes_for_scraping(pool: &DbPool) -> Result<Vec<ScraperN
|
||||
let skimmed_nodes = queries::get_described_bonded_nym_nodes(pool)
|
||||
.await
|
||||
.map(|nodes_dto| {
|
||||
nodes_dto.into_iter().filter_map(|node_dto| {
|
||||
let node_id = node_dto.node_id;
|
||||
let http_api_port = node_dto.http_api_port;
|
||||
match SkimmedNode::try_from(node_dto) {
|
||||
Ok(node) => Some((node, http_api_port)),
|
||||
nodes_dto.into_iter().filter_map(|node| {
|
||||
let node_id = node.node_id;
|
||||
match SkimmedNode::try_from(node) {
|
||||
Ok(node) => Some(node),
|
||||
Err(e) => {
|
||||
tracing::error!("Failed to decode node_id={}: {}", node_id, e);
|
||||
None
|
||||
@@ -34,7 +33,7 @@ pub(crate) async fn get_nodes_for_scraping(pool: &DbPool) -> Result<Vec<ScraperN
|
||||
})
|
||||
})?;
|
||||
|
||||
skimmed_nodes.for_each(|(node, http_api_port)| {
|
||||
skimmed_nodes.for_each(|node| {
|
||||
// TODO: relies on polyfilling: Nym nodes table might contain legacy mixnodes
|
||||
// as well. Categorize them here.
|
||||
let node_kind = if gateway_keys.contains(&node.ed25519_identity_pubkey.to_base58_string()) {
|
||||
@@ -55,7 +54,7 @@ pub(crate) async fn get_nodes_for_scraping(pool: &DbPool) -> Result<Vec<ScraperN
|
||||
.into_iter()
|
||||
.map(|ip| ip.to_string())
|
||||
.collect::<Vec<_>>(),
|
||||
http_api_port: http_api_port.map(|port| port as u16),
|
||||
http_api_port: node.mix_port.into(),
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
@@ -138,7 +138,6 @@ mod db_tests {
|
||||
performance: "1.0".to_string(),
|
||||
self_described: None,
|
||||
bond_info: None,
|
||||
http_api_port: None,
|
||||
};
|
||||
|
||||
let skimmed_node: nym_validator_client::nym_api::SkimmedNode =
|
||||
@@ -363,42 +362,22 @@ fn test_scraper_node_info_contact_addresses() {
|
||||
let node_info = ScraperNodeInfo {
|
||||
node_kind: ScrapeNodeKind::MixingNymNode { node_id: 123 },
|
||||
hosts: vec!["1.1.1.1".to_string(), "example.com".to_string()],
|
||||
http_api_port: None,
|
||||
http_api_port: 8080,
|
||||
};
|
||||
|
||||
let addresses = node_info.contact_addresses();
|
||||
|
||||
// Should generate multiple URLs for each host
|
||||
// When no custom port is specified only default ports should be used
|
||||
// Custom port (8080) should be inserted at the beginning
|
||||
assert!(addresses.contains(&"http://1.1.1.1:8080".to_string()));
|
||||
assert!(addresses.contains(&"http://example.com:8080".to_string()));
|
||||
assert!(addresses.contains(&"http://1.1.1.1:8000".to_string()));
|
||||
assert!(addresses.contains(&"https://1.1.1.1".to_string()));
|
||||
assert!(addresses.contains(&"http://1.1.1.1".to_string()));
|
||||
assert!(addresses.contains(&"http://example.com:8000".to_string()));
|
||||
// Check that URLs follow the expected pattern
|
||||
assert!(addresses.len() >= 8); // At least 4 URLs per host
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_scraper_node_info_contact_addresses_with_custom_http_api_port() {
|
||||
use crate::db::models::{ScrapeNodeKind, ScraperNodeInfo};
|
||||
|
||||
let node_info = ScraperNodeInfo {
|
||||
node_kind: ScrapeNodeKind::MixingNymNode { node_id: 123 },
|
||||
hosts: vec!["1.1.1.1".to_string(), "example.com".to_string()],
|
||||
http_api_port: Some(4444),
|
||||
};
|
||||
|
||||
let addresses = node_info.contact_addresses();
|
||||
|
||||
// Should generate multiple URLs for each host
|
||||
// Custom port (4444) should be the only port in the list
|
||||
assert!(addresses.contains(&"http://1.1.1.1:4444".to_string()));
|
||||
assert!(addresses.contains(&"http://example.com:4444".to_string()));
|
||||
// Check that URLs follow the expected pattern
|
||||
assert!(addresses.len() >= 2); // At least 4 URLs per host
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_scrape_node_kind_node_id() {
|
||||
use crate::db::models::ScrapeNodeKind;
|
||||
@@ -435,7 +414,6 @@ fn test_nym_node_dto_with_invalid_keys() {
|
||||
performance: "1.0".to_string(),
|
||||
self_described: None,
|
||||
bond_info: None,
|
||||
http_api_port: None,
|
||||
};
|
||||
|
||||
let result: Result<nym_validator_client::nym_api::SkimmedNode, _> = nym_node_dto.try_into();
|
||||
@@ -473,7 +451,6 @@ fn test_nym_node_dto_with_invalid_performance() {
|
||||
performance: "invalid_percent".to_string(),
|
||||
self_described: None,
|
||||
bond_info: None,
|
||||
http_api_port: None,
|
||||
};
|
||||
|
||||
let result: Result<nym_validator_client::nym_api::SkimmedNode, _> = nym_node_dto.try_into();
|
||||
|
||||
@@ -99,6 +99,7 @@ pub struct DVpnGatewayPerformance {
|
||||
pub struct DVpnGateway {
|
||||
pub identity_key: String,
|
||||
pub name: String,
|
||||
pub description: Option<String>,
|
||||
pub ip_packet_router: Option<IpPacketRouterDetails>,
|
||||
pub authenticator: Option<AuthenticatorDetails>,
|
||||
pub location: Location,
|
||||
@@ -326,6 +327,7 @@ impl DVpnGateway {
|
||||
Ok(Self {
|
||||
identity_key: gateway.gateway_identity_key,
|
||||
name: gateway.description.moniker,
|
||||
description: Some(gateway.description.details),
|
||||
ip_packet_router: self_described.ip_packet_router,
|
||||
authenticator: self_described.authenticator,
|
||||
location: Location {
|
||||
@@ -401,18 +403,17 @@ fn calculate_score(gateway: &Gateway, probe_outcome: &LastProbeResult) -> ScoreV
|
||||
/ 1000f64;
|
||||
|
||||
// get the file size downloaded in bytes and convert to MB, or default to 1MB
|
||||
let file_size_mb = p.downloaded_file_size_bytes_v4.unwrap_or_else(|| 1048576) as f64
|
||||
/ 1024f64
|
||||
/ 1024f64;
|
||||
let file_size_mb =
|
||||
p.downloaded_file_size_bytes_v4.unwrap_or(1048576) as f64 / 1024f64 / 1024f64;
|
||||
let speed_mbps = file_size_mb / duration_sec;
|
||||
|
||||
let file_download_score = if speed_mbps > 10.0 {
|
||||
let file_download_score = if speed_mbps > 5.0 {
|
||||
1.0
|
||||
} else if speed_mbps > 5.0 {
|
||||
0.75
|
||||
} else if speed_mbps > 2.0 {
|
||||
0.5
|
||||
0.75
|
||||
} else if speed_mbps > 1.0 {
|
||||
0.5
|
||||
} else if speed_mbps > 0.5 {
|
||||
0.25
|
||||
} else {
|
||||
0.1
|
||||
|
||||
@@ -0,0 +1,941 @@
|
||||
#!/bin/bash
|
||||
# Nym QUIC Bridge Deployment Helper Script
|
||||
# This script provides network configuration and troubleshooting tools for Nym QUIC bridges
|
||||
|
||||
network_device=$(ip route show default | awk '/default/ {print $5}')
|
||||
wg_tunnel_interface="nymwg"
|
||||
|
||||
BRIDGE_CONFIG_DIR="/opt/nym-bridge"
|
||||
BRIDGE_KEYS_DIR="$BRIDGE_CONFIG_DIR/keys"
|
||||
BRIDGE_CONFIG="$BRIDGE_CONFIG_DIR/bridges.toml"
|
||||
CLIENT_PARAMS="$BRIDGE_CONFIG_DIR/client_bridge_params.json"
|
||||
BRIDGE_BINARY="/usr/local/bin/nym-bridge"
|
||||
|
||||
|
||||
if ! dpkg -s iptables-persistent >/dev/null 2>&1; then
|
||||
echo "Installing iptables-persistent..."
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y iptables-persistent
|
||||
else
|
||||
echo "iptables-persistent is already installed."
|
||||
fi
|
||||
|
||||
fetch_and_display_ipv6() {
|
||||
ipv6_address=$(ip -6 addr show "$network_device" scope global | grep inet6 | awk '{print $2}')
|
||||
if [[ -z "$ipv6_address" ]]; then
|
||||
echo "No global IPv6 address found on $network_device."
|
||||
else
|
||||
echo "IPv6 address on $network_device: $ipv6_address"
|
||||
fi
|
||||
}
|
||||
|
||||
fetch_wg_ipv6_address() {
|
||||
ipv6_global_address=$(ip -6 addr show "$wg_tunnel_interface" scope global | grep inet6 | awk '{print $2}' | head -n 1)
|
||||
|
||||
if [[ -z "$ipv6_global_address" ]]; then
|
||||
echo "No globally routable IPv6 address found on $wg_tunnel_interface. Please configure IPv6 or check your network settings."
|
||||
exit 1
|
||||
else
|
||||
echo "Using IPv6 address: $ipv6_global_address"
|
||||
fi
|
||||
}
|
||||
|
||||
adjust_ip_forwarding() {
|
||||
ipv6_forwarding_setting="net.ipv6.conf.all.forwarding=1"
|
||||
ipv4_forwarding_setting="net.ipv4.ip_forward=1"
|
||||
|
||||
# Remove duplicate entries for these settings from the file
|
||||
sudo sed -i "/^net.ipv6.conf.all.forwarding=/d" /etc/sysctl.conf
|
||||
sudo sed -i "/^net.ipv4.ip_forward=/d" /etc/sysctl.conf
|
||||
|
||||
echo "$ipv6_forwarding_setting" | sudo tee -a /etc/sysctl.conf
|
||||
echo "$ipv4_forwarding_setting" | sudo tee -a /etc/sysctl.conf
|
||||
|
||||
sudo sysctl -p /etc/sysctl.conf
|
||||
|
||||
echo "IP forwarding enabled for IPv4 and IPv6."
|
||||
}
|
||||
|
||||
apply_bridge_iptables_rules() {
|
||||
echo "Applying iptables rules for QUIC bridge ($wg_tunnel_interface)..."
|
||||
sleep 1
|
||||
|
||||
# INPUT rules - allow incoming connections TO the bridge from WireGuard clients
|
||||
# CRITICAL: This allows mobile clients to reach the bandwidth controller at 10.1.0.1:51830
|
||||
sudo iptables -I INPUT -i "$wg_tunnel_interface" -j ACCEPT
|
||||
sudo ip6tables -I INPUT -i "$wg_tunnel_interface" -j ACCEPT
|
||||
|
||||
# NAT rules - for outbound traffic masquerading
|
||||
sudo iptables -t nat -A POSTROUTING -o "$network_device" -j MASQUERADE
|
||||
sudo ip6tables -t nat -A POSTROUTING -o "$network_device" -j MASQUERADE
|
||||
|
||||
# FORWARD rules - allow traffic through the bridge
|
||||
sudo iptables -A FORWARD -i "$wg_tunnel_interface" -o "$network_device" -j ACCEPT
|
||||
sudo iptables -A FORWARD -i "$network_device" -o "$wg_tunnel_interface" -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
sudo ip6tables -A FORWARD -i "$wg_tunnel_interface" -o "$network_device" -j ACCEPT
|
||||
sudo ip6tables -A FORWARD -i "$network_device" -o "$wg_tunnel_interface" -m state --state RELATED,ESTABLISHED -j ACCEPT
|
||||
|
||||
# Save rules
|
||||
sudo iptables-save | sudo tee /etc/iptables/rules.v4
|
||||
sudo ip6tables-save | sudo tee /etc/iptables/rules.v6
|
||||
|
||||
echo "Iptables rules applied successfully for QUIC bridge (including INPUT rules for bandwidth controller)."
|
||||
}
|
||||
|
||||
check_bridge_iptables() {
|
||||
echo "Inspecting iptables rules for QUIC bridge ($wg_tunnel_interface)..."
|
||||
echo "---------------------------------------"
|
||||
echo "IPv4 INPUT rules (for bandwidth controller):"
|
||||
iptables -L INPUT -v -n | grep -E "$wg_tunnel_interface|Chain INPUT" | head -20
|
||||
echo "---------------------------------------"
|
||||
echo "IPv4 FORWARD rules:"
|
||||
iptables -L FORWARD -v -n | awk -v dev="$wg_tunnel_interface" '/^Chain FORWARD/ || $0 ~ dev || $0 ~ "ufw-reject-forward"'
|
||||
echo "---------------------------------------"
|
||||
echo "IPv6 INPUT rules (for bandwidth controller):"
|
||||
ip6tables -L INPUT -v -n | grep -E "$wg_tunnel_interface|Chain INPUT" | head -20
|
||||
echo "---------------------------------------"
|
||||
echo "IPv6 FORWARD rules:"
|
||||
ip6tables -L FORWARD -v -n | awk -v dev="$wg_tunnel_interface" '/^Chain FORWARD/ || $0 ~ dev || $0 ~ "ufw6-reject-forward"'
|
||||
}
|
||||
|
||||
remove_duplicate_bridge_rules() {
|
||||
local script_name=$(basename "$0")
|
||||
|
||||
echo "Removing duplicate iptables rules for $wg_tunnel_interface..."
|
||||
|
||||
iptables-save | grep "$wg_tunnel_interface" | while read -r line; do
|
||||
sudo iptables -D ${line#-A } 2>/dev/null || echo "Failed to delete rule: $line"
|
||||
done
|
||||
|
||||
ip6tables-save | grep "$wg_tunnel_interface" | while read -r line; do
|
||||
sudo ip6tables -D ${line#-A } 2>/dev/null || echo "Failed to delete rule: $line"
|
||||
done
|
||||
|
||||
echo "Duplicates removed for $wg_tunnel_interface."
|
||||
echo "!!IMPORTANT!! You need to now reapply the iptables rules."
|
||||
echo "Run: ./$script_name apply_bridge_iptables_rules"
|
||||
}
|
||||
|
||||
configure_dns_and_icmp() {
|
||||
echo "Allowing ICMP (ping)..."
|
||||
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
|
||||
sudo iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
|
||||
sudo ip6tables -A INPUT -p ipv6-icmp -j ACCEPT
|
||||
sudo ip6tables -A OUTPUT -p ipv6-icmp -j ACCEPT
|
||||
|
||||
echo "Allowing DNS over UDP (port 53)..."
|
||||
sudo iptables -A INPUT -p udp --dport 53 -j ACCEPT
|
||||
sudo ip6tables -A INPUT -p udp --dport 53 -j ACCEPT
|
||||
|
||||
echo "Allowing DNS over TCP (port 53)..."
|
||||
sudo iptables -A INPUT -p tcp --dport 53 -j ACCEPT
|
||||
sudo ip6tables -A INPUT -p tcp --dport 53 -j ACCEPT
|
||||
|
||||
echo "Saving iptables rules..."
|
||||
sudo iptables-save | sudo tee /etc/iptables/rules.v4
|
||||
sudo ip6tables-save | sudo tee /etc/iptables/rules.v6
|
||||
|
||||
echo "DNS and ICMP configuration completed."
|
||||
}
|
||||
|
||||
check_ipv6_ipv4_forwarding() {
|
||||
result_ipv4=$(cat /proc/sys/net/ipv4/ip_forward)
|
||||
result_ipv6=$(cat /proc/sys/net/ipv6/conf/all/forwarding)
|
||||
echo "IPv4 forwarding is $([ "$result_ipv4" == "1" ] && echo "enabled" || echo "not enabled")."
|
||||
echo "IPv6 forwarding is $([ "$result_ipv6" == "1" ] && echo "enabled" || echo "not enabled")."
|
||||
}
|
||||
|
||||
check_ip_routing() {
|
||||
echo "IPv4 routing table:"
|
||||
ip route
|
||||
echo "---------------------------------------"
|
||||
echo "IPv6 routing table:"
|
||||
ip -6 route
|
||||
}
|
||||
|
||||
perform_pings() {
|
||||
echo "Performing IPv4 ping to google.com..."
|
||||
ping -c 4 google.com
|
||||
echo "---------------------------------------"
|
||||
echo "Performing IPv6 ping to google.com..."
|
||||
ping6 -c 4 google.com
|
||||
}
|
||||
|
||||
test_bridge_connectivity() {
|
||||
local green="\033[0;32m"
|
||||
local reset="\033[0m"
|
||||
local red="\033[0;31m"
|
||||
local yellow="\033[0;33m"
|
||||
|
||||
sleep 1
|
||||
echo
|
||||
echo -e "${yellow}Testing QUIC bridge connectivity on $wg_tunnel_interface...${reset}"
|
||||
echo -e "${yellow}If these tests succeed, it confirms the bridge can reach the outside world via IPv4 and IPv6.${reset}"
|
||||
echo -e "${yellow}However, external clients may experience different connectivity to your bridge.${reset}"
|
||||
|
||||
ipv4_address=$(ip addr show "$wg_tunnel_interface" | awk '/inet / {print $2}' | cut -d'/' -f1)
|
||||
ipv6_address=$(ip addr show "$wg_tunnel_interface" | awk '/inet6 / && $2 !~ /^fe80/ {print $2}' | cut -d'/' -f1)
|
||||
|
||||
if [[ -z "$ipv4_address" && -z "$ipv6_address" ]]; then
|
||||
echo -e "${red}No IP address found on $wg_tunnel_interface. Unable to test connectivity.${reset}"
|
||||
echo -e "${red}Please verify your bridge configuration and ensure the interface is up.${reset}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ -n "$ipv4_address" ]]; then
|
||||
echo
|
||||
echo -e "------------------------------------"
|
||||
echo -e "Detected IPv4 address: $ipv4_address"
|
||||
echo -e "Testing IPv4 connectivity..."
|
||||
echo
|
||||
|
||||
if ping -c 1 -I "$ipv4_address" google.com >/dev/null 2>&1; then
|
||||
echo -e "${green}IPv4 connectivity is working. Fetching test data...${reset}"
|
||||
joke=$(curl -s -H "Accept: application/json" --interface "$ipv4_address" https://icanhazdadjoke.com/ | jq -r .joke)
|
||||
[[ -n "$joke" && "$joke" != "null" ]] && echo -e "${green}IPv4 test joke: $joke${reset}" || echo -e "${red}Failed to fetch test data via IPv4.${reset}"
|
||||
else
|
||||
echo -e "${red}IPv4 connectivity is not working for $wg_tunnel_interface. Verify your routing and NAT settings.${reset}"
|
||||
fi
|
||||
else
|
||||
echo -e "${yellow}No IPv4 address found on $wg_tunnel_interface. Skipping IPv4 test.${reset}"
|
||||
fi
|
||||
|
||||
if [[ -n "$ipv6_address" ]]; then
|
||||
echo
|
||||
echo -e "------------------------------------"
|
||||
echo -e "Detected IPv6 address: $ipv6_address"
|
||||
echo -e "Testing IPv6 connectivity..."
|
||||
echo
|
||||
|
||||
if ping6 -c 1 -I "$ipv6_address" google.com >/dev/null 2>&1; then
|
||||
echo -e "${green}IPv6 connectivity is working. Fetching test data...${reset}"
|
||||
joke=$(curl -s -H "Accept: application/json" --interface "$ipv6_address" https://icanhazdadjoke.com/ | jq -r .joke)
|
||||
[[ -n "$joke" && "$joke" != "null" ]] && echo -e "${green}IPv6 test joke: $joke${reset}" || echo -e "${red}Failed to fetch test data via IPv6.${reset}"
|
||||
else
|
||||
echo -e "${red}IPv6 connectivity is not working for $wg_tunnel_interface. Verify your routing and NAT settings.${reset}"
|
||||
fi
|
||||
else
|
||||
echo -e "${yellow}No IPv6 address found on $wg_tunnel_interface. Skipping IPv6 test.${reset}"
|
||||
fi
|
||||
|
||||
echo -e "${green}Connectivity testing completed for $wg_tunnel_interface.${reset}"
|
||||
echo -e "------------------------------------"
|
||||
|
||||
sleep 2
|
||||
echo
|
||||
echo
|
||||
echo -e "${yellow}### Bridge Connectivity Testing Recommendations ###${reset}"
|
||||
echo -e "${yellow}- Test UDP connectivity on port 51822 (used for Nym QUIC/WireGuard)${reset}"
|
||||
echo -e "${yellow} From another machine: echo 'test message' | nc -u <your-ip-address> 51822${reset}"
|
||||
echo -e "${yellow}- Test bandwidth controller access on port 51830:${reset}"
|
||||
echo -e "${yellow} From inside the WireGuard tunnel: curl http://10.1.0.1:51830${reset}"
|
||||
echo -e "${yellow}- If connectivity issues persist, check port forwarding and firewall rules${reset}"
|
||||
echo
|
||||
}
|
||||
|
||||
check_bridge_service_status() {
|
||||
echo "Checking nym-bridge service status..."
|
||||
systemctl status nym-bridge.service --no-pager
|
||||
echo "---------------------------------------"
|
||||
echo "Checking nym-node service status..."
|
||||
systemctl status nym-node.service --no-pager
|
||||
}
|
||||
|
||||
show_bridge_logs() {
|
||||
local lines=${1:-50}
|
||||
echo "Showing last $lines lines of nym-bridge logs..."
|
||||
journalctl -u nym-bridge.service -n "$lines" --no-pager
|
||||
}
|
||||
|
||||
check_bridge_installation() {
|
||||
local green="\033[0;32m"
|
||||
local reset="\033[0m"
|
||||
local red="\033[0;31m"
|
||||
local yellow="\033[0;33m"
|
||||
|
||||
echo -e "${yellow}=== Nym QUIC Bridge Installation Status ===${reset}"
|
||||
echo ""
|
||||
|
||||
# Check binary
|
||||
if [[ -f "$BRIDGE_BINARY" ]]; then
|
||||
echo -e "${green}✓ Bridge binary found: $BRIDGE_BINARY${reset}"
|
||||
bridge_version=$($BRIDGE_BINARY --version 2>/dev/null | head -1 || echo "Unable to determine version")
|
||||
echo " Version: $bridge_version"
|
||||
else
|
||||
echo -e "${red}✗ Bridge binary not found at $BRIDGE_BINARY${reset}"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Check configuration directory
|
||||
if [[ -d "$BRIDGE_CONFIG_DIR" ]]; then
|
||||
echo -e "${green}✓ Configuration directory exists: $BRIDGE_CONFIG_DIR${reset}"
|
||||
else
|
||||
echo -e "${red}✗ Configuration directory not found: $BRIDGE_CONFIG_DIR${reset}"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Check keys directory
|
||||
if [[ -d "$BRIDGE_KEYS_DIR" ]]; then
|
||||
echo -e "${green}✓ Keys directory exists: $BRIDGE_KEYS_DIR${reset}"
|
||||
key_count=$(ls -1 "$BRIDGE_KEYS_DIR"/*.pem 2>/dev/null | wc -l)
|
||||
echo " Keys found: $key_count"
|
||||
else
|
||||
echo -e "${red}✗ Keys directory not found: $BRIDGE_KEYS_DIR${reset}"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Check configuration files
|
||||
if [[ -f "$BRIDGE_CONFIG" ]]; then
|
||||
echo -e "${green}✓ Bridge config found: $BRIDGE_CONFIG${reset}"
|
||||
else
|
||||
echo -e "${red}✗ Bridge config not found: $BRIDGE_CONFIG${reset}"
|
||||
fi
|
||||
|
||||
if [[ -f "$CLIENT_PARAMS" ]]; then
|
||||
echo -e "${green}✓ Client params found: $CLIENT_PARAMS${reset}"
|
||||
else
|
||||
echo -e "${red}✗ Client params not found: $CLIENT_PARAMS${reset}"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Check services
|
||||
echo -e "${yellow}Service Status:${reset}"
|
||||
if systemctl is-active --quiet nym-bridge.service; then
|
||||
echo -e "${green}✓ nym-bridge service is running${reset}"
|
||||
else
|
||||
echo -e "${red}✗ nym-bridge service is not running${reset}"
|
||||
fi
|
||||
|
||||
if systemctl is-active --quiet nym-node.service; then
|
||||
echo -e "${green}✓ nym-node service is running${reset}"
|
||||
else
|
||||
echo -e "${red}✗ nym-node service is not running${reset}"
|
||||
fi
|
||||
echo ""
|
||||
}
|
||||
|
||||
show_bridge_config() {
|
||||
echo "=== Bridge Configuration ==="
|
||||
echo ""
|
||||
|
||||
if [[ -f "$BRIDGE_CONFIG" ]]; then
|
||||
echo "Bridge config ($BRIDGE_CONFIG):"
|
||||
echo "---------------------------------------"
|
||||
cat "$BRIDGE_CONFIG"
|
||||
echo ""
|
||||
else
|
||||
echo "Bridge config not found at $BRIDGE_CONFIG"
|
||||
fi
|
||||
|
||||
if [[ -f "$CLIENT_PARAMS" ]]; then
|
||||
echo "Client parameters ($CLIENT_PARAMS):"
|
||||
echo "---------------------------------------"
|
||||
cat "$CLIENT_PARAMS"
|
||||
echo ""
|
||||
else
|
||||
echo "Client parameters not found at $CLIENT_PARAMS"
|
||||
fi
|
||||
}
|
||||
|
||||
show_bridge_keys() {
|
||||
local green="\033[0;32m"
|
||||
local reset="\033[0m"
|
||||
local red="\033[0;31m"
|
||||
local yellow="\033[0;33m"
|
||||
|
||||
echo -e "${yellow}=== Bridge Keys Information ===${reset}"
|
||||
echo ""
|
||||
|
||||
if [[ ! -d "$BRIDGE_KEYS_DIR" ]]; then
|
||||
echo -e "${red}Keys directory not found: $BRIDGE_KEYS_DIR${reset}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "Keys directory: $BRIDGE_KEYS_DIR"
|
||||
echo "---------------------------------------"
|
||||
|
||||
# List all key files
|
||||
if ls -1 "$BRIDGE_KEYS_DIR"/*.pem >/dev/null 2>&1; then
|
||||
for key_file in "$BRIDGE_KEYS_DIR"/*.pem; do
|
||||
key_name=$(basename "$key_file")
|
||||
echo -e "${green}Key file: $key_name${reset}"
|
||||
|
||||
# If it's a public key, show the content
|
||||
if [[ "$key_name" == *"_bridge_identity.pem" ]]; then
|
||||
echo " Type: ED25519 Bridge Identity (Private)"
|
||||
echo " Path: $key_file"
|
||||
|
||||
# Extract and show public key
|
||||
if command -v openssl >/dev/null 2>&1; then
|
||||
echo -e "${yellow} Public key (base64):${reset}"
|
||||
openssl pkey -in "$key_file" -pubout 2>/dev/null | grep -v "\---" | base64 -d | tail -c 32 | base64
|
||||
fi
|
||||
fi
|
||||
echo ""
|
||||
done
|
||||
else
|
||||
echo -e "${red}No key files found in $BRIDGE_KEYS_DIR${reset}"
|
||||
fi
|
||||
}
|
||||
|
||||
show_bridge_info() {
|
||||
local green="\033[0;32m"
|
||||
local reset="\033[0m"
|
||||
local yellow="\033[0;33m"
|
||||
|
||||
echo -e "${yellow}=== Nym QUIC Bridge Information ===${reset}"
|
||||
echo ""
|
||||
|
||||
# Network interfaces
|
||||
echo -e "${yellow}Network Configuration:${reset}"
|
||||
echo "Primary network device: $network_device"
|
||||
echo "WireGuard interface: $wg_tunnel_interface"
|
||||
|
||||
# Show IP addresses
|
||||
echo ""
|
||||
echo "IPv4 addresses:"
|
||||
ip -4 addr show | grep inet | awk '{print " " $2 " on " $NF}'
|
||||
|
||||
echo ""
|
||||
echo "IPv6 addresses:"
|
||||
ip -6 addr show scope global | grep inet6 | awk '{print " " $2 " on " $NF}'
|
||||
|
||||
echo ""
|
||||
echo -e "${yellow}Bridge Paths:${reset}"
|
||||
echo "Configuration: $BRIDGE_CONFIG_DIR"
|
||||
echo "Keys: $BRIDGE_KEYS_DIR"
|
||||
echo "Binary: $BRIDGE_BINARY"
|
||||
|
||||
echo ""
|
||||
echo -e "${yellow}Important Commands:${reset}"
|
||||
echo " Check bridge status: systemctl status nym-bridge"
|
||||
echo " Check nym-node status: systemctl status nym-node"
|
||||
echo " View bridge logs: journalctl -u nym-bridge -f"
|
||||
echo " View nym-node logs: journalctl -u nym-node -f"
|
||||
echo ""
|
||||
}
|
||||
|
||||
verify_bridge_prerequisites() {
|
||||
local green="\033[0;32m"
|
||||
local reset="\033[0m"
|
||||
local red="\033[0;31m"
|
||||
local yellow="\033[0;33m"
|
||||
|
||||
echo -e "${yellow}=== Verifying Bridge Prerequisites ===${reset}"
|
||||
echo ""
|
||||
|
||||
local all_good=true
|
||||
|
||||
# Check IP forwarding
|
||||
ipv4_forward=$(cat /proc/sys/net/ipv4/ip_forward)
|
||||
ipv6_forward=$(cat /proc/sys/net/ipv6/conf/all/forwarding)
|
||||
|
||||
if [[ "$ipv4_forward" == "1" ]]; then
|
||||
echo -e "${green}✓ IPv4 forwarding enabled${reset}"
|
||||
else
|
||||
echo -e "${red}✗ IPv4 forwarding disabled${reset}"
|
||||
echo " Fix: Run 'nym-bridge-helper adjust_ip_forwarding'"
|
||||
all_good=false
|
||||
fi
|
||||
|
||||
if [[ "$ipv6_forward" == "1" ]]; then
|
||||
echo -e "${green}✓ IPv6 forwarding enabled${reset}"
|
||||
else
|
||||
echo -e "${red}✗ IPv6 forwarding disabled${reset}"
|
||||
echo " Fix: Run 'nym-bridge-helper adjust_ip_forwarding'"
|
||||
all_good=false
|
||||
fi
|
||||
|
||||
# Check iptables-persistent
|
||||
if dpkg -s iptables-persistent >/dev/null 2>&1; then
|
||||
echo -e "${green}✓ iptables-persistent installed${reset}"
|
||||
else
|
||||
echo -e "${red}✗ iptables-persistent not installed${reset}"
|
||||
echo " Fix: This script will auto-install on first run"
|
||||
all_good=false
|
||||
fi
|
||||
|
||||
# Check required packages
|
||||
for pkg in openssl jq curl wg; do
|
||||
if command -v "$pkg" >/dev/null 2>&1; then
|
||||
echo -e "${green}✓ $pkg installed${reset}"
|
||||
else
|
||||
echo -e "${red}✗ $pkg not installed${reset}"
|
||||
if [[ "$pkg" == "wg" ]]; then
|
||||
echo " Install: sudo apt install wireguard-tools"
|
||||
fi
|
||||
all_good=false
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
if [[ "$all_good" == true ]]; then
|
||||
echo -e "${green}All prerequisites satisfied!${reset}"
|
||||
else
|
||||
echo -e "${yellow}Some prerequisites need attention. See above for fixes.${reset}"
|
||||
fi
|
||||
echo ""
|
||||
}
|
||||
|
||||
generate_bridge_keys() {
|
||||
local green="\033[0;32m"
|
||||
local reset="\033[0m"
|
||||
local red="\033[0;31m"
|
||||
local yellow="\033[0;33m"
|
||||
|
||||
echo -e "${yellow}=== Generating Bridge Keys ===${reset}"
|
||||
echo ""
|
||||
|
||||
# Create directories
|
||||
sudo mkdir -p "$BRIDGE_CONFIG_DIR"
|
||||
sudo mkdir -p "$BRIDGE_KEYS_DIR"
|
||||
sudo chmod 700 "$BRIDGE_KEYS_DIR"
|
||||
|
||||
# Generate ED25519 private key
|
||||
local key_file="$BRIDGE_KEYS_DIR/ed25519_bridge_identity.pem"
|
||||
|
||||
if [[ -f "$key_file" ]]; then
|
||||
echo -e "${yellow}Warning: Key file already exists at $key_file${reset}"
|
||||
read -p "Overwrite existing key? (yes/no): " confirm
|
||||
if [[ "$confirm" != "yes" ]]; then
|
||||
echo "Aborted. Keeping existing key."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Generating ED25519 key..."
|
||||
sudo openssl genpkey -algorithm ED25519 -out "$key_file"
|
||||
sudo chmod 600 "$key_file"
|
||||
|
||||
echo -e "${green}✓ Bridge key generated at $key_file${reset}"
|
||||
|
||||
# Extract and display public key
|
||||
echo ""
|
||||
echo "Extracting public key..."
|
||||
pubkey=$(sudo openssl pkey -in "$key_file" -pubout 2>/dev/null | grep -v "\---" | base64 -d | tail -c 32 | base64)
|
||||
echo -e "${green}Public key (base64): $pubkey${reset}"
|
||||
|
||||
echo ""
|
||||
echo -e "${yellow}Next steps:${reset}"
|
||||
echo "1. Run 'nym-bridge-helper create_client_params' to generate client parameters"
|
||||
echo "2. Run 'nym-bridge-helper create_bridge_config' to create bridge configuration"
|
||||
}
|
||||
|
||||
create_client_params() {
|
||||
local green="\033[0;32m"
|
||||
local reset="\033[0m"
|
||||
local red="\033[0;31m"
|
||||
local yellow="\033[0;33m"
|
||||
|
||||
echo -e "${yellow}=== Creating Client Bridge Parameters ===${reset}"
|
||||
echo ""
|
||||
|
||||
# Check if key exists
|
||||
local key_file="$BRIDGE_KEYS_DIR/ed25519_bridge_identity.pem"
|
||||
if [[ ! -f "$key_file" ]]; then
|
||||
echo -e "${red}Error: Bridge key not found at $key_file${reset}"
|
||||
echo "Run 'nym-bridge-helper generate_bridge_keys' first"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Get forward address
|
||||
read -p "Enter forward address (e.g., <IPv4>:51822, can be found by running 'curl -6 https://ifconfig.co/ip'): " forward_addr
|
||||
if [[ -z "$forward_addr" ]]; then
|
||||
echo -e "${red}Error: Forward address is required${reset}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Extract public key
|
||||
echo "Extracting public key..."
|
||||
pubkey=$(sudo openssl pkey -in "$key_file" -pubout 2>/dev/null | grep -v "\---" | base64 -d | tail -c 32 | base64)
|
||||
|
||||
# Create client params JSON
|
||||
echo "Creating client parameters file..."
|
||||
sudo tee "$CLIENT_PARAMS" > /dev/null <<EOF
|
||||
{
|
||||
"ed25519_bridge_identity": "$pubkey",
|
||||
"forward_address": "$forward_addr",
|
||||
"endpoint": {
|
||||
"Quic": {
|
||||
"host": "$forward_addr"
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
sudo chmod 644 "$CLIENT_PARAMS"
|
||||
|
||||
echo -e "${green}✓ Client parameters created at $CLIENT_PARAMS${reset}"
|
||||
echo ""
|
||||
echo "Content:"
|
||||
cat "$CLIENT_PARAMS"
|
||||
}
|
||||
|
||||
create_bridge_config() {
|
||||
local green="\033[0;32m"
|
||||
local reset="\033[0m"
|
||||
local red="\033[0;31m"
|
||||
local yellow="\033[0;33m"
|
||||
|
||||
echo -e "${yellow}=== Creating Bridge Configuration ===${reset}"
|
||||
echo ""
|
||||
|
||||
# Get configuration parameters
|
||||
read -p "Enter listening address (press enter for default: 0.0.0.0): " listen_addr
|
||||
listen_addr=${listen_addr:-0.0.0.0}
|
||||
|
||||
read -p "Enter listening port (press enter for default: 51822): " listen_port
|
||||
listen_port=${listen_port:-51822}
|
||||
|
||||
read -p "Enter tunnel device name (press enter for default: nymwg): " tunnel_dev
|
||||
tunnel_dev=${tunnel_dev:-nymwg}
|
||||
|
||||
read -p "Enter tunnel IPv4 address (press enter for default: 10.1.0.1/24): " tunnel_ipv4
|
||||
tunnel_ipv4=${tunnel_ipv4:-10.1.0.1/24}
|
||||
|
||||
read -p "Enter tunnel IPv6 address (optional, can be found by running 'curl -6 https://ifconfig.co/ip', press enter to skip): " tunnel_ipv6
|
||||
|
||||
read -p "Enter WireGuard private key (or press enter to generate): " wg_privkey
|
||||
if [[ -z "$wg_privkey" ]]; then
|
||||
echo "Generating WireGuard private key..."
|
||||
wg_privkey=$(wg genkey)
|
||||
wg_pubkey=$(echo "$wg_privkey" | wg pubkey)
|
||||
echo -e "${green}Generated WireGuard public key: $wg_pubkey${reset}"
|
||||
fi
|
||||
|
||||
# Create bridges.toml
|
||||
echo "Creating bridge configuration..."
|
||||
sudo tee "$BRIDGE_CONFIG" > /dev/null <<EOF
|
||||
# Nym QUIC Bridge Configuration
|
||||
|
||||
[[bridges]]
|
||||
# Listening address and port for the bridge
|
||||
listening_address = "$listen_addr:$listen_port"
|
||||
|
||||
# WireGuard tunnel configuration
|
||||
tunnel_device_name = "$tunnel_dev"
|
||||
tunnel_device_address = "$tunnel_ipv4"
|
||||
EOF
|
||||
|
||||
if [[ -n "$tunnel_ipv6" ]]; then
|
||||
echo "tunnel_device_ipv6_address = \"$tunnel_ipv6\"" | sudo tee -a "$BRIDGE_CONFIG" > /dev/null
|
||||
fi
|
||||
|
||||
sudo tee -a "$BRIDGE_CONFIG" > /dev/null <<EOF
|
||||
|
||||
# Bridge identity key
|
||||
bridge_identity_private_key_file = "$BRIDGE_KEYS_DIR/ed25519_bridge_identity.pem"
|
||||
|
||||
# WireGuard private key
|
||||
wireguard_private_key = "$wg_privkey"
|
||||
|
||||
# Additional settings
|
||||
bandwidth_controller_port = 51830
|
||||
EOF
|
||||
|
||||
sudo chmod 644 "$BRIDGE_CONFIG"
|
||||
|
||||
echo -e "${green}✓ Bridge configuration created at $BRIDGE_CONFIG${reset}"
|
||||
echo ""
|
||||
echo "Configuration preview:"
|
||||
cat "$BRIDGE_CONFIG"
|
||||
}
|
||||
|
||||
create_bridge_service() {
|
||||
local green="\033[0;32m"
|
||||
local reset="\033[0m"
|
||||
local red="\033[0;31m"
|
||||
local yellow="\033[0;33m"
|
||||
|
||||
echo -e "${yellow}=== Creating nym-bridge systemd Service ===${reset}"
|
||||
echo ""
|
||||
|
||||
# Check if bridge binary exists
|
||||
if [[ ! -f "$BRIDGE_BINARY" ]]; then
|
||||
echo -e "${red}Error: Bridge binary not found at $BRIDGE_BINARY${reset}"
|
||||
echo "Please install the nym-bridge binary first"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check if config exists
|
||||
if [[ ! -f "$BRIDGE_CONFIG" ]]; then
|
||||
echo -e "${red}Error: Bridge config not found at $BRIDGE_CONFIG${reset}"
|
||||
echo "Run 'nym-bridge-helper create_bridge_config' first"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Create systemd service file
|
||||
local service_file="/etc/systemd/system/nym-bridge.service"
|
||||
|
||||
echo "Creating systemd service file..."
|
||||
sudo tee "$service_file" > /dev/null <<EOF
|
||||
[Unit]
|
||||
Description=Nym QUIC Bridge
|
||||
After=network.target nym-node.service
|
||||
Wants=nym-node.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
ExecStart=$BRIDGE_BINARY --config $BRIDGE_CONFIG
|
||||
Restart=on-failure
|
||||
RestartSec=10
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=nym-bridge
|
||||
|
||||
# Security settings
|
||||
NoNewPrivileges=false
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ReadWritePaths=$BRIDGE_CONFIG_DIR
|
||||
|
||||
# Network capabilities
|
||||
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
|
||||
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
echo -e "${green}✓ Systemd service file created at $service_file${reset}"
|
||||
|
||||
# Reload systemd
|
||||
echo "Reloading systemd daemon..."
|
||||
sudo systemctl daemon-reload
|
||||
|
||||
echo ""
|
||||
echo -e "${green}Service created successfully!${reset}"
|
||||
echo ""
|
||||
echo "To enable and start the service:"
|
||||
echo " sudo systemctl enable nym-bridge"
|
||||
echo " sudo systemctl start nym-bridge"
|
||||
echo ""
|
||||
echo "To check status:"
|
||||
echo " sudo systemctl status nym-bridge"
|
||||
}
|
||||
|
||||
install_bridge_binary() {
|
||||
local green="\033[0;32m"
|
||||
local reset="\033[0m"
|
||||
local red="\033[0;31m"
|
||||
local yellow="\033[0;33m"
|
||||
|
||||
echo -e "${yellow}=== Installing nym-bridge Binary ===${reset}"
|
||||
echo ""
|
||||
|
||||
read -p "Enter bridge binary URL for your system from here https://builds.ci.nymte.ch/QUIC/: " binary_url
|
||||
if [[ -z "$binary_url" ]]; then
|
||||
echo -e "${red}Error: Binary URL is required${reset}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "Downloading nym-bridge binary..."
|
||||
if sudo curl -L "$binary_url" -o "$BRIDGE_BINARY"; then
|
||||
sudo chmod 755 "$BRIDGE_BINARY"
|
||||
echo -e "${green}✓ Bridge binary installed at $BRIDGE_BINARY${reset}"
|
||||
|
||||
# Show version
|
||||
echo ""
|
||||
echo "Binary version:"
|
||||
$BRIDGE_BINARY --version || echo "Unable to determine version"
|
||||
else
|
||||
echo -e "${red}✗ Failed to download bridge binary${reset}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
full_bridge_setup() {
|
||||
local green="\033[0;32m"
|
||||
local reset="\033[0m"
|
||||
local yellow="\033[0;33m"
|
||||
|
||||
echo -e "${yellow}========================================${reset}"
|
||||
echo -e "${yellow} Nym QUIC Bridge - Full Setup${reset}"
|
||||
echo -e "${yellow}========================================${reset}"
|
||||
echo ""
|
||||
|
||||
echo "This will guide you through complete bridge setup"
|
||||
echo ""
|
||||
|
||||
# Step 1: Prerequisites
|
||||
echo "Step 1/7: Checking prerequisites..."
|
||||
verify_bridge_prerequisites
|
||||
read -p "Press Enter to continue..."
|
||||
|
||||
# Step 2: Install binary
|
||||
echo ""
|
||||
echo "Step 2/7: Installing bridge binary..."
|
||||
install_bridge_binary
|
||||
read -p "Press Enter to continue..."
|
||||
|
||||
# Step 3: Generate keys
|
||||
echo ""
|
||||
echo "Step 3/7: Generating bridge keys..."
|
||||
generate_bridge_keys
|
||||
read -p "Press Enter to continue..."
|
||||
|
||||
# Step 4: Create client params
|
||||
echo ""
|
||||
echo "Step 4/7: Creating client parameters..."
|
||||
create_client_params
|
||||
read -p "Press Enter to continue..."
|
||||
|
||||
# Step 5: Create bridge config
|
||||
echo ""
|
||||
echo "Step 5/7: Creating bridge configuration..."
|
||||
create_bridge_config
|
||||
read -p "Press Enter to continue..."
|
||||
|
||||
# Step 6: Create service
|
||||
echo ""
|
||||
echo "Step 6/7: Creating systemd service..."
|
||||
create_bridge_service
|
||||
read -p "Press Enter to continue..."
|
||||
|
||||
# Step 7: Network setup
|
||||
echo ""
|
||||
echo "Step 7/7: Configuring network..."
|
||||
adjust_ip_forwarding
|
||||
apply_bridge_iptables_rules
|
||||
configure_dns_and_icmp
|
||||
|
||||
echo ""
|
||||
echo -e "${green}========================================${reset}"
|
||||
echo -e "${green} Bridge Setup Complete!${reset}"
|
||||
echo -e "${green}========================================${reset}"
|
||||
echo ""
|
||||
echo "To start the bridge:"
|
||||
echo " sudo systemctl enable nym-bridge"
|
||||
echo " sudo systemctl start nym-bridge"
|
||||
echo ""
|
||||
echo "To check status:"
|
||||
echo " nym-bridge-helper check_bridge_service_status"
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
fetch_and_display_ipv6)
|
||||
fetch_and_display_ipv6
|
||||
;;
|
||||
fetch_wg_ipv6_address)
|
||||
fetch_wg_ipv6_address
|
||||
;;
|
||||
apply_bridge_iptables_rules)
|
||||
apply_bridge_iptables_rules
|
||||
;;
|
||||
check_bridge_iptables)
|
||||
check_bridge_iptables
|
||||
;;
|
||||
remove_duplicate_bridge_rules)
|
||||
remove_duplicate_bridge_rules
|
||||
;;
|
||||
configure_dns_and_icmp)
|
||||
configure_dns_and_icmp
|
||||
;;
|
||||
adjust_ip_forwarding)
|
||||
adjust_ip_forwarding
|
||||
;;
|
||||
check_ipv6_ipv4_forwarding)
|
||||
check_ipv6_ipv4_forwarding
|
||||
;;
|
||||
check_ip_routing)
|
||||
check_ip_routing
|
||||
;;
|
||||
perform_pings)
|
||||
perform_pings
|
||||
;;
|
||||
test_bridge_connectivity)
|
||||
test_bridge_connectivity
|
||||
;;
|
||||
check_bridge_service_status)
|
||||
check_bridge_service_status
|
||||
;;
|
||||
show_bridge_logs)
|
||||
show_bridge_logs "$2"
|
||||
;;
|
||||
check_bridge_installation)
|
||||
check_bridge_installation
|
||||
;;
|
||||
show_bridge_config)
|
||||
show_bridge_config
|
||||
;;
|
||||
show_bridge_keys)
|
||||
show_bridge_keys
|
||||
;;
|
||||
show_bridge_info)
|
||||
show_bridge_info
|
||||
;;
|
||||
verify_bridge_prerequisites)
|
||||
verify_bridge_prerequisites
|
||||
;;
|
||||
generate_bridge_keys)
|
||||
generate_bridge_keys
|
||||
;;
|
||||
create_client_params)
|
||||
create_client_params
|
||||
;;
|
||||
create_bridge_config)
|
||||
create_bridge_config
|
||||
;;
|
||||
create_bridge_service)
|
||||
create_bridge_service
|
||||
;;
|
||||
install_bridge_binary)
|
||||
install_bridge_binary
|
||||
;;
|
||||
full_bridge_setup)
|
||||
full_bridge_setup
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 [command] [options]"
|
||||
echo ""
|
||||
echo "Nym QUIC Bridge Deployment Helper Script"
|
||||
echo ""
|
||||
echo "Bridge Installation & Configuration:"
|
||||
echo " check_bridge_installation - Check bridge installation status"
|
||||
echo " show_bridge_config - Display bridge configuration files"
|
||||
echo " show_bridge_keys - Display bridge key information"
|
||||
echo " show_bridge_info - Show comprehensive bridge information"
|
||||
echo " verify_bridge_prerequisites - Verify all prerequisites are met"
|
||||
echo ""
|
||||
echo "Bridge Setup Commands:"
|
||||
echo " install_bridge_binary - Download and install nym-bridge binary"
|
||||
echo " generate_bridge_keys - Generate ED25519 bridge identity keys"
|
||||
echo " create_client_params - Create client_bridge_params.json"
|
||||
echo " create_bridge_config - Create bridges.toml configuration"
|
||||
echo " create_bridge_service - Create systemd service file"
|
||||
echo " full_bridge_setup - Interactive full bridge setup wizard"
|
||||
echo ""
|
||||
echo "Network Configuration Commands:"
|
||||
echo " adjust_ip_forwarding - Enable IPv4 and IPv6 forwarding"
|
||||
echo " apply_bridge_iptables_rules - Apply iptables rules for QUIC bridge (nymwg)"
|
||||
echo " configure_dns_and_icmp - Allow ICMP ping tests and configure DNS"
|
||||
echo " remove_duplicate_bridge_rules - Remove duplicate iptables rules for nymwg"
|
||||
echo ""
|
||||
echo "Network Inspection Commands:"
|
||||
echo " fetch_and_display_ipv6 - Show IPv6 on default network device"
|
||||
echo " fetch_wg_ipv6_address - Fetch IPv6 for nymwg interface"
|
||||
echo " check_bridge_iptables - Check iptables rules for nymwg"
|
||||
echo " check_ipv6_ipv4_forwarding - Check IPv4 and IPv6 forwarding status"
|
||||
echo " check_ip_routing - Display IP routing tables"
|
||||
echo ""
|
||||
echo "Testing Commands:"
|
||||
echo " perform_pings - Test IPv4 and IPv6 connectivity"
|
||||
echo " test_bridge_connectivity - Comprehensive bridge connectivity test"
|
||||
echo ""
|
||||
echo "Service Management Commands:"
|
||||
echo " check_bridge_service_status - Check nym-bridge and nym-node service status"
|
||||
echo " show_bridge_logs [lines] - Show recent nym-bridge logs (default: 50 lines)"
|
||||
echo ""
|
||||
echo "Quick Start:"
|
||||
echo " 1. Run 'verify_bridge_prerequisites' to check prerequisites"
|
||||
echo " 2. Run 'check_bridge_installation' to verify installation"
|
||||
echo " 3. Run 'test_bridge_connectivity' to test connectivity"
|
||||
echo ""
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "Operation '$1' completed successfully."
|
||||
|
||||
@@ -31,6 +31,7 @@ use nym_crypto::hkdf::DerivationMaterial;
|
||||
use nym_socks5_client_core::config::Socks5;
|
||||
use nym_task::ShutdownTracker;
|
||||
use nym_topology::provider_trait::TopologyProvider;
|
||||
use nym_topology::RoutingNode;
|
||||
use nym_validator_client::{nyxd, QueryHttpRpcNyxdClient, UserAgent};
|
||||
use rand::rngs::OsRng;
|
||||
use std::path::Path;
|
||||
@@ -530,27 +531,37 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
async fn new_gateway_setup(&self) -> Result<GatewaySetup, ClientCoreError> {
|
||||
/// Attempt to retrieve list of all gateways available for registration
|
||||
async fn available_gateways(&mut self) -> Result<Vec<RoutingNode>, ClientCoreError> {
|
||||
if let Some(ref mut custom_provider) = self.custom_topology_provider {
|
||||
if let Some(topology) = custom_provider.get_new_topology().await {
|
||||
return Ok(topology.entry_gateways().cloned().collect());
|
||||
}
|
||||
}
|
||||
|
||||
let nym_api_endpoints = self.get_api_endpoints();
|
||||
|
||||
let selection_spec = GatewaySelectionSpecification::new(
|
||||
self.config.user_chosen_gateway.clone(),
|
||||
None,
|
||||
self.force_tls,
|
||||
);
|
||||
|
||||
let user_agent = self.user_agent.clone();
|
||||
|
||||
let topology_cfg = &self.config.debug_config.topology;
|
||||
let user_agent = self.user_agent.clone();
|
||||
let mut rng = OsRng;
|
||||
let available_gateways = gateways_for_init(
|
||||
|
||||
gateways_for_init(
|
||||
&mut rng,
|
||||
&nym_api_endpoints,
|
||||
user_agent,
|
||||
topology_cfg.minimum_gateway_performance,
|
||||
topology_cfg.ignore_ingress_epoch_role,
|
||||
)
|
||||
.await?;
|
||||
.await
|
||||
}
|
||||
|
||||
async fn new_gateway_setup(&mut self) -> Result<GatewaySetup, ClientCoreError> {
|
||||
let selection_spec = GatewaySelectionSpecification::new(
|
||||
self.config.user_chosen_gateway.clone(),
|
||||
None,
|
||||
self.force_tls,
|
||||
);
|
||||
|
||||
let available_gateways = self.available_gateways().await?;
|
||||
|
||||
Ok(GatewaySetup::New {
|
||||
specification: selection_spec,
|
||||
@@ -759,7 +770,7 @@ where
|
||||
client_output,
|
||||
client_state.clone(),
|
||||
nym_address,
|
||||
started_client.shutdown_handle.child_tracker(),
|
||||
started_client.shutdown_handle.clone(),
|
||||
packet_type,
|
||||
);
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ use std::pin::Pin;
|
||||
use std::sync::Arc;
|
||||
use std::task::{Context, Poll};
|
||||
use tokio::sync::RwLockReadGuard;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
|
||||
/// Client connected to the Nym mixnet.
|
||||
pub struct MixnetClient {
|
||||
@@ -124,9 +123,9 @@ impl MixnetClient {
|
||||
}
|
||||
|
||||
/// Get a child token of the root, to monitor unexpected shutdown, without causing one
|
||||
pub fn cancellation_token(&self) -> CancellationToken {
|
||||
self.shutdown_handle.child_shutdown_token().inner().clone()
|
||||
}
|
||||
// pub fn cancellation_token(&self) -> CancellationToken {
|
||||
// self.shutdown_handle.child_shutdown_token().inner().clone()
|
||||
// }
|
||||
|
||||
pub fn client_request_sender(&self) -> ClientRequestSender {
|
||||
self.client_request_sender.clone()
|
||||
@@ -199,6 +198,13 @@ impl MixnetClient {
|
||||
self.client_state.topology_accessor.release_manual_control()
|
||||
}
|
||||
|
||||
/// Returns a shutdown event handle that can be used for waiting for the client to shutdown.
|
||||
pub fn shutdown_event(&self) -> ShutdownEventHandle {
|
||||
ShutdownEventHandle {
|
||||
shutdown_handle: self.shutdown_handle.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Wait for messages from the mixnet
|
||||
pub async fn wait_for_messages(&mut self) -> Option<Vec<ReconstructedMessage>> {
|
||||
self.reconstructed_receiver.next().await
|
||||
@@ -340,3 +346,16 @@ impl MixnetMessageSender for MixnetClientSender {
|
||||
.map_err(|_| Error::MessageSendingFailure)
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle for waiting on the shutdown event of the mixnet client.
|
||||
pub struct ShutdownEventHandle {
|
||||
shutdown_handle: ShutdownTracker,
|
||||
}
|
||||
|
||||
impl ShutdownEventHandle {
|
||||
/// Returns once mixnet client has been shut down.
|
||||
/// If mixnet client is already shut down, returns immediately.
|
||||
pub async fn wait(&self) {
|
||||
self.shutdown_handle.wait_for_tracker().await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,48 +3,110 @@
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*/
|
||||
|
||||
-- 1. Rename old table to preserve data
|
||||
ALTER TABLE network
|
||||
RENAME TO network_old;
|
||||
|
||||
CREATE TABLE network_old
|
||||
-- 2. Insert placeholder account (so that old networks would have _some_ value for performance contract)
|
||||
INSERT INTO account (address, mnemonic)
|
||||
VALUES ('n1tq2kggc6y44yqmnafh98vexxav8666cfkgvygf',
|
||||
'opinion scene salon slice noise easy security drift brown custom verb express old matrix mammal choose attract trash general staff manual elite destroy strategy');
|
||||
|
||||
-- 3. Insert placeholder contract and record its id
|
||||
INSERT INTO contract (name, address, admin_address)
|
||||
VALUES ('placeholder', 'n14gl07zh58rydd4k9tyw320zvqd79vrwnjj4x9g', 'n1tq2kggc6y44yqmnafh98vexxav8666cfkgvygf');
|
||||
|
||||
CREATE TEMP TABLE tmp_placeholder
|
||||
(
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL,
|
||||
|
||||
mixnet_contract_id INTEGER NOT NULL REFERENCES contract (id),
|
||||
vesting_contract_id INTEGER NOT NULL REFERENCES contract (id),
|
||||
ecash_contract_id INTEGER NOT NULL REFERENCES contract (id),
|
||||
cw3_multisig_contract_id INTEGER NOT NULL REFERENCES contract (id),
|
||||
cw4_group_contract_id INTEGER NOT NULL REFERENCES contract (id),
|
||||
dkg_contract_id INTEGER NOT NULL REFERENCES contract (id),
|
||||
|
||||
rewarder_address TEXT NOT NULL REFERENCES account (address),
|
||||
ecash_holding_account_address TEXT NOT NULL REFERENCES account (address)
|
||||
id INTEGER NOT NULL
|
||||
);
|
||||
INSERT INTO tmp_placeholder
|
||||
VALUES (last_insert_rowid());
|
||||
|
||||
INSERT INTO network_old
|
||||
SELECT *
|
||||
from network;
|
||||
|
||||
DROP TABLE network;
|
||||
|
||||
-- 4. Create the new network table with the new column
|
||||
CREATE TABLE network
|
||||
(
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL,
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL,
|
||||
|
||||
mixnet_contract_id INTEGER NOT NULL REFERENCES contract (id),
|
||||
vesting_contract_id INTEGER NOT NULL REFERENCES contract (id),
|
||||
ecash_contract_id INTEGER NOT NULL REFERENCES contract (id),
|
||||
cw3_multisig_contract_id INTEGER NOT NULL REFERENCES contract (id),
|
||||
cw4_group_contract_id INTEGER NOT NULL REFERENCES contract (id),
|
||||
dkg_contract_id INTEGER NOT NULL REFERENCES contract (id),
|
||||
performance_contract_id INTEGER NOT NULL REFERENCES contract (id),
|
||||
mixnet_contract_id INTEGER NOT NULL REFERENCES contract (id),
|
||||
vesting_contract_id INTEGER NOT NULL REFERENCES contract (id),
|
||||
ecash_contract_id INTEGER NOT NULL REFERENCES contract (id),
|
||||
cw3_multisig_contract_id INTEGER NOT NULL REFERENCES contract (id),
|
||||
cw4_group_contract_id INTEGER NOT NULL REFERENCES contract (id),
|
||||
dkg_contract_id INTEGER NOT NULL REFERENCES contract (id),
|
||||
performance_contract_id INTEGER NOT NULL REFERENCES contract (id),
|
||||
|
||||
rewarder_address TEXT NOT NULL REFERENCES account (address),
|
||||
ecash_holding_account_address TEXT NOT NULL REFERENCES account (address)
|
||||
rewarder_address TEXT NOT NULL REFERENCES account (address),
|
||||
ecash_holding_account_address TEXT NOT NULL REFERENCES account (address)
|
||||
);
|
||||
|
||||
-- 5. Copy existing data into the new table
|
||||
INSERT INTO network(id, name, created_at,
|
||||
mixnet_contract_id, vesting_contract_id, ecash_contract_id,
|
||||
cw3_multisig_contract_id, cw4_group_contract_id, dkg_contract_id,
|
||||
performance_contract_id,
|
||||
rewarder_address, ecash_holding_account_address)
|
||||
SELECT n.id,
|
||||
n.name,
|
||||
n.created_at,
|
||||
n.mixnet_contract_id,
|
||||
n.vesting_contract_id,
|
||||
n.ecash_contract_id,
|
||||
n.cw3_multisig_contract_id,
|
||||
n.cw4_group_contract_id,
|
||||
n.dkg_contract_id,
|
||||
t.id, -- use the placeholder contract id
|
||||
n.rewarder_address,
|
||||
n.ecash_holding_account_address
|
||||
FROM network_old AS n
|
||||
CROSS JOIN tmp_placeholder AS t;
|
||||
|
||||
-- 6. recreate metadata table due to change in FK
|
||||
ALTER TABLE metadata
|
||||
RENAME TO metadata_old;
|
||||
|
||||
CREATE TABLE metadata
|
||||
(
|
||||
id INTEGER PRIMARY KEY CHECK (id = 0),
|
||||
latest_network_id INTEGER REFERENCES network (id),
|
||||
|
||||
master_mnemonic TEXT NOT NULL,
|
||||
rpc_endpoint TEXT NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO metadata
|
||||
SELECT *
|
||||
FROM metadata_old;
|
||||
|
||||
-- 7. recreate node table due to change in FK
|
||||
ALTER Table node
|
||||
RENAME TO node_old;
|
||||
|
||||
CREATE TABLE node
|
||||
(
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
identity_key TEXT NOT NULL,
|
||||
network_id INTEGER NOT NULL REFERENCES network (id),
|
||||
|
||||
-- i.e. mixnode or gateway
|
||||
bonded_type TEXT NOT NULL,
|
||||
owner_address TEXT NOT NULL REFERENCES account (address)
|
||||
);
|
||||
|
||||
INSERT INTO node
|
||||
SELECT *
|
||||
FROM node_old;
|
||||
|
||||
-- 8. Clean up
|
||||
DROP TABLE tmp_placeholder;
|
||||
DROP TABLE metadata_old;
|
||||
DROP TABLE node_old;
|
||||
DROP TABLE network_old;
|
||||
|
||||
|
||||
CREATE TABLE authorised_network_monitor
|
||||
(
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
|
||||
Reference in New Issue
Block a user